summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/map/battle.c50
-rw-r--r--src/map/skill.c36
-rw-r--r--src/map/status.c67
3 files changed, 85 insertions, 68 deletions
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)