diff options
-rw-r--r-- | Changelog-Trunk.txt | 12 | ||||
-rw-r--r-- | db/skill_cast_db.txt | 4 | ||||
-rw-r--r-- | db/skill_unit_db.txt | 2 | ||||
-rw-r--r-- | src/map/battle.c | 10 | ||||
-rw-r--r-- | src/map/map.h | 3 | ||||
-rw-r--r-- | src/map/mob.c | 22 | ||||
-rw-r--r-- | src/map/npc.c | 9 | ||||
-rw-r--r-- | src/map/skill.c | 67 |
8 files changed, 68 insertions, 61 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index a280c72f3..492399d8f 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,18 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2006/08/07
+ * Fixed HT_BLITZBEAT hitting neutral characters when it auto-triggers.
+ [Skotlex]
+ * Simplified the Tatami Gaeshi code. [Skotlex]
+ * Fixed AS_SPLASHER doing full damage on everyone except targetted char
+ instead of the other way around. [Skotlex]
+ * Fixed KAENSIN clearing out SUITON cells and viceversa. [Skotlex]
+ * The spawn area is now seen as range rather than absolute for mob spawn
+ lines. This means that x,y,10,10 will spawn the mob on a 21x21 grid around
+ the given x,y point. [Skotlex]
+ * Some clean up of the mob-spawn code. Now you can specify negative areas,
+ so that a spawn location such as 100,150,0,-1 will spawn a mob always on
+ x=100, but any Y value of the current map. [Skotlex]
* Reflected damage will now also have a chance of draining hp/sp. [Skotlex]
* Adjusted the order in which option/sc change packets are sent to match
Aegis's [Skotlex]
diff --git a/db/skill_cast_db.txt b/db/skill_cast_db.txt index 27d99c583..4540481ce 100644 --- a/db/skill_cast_db.txt +++ b/db/skill_cast_db.txt @@ -885,8 +885,8 @@ 525,1000,1000,0,0,0
//-- NJ_ZENYNAGE
526,0,5000,0,0,0
-//-- NJ_TATAMIGAESHI // Duration1 used for SC_TATAMIGAESHI and ground visual effect and Duration2 for "damage-can-be-done" duration
-527,0,3000,0,3000,200 // ex> Skill will only hit during 200 first ticks (concretely do only 1 hit just after being casted)
+//-- NJ_TATAMIGAESHI // Duration1 is land-effect. Duration2 is the range-inmunity effect
+527,0,3000,0,500,3000
//-- NJ_KASUMIKIRI // Delay unknown (if there is one)
528,0,0,0,30000:60000:90000:120000:150000:180000:210000:240000:270000:300000,0
//-- NJ_SHADOWJUMP // Delay unknown (if there is one)
diff --git a/db/skill_unit_db.txt b/db/skill_unit_db.txt index 6e39ac2a2..78b9eddb1 100644 --- a/db/skill_unit_db.txt +++ b/db/skill_unit_db.txt @@ -89,6 +89,6 @@ 488,0xb9, , 3, 0, -1,all, 0x200 //CG_HERMODE
516,0xba, , 0, 3, 100,enemy, 0x000 //GS_DESPERADO
521,0xc2, , 0, 1,1000,enemy, 0x006 //GS_GROUNDDRIFT
-527,0xbc, , -1, 0,2500,enemy, 0x000 //NJ_TATAMIGAESHI
+527,0xbc, , -1, 0,1000,enemy, 0x000 //NJ_TATAMIGAESHI
535,0xbd, , -1, 0, 200,enemy, 0x008 //NJ_KAENSIN
538,0xbb,,1:1:1:2:2:2:3:3:3:4,0,-1,all,0x000 //NJ_SUITON
diff --git a/src/map/battle.c b/src/map/battle.c index 9b846e82c..13bca77a4 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2276,21 +2276,13 @@ struct Damage battle_calc_magic_attack( switch(skill_num){ case MG_NAPALMBEAT: + case MG_FIREBALL: skillratio += skill_lv*10-30; break; case MG_SOULSTRIKE: if (battle_check_undead(tstatus->race,tstatus->def_ele)) skillratio += 5*skill_lv; break; - case MG_FIREBALL: - if(mflag>2) - ad.damage = 0; - else { - int drate[]={100,90,70}; - MATK_RATE(drate[mflag]); - skillratio += 70+10*skill_lv; - } - break; case MG_FIREWALL: skillratio -= 50; break; diff --git a/src/map/map.h b/src/map/map.h index 68fd25d7b..071bec81c 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -859,7 +859,8 @@ struct guardian_data { // Expanded to specify all mob-related spawn data by [Skotlex]
struct spawn_data {
short class_; //Class, used because a mob can change it's class
- unsigned short m,x,y,xs,ys; //Spawn information (map, point, spawn-area around point)
+ unsigned short m,x,y; //Spawn information (map, point, spawn-area around point)
+ signed short xs,ys;
unsigned short num; //Number of mobs using this structure.
unsigned int level; //Custom level.
unsigned int delay1,delay2; //Min delay before respawning after spawn/death
diff --git a/src/map/mob.c b/src/map/mob.c index 15cb12e6b..a7832a972 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -633,28 +633,18 @@ int mob_spawn (struct mob_data *md) if (md->spawn) { //Respawn data md->bl.m = md->spawn->m; + md->bl.x = md->spawn->x; + md->bl.y = md->spawn->y; - if ((md->spawn->x == 0 && md->spawn->y == 0) || md->spawn->xs || md->spawn->ys) + if ((md->bl.x == 0 && md->bl.y == 0) || md->spawn->xs || md->spawn->ys) { //Monster can be spawned on an area. - short x, y, xs, ys; - if (md->spawn->x == 0 && md->spawn->y == 0) - x = y = xs = ys = -1; - else { - x = md->spawn->x; - y = md->spawn->y; - xs = md->spawn->xs/2; - ys = md->spawn->ys/2; - } - if (!map_search_freecell(NULL, md->spawn->m, &x, &y, xs, ys, battle_config.no_spawn_on_player?5:1)) { + if (!map_search_freecell(NULL, -1, + &md->bl.x, &md->bl.y, md->spawn->xs, md->spawn->ys, + battle_config.no_spawn_on_player?4:0)) { // retry again later add_timer(tick+5000,mob_delayspawn,md->bl.id,0); return 1; } - md->bl.x = x; - md->bl.y = y; - } else { - md->bl.x = md->spawn->x; - md->bl.y = md->spawn->y; } } memset(&md->state, 0, sizeof(md->state)); diff --git a/src/map/npc.c b/src/map/npc.c index 0ebec7aaf..90345feea 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -2209,17 +2209,18 @@ int npc_parse_mob (char *w1, char *w2, char *w3, char *w4) mob.class_ = (short) class_;
mob.x = (unsigned short)x;
mob.y = (unsigned short)y;
- mob.xs = (unsigned short)xs;
- mob.ys = (unsigned short)ys;
+ mob.xs = (signed short)xs;
+ mob.ys = (signed short)ys;
if (mob.num > 1 && battle_config.mob_count_rate != 100) {
if ((mob.num = mob.num * battle_config.mob_count_rate / 100) < 1)
mob.num = 1;
}
- if (battle_config.force_random_spawn)
+ if (battle_config.force_random_spawn || (mob.x == 0 && mob.y == 0))
{ //Force a random spawn anywhere on the map.
- mob.x = mob.y = mob.xs = mob.ys = 0;
+ mob.x = mob.y = 0;
+ mob.xs = mob.ys = -1;
}
//Apply the spawn delay fix [Skotlex]
diff --git a/src/map/skill.c b/src/map/skill.c index 60802d79a..2fb5ce253 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -2082,10 +2082,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds //Only knockback if it's still alive, otherwise a "ghost" is left behind. [Skotlex] if (dmg.blewcount > 0 && !status_isdead(bl)) - { - if ( skillid != NJ_TATAMIGAESHI ) skill_blown(dsrc,bl,dmg.blewcount); - else skill_blown(src,bl,dmg.blewcount); - } + skill_blown(skillid==NJ_TATAMIGAESHI?src:dsrc,bl,dmg.blewcount); //Delayed damage must be dealt after the knockback (it needs to know actual position of target) if (dmg.amotion) @@ -2830,8 +2827,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int //Splash attack skills. case AS_SPLASHER: - if ( (flag&1) && bl->id != skill_area_temp[1] ) - { + if ((flag&1) && bl->id == skill_area_temp[1]) + { //Should do 100% damage on targetted character. skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, 1); break; } @@ -2842,19 +2839,21 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int case MG_NAPALMBEAT: case MG_FIREBALL: case HW_NAPALMVULCAN: - case HT_BLITZBEAT: case NJ_HUUMA: case NJ_BAKUENRYU: - if (flag & 1) { //Invoked from map_foreachinarea, skill_area_temp[0] holds number of targets to divide damage by. + if (flag&1) //Invoked from map_foreachinarea, skill_area_temp[0] holds number of targets to divide damage by. skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, skill_area_temp[0]); - } else { + else { if ( skillid == NJ_BAKUENRYU ) clif_skill_nodamage(src,bl,skillid,skilllv,1); skill_area_temp[0] = 0; skill_area_temp[1] = bl->id; - if ( (skill_get_nk(skillid)&NK_SPLASHSPLIT) || (skillid==HT_BLITZBEAT && flag&0xf00000) ) //Warning, 0x100000 is currently BCT_NEUTRAL, so don't mix it when asking for the enemy. [Skotlex] + if (skill_get_nk(skillid)&NK_SPLASHSPLIT) map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), BL_CHAR, - src, skillid, skilllv, tick, flag|BCT_ENEMY, skill_area_sub_count); + src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count); + else + skill_area_temp[0] = 1; + map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), BL_CHAR, src, skillid, skilllv, tick, flag|BCT_ENEMY|1, @@ -2862,6 +2861,26 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int } break; + //Done apart because you can't mix the flag with BCT_ENEMY for auto-blitz. + case HT_BLITZBEAT: + if (flag&1) //Warning, 0x100000 is currently BCT_NEUTRAL, so don't mix it when asking for the enemy. [Skotlex] + skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, skill_area_temp[0]); + else { + skill_area_temp[0] = 0; + skill_area_temp[1] = bl->id; + //Warning, 0x100000 is currently BCT_NEUTRAL, so don't mix it when asking for the enemy. [Skotlex] + if (skillid==HT_BLITZBEAT && flag&0xf00000) + map_foreachinrange(skill_area_sub, bl, + skill_get_splash(skillid, skilllv), BL_CHAR, + src, skillid, skilllv, tick, BCT_ENEMY, skill_area_sub_count); + else + skill_area_temp[0] = 1; + map_foreachinrange(skill_area_sub, bl, + skill_get_splash(skillid, skilllv), BL_CHAR, + src, skillid, skilllv, tick, BCT_ENEMY|1, + skill_castend_damage_id); + } + break; case SM_MAGNUM: if(flag&1) skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); @@ -3110,8 +3129,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int int dir = map_calc_dir(src,bl->x,bl->y); status_change_end(src, SC_HIDING, -1); skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag); - if (unit_movepos(src, bl->x - dirx[dir], bl->y - diry[dir], 0, 0)) // fixed... sorry for this o_O - clif_slide(src,bl->x - dirx[dir],bl->y - diry[dir]); + if (unit_movepos(src, bl->x - dirx[dir], bl->y - diry[dir], 0, 0)) + clif_slide(src,src->x,src->y); } break; case NJ_ISSEN: @@ -6221,7 +6240,7 @@ int skill_castend_pos2 (struct block_list *src, int x, int y, int skillid, int s } break; case NJ_TATAMIGAESHI: - sc_start(src,type,100,skilllv,skill_get_time(skillid,skilllv)); + sc_start(src,type,100,skilllv,skill_get_time2(skillid,skilllv)); skill_unitsetting(src,skillid,skilllv,src->x,src->y,0); break; @@ -6632,7 +6651,7 @@ struct skill_unit_group *skill_unitsetting (struct block_list *src, int skillid, if (sd) val1 = sd->status.child; break; case NJ_KAENSIN: - skill_clear_group(src, 1); //Delete previous Kaensins + skill_clear_group(src, 4); //Delete previous Kaensins val2 = (skilllv+1)/2 + 4; break; @@ -7157,17 +7176,6 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns } case UNT_TATAMIGAESHI: - { - struct skill_unit_group *sug; // better name needed :D - - if ( (sug = map_find_skill_unit_oncell(bl,bl->x,bl->y,NJ_TATAMIGAESHI,NULL)->group) != NULL ) - { - if ( DIFF_TICK(gettick(), sug->tick) <= skill_get_time2(sg->skill_id, sg->skill_lv) ) - skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); - } - break; - } - case UNT_DEMONSTRATION: skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0); break; @@ -9144,10 +9152,13 @@ int skill_clear_group (struct block_list *bl, int flag) case SA_VIOLENTGALE: case SA_LANDPROTECTOR: case NJ_SUITON: - case NJ_KAENSIN: if (flag&1) group[count++]= ud->skillunit[i]; break; + case NJ_KAENSIN: + if (flag&4) + group[count++]= ud->skillunit[i]; + break; default: if (flag&2 && skill_get_inf2(ud->skillunit[i]->skill_id)&INF2_TRAP) group[count++]= ud->skillunit[i]; @@ -9259,7 +9270,7 @@ int skill_landprotector (struct block_list *bl, va_list ap) case NJ_SUITON: case NJ_KAENSIN: switch (unit->group->skill_id) - { //These override each other. + { //These cannot override each other. case SA_VOLCANO: case SA_DELUGE: case SA_VIOLENTGALE: |