From 0124990b7ff13e4bf963b7c054ce3412e8d8ddcd Mon Sep 17 00:00:00 2001 From: rud0lp20 Date: Mon, 16 Jul 2012 10:16:37 +0000 Subject: Fixed bugreport:6233 traps should now hit/damage all targets inside gvg/pvp grounds. Follow up r16424 update for Sura skills to its official behavior and damage formula(SR_EARTHSHAKER,SR_RAMPAGEBLASTER,SR_KNUCKLEARROW,SR_GENTLETOUCH_QUITE,SR_GENTLETOUCH_CHANGE,SR_GENTLETOUCH_REVITALIZE[bugreport:5634]). git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16429 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/battle.c | 50 ++++++++++++++++++++++++++++++------------ src/map/skill.c | 36 +++++++++++++++--------------- src/map/status.c | 67 ++++++++++++++++++++++++++------------------------------ 3 files changed, 85 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/src/map/battle.c b/src/map/battle.c index 02cb4b466..ee7cd6869 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -2306,11 +2306,20 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo RE_LVL_DMOD(100); break; case SR_EARTHSHAKER: - skillratio += 50 * skill_lv - 50;// Need to code a check to make the ratio 3x when hitting a hidden player. [Rytech] + if( tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || // [(Skill Level x 150) x (Caster’s Base Level / 100) + (Caster’s INT x 3)] % + tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKINGEXCEED] || tsc->data[SC__INVISIBILITY]) ){ + skillratio = 150 * skill_lv; + RE_LVL_DMOD(100); + skillratio += sstatus->int_ * 3; + }else{ //[(Skill Level x 50) x (Caster’s Base Level / 100) + (Caster’s INT x 2)] % + skillratio += 50 * (skill_lv-2); + RE_LVL_DMOD(100); + skillratio += sstatus->int_ * 2; + } break; case SR_FALLENEMPIRE:// ATK [(Skill Level x 150 + 100) x Caster’s Base Level / 150] % skillratio += 150 *skill_lv; - RE_LVL_DMOD(100); + RE_LVL_DMOD(150); break; case SR_TIGERCANNON:// ATK [((Caster’s consumed HP + SP) / 4) x Caster’s Base Level / 100] % { @@ -2323,22 +2332,27 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo } break; case SR_RAMPAGEBLASTER: - if( sc && sc->data[SC_EXPLOSIONSPIRITS] ) - skillratio += 40 * skill_lv * (sd?sd->spiritball_old:5) - 100; - else - skillratio += 20 * skill_lv * (sd?sd->spiritball_old:5) - 100; + skillratio += 20 * skill_lv * (sd?sd->spiritball_old:5) - 100; + if( sc && sc->data[SC_EXPLOSIONSPIRITS] ){ + skillratio += sc->data[SC_EXPLOSIONSPIRITS]->val1 * 20; + RE_LVL_DMOD(120); + }else + RE_LVL_DMOD(150); break; case SR_KNUCKLEARROW: - if( wflag&4 ) - skillratio = 150 * skill_lv; //+Knockback Damage (Must check and test. [Rytech]) - else + if( wflag&4 ){ // ATK [(Skill Level x 150) + (1000 x Target’s current weight / Maximum weight) + (Target’s Base Level x 5) x (Caster’s Base Level / 150)] % + skillratio = 150 * skill_lv + status_get_lv(target) * 5 * (status_get_lv(src) / 100) ; + if( tsd && tsd->weight ) + skillratio += 100 * (tsd->weight / tsd->max_weight); + }else // ATK [(Skill Level x 100 + 500) x Caster’s Base Level / 100] % skillratio += 400 + (100 * skill_lv); + RE_LVL_DMOD(100); break; case SR_WINDMILL: // ATK [(Caster’s Base Level + Caster’s DEX) x Caster’s Base Level / 100] % skillratio = status_get_lv(src) + sstatus->dex; RE_LVL_DMOD(100); break; - case SR_GATEOFHELL: + case SR_GATEOFHELL: if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE ) skillratio += 800 * skill_lv -100; @@ -2348,9 +2362,11 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo break; case SR_GENTLETOUCH_QUIET: skillratio += 100 * skill_lv - 100 + sstatus->dex; + RE_LVL_DMOD(100); break; case SR_HOWLINGOFLION: skillratio += 300 * skill_lv - 100; + RE_LVL_DMOD(150); break; case SR_RIDEINLIGHTNING: // ATK [{(Skill Level x 200) + Additional Damage} x Caster’s Base Level / 100] % if( (sstatus->rhw.ele) == ELE_WIND || (sstatus->lhw.ele) == ELE_WIND ) @@ -2567,10 +2583,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo if( (sstatus->rhw.ele) == ELE_WIND || (sstatus->lhw.ele) == ELE_WIND ) ATK_ADDRATE(50); break; - case SR_EARTHSHAKER: - if( tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKINGEXCEED]) ) - ATK_ADDRATE(150+150*skill_lv); - break; } if( sd ) @@ -2644,6 +2656,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo def2 -= def2 * i / 100; } + if( tsc && tsc->data[SC_GT_REVITALIZE] && tsc->data[SC_GT_REVITALIZE]->val4 ) + def2 += 2 * tsc->data[SC_GT_REVITALIZE]->val4; + if( battle_config.vit_penalty_type && battle_config.vit_penalty_target&target->type ) { unsigned char target_count; //256 max targets should be a sane max target_count = unit_counttargeted(target); @@ -2720,8 +2735,15 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo #endif ATK_ADD(20*lv); } + if(sc->data[SC_GN_CARTBOOST]) ATK_ADD(10*sc->data[SC_GN_CARTBOOST]->val1); + + if(sc->data[SC_GT_CHANGE] && sc->data[SC_GT_CHANGE]->val2){ + struct block_list *bl; // ATK increase: ATK [{(Caster’s DEX / 4) + (Caster’s STR / 2)} x Skill Level / 5] + if( bl = map_id2bl(sc->data[SC_GT_CHANGE]->val2) ) + ATK_ADD( ( status_get_dex(bl)/4 + status_get_str(bl)/2 ) * sc->data[SC_GT_CHANGE]->val1 / 5 ); + } } //Refine bonus diff --git a/src/map/skill.c b/src/map/skill.c index d7daf262f..cba56d3fe 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1254,8 +1254,11 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int else if( dstmd && !is_boss(bl) ) sc_start(bl, SC_STUN, 100, skilllv, 1000 + 1000 * (rnd() %3)); break; - case SR_GENTLETOUCH_QUIET: - sc_start(bl, SC_SILENCE, 2 * skilllv, skilllv, skill_get_time(skillid, skilllv)); + case SR_GENTLETOUCH_QUIET: // [(Skill Level x 5) + (Caster’s DEX + Caster’s Base Level) / 10] + sc_start(bl, SC_SILENCE, 5 * skilllv + (sstatus->dex + status_get_lv(src)) / 10, skilllv, skill_get_time(skillid, skilllv)); + break; + case SR_EARTHSHAKER: + sc_start(bl,SC_STUN, 25 + 5 * skilllv,skilllv,skill_get_time(skillid,skilllv)); break; case SR_HOWLINGOFLION: sc_start(bl, SC_FEAR, 5 + 5 * skilllv, skilllv, skill_get_time(skillid, skilllv)); @@ -4319,20 +4322,14 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int break; case SR_EARTHSHAKER: - if( flag&1 ) { - struct status_change *tsc = status_get_sc(bl); - if( tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKING] || tsc->data[SC_CLOAKINGEXCEED]) ) { - status_change_end(bl, SC_HIDING, INVALID_TIMER); - status_change_end(bl, SC_CLOAKING, INVALID_TIMER); - status_change_end(bl, SC_CHASEWALK, INVALID_TIMER); - status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); - sc_start(bl,SC_STUN, 25 + 5 * skilllv,skilllv,skill_get_time(skillid,skilllv));//Does it apply the stun chance to targets knocked out of hiding, or it applys allways? [Rytech] - skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag); - } else - skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag); - } else + if( flag&1 ) { //by default cloaking skills are remove by aoe skills so no more checking/removing except hiding and cloaking exceed. + status_change_end(bl, SC_HIDING, INVALID_TIMER); + status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); + skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag); + } else{ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id); - clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6); + clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6); + } break; case WM_LULLABY_DEEPSLEEP: @@ -5130,8 +5127,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case SR_CRESCENTELBOW: case SR_LIGHTNINGWALK: case SR_GENTLETOUCH_ENERGYGAIN: - case SR_GENTLETOUCH_CHANGE: - case SR_GENTLETOUCH_REVITALIZE: case GN_CARTBOOST: clif_skill_nodamage(src,bl,skillid,skilllv, sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv))); @@ -8152,6 +8147,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in clif_skill_nodamage(src,bl,skillid,skilllv,1); } break; + case SR_GENTLETOUCH_CHANGE: + case SR_GENTLETOUCH_REVITALIZE: + clif_skill_nodamage(src,bl,skillid,skilllv, + sc_start2(bl,type,100,skilllv,src->id,skill_get_time(skillid,skilllv))); + break; case WA_SWING_DANCE: case WA_MOONLIT_SERENADE: if( sd == NULL || sd->status.party_id == 0 || (flag & 1) ) @@ -13990,7 +13990,7 @@ static int skill_trap_splash (struct block_list *bl, va_list ap) nullpo_ret(sg = unit->group); nullpo_ret(ss = map_id2bl(sg->src_id)); - if(battle_check_target(src,bl,BCT_ENEMY) <= 0) + if(battle_check_target(src,bl,sg->target_flag) <= 0) return 0; switch(sg->unit_id){ diff --git a/src/map/status.c b/src/map/status.c index 0ce76f844..1a47ef489 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -627,10 +627,10 @@ void initChangeTables(void) { set_sc( SR_CRESCENTELBOW , SC_CRESCENTELBOW , SI_CRESCENTELBOW , SCB_NONE ); set_sc_with_vfx( SR_CURSEDCIRCLE , SC_CURSEDCIRCLE_TARGET, SI_CURSEDCIRCLE_TARGET , SCB_NONE ); set_sc( SR_LIGHTNINGWALK , SC_LIGHTNINGWALK , SI_LIGHTNINGWALK , SCB_NONE ); - set_sc( SR_RAISINGDRAGON , SC_RAISINGDRAGON , SI_RAISINGDRAGON , SCB_REGEN|SCB_MAXHP|SCB_MAXSP/*|SCB_ASPD*/ ); + set_sc( SR_RAISINGDRAGON , SC_RAISINGDRAGON , SI_RAISINGDRAGON , SCB_REGEN|SCB_MAXHP|SCB_MAXSP ); set_sc( SR_GENTLETOUCH_ENERGYGAIN, SC_GT_ENERGYGAIN , SI_GENTLETOUCH_ENERGYGAIN, SCB_NONE ); - set_sc( SR_GENTLETOUCH_CHANGE , SC_GT_CHANGE , SI_GENTLETOUCH_CHANGE , SCB_BATK|SCB_ASPD|SCB_DEF|SCB_MDEF ); - set_sc( SR_GENTLETOUCH_REVITALIZE, SC_GT_REVITALIZE , SI_GENTLETOUCH_REVITALIZE, SCB_MAXHP|SCB_VIT|SCB_DEF2|SCB_REGEN|SCB_ASPD|SCB_SPEED ); + set_sc( SR_GENTLETOUCH_CHANGE , SC_GT_CHANGE , SI_GENTLETOUCH_CHANGE , SCB_ASPD|SCB_MDEF|SCB_MAXHP ); + set_sc( SR_GENTLETOUCH_REVITALIZE, SC_GT_REVITALIZE , SI_GENTLETOUCH_REVITALIZE, SCB_MAXHP|SCB_REGEN ); /** * Wanderer / Minstrel **/ @@ -3387,6 +3387,11 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str } else regen->flag&=~sce->val4; //Remove regen as specified by val4 } + if(sc->data[SC_GT_REVITALIZE]){ + regen->hp = cap_value(regen->hp*sc->data[SC_GT_REVITALIZE]->val3/100, 1, SHRT_MAX); + regen->state.walk= 1; + } + } void status_calc_state( struct block_list *bl, struct status_change *sc, enum scs_flag flag, bool start ) { @@ -4125,9 +4130,6 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang vit += sc->data[SC_INSPIRATION]->val3; if(sc->data[SC_STOMACHACHE]) vit -= sc->data[SC_STOMACHACHE]->val1; - if(sc->data[SC_GT_REVITALIZE]) - vit += sc->data[SC_GT_REVITALIZE]->val1; - return (unsigned short)cap_value(vit,0,USHRT_MAX); } @@ -4322,8 +4324,6 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan batk -= batk * sc->data[SC_MELODYOFSINK]->val3/100; if(sc->data[SC_BEYONDOFWARCRY]) batk += batk * sc->data[SC_BEYONDOFWARCRY]->val3/100; - if(sc->data[SC_GT_CHANGE]) - batk += batk * sc->data[SC_GT_CHANGE]->val3 / 100; if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2) batk += 50; if(bl->type == BL_ELEM @@ -4690,8 +4690,6 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc, def -= def * (10 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100; if(sc->data[SC_EARTHDRIVE]) def -= def * 25 / 100; - if( sc->data[SC_GT_CHANGE] ) - def -= def * sc->data[SC_GT_CHANGE]->val3 / 100; if( sc->data[SC_ROCK_CRUSHER] ) def -= def * sc->data[SC_ROCK_CRUSHER]->val2 / 100; if( sc->data[SC_POWER_OF_GAIA] ) @@ -4754,8 +4752,8 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change def2 += sc->data[SC_SHIELDSPELL_REF]->val2; if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 ) def2 += (5 + sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2); - if( sc->data[SC_GT_REVITALIZE] ) - def2 += def2 * ( 50 + 10 * sc->data[SC_GT_REVITALIZE]->val1 ) / 100; + if( sc->data[SC_GT_REVITALIZE] && sc->data[SC_GT_REVITALIZE]->val4) + def2 += def2 * sc->data[SC_GT_REVITALIZE]->val4 / 100; #ifdef RENEWAL return (short)cap_value(def2,SHRT_MIN,SHRT_MAX); @@ -4802,8 +4800,8 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, mdef -= mdef * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100; if(sc->data[SC_SYMPHONYOFLOVER]) mdef += mdef * sc->data[SC_SYMPHONYOFLOVER]->val2 / 100; - if(sc->data[SC_GT_CHANGE]) - mdef -= mdef * sc->data[SC_GT_CHANGE]->val3 / 100; + if(sc->data[SC_GT_CHANGE] && sc->data[SC_GT_CHANGE]->val4) + mdef -= mdef * sc->data[SC_GT_CHANGE]->val4 / 100; if(sc->data[SC_WATER_BARRIER]) mdef += sc->data[SC_WATER_BARRIER]->val2; if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3) @@ -4983,13 +4981,9 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha if( sc->data[SC_HOVERING] ) val = max( val, 10 ); if( sc->data[SC_GN_CARTBOOST] ) - val = max( val, sc->data[SC_GN_CARTBOOST]->val2 ); - if( sc->data[SC_GT_REVITALIZE] ) - val = max( val, sc->data[SC_GT_REVITALIZE]->val2 ); + val = max( val, sc->data[SC_GN_CARTBOOST]->val2 ); if( sc->data[SC_SWINGDANCE] ) val = max( val, sc->data[SC_SWINGDANCE]->val2 ); - if( sc->data[SC_GT_REVITALIZE] ) - val = max( val, sc->data[SC_GT_REVITALIZE]->val2 ); if( sc->data[SC_WIND_STEP_OPTION] ) val = max( val, sc->data[SC_WIND_STEP_OPTION]->val2 ); @@ -5136,9 +5130,7 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s if( sc->data[SC_EARTHDRIVE] ) skills2 -= 25; if( sc->data[SC_GT_CHANGE] ) - skills2 += (sc->data[SC_GT_CHANGE]->val2/200); - if( sc->data[SC_GT_REVITALIZE] ) - skills2 += sc->data[SC_GT_REVITALIZE]->val2; + skills2 += sc->data[SC_GT_CHANGE]->val3; if( sc->data[SC_MELON_BOMB] ) skills2 -= sc->data[SC_MELON_BOMB]->val1; if( sc->data[SC_BOOST500] ) @@ -5277,13 +5269,8 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change * aspd_rate += sc->data[SC_GLOOMYDAY]->val3 * 10; if( sc->data[SC_EARTHDRIVE] ) aspd_rate += 250; - /*As far I tested the skill there is no ASPD addition is applied. [Jobbie] */ - //if( sc->data[SC_RAISINGDRAGON] ) - // aspd_rate -= 100; //FIXME: Need official ASPD bonus of this status. [Jobbie] if( sc->data[SC_GT_CHANGE] ) - aspd_rate -= (sc->data[SC_GT_CHANGE]->val2/200) * 10; - if( sc->data[SC_GT_REVITALIZE] ) - aspd_rate -= sc->data[SC_GT_REVITALIZE]->val2 * 10; + aspd_rate -= sc->data[SC_GT_CHANGE]->val3 * 10; if( sc->data[SC_MELON_BOMB] ) aspd_rate += sc->data[SC_MELON_BOMB]->val1 * 10; if( sc->data[SC_BOOST500] ) @@ -5346,10 +5333,10 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang maxhp += maxhp * 3 * sc->data[SC_INSPIRATION]->val1 / 100; if(sc->data[SC_RAISINGDRAGON]) maxhp += maxhp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100; - if(sc->data[SC_GT_CHANGE]) - maxhp -= maxhp * (2 * sc->data[SC_GT_CHANGE]->val1) / 100; - if(sc->data[SC_GT_REVITALIZE]) - maxhp += maxhp * (3 * sc->data[SC_GT_REVITALIZE]->val1) / 100; + if(sc->data[SC_GT_CHANGE]) // Max HP decrease: [Skill Level x 4] % + maxhp -= maxhp * (4 * sc->data[SC_GT_CHANGE]->val1) / 100; + if(sc->data[SC_GT_REVITALIZE])// Max HP increase: [Skill Level x 2] % + maxhp += maxhp * (2 * sc->data[SC_GT_REVITALIZE]->val1) / 100; if(sc->data[SC_MUSTLE_M]) maxhp += maxhp * sc->data[SC_MUSTLE_M]->val1/100; if(sc->data[SC_SOLID_SKIN_OPTION]) @@ -8090,12 +8077,20 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val tick_time = 5000; // [GodLesZ] tick time break; case SC_GT_CHANGE: - if( sd ) val2 = (13 * val1 / 2) * sd->status.agi; //Aspd - old formula. - val3 = 20 + 1 * val1; //Base Atk, Reduction to DEF & MDEF + {// take note there is no def increase as skill desc says. [malufett] + struct block_list * src; + val3 = status->agi * val1 / 60; // ASPD increase: [(Target’s AGI x Skill Level) / 60] % + if( (src = map_id2bl(val2)) ) + val4 = ( 200/status_get_int(src) ) * val1;// MDEF decrease: MDEF [(200 / Caster’s INT) x Skill Level] + } break; case SC_GT_REVITALIZE: - val2 = 5 * val1; //Custom value VIT, ASPD, SPEED bonus. - val3 = 60 + 40 * val1; //HP recovery + {// take note there is no vit,aspd,speed increase as skill desc says. [malufett] + struct block_list * src; + val3 = val1 * 30 + 150; // Natural HP recovery increase: [(Skill Level x 30) + 50] % + if( (src = map_id2bl(val2)) ) // the stat def is not shown in the status window and it is process differently + val4 = ( status_get_vit(src)/4 ) * val1; // STAT DEF increase: [(Caster’s VIT / 4) x Skill Level] + } break; case SC_PYROTECHNIC_OPTION: val2 = 60; // Watk TODO: Renewal (Atk2) -- cgit v1.2.3-70-g09d2