From 81a85e322a784f6237b1948c53dca39bffb42f18 Mon Sep 17 00:00:00 2001 From: Inkfish Date: Thu, 7 May 2009 12:15:14 +0000 Subject: * Fixed splash damage from Baphomet Card might miss. [Inkfish] * Check if group unit is expired before processing it. (bugreport:3054) [Inkfish] * Fixed Grand Corss outdated behavior (bugreport:1590) [Inkfish] - use new damage formula - DEF is reduced to 2/3 during cast time - block shields switching within attack duration - monsters don't damage themselves any more - intervals between hits are 300ms git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13736 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 13 +++++++++--- db/skill_unit_db.txt | 4 ++-- src/map/battle.c | 58 +++++++++++++++++++++++++-------------------------- src/map/skill.c | 59 +++++++++++++++++++++++++++++++++------------------- src/map/status.c | 2 ++ src/map/unit.c | 40 ++++++++++++++++++++++++++--------- 6 files changed, 110 insertions(+), 66 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index dacb7f899..1ff24936c 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -2,9 +2,16 @@ Date Added AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. - -2009/05/07 - * Added check on stackable items to 'checkweight' (bugreport:1569, bugreport:2756, bugreport 2994) [Inkfish] +09/05/07 + * Fixed splash damage from Baphomet Card might miss. [Inkfish] + * Check if group unit is expired before processing it. (bugreport:3054) [Inkfish] + * Fixed Grand Corss outdated behavior (bugreport:1590) [Inkfish] + - use new damage formula + - DEF is reduced to 2/3 during cast time + - block shields switching within attack duration + - monsters don't damage themselves any more + - intervals between hits are 300ms + * Added check on stackable items to 'checkweight' (bugreport:1569, bugreport:2756, bugreport:2994) [Inkfish] * Fixed flee penalty wasn't applied for battleground and wouldn't be restored on map change [Inkfish] * Fixed players can pull water from ME cell (follow up to r13730) [Inkfish] 2009/05/04 diff --git a/db/skill_unit_db.txt b/db/skill_unit_db.txt index aa7e60c7e..8cfab0c26 100644 --- a/db/skill_unit_db.txt +++ b/db/skill_unit_db.txt @@ -52,7 +52,7 @@ 140,0x92, , -1, 0,1000,enemy, 0x000 //AS_VENOMDUST 220,0xb0, , 0, 0, -1,all, 0x002 //RG_GRAFFITI 229,0xb1, , 0, 1,1000,enemy, 0x006 //AM_DEMONSTRATION -254,0x86, , -1, 0, 400,enemy, 0x010 //CR_GRANDCROSS +254,0x86, , -1, 0, 300,enemy, 0x010 //CR_GRANDCROSS 285,0x9a, , 3, 0, -1,all, 0x010 //SA_VOLCANO 286,0x9b, , 3, 0, -1,all, 0x010 //SA_DELUGE 287,0x9c, , 3, 0, -1,all, 0x010 //SA_VIOLENTGALE @@ -76,7 +76,7 @@ 329,0xae, , 3, 0, -1,all, 0x140 //DC_FORTUNEKISS 330,0xaf, , 3, 0, -1,all, 0x140 //DC_SERVICEFORYOU 336,0xb2, , 0,-1, -1,noone, 0x000 //WE_CALLPARTNER -339,0x86, , -1, 0, 400,enemy, 0x000 //NPC_DARKGRANDCROSS +339,0x86, , -1, 0, 300,enemy, 0x000 //NPC_DARKGRANDCROSS 362,0xb4, , 0, 2, 300,all, 0x000 //HP_BASILICA 369,0xb3, , -1, 0,10000,all, 0x008 //PA_GOSPEL 395,0xb5, , 4, 0, -1,all, 0x200 //CG_MOONLIT diff --git a/src/map/battle.c b/src/map/battle.c index 9d6ead21e..2b9443e82 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -141,7 +141,7 @@ struct block_list* battle_getenemy(struct block_list *target, int type, int rang return bl_list[rand()%c]; } -// ƒ_ƒ??[ƒW‚Ì’x‰„ +// ƒ_??[ƒW‚Ì’x‰„ struct delay_damage { struct block_list *src; int target; @@ -268,7 +268,7 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag } /*========================================== - * ƒ_ƒ??[ƒW?Å?IŒvŽZ + * ƒ_??[ƒW??IŒvŽZ *------------------------------------------*/ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,int div_,int skill_num,int skill_lv,int flag) { @@ -645,7 +645,7 @@ static int battle_calc_drain(int damage, int rate, int per) } /*========================================== - * ?C—ûƒ_ƒ??[ƒW + * ?C—ûƒ_??[ƒW *------------------------------------------*/ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int dmg,int type) { @@ -1116,21 +1116,19 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo flag.hit = 1; //SG_FUSION always hit [Komurka] flag.idef = flag.idef2 = 1; //def ignore [Komurka] } - if (skill_num && !flag.hit) + if( !flag.hit ) switch(skill_num) { case AS_SPLASHER: - if (wflag) // Always hits the one exploding. - break; - flag.hit = 1; + if( !wflag ) // Always hits the one exploding. + flag.hit = 1; break; case CR_SHIELDBOOMERANG: - if (sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_CRUSADER) + if( sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_CRUSADER ) flag.hit = 1; break; - case 0: - //If flag, this is splash damage from Baphomet Card and it always hits. - if (wflag) + case 0: + if( wflag ) //If flag, this is splash damage from Baphomet Card and it always hits. flag.hit = 1; break; } @@ -1888,9 +1886,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo else if(wd.div_ < 0) //Since the attack missed... wd.div_ *= -1; - if(skill_num == CR_GRANDCROSS || skill_num == NPC_GRANDDARKNESS) - return wd; //Enough, rest is not needed. - if(sd && (skill=pc_checkskill(sd,BS_WEAPONRESEARCH)) > 0) ATK_ADD(skill*2); @@ -1918,6 +1913,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo } } + if(skill_num == CR_GRANDCROSS || skill_num == NPC_GRANDDARKNESS) + return wd; //Enough, rest is not needed. + if (sd) { if (skill_num != CR_SHIELDBOOMERANG) //Only Shield boomerang doesn't takes the Star Crumbs bonus. @@ -2462,19 +2460,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list else ad.damage = ad.damage * (100-mdef)/100 - mdef2; } - - if(skill_num == CR_GRANDCROSS || skill_num == NPC_GRANDDARKNESS) - { //Apply the physical part of the skill's damage. [Skotlex] - struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag); - ad.damage = (wd.damage + ad.damage) * (100 + 40*skill_lv)/100; - if(src==target) - { - if (src->type == BL_PC) - ad.damage = ad.damage/2; - else - ad.damage = 0; - } - } if (skill_num == NPC_EARTHQUAKE) { //Adds atk2 to the damage, should be influenced by number of hits and skill-ratio, but not mdef reductions. [Skotlex] @@ -2491,6 +2476,19 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list if (!(nk&NK_NO_ELEFIX)) ad.damage=battle_attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv); + if( skill_num == CR_GRANDCROSS || skill_num == NPC_GRANDDARKNESS ) + { //Apply the physical part of the skill's damage. [Skotlex] + struct Damage wd = battle_calc_weapon_attack(src,target,skill_num,skill_lv,mflag); + ad.damage = battle_attr_fix(src, target, wd.damage + ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv); + if( src == target ) + { + if( src->type == BL_PC ) + ad.damage = ad.damage/2; + else + ad.damage = 0; + } + } + if (sd && !(nk&NK_NO_CARDFIX_ATK)) { short t_class = status_get_class(target); short cardfix=1000; @@ -2561,7 +2559,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list } /*========================================== - * ‚»‚Ì‘¼ƒ_ƒ??[ƒWŒvŽZ + * ‚»‚Ì‘¼ƒ_??[ƒWŒvŽZ *------------------------------------------*/ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,int skill_num,int skill_lv,int mflag) { @@ -2797,7 +2795,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * return md; } /*========================================== - * ƒ_ƒ??[ƒWŒvŽZˆêŠ‡?ˆ—?—p + * ƒ_??[ƒWŒvŽZˆêŠ‡?ˆ—?—p *------------------------------------------*/ struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,int skill_num,int skill_lv,int count) { @@ -2899,7 +2897,7 @@ void battle_drain(TBL_PC *sd, struct block_list *tbl, int rdamage, int ldamage, } /*========================================== - * ’Ê?í?UŒ‚?ˆ—?‚Ü‚Æ‚ß + * ’Ê??UŒ‚?ˆ—?‚Ü‚Æ‚ß *------------------------------------------*/ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* target, unsigned int tick, int flag) { diff --git a/src/map/skill.c b/src/map/skill.c index a5600d74b..18c09f135 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -5567,6 +5567,9 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr data) } ud->skilltimer = INVALID_TIMER; + + if( sd && (ud->skillid == CR_GRANDCROSS || ud->skillid == NPC_GRANDDARKNESS) ) + status_calc_bl(&sd->bl, SCB_DEF); // restore original DEF } if (ud->skilltarget == id) @@ -5691,6 +5694,16 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr data) case GS_DESPERADO: sd->canequip_tick = tick + skill_get_time(ud->skillid, ud->skilllv); break; + case CR_GRANDCROSS: + case NPC_GRANDDARKNESS: + if( (sc = status_get_sc(src)) && sc->data[SC_STRIPSHIELD] ) + { + const struct TimerData *timer = get_timer(sc->data[SC_STRIPSHIELD]->timer); + if( timer && timer->func == status_change_timer && DIFF_TICK(timer->tick,gettick()+skill_get_time(ud->skillid, ud->skilllv)) > 0 ) + break; + } + sc_start2(src, SC_STRIPSHIELD, 100, 0, 1, skill_get_time(ud->skillid, ud->skilllv)); + break; } } if (skill_get_state(ud->skillid) != ST_MOVE_ENABLE) @@ -10032,27 +10045,6 @@ static int skill_unit_timer_sub (DBKey key, void* data, va_list ap) nullpo_retr(0, group); - dissonance = skill_dance_switch(unit, 0); - - if( unit->range >= 0 && group->interval != -1 ) - { - if( battle_config.skill_wall_check ) - map_foreachinshootrange(skill_unit_timer_sub_onplace, bl, unit->range, group->bl_flag, bl,tick); - else - map_foreachinrange(skill_unit_timer_sub_onplace, bl, unit->range, group->bl_flag, bl,tick); - - if(unit->range == -1) //Unit disabled, but it should not be deleted yet. - group->unit_id = UNT_USED_TRAPS; - - if( !unit->alive ) - { - if( dissonance ) skill_dance_switch(unit, 1); - return 0; - } - } - - if( dissonance ) skill_dance_switch(unit, 1); - // check for expiration if( (DIFF_TICK(tick,group->tick) >= group->limit || DIFF_TICK(tick,group->tick) >= unit->limit) ) {// skill unit expired (inlined from skill_unit_onlimit()) @@ -10173,6 +10165,31 @@ static int skill_unit_timer_sub (DBKey key, void* data, va_list ap) } } + //Don't continue if unit or even group is expired and has been deleted. + if( !group || !unit->alive ) + return 0; + + dissonance = skill_dance_switch(unit, 0); + + if( unit->range >= 0 && group->interval != -1 ) + { + if( battle_config.skill_wall_check ) + map_foreachinshootrange(skill_unit_timer_sub_onplace, bl, unit->range, group->bl_flag, bl,tick); + else + map_foreachinrange(skill_unit_timer_sub_onplace, bl, unit->range, group->bl_flag, bl,tick); + + if(unit->range == -1) //Unit disabled, but it should not be deleted yet. + group->unit_id = UNT_USED_TRAPS; + + if( !unit->alive ) + { + if( dissonance ) skill_dance_switch(unit, 1); + return 0; + } + } + + if( dissonance ) skill_dance_switch(unit, 1); + return 0; } /*========================================== diff --git a/src/map/status.c b/src/map/status.c index 1fe6ec122..c7b7b1567 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -4930,6 +4930,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; case SC_STRIPSHIELD: + if( val2 == 1 ) val2 = 0; //GX effect. Do not take shield off.. + else if (sd) { int i; if(sd->unstripable_equip&EQP_SHIELD) diff --git a/src/map/unit.c b/src/map/unit.c index bd2997723..b5a56fb4b 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1072,14 +1072,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh ud->canact_tick = tick + casttime + 100; if ( battle_config.display_status_timers && sd ) clif_status_change(src, SI_ACTIONDELAY, 1, casttime); - if( sd ) - { - switch( skill_num ) - { - case CG_ARROWVULCAN: - sd->canequip_tick = tick + casttime; - } - } + ud->skilltarget = target_id; ud->skillx = 0; ud->skilly = 0; @@ -1099,9 +1092,24 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh status_calc_bl(&sd->bl, SCB_SPEED); else unit_stop_walking(src,1); + + if( sd ) + { + switch( skill_num ) + { + case CG_ARROWVULCAN: + sd->canequip_tick = tick + casttime; + break; + case CR_GRANDCROSS: + case NPC_GRANDDARKNESS: + status_calc_bl(src, SCB_DEF); + break; + } + } } else skill_castend_id(ud->skilltimer,tick,src->id,0); + return 1; } @@ -1613,8 +1621,6 @@ int unit_skillcastcancel(struct block_list *bl,int type) ud->canact_tick = tick; if ( battle_config.display_status_timers && sd ) clif_status_change(bl, SI_ACTIONDELAY, 0, 0); - if( sd ) - sd->canequip_tick = tick; if(type&1 && sd) skill = sd->skillid_old; @@ -1633,6 +1639,20 @@ int unit_skillcastcancel(struct block_list *bl,int type) if( sd && pc_checkskill(sd,SA_FREECAST) > 0 ) status_calc_bl(&sd->bl, SCB_SPEED); + if( sd ) + { + switch( skill ) + { + case CG_ARROWVULCAN: + sd->canequip_tick = tick; + break; + case CR_GRANDCROSS: + case NPC_GRANDDARKNESS: + status_calc_bl(bl, SCB_DEF); + break; + } + } + if(bl->type==BL_MOB) ((TBL_MOB*)bl)->skillidx = -1; clif_skillcastcancel(bl); -- cgit v1.2.3-60-g2f50