diff options
author | Inkfish <Inkfish@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2009-05-07 12:15:14 +0000 |
---|---|---|
committer | Inkfish <Inkfish@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2009-05-07 12:15:14 +0000 |
commit | 81a85e322a784f6237b1948c53dca39bffb42f18 (patch) | |
tree | 575dbb13c007d1b2e42881993c0cdd2ea86b4dfe /src | |
parent | a609245253626fd1d8112d4b05959471723b7d8f (diff) | |
download | hercules-81a85e322a784f6237b1948c53dca39bffb42f18.tar.gz hercules-81a85e322a784f6237b1948c53dca39bffb42f18.tar.bz2 hercules-81a85e322a784f6237b1948c53dca39bffb42f18.tar.xz hercules-81a85e322a784f6237b1948c53dca39bffb42f18.zip |
* 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
Diffstat (limited to 'src')
-rw-r--r-- | src/map/battle.c | 58 | ||||
-rw-r--r-- | src/map/skill.c | 59 | ||||
-rw-r--r-- | src/map/status.c | 2 | ||||
-rw-r--r-- | src/map/unit.c | 40 |
4 files changed, 98 insertions, 61 deletions
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); |