summaryrefslogtreecommitdiff
path: root/src/map/skill.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/skill.c')
-rw-r--r--src/map/skill.c3387
1 files changed, 1849 insertions, 1538 deletions
diff --git a/src/map/skill.c b/src/map/skill.c
index ab937fadd..37ee297ca 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -47,13 +47,13 @@
// ranges reserved for mapping skill ids to skilldb offsets
#define HM_SKILLRANGEMIN 750
-#define HM_SKILLRANGEMAX HM_SKILLRANGEMIN + MAX_HOMUNSKILL
-#define MC_SKILLRANGEMIN HM_SKILLRANGEMAX + 1
-#define MC_SKILLRANGEMAX MC_SKILLRANGEMIN + MAX_MERCSKILL
-#define EL_SKILLRANGEMIN MC_SKILLRANGEMAX + 1
-#define EL_SKILLRANGEMAX EL_SKILLRANGEMIN + MAX_ELEMENTALSKILL
-#define GD_SKILLRANGEMIN EL_SKILLRANGEMAX + 1
-#define GD_SKILLRANGEMAX GD_SKILLRANGEMIN + MAX_GUILDSKILL
+#define HM_SKILLRANGEMAX (HM_SKILLRANGEMIN + MAX_HOMUNSKILL)
+#define MC_SKILLRANGEMIN (HM_SKILLRANGEMAX + 1)
+#define MC_SKILLRANGEMAX (MC_SKILLRANGEMIN + MAX_MERCSKILL)
+#define EL_SKILLRANGEMIN (MC_SKILLRANGEMAX + 1)
+#define EL_SKILLRANGEMAX (EL_SKILLRANGEMIN + MAX_ELEMENTALSKILL)
+#define GD_SKILLRANGEMIN (EL_SKILLRANGEMAX + 1)
+#define GD_SKILLRANGEMAX (GD_SKILLRANGEMIN + MAX_GUILDSKILL)
#if GD_SKILLRANGEMAX > 999
#error GD_SKILLRANGEMAX is greater than 999
@@ -131,17 +131,17 @@ void skill_chk(uint16* skill_id) {
*skill_id = skill->get_index(*skill_id); // checks/adjusts id
}
-#define skill_get(var,id) { skill->chk(&id); if(!id) return 0; return var; }
-#define skill_get2(var,id,lv) { \
- skill->chk(&id); \
- if(!id) return 0; \
- if( lv > MAX_SKILL_LEVEL && var > 1 ) { \
- int lv2 = lv; lv = skill->db[id].max; \
- return (var) + ((lv2-lv)/2);\
+#define skill_get(var,id) do { skill->chk(&(id)); if(!(id)) return 0; return (var); } while(0)
+#define skill_get2(var,id,lv) do { \
+ skill->chk(&(id)); \
+ if(!(id)) return 0; \
+ if( (lv) > MAX_SKILL_LEVEL && (var) > 1 ) { \
+ int lv2__ = (lv); (lv) = skill->db[(id)].max; \
+ return (var) + ((lv2__-(lv))/2);\
} \
- return var;\
-}
-#define skill_glv(lv) min(lv,MAX_SKILL_LEVEL-1)
+ return (var);\
+} while(0)
+#define skill_glv(lv) min((lv),MAX_SKILL_LEVEL-1)
// Skill DB
int skill_get_hit( uint16 skill_id ) { skill_get (skill->db[skill_id].hit, skill_id); }
int skill_get_inf( uint16 skill_id ) { skill_get (skill->db[skill_id].inf, skill_id); }
@@ -328,6 +328,8 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
struct map_session_data *tsd = BL_CAST(BL_PC, target);
struct status_change* sc;
+ nullpo_ret(src);
+
switch( skill_id ) {
case BA_APPLEIDUN:
#ifdef RENEWAL
@@ -372,6 +374,11 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
if( tsd && (skill2_lv = pc->skillheal2_bonus(tsd, skill_id)) )
hp += hp*skill2_lv/100;
+ sc = status->get_sc(src);
+ if( sc && sc->count && sc->data[SC_OFFERTORIUM] ) {
+ if( skill_id == AB_HIGHNESSHEAL || skill_id == AB_CHEAL || skill_id == PR_SANCTUARY || skill_id == AL_HEAL )
+ hp += hp * sc->data[SC_OFFERTORIUM]->val2 / 100;
+ }
sc = status->get_sc(target);
if( sc && sc->count ) {
if( sc->data[SC_CRITICALWOUND] && heal ) // Critical Wound has no effect on offensive heal. [Inkfish]
@@ -382,8 +389,8 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
hp += hp * sc->data[SC_HEALPLUS]->val1/100; // Only affects Heal, Sanctuary and PotionPitcher.(like bHealPower) [Inkfish]
if( sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2)
hp += hp / 10;
- if( sc->data[SC_OFFERTORIUM] && (skill_id == AB_HIGHNESSHEAL || skill_id == AB_CHEAL || skill_id == PR_SANCTUARY || skill_id == AL_HEAL) )
- hp += hp * sc->data[SC_OFFERTORIUM]->val2 / 100;
+ if ( sc && sc->data[SC_VITALITYACTIVATION] )
+ hp = hp * 150 / 100;
}
#ifdef RENEWAL
@@ -424,7 +431,7 @@ int can_copy (struct map_session_data *sd, uint16 skill_id, struct block_list* b
return 0;
// Couldn't preserve 3rd Class skills except only when using Reproduce skill. [Jobbie]
- if( !(sd->sc.data[SC__REPRODUCE]) && (skill_id >= RK_ENCHANTBLADE && skill_id <= SR_RIDEINLIGHTNING) )
+ if( !(sd->sc.data[SC__REPRODUCE]) && ((skill_id >= RK_ENCHANTBLADE && skill_id <= SR_RIDEINLIGHTNING) || (skill_id >= KO_YAMIKUMO && skill_id <= OB_AKAITSUKI)))
return 0;
// Reproduce will only copy skills according on the list. [Jobbie]
else if( sd->sc.data[SC__REPRODUCE] && !skill->reproduce_db[skill->get_index(skill_id)] )
@@ -444,7 +451,7 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd)
if (idx == 0)
return 1; // invalid skill id
- if (pc->has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL))
+ if (pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL))
return 0; // can do any damn thing they want
if( skill_id == AL_TELEPORT && sd->skillitem == skill_id && sd->skillitemlv > 2 )
@@ -460,7 +467,7 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd)
return 1;
}
- if (sd->blockskill[idx] > 0) {
+ if (sd->blockskill[idx]) {
clif->skill_fail(sd, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0);
return 1;
}
@@ -552,11 +559,10 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd)
}
break;
- case WM_SIRCLEOFNATURE:
- case WM_SOUND_OF_DESTRUCTION:
case SC_MANHOLE:
- case WM_LULLABY_DEEPSLEEP:
+ case WM_SOUND_OF_DESTRUCTION:
case WM_SATURDAY_NIGHT_FEVER:
+ case WM_LULLABY_DEEPSLEEP:
if( !map_flag_vs(m) ) {
clif->skill_mapinfomessage(sd,2); // This skill uses this msg instead of skill fails.
return 1;
@@ -639,7 +645,7 @@ struct s_skill_unit_layout* skill_get_unit_layout (uint16 skill_id, uint16 skill
/*==========================================
*
*------------------------------------------*/
-int skill_additional_effect(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int dmg_lv, unsigned int tick) {
+int skill_additional_effect(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int dmg_lv, int64 tick) {
struct map_session_data *sd, *dstsd;
struct mob_data *md, *dstmd;
struct status_data *sstatus, *tstatus;
@@ -700,10 +706,10 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
temp = skill->get_time2(status->sc2skill(type),7);
if (sd->addeff[i].flag&ATF_TARGET)
- status->change_start(bl,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,0);
+ status->change_start(src,bl,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,0);
if (sd->addeff[i].flag&ATF_SELF)
- status->change_start(src,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,0);
+ status->change_start(src,src,type,rate,7,0,(type == SC_BURNING)?src->id:0,0,temp,0);
}
}
@@ -718,9 +724,9 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
temp = skill->get_time2(status->sc2skill(type),7);
if( sd->addeff3[i].target&ATF_TARGET )
- status->change_start(bl,type,sd->addeff3[i].rate,7,0,0,0,temp,0);
+ status->change_start(src,bl,type,sd->addeff3[i].rate,7,0,0,0,temp,0);
if( sd->addeff3[i].target&ATF_SELF )
- status->change_start(src,type,sd->addeff3[i].rate,7,0,0,0,temp,0);
+ status->change_start(src,src,type,sd->addeff3[i].rate,7,0,0,0,temp,0);
}
}
}
@@ -754,15 +760,15 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
// Chance to trigger Taekwon kicks [Dralnu]
if(sc && !sc->data[SC_COMBOATTACK]) {
if(sc->data[SC_STORMKICK_READY] &&
- sc_start(src,SC_COMBOATTACK, 15, TK_STORMKICK,
+ sc_start(NULL,src,SC_COMBOATTACK, 15, TK_STORMKICK,
(2000 - 4*sstatus->agi - 2*sstatus->dex)))
; //Stance triggered
else if(sc->data[SC_DOWNKICK_READY] &&
- sc_start(src,SC_COMBOATTACK, 15, TK_DOWNKICK,
+ sc_start(NULL,src,SC_COMBOATTACK, 15, TK_DOWNKICK,
(2000 - 4*sstatus->agi - 2*sstatus->dex)))
; //Stance triggered
else if(sc->data[SC_TURNKICK_READY] &&
- sc_start(src,SC_COMBOATTACK, 15, TK_TURNKICK,
+ sc_start(NULL,src,SC_COMBOATTACK, 15, TK_TURNKICK,
(2000 - 4*sstatus->agi - 2*sstatus->dex)))
; //Stance triggered
else if (sc->data[SC_COUNTERKICK_READY]) { //additional chance from SG_FRIEND [Komurka]
@@ -771,7 +777,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
rate += rate*sc->data[SC_SKILLRATE_UP]->val2/100;
status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER);
}
- sc_start2(src, SC_COMBOATTACK, rate, TK_COUNTER, bl->id,
+ sc_start2(NULL, src, SC_COMBOATTACK, rate, TK_COUNTER, bl->id,
(2000 - 4*sstatus->agi - 2*sstatus->dex));
}
}
@@ -783,11 +789,11 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
struct status_change_entry *sce;
// Enchant Poison gives a chance to poison attacked enemies
if((sce=sc->data[SC_ENCHANTPOISON])) //Don't use sc_start since chance comes in 1/10000 rate.
- status->change_start(bl,SC_POISON,sce->val2, sce->val1,src->id,0,0,
+ status->change_start(src,bl,SC_POISON,sce->val2, sce->val1,src->id,0,0,
skill->get_time2(AS_ENCHANTPOISON,sce->val1),0);
// Enchant Deadly Poison gives a chance to deadly poison attacked enemies
if((sce=sc->data[SC_EDP]))
- sc_start4(bl,SC_DPOISON,sce->val2, sce->val1,src->id,0,0,
+ sc_start4(src,bl,SC_DPOISON,sce->val2, sce->val1,src->id,0,0,
skill->get_time2(ASC_EDP,sce->val1));
}
}
@@ -795,12 +801,12 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
case SM_BASH:
if( sd && skill_lv > 5 && pc->checkskill(sd,SM_FATALBLOW)>0 )
- status->change_start(bl,SC_STUN,500*(skill_lv-5)*sd->status.base_level/50,
+ status->change_start(src,bl,SC_STUN,500*(skill_lv-5)*sd->status.base_level/50,
skill_lv,0,0,0,skill->get_time2(SM_FATALBLOW,skill_lv),0);
break;
case MER_CRASH:
- sc_start(bl,SC_STUN,(6*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_STUN,(6*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case AS_VENOMKNIFE:
@@ -808,14 +814,14 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
skill_lv = pc->checkskill(sd, TF_POISON);
case TF_POISON:
case AS_SPLASHER:
- if(!sc_start2(bl,SC_POISON,(4*skill_lv+10),skill_lv,src->id,skill->get_time2(skill_id,skill_lv))
+ if(!sc_start2(src,bl,SC_POISON,(4*skill_lv+10),skill_lv,src->id,skill->get_time2(skill_id,skill_lv))
&& sd && skill_id==TF_POISON
)
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
case AS_SONICBLOW:
- sc_start(bl,SC_STUN,(2*skill_lv+10),skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_STUN,(2*skill_lv+10),skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case WZ_FIREPILLAR:
@@ -826,14 +832,14 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
#ifndef RENEWAL
case WZ_FROSTNOVA:
#endif
- if( !sc_start(bl,SC_FREEZE,skill_lv*3+35,skill_lv,skill->get_time2(skill_id,skill_lv))
+ if( !sc_start(src,bl,SC_FREEZE,skill_lv*3+35,skill_lv,skill->get_time2(skill_id,skill_lv))
&& sd && skill_id == MG_FROSTDIVER )
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
#ifdef RENEWAL
case WZ_FROSTNOVA:
- sc_start(bl,SC_FREEZE,skill_lv*5+33,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_FREEZE,skill_lv*5+33,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
#endif
@@ -842,11 +848,11 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
* Storm Gust counter was dropped in renewal
**/
#ifdef RENEWAL
- sc_start(bl,SC_FREEZE,65-(5*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_FREEZE,65-(5*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv));
#else
//Tharis pointed out that this is normal freeze chance with a base of 300%
if(tsc->sg_counter >= 3 &&
- sc_start(bl,SC_FREEZE,300,skill_lv,skill->get_time2(skill_id,skill_lv)))
+ sc_start(src,bl,SC_FREEZE,300,skill_lv,skill->get_time2(skill_id,skill_lv)))
tsc->sg_counter = 0;
/**
* being it only resets on success it'd keep stacking and eventually overflowing on mvps, so we reset at a high value
@@ -857,25 +863,25 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
break;
case WZ_METEOR:
- sc_start(bl,SC_STUN,3*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_STUN,3*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case WZ_VERMILION:
- sc_start(bl,SC_BLIND,4*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_BLIND,4*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case HT_FREEZINGTRAP:
case MA_FREEZINGTRAP:
- sc_start(bl,SC_FREEZE,(3*skill_lv+35),skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_FREEZE,(3*skill_lv+35),skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case HT_FLASHER:
- sc_start(bl,SC_BLIND,(10*skill_lv+30),skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_BLIND,(10*skill_lv+30),skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case HT_LANDMINE:
case MA_LANDMINE:
- sc_start(bl,SC_STUN,(5*skill_lv+30),skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_STUN,(5*skill_lv+30),skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case HT_SHOCKWAVE:
@@ -884,33 +890,32 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
case HT_SANDMAN:
case MA_SANDMAN:
- sc_start(bl,SC_SLEEP,(10*skill_lv+40),skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_SLEEP,(10*skill_lv+40),skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case TF_SPRINKLESAND:
- sc_start(bl,SC_BLIND,20,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_BLIND,20,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case TF_THROWSTONE:
- if( !sc_start(bl,SC_STUN,3,skill_lv,skill->get_time(skill_id,skill_lv)) )
- sc_start(bl,SC_BLIND,3,skill_lv,skill->get_time2(skill_id,skill_lv));
+ if( !sc_start(src,bl,SC_STUN,3,skill_lv,skill->get_time(skill_id,skill_lv)) )
+ sc_start(src,bl,SC_BLIND,3,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case NPC_DARKCROSS:
case CR_HOLYCROSS:
- sc_start(bl,SC_BLIND,3*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_BLIND,3*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case CR_GRANDCROSS:
case NPC_GRANDDARKNESS:
//Chance to cause blind status vs demon and undead element, but not against players
if(!dstsd && (battle->check_undead(tstatus->race,tstatus->def_ele) || tstatus->race == RC_DEMON))
- sc_start(bl,SC_BLIND,100,skill_lv,skill->get_time2(skill_id,skill_lv));
- attack_type |= BF_WEAPON;
+ sc_start(src,bl,SC_BLIND,100,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case AM_ACIDTERROR:
- sc_start2(bl,SC_BLOODING,(skill_lv*3),skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
+ sc_start2(src,bl,SC_BLOODING,(skill_lv*3),skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
if (skill->break_equip(bl, EQP_ARMOR, 100*skill->get_time(skill_id,skill_lv), BCT_ENEMY))
clif->emotion(bl,E_OMG);
break;
@@ -920,7 +925,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
break;
case CR_SHIELDCHARGE:
- sc_start(bl,SC_STUN,(15+skill_lv*5),skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_STUN,(15+skill_lv*5),skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case PA_PRESSURE:
@@ -928,28 +933,28 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
break;
case RG_RAID:
- sc_start(bl,SC_STUN,(10+3*skill_lv),skill_lv,skill->get_time(skill_id,skill_lv));
- sc_start(bl,SC_BLIND,(10+3*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_STUN,(10+3*skill_lv),skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,SC_BLIND,(10+3*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv));
#ifdef RENEWAL
- sc_start(bl,SC_RAID,100,7,5000);
+ sc_start(src,bl,SC_RAID,100,7,5000);
break;
case RG_BACKSTAP:
- sc_start(bl,SC_STUN,(5+2*skill_lv),skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,SC_STUN,(5+2*skill_lv),skill_lv,skill->get_time(skill_id,skill_lv));
#endif
break;
case BA_FROSTJOKER:
- sc_start(bl,SC_FREEZE,(15+5*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_FREEZE,(15+5*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case DC_SCREAM:
- sc_start(bl,SC_STUN,(25+5*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_STUN,(25+5*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case BD_LULLABY:
- sc_start(bl,SC_SLEEP,15,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_SLEEP,15,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case DC_UGLYDANCE:
@@ -960,11 +965,11 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
break;
case SL_STUN:
if (tstatus->size==SZ_MEDIUM) //Only stuns mid-sized mobs.
- sc_start(bl,SC_STUN,(30+10*skill_lv),skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,SC_STUN,(30+10*skill_lv),skill_lv,skill->get_time(skill_id,skill_lv));
break;
case NPC_PETRIFYATTACK:
- sc_start4(bl,status->skill2sc(skill_id),50+10*skill_lv,
+ sc_start4(src,bl,status->skill2sc(skill_id),50+10*skill_lv,
skill_lv,0,0,skill->get_time(skill_id,skill_lv),
skill->get_time2(skill_id,skill_lv));
break;
@@ -975,14 +980,14 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
case NPC_SILENCEATTACK:
case NPC_STUNATTACK:
case NPC_HELLPOWER:
- sc_start(bl,status->skill2sc(skill_id),50+10*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,status->skill2sc(skill_id),50+10*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case NPC_ACIDBREATH:
case NPC_ICEBREATH:
- sc_start(bl,status->skill2sc(skill_id),70,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,status->skill2sc(skill_id),70,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case NPC_BLEEDING:
- sc_start2(bl,SC_BLOODING,(20*skill_lv),skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
+ sc_start2(src,bl,SC_BLOODING,(20*skill_lv),skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
break;
case NPC_MENTALBREAKER:
{
@@ -1008,32 +1013,32 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
break;
case CH_TIGERFIST:
- sc_start(bl,SC_STOP,(10+skill_lv*10),0,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_STOP,(10+skill_lv*10),0,skill->get_time2(skill_id,skill_lv));
break;
case LK_SPIRALPIERCE:
case ML_SPIRALPIERCE:
- sc_start(bl,SC_ANKLESNARE,100,0,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_ANKLESNARE,100,0,skill->get_time2(skill_id,skill_lv));
break;
case ST_REJECTSWORD:
- sc_start(bl,SC_AUTOCOUNTER,(skill_lv*15),skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,SC_AUTOCOUNTER,(skill_lv*15),skill_lv,skill->get_time(skill_id,skill_lv));
break;
case PF_FOGWALL:
if (src != bl && !tsc->data[SC_DELUGE])
- sc_start(bl,SC_BLIND,100,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_BLIND,100,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case LK_HEADCRUSH: //Headcrush has chance of causing Bleeding status, except on demon and undead element
if (!(battle->check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON))
- sc_start2(bl, SC_BLOODING,50, skill_lv, src->id, skill->get_time2(skill_id,skill_lv));
+ sc_start2(src, bl, SC_BLOODING,50, skill_lv, src->id, skill->get_time2(skill_id,skill_lv));
break;
case LK_JOINTBEAT:
if (tsc->jb_flag) {
enum sc_type type = status->skill2sc(skill_id);
- sc_start4(bl,type,(5*skill_lv+5),skill_lv,tsc->jb_flag&BREAK_FLAGS,src->id,0,skill->get_time2(skill_id,skill_lv));
+ sc_start4(src,bl,type,(5*skill_lv+5),skill_lv,tsc->jb_flag&BREAK_FLAGS,src->id,0,skill->get_time2(skill_id,skill_lv));
tsc->jb_flag = 0;
}
break;
@@ -1041,22 +1046,22 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
//Any enemies hit by this skill will receive Stun, Darkness, or external bleeding status ailment with a 5%+5*skill_lv% chance.
switch(rnd()%3) {
case 0:
- sc_start(bl,SC_BLIND,(5+skill_lv*5),skill_lv,skill->get_time2(skill_id,1));
+ sc_start(src,bl,SC_BLIND,(5+skill_lv*5),skill_lv,skill->get_time2(skill_id,1));
break;
case 1:
- sc_start(bl,SC_STUN,(5+skill_lv*5),skill_lv,skill->get_time2(skill_id,2));
+ sc_start(src,bl,SC_STUN,(5+skill_lv*5),skill_lv,skill->get_time2(skill_id,2));
break;
default:
- sc_start2(bl,SC_BLOODING,(5+skill_lv*5),skill_lv,src->id,skill->get_time2(skill_id,3));
+ sc_start2(src,bl,SC_BLOODING,(5+skill_lv*5),skill_lv,src->id,skill->get_time2(skill_id,3));
}
break;
case HW_NAPALMVULCAN:
- sc_start(bl,SC_CURSE,5*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_CURSE,5*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case WS_CARTTERMINATION: // Cart termination
- sc_start(bl,SC_STUN,5*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_STUN,5*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case CR_ACIDDEMONSTRATION:
@@ -1064,7 +1069,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
break;
case TK_DOWNKICK:
- sc_start(bl,SC_STUN,100,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_STUN,100,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case TK_JUMPKICK:
@@ -1081,20 +1086,20 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
case TK_TURNKICK:
case MO_BALKYOUNG: //Note: attack_type is passed as BF_WEAPON for the actual target, BF_MISC for the splash-affected mobs.
if(attack_type&BF_MISC) //70% base stun chance...
- sc_start(bl,SC_STUN,70,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_STUN,70,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case GS_BULLSEYE: //0.1% coma rate.
if(tstatus->race == RC_BRUTE || tstatus->race == RC_DEMIHUMAN)
- status->change_start(bl,SC_COMA,10,skill_lv,0,src->id,0,0,0);
+ status->change_start(src,bl,SC_COMA,10,skill_lv,0,src->id,0,0,0);
break;
case GS_PIERCINGSHOT:
- sc_start2(bl,SC_BLOODING,(skill_lv*3),skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
+ sc_start2(src,bl,SC_BLOODING,(skill_lv*3),skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
break;
case NJ_HYOUSYOURAKU:
- sc_start(bl,SC_FREEZE,(10+10*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_FREEZE,(10+10*skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case GS_FLING:
- sc_start(bl,SC_FLING,100, sd?sd->spiritball_old:5,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,SC_FLING,100, sd?sd->spiritball_old:5,skill->get_time(skill_id,skill_lv));
break;
case GS_DISARM:
rate = 3*skill_lv;
@@ -1104,112 +1109,132 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
break;
case NPC_EVILLAND:
- sc_start(bl,SC_BLIND,5*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_BLIND,5*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case NPC_HELLJUDGEMENT:
- sc_start(bl,SC_CURSE,100,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_CURSE,100,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case NPC_CRITICALWOUND:
- sc_start(bl,SC_CRITICALWOUND,100,skill_lv,skill->get_time2(skill_id,skill_lv));
- break;
- case RK_HUNDREDSPEAR:
- if( !sd || pc->checkskill(sd,KN_SPEARBOOMERANG) == 0 )
- break; // Spear Boomerang auto cast chance only works if you have mastered Spear Boomerang.
- rate = 10 + 3 * skill_lv;
- if( rnd()%100 < rate )
- skill->castend_damage_id(src,bl,KN_SPEARBOOMERANG,1,tick,0);
+ sc_start(src,bl,SC_CRITICALWOUND,100,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case RK_WINDCUTTER:
- sc_start(bl,SC_FEAR,3+2*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,SC_FEAR,3+2*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
break;
case RK_DRAGONBREATH:
- sc_start4(bl,SC_BURNING,5+5*skill_lv,skill_lv,0,src->id,0,skill->get_time(skill_id,skill_lv));
+ sc_start4(src,bl,SC_BURNING,15,skill_lv,1000,src->id,0,skill->get_time(skill_id,skill_lv));
break;
case RK_DRAGONBREATH_WATER:
- sc_start(bl,SC_FROSTMISTY,5+5*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start4(src,bl,SC_FROSTMISTY,15,skill_lv,1000,src->id,0,skill->get_time(skill_id,skill_lv));
break;
case AB_ADORAMUS:
if( tsc && !tsc->data[SC_DEC_AGI] ) //Prevent duplicate agi-down effect.
- sc_start(bl, SC_ADORAMUS, 100, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, SC_ADORAMUS, skill_lv * 4 + (sd? sd->status.job_level:50)/2, skill_lv, skill->get_time(skill_id, skill_lv));
break;
case WL_CRIMSONROCK:
- sc_start(bl, SC_STUN, 40, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, SC_STUN, 40, skill_lv, skill->get_time(skill_id, skill_lv));
break;
case WL_COMET:
- sc_start4(bl,SC_BURNING,100,skill_lv,0,src->id,0,skill->get_time2(skill_id,skill_lv));
+ sc_start4(src,bl,SC_BURNING,100,skill_lv,0,src->id,0,skill->get_time2(skill_id,skill_lv));
break;
case WL_EARTHSTRAIN:
- {
- // lv 1 & 2 = Strip Helm, lv 3 = Strip Armor, lv 4 = Strip Weapon and lv 5 = Strip Accessory. [malufett]
- const int pos[5] = { EQP_HELM, EQP_HELM, EQP_ARMOR, EQP_WEAPON, EQP_ACC };
- skill->strip_equip(bl, pos[skill_lv], 6 * skill_lv + status->get_lv(src) / 4 + status_get_dex(src) / 10,
- skill_lv, skill->get_time2(skill_id,skill_lv));
- }
+ {
+ int i;
+ const int pos[5] = { EQP_WEAPON, EQP_HELM, EQP_SHIELD, EQP_ARMOR, EQP_ACC };
+
+ for( i = 0; i < skill_lv; i++ )
+ skill->strip_equip(bl,pos[i], 6 * skill_lv + status->get_lv(src) / 4 + status_get_dex(src) / 10,
+ skill_lv,skill->get_time2(skill_id,skill_lv));
+ }
break;
case WL_JACKFROST:
- sc_start(bl,SC_FREEZE,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,SC_FREEZE,100,skill_lv,skill->get_time(skill_id,skill_lv));
break;
case WL_FROSTMISTY:
- sc_start(bl,SC_FROSTMISTY,25 + 5 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,SC_FROSTMISTY,25 + 5 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
break;
case RA_WUGBITE:
- sc_start(bl, SC_WUGBITE, (sd ? pc->checkskill(sd,RA_TOOTHOFWUG)*2 : 0), skill_lv, (skill->get_time(skill_id,skill_lv) + (sd ? pc->checkskill(sd,RA_TOOTHOFWUG)*500 : 0)) );
+ rate = 50 + 10 * skill_lv + 2 * (sd ? pc->checkskill(sd,RA_TOOTHOFWUG) : 0) - tstatus->agi / 4;
+ if ( rate < 50 )
+ rate = 50;
+ sc_start(src,bl,SC_WUGBITE, rate, skill_lv, skill->get_time(skill_id, skill_lv) + (sd ? pc->checkskill(sd,RA_TOOTHOFWUG) * 500 : 0));
break;
case RA_SENSITIVEKEEN:
if( rnd()%100 < 8 * skill_lv )
skill->castend_damage_id(src, bl, RA_WUGBITE, sd ? pc->checkskill(sd, RA_WUGBITE):skill_lv, tick, SD_ANIMATION);
break;
+ case RA_MAGENTATRAP:
+ case RA_COBALTTRAP:
+ case RA_MAIZETRAP:
+ case RA_VERDURETRAP:
+ if( dstmd && !(dstmd->status.mode&MD_BOSS) )
+ sc_start2(src,bl,SC_ARMOR_PROPERTY,100,skill_lv,skill->get_ele(skill_id,skill_lv),skill->get_time2(skill_id,skill_lv));
+ break;
case RA_FIRINGTRAP:
case RA_ICEBOUNDTRAP:
- sc_start4(bl, (skill_id == RA_FIRINGTRAP) ? SC_BURNING:SC_FROSTMISTY, 40 + 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time2(skill_id, skill_lv));
+ sc_start4(src, bl, (skill_id == RA_FIRINGTRAP) ? SC_BURNING:SC_FROSTMISTY, 50 + 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time2(skill_id, skill_lv));
break;
case NC_PILEBUNKER:
- if( rnd()%100 < 5 + 15*skill_lv )
- { //Deactivatable Statuses: Kyrie Eleison, Auto Guard, Steel Body, Assumptio, and Millennium Shield
+ if( rnd()%100 < 25 + 15 *skill_lv ) {
+ //Deactivatable Statuses: Kyrie Eleison, Auto Guard, Steel Body, Assumptio, and Millennium Shield
status_change_end(bl, SC_KYRIE, INVALID_TIMER);
- status_change_end(bl, SC_AUTOGUARD, INVALID_TIMER);
- status_change_end(bl, SC_STEELBODY, INVALID_TIMER);
status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
+ status_change_end(bl, SC_STEELBODY, INVALID_TIMER);
+ status_change_end(bl, SC_GENTLETOUCH_CHANGE, INVALID_TIMER);
+ status_change_end(bl, SC_GENTLETOUCH_REVITALIZE, INVALID_TIMER);
+ status_change_end(bl, SC_AUTOGUARD, INVALID_TIMER);
+ status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
+ status_change_end(bl, SC_DEFENDER, INVALID_TIMER);
+ status_change_end(bl, SC_LG_REFLECTDAMAGE, INVALID_TIMER);
+ status_change_end(bl, SC_PRESTIGE, INVALID_TIMER);
+ status_change_end(bl, SC_BANDING, INVALID_TIMER);
status_change_end(bl, SC_MILLENNIUMSHIELD, INVALID_TIMER);
}
break;
case NC_FLAMELAUNCHER:
- sc_start4(bl, SC_BURNING, 50 + 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time2(skill_id, skill_lv));
+ sc_start4(src, bl, SC_BURNING, 20 + 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time2(skill_id, skill_lv));
break;
case NC_COLDSLOWER:
- sc_start(bl, SC_FREEZE, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
- sc_start(bl, SC_FROSTMISTY, 20 + 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, SC_FREEZE, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
+ if ( tsc && !tsc->data[SC_FREEZE] )
+ sc_start(src, bl, SC_FROSTMISTY, 20 + 10 * skill_lv, skill_lv, skill->get_time2(skill_id, skill_lv));
break;
case NC_POWERSWING:
- sc_start(bl, SC_STUN, 5*skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
+ // Use flag=2, the stun duration is not vit-reduced.
+ status->change_start(src, bl, SC_STUN, 5*skill_lv*100, skill_lv, 0, 0, 0, skill->get_time(skill_id, skill_lv), 2);
if( rnd()%100 < 5*skill_lv )
skill->castend_damage_id(src, bl, NC_AXEBOOMERANG, pc->checkskill(sd, NC_AXEBOOMERANG), tick, 1);
break;
case NC_MAGMA_ERUPTION:
- sc_start4(bl, SC_BURNING, 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time2(skill_id, skill_lv));
- sc_start(bl, SC_STUN, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start4(src, bl, SC_BURNING, 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time2(skill_id, skill_lv));
+ sc_start(src, bl, SC_STUN, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
break;
case GC_WEAPONCRUSH:
skill->castend_nodamage_id(src,bl,skill_id,skill_lv,tick,BCT_ENEMY);
break;
case GC_DARKCROW:
- sc_start(bl, SC_DARKCROW, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, SC_DARKCROW, 100, skill_lv, skill->get_time(skill_id, skill_lv));
break;
case LG_SHIELDPRESS:
- sc_start(bl, SC_STUN, 30 + 8 * skill_lv, skill_lv, skill->get_time(skill_id,skill_lv));
+ rate = 30 + 8 * skill_lv + sstatus->dex / 10 + (sd? sd->status.job_level:0) / 4;
+ sc_start(src, bl, SC_STUN, rate, skill_lv, skill->get_time(skill_id,skill_lv));
break;
case LG_PINPOINTATTACK:
- rate = 30 + (((5 * (sd?pc->checkskill(sd,LG_PINPOINTATTACK):skill_lv)) + (sstatus->agi + status->get_lv(src))) / 10);
+ rate = 30 + 5 * (sd ? pc->checkskill(sd,LG_PINPOINTATTACK) : 1) + (sstatus->agi + status->get_lv(src)) / 10;
switch( skill_lv ) {
case 1:
- sc_start2(bl,SC_BLOODING,rate,skill_lv,src->id,skill->get_time(skill_id,skill_lv));
+ sc_start(src, bl,SC_BLOODING,rate,skill_lv,skill->get_time(skill_id,skill_lv));
break;
case 2:
- if( dstsd && dstsd->spiritball && rnd()%100 < rate )
- pc->delspiritball(dstsd, dstsd->spiritball, 0);
+ skill->break_equip(bl, EQP_HELM, rate*100, BCT_ENEMY);
break;
- default:
- skill->break_equip(bl,(skill_lv == 3) ? EQP_SHIELD : (skill_lv == 4) ? EQP_ARMOR : EQP_WEAPON,rate * 100,BCT_ENEMY);
+ case 3:
+ skill->break_equip(bl, EQP_SHIELD, rate*100, BCT_ENEMY);
+ break;
+ case 4:
+ skill->break_equip(bl, EQP_ARMOR, rate*100, BCT_ENEMY);
+ break;
+ case 5:
+ skill->break_equip(bl, EQP_WEAPON, rate*100, BCT_ENEMY);
break;
}
break;
@@ -1218,135 +1243,103 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
if( rnd()%100 < rate && dstsd ) // Uses skill->addtimerskill to avoid damage and setsit packet overlaping. Officially clif->setsit is received about 500 ms after damage packet.
skill->addtimerskill(src,tick+500,bl->id,0,0,skill_id,skill_lv,BF_WEAPON,0);
else if( dstmd && !is_boss(bl) )
- sc_start(bl,SC_STOP,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src, bl,SC_STOP,100,skill_lv,skill->get_time(skill_id,skill_lv));
break;
case LG_RAYOFGENESIS: // 50% chance to cause Blind on Undead and Demon monsters.
if ( battle->check_undead(tstatus->race, tstatus->def_ele) || tstatus->race == RC_DEMON )
- sc_start(bl, SC_BLIND,50, skill_lv, skill->get_time(skill_id,skill_lv));
+ sc_start(src, bl, SC_BLIND,50, skill_lv, skill->get_time(skill_id,skill_lv));
break;
case LG_EARTHDRIVE:
- skill->break_equip(src, EQP_SHIELD, 500, BCT_SELF);
- sc_start(bl, SC_EARTHDRIVE, 100, skill_lv, skill->get_time(skill_id, skill_lv));
+ skill->break_equip(src, EQP_SHIELD, 100 * skill_lv, BCT_SELF);
+ sc_start(src, bl, SC_EARTHDRIVE, 100, skill_lv, skill->get_time(skill_id, skill_lv));
break;
case SR_DRAGONCOMBO:
- sc_start(bl, SC_STUN, 1 + skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, SC_STUN, 1 + skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
break;
case SR_FALLENEMPIRE:
- sc_start(bl, SC_STOP, 100, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, SC_STOP, 100, skill_lv, skill->get_time(skill_id, skill_lv));
break;
case SR_WINDMILL:
if( dstsd )
skill->addtimerskill(src,tick+status_get_amotion(src),bl->id,0,0,skill_id,skill_lv,BF_WEAPON,0);
else if( dstmd && !is_boss(bl) )
- sc_start(bl, SC_STUN, 100, skill_lv, 1000 + 1000 * (rnd() %3));
+ sc_start(src, bl, SC_STUN, 100, skill_lv, 1000 + 1000 * (rnd() %3));
break;
case SR_GENTLETOUCH_QUIET: // [(Skill Level x 5) + (Caster?s DEX + Caster?s Base Level) / 10]
- sc_start(bl, SC_SILENCE, 5 * skill_lv + (sstatus->dex + status->get_lv(src)) / 10, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, SC_SILENCE, 5 * skill_lv + (sstatus->dex + status->get_lv(src)) / 10, skill_lv, skill->get_time(skill_id, skill_lv));
break;
case SR_EARTHSHAKER:
- sc_start(bl,SC_STUN, 25 + 5 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src, bl,SC_STUN, 25 + 5 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
break;
case SR_HOWLINGOFLION:
- sc_start(bl, SC_FEAR, 5 + 5 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
- break;
- case WM_SOUND_OF_DESTRUCTION:
- if( rnd()%100 < 5 + 5 * skill_lv ) { // Temporarly Check Until We Get the Official Formula
- status_change_end(bl, SC_DANCING, INVALID_TIMER);
- status_change_end(bl, SC_RICHMANKIM, INVALID_TIMER);
- status_change_end(bl, SC_ETERNALCHAOS, INVALID_TIMER);
- status_change_end(bl, SC_DRUMBATTLE, INVALID_TIMER);
- status_change_end(bl, SC_NIBELUNGEN, INVALID_TIMER);
- status_change_end(bl, SC_INTOABYSS, INVALID_TIMER);
- status_change_end(bl, SC_SIEGFRIED, INVALID_TIMER);
- status_change_end(bl, SC_WHISTLE, INVALID_TIMER);
- status_change_end(bl, SC_ASSNCROS, INVALID_TIMER);
- status_change_end(bl, SC_POEMBRAGI, INVALID_TIMER);
- status_change_end(bl, SC_APPLEIDUN, INVALID_TIMER);
- status_change_end(bl, SC_HUMMING, INVALID_TIMER);
- status_change_end(bl, SC_FORTUNE, INVALID_TIMER);
- status_change_end(bl, SC_SERVICEFORYOU, INVALID_TIMER);
- status_change_end(bl, SC_LONGING, INVALID_TIMER);
- status_change_end(bl, SC_SWING, INVALID_TIMER);
- status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER);
- status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER);
- status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER);
- status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
- status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
- status_change_end(bl, SC_DC_WINKCHARM, INVALID_TIMER);
- status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER);
- status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER);
- status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER);
- status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
- status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER);
- status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER);
- }
+ sc_start(src, bl, SC_FEAR, 5 + 5 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
break;
case SO_EARTHGRAVE:
- sc_start2(bl, SC_BLOODING, 5 * skill_lv, skill_lv, src->id, skill->get_time2(skill_id, skill_lv)); // Need official rate. [LimitLine]
+ sc_start2(src, bl, SC_BLOODING, 5 * skill_lv, skill_lv, src->id, skill->get_time2(skill_id, skill_lv)); // Need official rate. [LimitLine]
break;
case SO_DIAMONDDUST:
rate = 5 + 5 * skill_lv;
if( sc && sc->data[SC_COOLER_OPTION] )
- rate += rate * sc->data[SC_COOLER_OPTION]->val2 / 100;
- sc_start(bl, SC_COLD, rate, skill_lv, skill->get_time2(skill_id, skill_lv));
+ rate += sc->data[SC_COOLER_OPTION]->val3 / 5;
+ sc_start(src, bl, SC_COLD, rate, skill_lv, skill->get_time2(skill_id, skill_lv));
break;
case SO_VARETYR_SPEAR:
- sc_start(bl, SC_STUN, 5 + 5 * skill_lv, skill_lv, skill->get_time2(skill_id, skill_lv));
+ sc_start(src, bl, SC_STUN, 5 + 5 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
break;
case GN_SLINGITEM_RANGEMELEEATK:
if( sd ) {
switch( sd->itemid ) { // Starting SCs here instead of do it in skill->additional_effect to simplify the code.
- case 13261:
- sc_start(bl, SC_STUN, 100, skill_lv, skill->get_time2(GN_SLINGITEM, skill_lv));
- sc_start2(bl, SC_BLOODING, 100, skill_lv, src->id, skill->get_time2(GN_SLINGITEM, skill_lv));
+ case ITEMID_COCONUT_BOMB:
+ sc_start(src, bl, SC_STUN, 100, skill_lv, 5000); // 5 seconds until I get official
+ sc_start(src, bl, SC_BLOODING, 100, skill_lv, 10000);
break;
- case 13262:
- sc_start(bl, SC_MELON_BOMB, 100, skill_lv, skill->get_time(GN_SLINGITEM, skill_lv)); // Reduces ASPD and moviment speed
+ case ITEMID_MELON_BOMB:
+ sc_start(src, bl, SC_MELON_BOMB, 100, skill_lv, 60000); // Reduces ASPD and moviment speed
break;
- case 13264:
- sc_start(bl, SC_BANANA_BOMB, 100, skill_lv, skill->get_time(GN_SLINGITEM, skill_lv)); // Reduces LUK ??Needed confirm it, may be it's bugged in kRORE?
- sc_start(bl, SC_BANANA_BOMB_SITDOWN_POSTDELAY, 75, skill_lv, skill->get_time(GN_SLINGITEM_RANGEMELEEATK,skill_lv)); // Sitdown for 3 seconds.
+ case ITEMID_BANANA_BOMB:
+ sc_start(src, bl, SC_BANANA_BOMB, 100, skill_lv, 60000); // Reduces LUK? Needed confirm it, may be it's bugged in kRORE?
+ sc_start(src, bl, SC_BANANA_BOMB_SITDOWN_POSTDELAY, (sd? sd->status.job_level:0) + sstatus->dex / 6 + tstatus->agi / 4 - tstatus->luk / 5 - status->get_lv(bl) + status->get_lv(src), skill_lv, 1000); // Sitdown for 3 seconds.
break;
}
sd->itemid = -1;
}
break;
case GN_HELLS_PLANT_ATK:
- sc_start(bl, SC_STUN, 5 + 5 * skill_lv, skill_lv, skill->get_time2(skill_id, skill_lv));
- sc_start2(bl, SC_BLOODING, 20 + 10 * skill_lv, skill_lv, src->id,skill->get_time2(skill_id, skill_lv));
+ sc_start(src, bl, SC_STUN, 20 + 10 * skill_lv, skill_lv, skill->get_time2(skill_id, skill_lv));
+ sc_start2(src, bl, SC_BLOODING, 5 + 5 * skill_lv, skill_lv, src->id,skill->get_time2(skill_id, skill_lv));
break;
case EL_WIND_SLASH: // Non confirmed rate.
- sc_start2(bl, SC_BLOODING, 25, skill_lv, src->id, skill->get_time(skill_id,skill_lv));
+ sc_start2(src, bl, SC_BLOODING, 25, skill_lv, src->id, skill->get_time(skill_id,skill_lv));
break;
case EL_STONE_HAMMER:
rate = 10 * skill_lv;
- sc_start(bl, SC_STUN, rate, skill_lv, skill->get_time(skill_id,skill_lv));
+ sc_start(src, bl, SC_STUN, rate, skill_lv, skill->get_time(skill_id,skill_lv));
break;
case EL_ROCK_CRUSHER:
case EL_ROCK_CRUSHER_ATK:
- sc_start(bl,status->skill2sc(skill_id),50,skill_lv,skill->get_time(EL_ROCK_CRUSHER,skill_lv));
+ sc_start(src, bl,status->skill2sc(skill_id),50,skill_lv,skill->get_time(EL_ROCK_CRUSHER,skill_lv));
break;
case EL_TYPOON_MIS:
- sc_start(bl,SC_SILENCE,10*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src, bl,SC_SILENCE,10*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
break;
case KO_JYUMONJIKIRI:
- sc_start(bl,SC_KO_JYUMONJIKIRI,90,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src, bl,SC_KO_JYUMONJIKIRI,90,skill_lv,skill->get_time(skill_id,skill_lv));
break;
case KO_MAKIBISHI:
- sc_start(bl, SC_STUN, 10 * skill_lv, skill_lv, 1000 * (skill_lv / 2 + 2));
+ sc_start(src, bl, SC_STUN, 10 * skill_lv, skill_lv, 1000 * (skill_lv / 2 + 2));
break;
case MH_LAVA_SLIDE:
- if (tsc && !tsc->data[SC_BURNING]) sc_start4(bl, SC_BURNING, 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time(skill_id, skill_lv));
+ if (tsc && !tsc->data[SC_BURNING]) sc_start4(src, bl, SC_BURNING, 10 * skill_lv, skill_lv, 0, src->id, 0, skill->get_time(skill_id, skill_lv));
break;
case MH_STAHL_HORN:
- sc_start(bl, SC_STUN, (20 + 4 * (skill_lv-1)), skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, SC_STUN, (20 + 4 * (skill_lv-1)), skill_lv, skill->get_time(skill_id, skill_lv));
break;
case MH_NEEDLE_OF_PARALYZE:
- sc_start(bl, SC_NEEDLE_OF_PARALYZE, 40 + (5*skill_lv), skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, SC_NEEDLE_OF_PARALYZE, 40 + (5*skill_lv), skill_lv, skill->get_time(skill_id, skill_lv));
break;
case GN_ILLUSIONDOPING:
- if( sc_start(bl, SC_ILLUSIONDOPING, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)) ) //custom rate.
- sc_start(bl, SC_ILLUSION, 100, skill_lv, skill->get_time(skill_id, skill_lv));
+ if( sc_start(src, bl, SC_ILLUSIONDOPING, 10 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv)) ) //custom rate.
+ sc_start(src, bl, SC_ILLUSION, 100, skill_lv, skill->get_time(skill_id, skill_lv));
break;
}
@@ -1356,14 +1349,14 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
src = sd?&sd->bl:src;
}
- if( attack_type&BF_WEAPON ) {
+ if( attack_type&BF_WEAPON && skill_id != CR_REFLECTSHIELD ) {
// Coma, Breaking Equipment
if( sd && sd->special_state.bonus_coma ) {
rate = sd->weapon_coma_ele[tstatus->def_ele];
rate += sd->weapon_coma_race[tstatus->race];
rate += sd->weapon_coma_race[tstatus->mode&MD_BOSS?RC_BOSS:RC_NONBOSS];
if (rate)
- status->change_start(bl, SC_COMA, rate, 0, 0, src->id, 0, 0, 0);
+ status->change_start(src, bl, SC_COMA, rate, 0, 0, src->id, 0, 0, 0);
}
if( sd && battle_config.equip_self_break_rate )
{ // Self weapon breaking
@@ -1434,7 +1427,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
if( sd && !status->isdead(bl) && sd->autospell[0].id ) {
struct block_list *tbl;
struct unit_data *ud;
- int i, skill_lv, type, notok;
+ int i, auto_skill_lv, type, notok;
for (i = 0; i < ARRAYLENGTH(sd->autospell) && sd->autospell[i].id; i++) {
@@ -1452,8 +1445,8 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
if ( notok )
continue;
- skill_lv = sd->autospell[i].lv?sd->autospell[i].lv:1;
- if (skill_lv < 0) skill_lv = 1+rnd()%(-skill_lv);
+ auto_skill_lv = sd->autospell[i].lv?sd->autospell[i].lv:1;
+ if (auto_skill_lv < 0) auto_skill_lv = 1+rnd()%(-auto_skill_lv);
rate = (!sd->state.arrow_atk) ? sd->autospell[i].rate : sd->autospell[i].rate / 2;
@@ -1466,18 +1459,18 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
int maxcount = 0;
if( !(BL_PC&battle_config.skill_reiteration) &&
skill->get_unit_flag(temp)&UF_NOREITERATION &&
- skill->check_unit_range(src,tbl->x,tbl->y,temp,skill_lv)
+ skill->check_unit_range(src,tbl->x,tbl->y,temp,auto_skill_lv)
) {
continue;
}
if( BL_PC&battle_config.skill_nofootset &&
skill->get_unit_flag(temp)&UF_NOFOOTSET &&
- skill->check_unit_range2(src,tbl->x,tbl->y,temp,skill_lv)
+ skill->check_unit_range2(src,tbl->x,tbl->y,temp,auto_skill_lv)
) {
continue;
}
if( BL_PC&battle_config.land_skill_limit &&
- (maxcount = skill->get_maxcount(temp, skill_lv)) > 0
+ (maxcount = skill->get_maxcount(temp, auto_skill_lv)) > 0
) {
int v;
for(v=0;v<MAX_SKILLUNITGROUP && sd->ud.skillunit[v] && maxcount;v++) {
@@ -1490,7 +1483,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
}
}
if( battle_config.autospell_check_range &&
- !battle->check_range(src, tbl, skill->get_range2(src, temp,skill_lv) + (temp == RG_CLOSECONFINE?0:1)) )
+ !battle->check_range(src, tbl, skill->get_range2(src, temp,auto_skill_lv) + (temp == RG_CLOSECONFINE?0:1)) )
continue;
if (temp == AS_SONICBLOW)
@@ -1499,24 +1492,24 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
type = CAST_GROUND;
sd->state.autocast = 1;
- skill->consume_requirement(sd,temp,skill_lv,1);
+ skill->consume_requirement(sd,temp,auto_skill_lv,1);
skill->toggle_magicpower(src, temp);
switch (type) {
case CAST_GROUND:
- skill->castend_pos2(src, tbl->x, tbl->y, temp, skill_lv, tick, 0);
+ skill->castend_pos2(src, tbl->x, tbl->y, temp, auto_skill_lv, tick, 0);
break;
case CAST_NODAMAGE:
- skill->castend_nodamage_id(src, tbl, temp, skill_lv, tick, 0);
+ skill->castend_nodamage_id(src, tbl, temp, auto_skill_lv, tick, 0);
break;
case CAST_DAMAGE:
- skill->castend_damage_id(src, tbl, temp, skill_lv, tick, 0);
+ skill->castend_damage_id(src, tbl, temp, auto_skill_lv, tick, 0);
break;
}
sd->state.autocast = 0;
//Set canact delay. [Skotlex]
ud = unit->bl2ud(src);
if (ud) {
- rate = skill->delay_fix(src, temp, skill_lv);
+ rate = skill->delay_fix(src, temp, auto_skill_lv);
if (DIFF_TICK(ud->canact_tick, tick + rate) < 0){
ud->canact_tick = tick+rate;
if ( battle_config.display_status_timers && sd )
@@ -1569,7 +1562,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
return 0;
}
-int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint16 skill_id, unsigned int tick) {
+int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint16 skill_id, int64 tick) {
int temp, skill_lv, i, type, notok;
struct block_list *tbl;
@@ -1667,7 +1660,7 @@ int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint1
* type of skills, so not every instance of skill->additional_effect needs a call
* to this one.
*/
-int skill_counter_additional_effect(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, unsigned int tick) {
+int skill_counter_additional_effect(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int attack_type, int64 tick) {
int rate;
struct map_session_data *sd=NULL;
struct map_session_data *dstsd=NULL;
@@ -1700,19 +1693,19 @@ int skill_counter_additional_effect(struct block_list* src, struct block_list *b
time = skill->get_time2(status->sc2skill(type),7);
if (dstsd->addeff2[i].flag&ATF_TARGET)
- status->change_start(src,type,rate,7,0,0,0,time,0);
+ status->change_start(bl,src,type,rate,7,0,0,0,time,0);
if (dstsd->addeff2[i].flag&ATF_SELF && !status->isdead(bl))
- status->change_start(bl,type,rate,7,0,0,0,time,0);
+ status->change_start(bl,bl,type,rate,7,0,0,0,time,0);
}
}
switch(skill_id){
case MO_EXTREMITYFIST:
- sc_start(src,SC_EXTREMITYFIST,100,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,src,SC_EXTREMITYFIST,100,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case GS_FULLBUSTER:
- sc_start(src,SC_BLIND,2*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,src,SC_BLIND,2*skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case HFLI_SBR44: //[orn]
case HVAN_EXPLOSION:
@@ -1731,7 +1724,7 @@ int skill_counter_additional_effect(struct block_list* src, struct block_list *b
if( sd && (sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR
&& rnd()%10000 < battle_config.sg_miracle_skill_ratio) //SG_MIRACLE [Komurka]
- sc_start(src,SC_MIRACLE,100,1,battle_config.sg_miracle_skill_duration);
+ sc_start(src,src,SC_MIRACLE,100,1,battle_config.sg_miracle_skill_duration);
if( sd && skill_id && attack_type&BF_MAGIC && status->isdead(bl)
&& !(skill->get_inf(skill_id)&(INF_GROUND_SKILL|INF_SELF_SKILL))
@@ -1779,7 +1772,7 @@ int skill_counter_additional_effect(struct block_list* src, struct block_list *b
if(dstsd && !status->isdead(bl) && dstsd->autospell2[0].id && !(skill_id && skill->get_nk(skill_id)&NK_NO_DAMAGE)) {
struct block_list *tbl;
struct unit_data *ud;
- int i, skill_id, skill_lv, rate, type, notok;
+ int i, auto_skill_id, auto_skill_lv, type, notok;
for (i = 0; i < ARRAYLENGTH(dstsd->autospell2) && dstsd->autospell2[i].id; i++) {
@@ -1788,16 +1781,16 @@ int skill_counter_additional_effect(struct block_list* src, struct block_list *b
dstsd->autospell2[i].flag&attack_type&BF_SKILLMASK))
continue; // one or more trigger conditions were not fulfilled
- skill_id = (dstsd->autospell2[i].id > 0) ? dstsd->autospell2[i].id : -dstsd->autospell2[i].id;
- skill_lv = dstsd->autospell2[i].lv?dstsd->autospell2[i].lv:1;
- if (skill_lv < 0) skill_lv = 1+rnd()%(-skill_lv);
+ auto_skill_id = (dstsd->autospell2[i].id > 0) ? dstsd->autospell2[i].id : -dstsd->autospell2[i].id;
+ auto_skill_lv = dstsd->autospell2[i].lv?dstsd->autospell2[i].lv:1;
+ if (auto_skill_lv < 0) auto_skill_lv = 1+rnd()%(-auto_skill_lv);
rate = dstsd->autospell2[i].rate;
if (attack_type&BF_LONG)
rate>>=1;
dstsd->state.autocast = 1;
- notok = skill->not_ok(skill_id, dstsd);
+ notok = skill->not_ok(auto_skill_id, dstsd);
dstsd->state.autocast = 0;
if ( notok )
@@ -1808,26 +1801,26 @@ int skill_counter_additional_effect(struct block_list* src, struct block_list *b
tbl = (dstsd->autospell2[i].id < 0) ? bl : src;
- if( (type = skill->get_casttype(skill_id)) == CAST_GROUND ) {
+ if( (type = skill->get_casttype(auto_skill_id)) == CAST_GROUND ) {
int maxcount = 0;
if( !(BL_PC&battle_config.skill_reiteration) &&
- skill->get_unit_flag(skill_id)&UF_NOREITERATION &&
- skill->check_unit_range(bl,tbl->x,tbl->y,skill_id,skill_lv)
+ skill->get_unit_flag(auto_skill_id)&UF_NOREITERATION &&
+ skill->check_unit_range(bl,tbl->x,tbl->y,auto_skill_id,auto_skill_lv)
) {
continue;
}
if( BL_PC&battle_config.skill_nofootset &&
- skill->get_unit_flag(skill_id)&UF_NOFOOTSET &&
- skill->check_unit_range2(bl,tbl->x,tbl->y,skill_id,skill_lv)
+ skill->get_unit_flag(auto_skill_id)&UF_NOFOOTSET &&
+ skill->check_unit_range2(bl,tbl->x,tbl->y,auto_skill_id,auto_skill_lv)
) {
continue;
}
if( BL_PC&battle_config.land_skill_limit &&
- (maxcount = skill->get_maxcount(skill_id, skill_lv)) > 0
+ (maxcount = skill->get_maxcount(auto_skill_id, auto_skill_lv)) > 0
) {
int v;
for(v=0;v<MAX_SKILLUNITGROUP && dstsd->ud.skillunit[v] && maxcount;v++) {
- if(dstsd->ud.skillunit[v]->skill_id == skill_id)
+ if(dstsd->ud.skillunit[v]->skill_id == auto_skill_id)
maxcount--;
}
if( maxcount == 0 ) {
@@ -1836,27 +1829,27 @@ int skill_counter_additional_effect(struct block_list* src, struct block_list *b
}
}
- if( !battle->check_range(src, tbl, skill->get_range2(src, skill_id,skill_lv) + (skill_id == RG_CLOSECONFINE?0:1)) && battle_config.autospell_check_range )
+ if( !battle->check_range(src, tbl, skill->get_range2(src, auto_skill_id,auto_skill_lv) + (auto_skill_id == RG_CLOSECONFINE?0:1)) && battle_config.autospell_check_range )
continue;
dstsd->state.autocast = 1;
- skill->consume_requirement(dstsd,skill_id,skill_lv,1);
+ skill->consume_requirement(dstsd,auto_skill_id,auto_skill_lv,1);
switch (type) {
case CAST_GROUND:
- skill->castend_pos2(bl, tbl->x, tbl->y, skill_id, skill_lv, tick, 0);
+ skill->castend_pos2(bl, tbl->x, tbl->y, auto_skill_id, auto_skill_lv, tick, 0);
break;
case CAST_NODAMAGE:
- skill->castend_nodamage_id(bl, tbl, skill_id, skill_lv, tick, 0);
+ skill->castend_nodamage_id(bl, tbl, auto_skill_id, auto_skill_lv, tick, 0);
break;
case CAST_DAMAGE:
- skill->castend_damage_id(bl, tbl, skill_id, skill_lv, tick, 0);
+ skill->castend_damage_id(bl, tbl, auto_skill_id, auto_skill_lv, tick, 0);
break;
}
dstsd->state.autocast = 0;
//Set canact delay. [Skotlex]
ud = unit->bl2ud(bl);
if (ud) {
- rate = skill->delay_fix(bl, skill_id, skill_lv);
+ rate = skill->delay_fix(bl, auto_skill_id, auto_skill_lv);
if (DIFF_TICK(ud->canact_tick, tick + rate) < 0){
ud->canact_tick = tick+rate;
if ( battle_config.display_status_timers && dstsd )
@@ -1936,7 +1929,7 @@ int skill_break_equip (struct block_list *bl, unsigned short where, int rate, in
else if (rnd()%10000 >= rate)
where&=~where_list[i];
else if (!sd && !(status_get_mode(bl)&MD_BOSS)) //Cause Strip effect.
- sc_start(bl,scatk[i],100,0,skill->get_time(status->sc2skill(scatk[i]),1));
+ sc_start(bl,bl,scatk[i],100,0,skill->get_time(status->sc2skill(scatk[i]),1));
}
}
if (!where) //Nothing to break.
@@ -2001,7 +1994,7 @@ int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int
if (!where) return 0;
for (i = 0; i < ARRAYLENGTH(pos); i++) {
- if (where&pos[i] && !sc_start(bl, sc_atk[i], 100, lv, time))
+ if (where&pos[i] && !sc_start(bl, bl, sc_atk[i], 100, lv, time))
where&=~pos[i];
}
return where?1:0;
@@ -2043,7 +2036,7 @@ int skill_blown(struct block_list* src, struct block_list* target, int count, in
break;
case BL_SKILL:
su = (struct skill_unit *)target;
- if( su && su->group && su->group->unit_id == UNT_ANKLESNARE )
+ if( su && su->group && (su->group->unit_id == UNT_ANKLESNARE || su->group->unit_id == UNT_REVERBERATION))
return 0; // ankle snare cannot be knocked back
break;
}
@@ -2109,15 +2102,15 @@ int skill_magic_reflect(struct block_list* src, struct block_list* bl, int type)
* flag&0x2000 is used to signal that the skill_lv should be passed as -1 to the
* client (causes player characters to not scream skill name)
*-------------------------------------------------------------------------*/
-int skill_attack (int attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) {
+int skill_attack(int attack_type, struct block_list* src, struct block_list *dsrc, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
struct Damage dmg;
struct status_data *sstatus, *tstatus;
struct status_change *sc;
struct map_session_data *sd, *tsd;
int type;
int64 damage;
- int8 rmdamage=0;//magic reflected
- bool additional_effects = true;
+ bool rmdamage = false;//magic reflected
+ bool additional_effects = true, shadow_flag = false;
if(skill_id > 0 && !skill_lv) return 0;
@@ -2173,7 +2166,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
if( (dmg.damage || dmg.damage2) && (type = skill->magic_reflect(src, bl, src==dsrc)) ) {
//Magic reflection, switch caster/target
struct block_list *tbl = bl;
- rmdamage = 1;
+ rmdamage = true;
bl = src;
src = tbl;
dsrc = tbl;
@@ -2184,11 +2177,12 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
sc = NULL; //Don't need it.
/* bugreport:2564 flag&2 disables double casting trigger */
flag |= 2;
-
+ /* bugreport:7859 magical reflect'd zeroes blewcount */
+ dmg.blewcount = 0;
//Spirit of Wizard blocks Kaite's reflection
if( type == 2 && sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_WIZARD )
{ //Consume one Fragment per hit of the casted skill? [Skotlex]
- type = tsd?pc->search_inventory (tsd, 7321):0;
+ type = tsd?pc->search_inventory(tsd, ITEMID_FRAGMENT_OF_CRYSTAL):0;
if (type >= 0) {
if ( tsd ) pc->delitem(tsd, type, 1, 0, 1, LOG_TYPE_CONSUME);
dmg.damage = dmg.damage2 = 0;
@@ -2275,7 +2269,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
}
if(sd) {
- int flag = 0; //Used to signal if this skill can be combo'ed later on.
+ int combo = 0; //Used to signal if this skill can be combo'ed later on.
struct status_change_entry *sce;
if ((sce = sd->sc.data[SC_COMBOATTACK])) {//End combo state after skill is invoked. [Skotlex]
switch (skill_id) {
@@ -2301,29 +2295,29 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
switch(skill_id) {
case MO_TRIPLEATTACK:
if (pc->checkskill(sd, MO_CHAINCOMBO) > 0 || pc->checkskill(sd, SR_DRAGONCOMBO) > 0)
- flag=1;
+ combo=1;
break;
case MO_CHAINCOMBO:
if(pc->checkskill(sd, MO_COMBOFINISH) > 0 && sd->spiritball > 0)
- flag=1;
+ combo=1;
break;
case MO_COMBOFINISH:
if (sd->status.party_id>0) //bonus from SG_FRIEND [Komurka]
party->skill_check(sd, sd->status.party_id, MO_COMBOFINISH, skill_lv);
if (pc->checkskill(sd, CH_TIGERFIST) > 0 && sd->spiritball > 0)
- flag=1;
+ combo=1;
case CH_TIGERFIST:
- if (!flag && pc->checkskill(sd, CH_CHAINCRUSH) > 0 && sd->spiritball > 1)
- flag=1;
+ if (!combo && pc->checkskill(sd, CH_CHAINCRUSH) > 0 && sd->spiritball > 1)
+ combo=1;
case CH_CHAINCRUSH:
- if (!flag && pc->checkskill(sd, MO_EXTREMITYFIST) > 0 && sd->spiritball > 0 && sd->sc.data[SC_EXPLOSIONSPIRITS])
- flag=1;
+ if (!combo && pc->checkskill(sd, MO_EXTREMITYFIST) > 0 && sd->spiritball > 0 && sd->sc.data[SC_EXPLOSIONSPIRITS])
+ combo=1;
break;
case AC_DOUBLE:
if( (tstatus->race == RC_BRUTE || tstatus->race == RC_INSECT) && pc->checkskill(sd, HT_POWER))
{
//TODO: This code was taken from Triple Blows, is this even how it should be? [Skotlex]
- sc_start2(src,SC_COMBOATTACK,100,HT_POWER,bl->id,2000);
+ sc_start2(NULL,src,SC_COMBOATTACK,100,HT_POWER,bl->id,2000);
clif->combo_delay(src,2000);
}
break;
@@ -2337,7 +2331,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
case SL_STIN:
case SL_STUN:
if (skill_lv >= 7 && !sd->sc.data[SC_SMA_READY])
- sc_start(src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA, skill_lv));
+ sc_start(src, src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA, skill_lv));
break;
case GS_FULLBUSTER:
//Can't attack nor use items until skill's delay expires. [Skotlex]
@@ -2345,21 +2339,21 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
break;
case TK_DODGE:
if( pc->checkskill(sd, TK_JUMPKICK) > 0 )
- flag = 1;
+ combo = 1;
break;
case SR_DRAGONCOMBO:
if( pc->checkskill(sd, SR_FALLENEMPIRE) > 0 )
- flag = 1;
+ combo = 1;
break;
case SR_FALLENEMPIRE:
if( pc->checkskill(sd, SR_TIGERCANNON) > 0 || pc->checkskill(sd, SR_GATEOFHELL) > 0 )
- flag = 1;
+ combo = 1;
break;
} //Switch End
- if (flag) { //Possible to chain
- if ( (flag = DIFF_TICK(sd->ud.canact_tick, tick)) < 50 ) flag = 50;/* less is a waste. */
- sc_start2(src,SC_COMBOATTACK,100,skill_id,bl->id,flag);
- clif->combo_delay(src, flag);
+ if (combo) { //Possible to chain
+ if ( (combo = DIFF_TICK32(sd->ud.canact_tick, tick)) < 50 ) combo = 50;/* less is a waste. */
+ sc_start2(NULL,src,SC_COMBOATTACK,100,skill_id,bl->id,combo);
+ clif->combo_delay(src, combo);
}
}
@@ -2379,7 +2373,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
case NPC_CRITICALSLASH:
case TF_DOUBLE:
case GS_CHAINACTION:
- dmg.dmotion = clif->damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,dmg.type,dmg.damage2);
+ dmg.dmotion = clif->damage(src,bl,dmg.amotion,dmg.dmotion,damage,dmg.div_,dmg.type,dmg.damage2);
break;
case AS_SPLASHER:
@@ -2404,7 +2398,11 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,WL_CHAINLIGHTNING,-2,6);
break;
case LG_OVERBRAND_BRANDISH:
+ case LG_OVERBRAND:
+ dmg.amotion = status_get_amotion(src) * 2;
case LG_OVERBRAND_PLUSATK:
+ dmg.dmotion = clif->skill_damage(dsrc,bl,tick,status_get_amotion(src),dmg.dmotion,damage,dmg.div_,skill_id,-1,5);
+ break;
case EL_FIRE_BOMB:
case EL_FIRE_BOMB_ATK:
case EL_FIRE_WAVE:
@@ -2422,18 +2420,23 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
case EL_HURRICANE:
case EL_HURRICANE_ATK:
case KO_BAKURETSU:
- case GN_CRAZYWEED_ATK:
case NC_MAGMA_ERUPTION:
dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,5);
break;
case GN_SLINGITEM_RANGEMELEEATK:
dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,GN_SLINGITEM,-2,6);
break;
+ case SC_FEINTBOMB:
+ dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,skill_lv,5);
+ break;
+ case GN_CRAZYWEED_ATK:
+ dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id, -2, 6);
+ break;
case EL_STONE_RAIN:
dmg.dmotion = clif->skill_damage(dsrc,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,(flag&1)?8:5);
break;
case WM_SEVERE_RAINSTORM_MELEE:
- dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_SEVERE_RAINSTORM,skill_lv,5);
+ dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_SEVERE_RAINSTORM,-2,6);
break;
case WM_REVERBERATION_MELEE:
case WM_REVERBERATION_MAGIC:
@@ -2508,6 +2511,9 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
case GN_HELLS_PLANT_ATK:
copy_skill = GN_HELLS_PLANT;
break;
+ case GN_SLINGITEM_RANGEMELEEATK:
+ copy_skill = GN_SLINGITEM;
+ break;
case LG_OVERBRAND_BRANDISH:
case LG_OVERBRAND_PLUSATK:
copy_skill = LG_OVERBRAND;
@@ -2533,8 +2539,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
}
tsd->reproduceskill_id = copy_skill;
- pc_setglobalreg(tsd, "REPRODUCE_SKILL", copy_skill);
- pc_setglobalreg(tsd, "REPRODUCE_SKILL_LV", lv);
+ pc_setglobalreg(tsd, script->add_str("REPRODUCE_SKILL"), copy_skill);
+ pc_setglobalreg(tsd, script->add_str("REPRODUCE_SKILL_LV"), lv);
tsd->status.skill[cidx].id = copy_skill;
tsd->status.skill[cidx].lv = lv;
@@ -2556,8 +2562,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
lv = type;
tsd->cloneskill_id = copy_skill;
- pc_setglobalreg(tsd, "CLONE_SKILL", copy_skill);
- pc_setglobalreg(tsd, "CLONE_SKILL_LV", lv);
+ pc_setglobalreg(tsd, script->add_str("CLONE_SKILL"), copy_skill);
+ pc_setglobalreg(tsd, script->add_str("CLONE_SKILL_LV"), lv);
tsd->status.skill[cidx].id = copy_skill;
tsd->status.skill[cidx].lv = lv;
@@ -2574,10 +2580,12 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
if (ud && DIFF_TICK(ud->attackabletime, tick + type) < 0)
ud->attackabletime = tick + type;
}
+
+ shadow_flag = skill->check_shadowform(bl, damage, dmg.div_);
if( !dmg.amotion ) {
//Instant damage
- if( !sc || (!sc->data[SC_DEVOTION] && skill_id != CR_REFLECTSHIELD) )
+ if( (!sc || (!sc->data[SC_DEVOTION] && skill_id != CR_REFLECTSHIELD)) && !shadow_flag)
status_fix_damage(src,bl,damage,dmg.dmotion); //Deal damage before knockback to allow stuff like firewall+storm gust combo.
if( !status->isdead(bl) && additional_effects )
skill->additional_effect(src,bl,skill_id,skill_lv,dmg.flag,dmg.dmg_lv,tick);
@@ -2586,7 +2594,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
}
// Hell Inferno burning status only starts if Fire part hits.
if( skill_id == WL_HELLINFERNO && dmg.damage > 0 && !(flag&ELE_DARK) )
- sc_start4(bl,SC_BURNING,55+5*skill_lv,skill_lv,0,src->id,0,skill->get_time(skill_id,skill_lv));
+ sc_start4(src,bl,SC_BURNING,55+5*skill_lv,skill_lv,0,src->id,0,skill->get_time(skill_id,skill_lv));
// Apply knock back chance in SC_TRIANGLESHOT skill.
else if( skill_id == SC_TRIANGLESHOT && rnd()%100 > (1 + skill_lv) )
dmg.blewcount = 0;
@@ -2599,7 +2607,6 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
case MG_FIREWALL:
case PR_SANCTUARY:
case SC_TRIANGLESHOT:
- case LG_OVERBRAND:
case SR_KNUCKLEARROW:
case GN_WALLOFTHORN:
case EL_FIRE_MANTLE:
@@ -2607,7 +2614,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
break;
// This ensures the storm randomly pushes instead of exactly a cell backwards per official mechanics.
case WZ_STORMGUST:
- dir = rand()%8;
+ dir = rnd()%8;
break;
case WL_CRIMSONROCK:
dir = map->calc_dir(bl,skill->area_temp[4],skill->area_temp[5]);
@@ -2621,15 +2628,9 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
//blown-specific handling
switch( skill_id ) {
- case LG_OVERBRAND:
- if( skill->blown(dsrc,bl,dmg.blewcount,dir,0) ) {
- short dir_x, dir_y;
- dir_x = dirx[(dir+4)%8];
- dir_y = diry[(dir+4)%8];
- if( map->getcell(bl->m, bl->x+dir_x, bl->y+dir_y, CELL_CHKNOPASS) != 0 )
- skill->addtimerskill(src, tick + status_get_amotion(src), bl->id, 0, 0, LG_OVERBRAND_PLUSATK, skill_lv, BF_WEAPON, flag );
- } else
- skill->addtimerskill(src, tick + status_get_amotion(src), bl->id, 0, 0, LG_OVERBRAND_PLUSATK, skill_lv, BF_WEAPON, flag );
+ case LG_OVERBRAND_BRANDISH:
+ if( skill->blown(dsrc,bl,dmg.blewcount,dir,0) < dmg.blewcount )
+ skill->addtimerskill(src, tick + status_get_amotion(src), bl->id, 0, 0, LG_OVERBRAND_PLUSATK, skill_lv, BF_WEAPON, flag|SD_ANIMATION);
break;
case SR_KNUCKLEARROW:
if( skill->blown(dsrc,bl,dmg.blewcount,dir,0) && !(flag&4) ) {
@@ -2640,11 +2641,6 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
skill->addtimerskill(src, tick + 300 * ((flag&2) ? 1 : 2), bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag|4);
}
break;
- case GN_WALLOFTHORN:
- unit->stop_walking(bl,1);
- skill->blown(dsrc,bl,dmg.blewcount,dir, 0x2 );
- clif->fixpos(bl);
- break;
default:
skill->blown(dsrc,bl,dmg.blewcount,dir, 0x0 );
if ( !dmg.blewcount && bl->type == BL_SKILL && damage > 0 ){
@@ -2657,8 +2653,15 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
}
//Delayed damage must be dealt after the knockback (it needs to know actual position of target)
- if (dmg.amotion)
- battle->delay_damage(tick, dmg.amotion,src,bl,dmg.flag,skill_id,skill_lv,damage,dmg.dmg_lv,dmg.dmotion, additional_effects);
+ if (dmg.amotion){
+ if( shadow_flag ){
+ if( !status->isdead(bl) && additional_effects )
+ skill->additional_effect(src,bl,skill_id,skill_lv,dmg.flag,dmg.dmg_lv,tick);
+ if( dmg.flag > ATK_BLOCK )
+ skill->counter_additional_effect(src,bl,skill_id,skill_lv,dmg.flag,tick);
+ }else
+ battle->delay_damage(tick, dmg.amotion,src,bl,dmg.flag,skill_id,skill_lv,damage,dmg.dmg_lv,dmg.dmotion, additional_effects);
+ }
if( sc && sc->data[SC_DEVOTION] && skill_id != PA_PRESSURE ) {
struct status_change_entry *sce = sc->data[SC_DEVOTION];
@@ -2670,12 +2673,12 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
) && check_distance_bl(bl, d_bl, sce->val3) )
{
if(!rmdamage){
- clif->damage(d_bl,d_bl, timer->gettick(), 0, 0, damage, 0, 0, 0);
+ clif->damage(d_bl,d_bl, 0, 0, damage, 0, 0, 0);
status_fix_damage(NULL,d_bl, damage, 0);
} else{ //Reflected magics are done directly on the target not on paladin
//This check is only for magical skill.
//For BF_WEAPON skills types track var rdamage and function battle_calc_return_damage
- clif->damage(bl,bl, timer->gettick(), 0, 0, damage, 0, 0, 0);
+ clif->damage(bl,bl, 0, 0, damage, 0, 0, 0);
status_fix_damage(bl,bl, damage, 0);
}
}
@@ -2721,8 +2724,11 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
{
struct status_change *ssc = status->get_sc(src);
if( ssc && ssc->data[SC_POISONINGWEAPON] && rnd()%100 < 70 + 5*skill_lv ) {
- sc_start(bl,ssc->data[SC_POISONINGWEAPON]->val2,100,ssc->data[SC_POISONINGWEAPON]->val1,skill->get_time2(GC_POISONINGWEAPON, 1));
- status_change_end(src,SC_POISONINGWEAPON,INVALID_TIMER);
+ short rate = 100;
+ if ( ssc->data[SC_POISONINGWEAPON]->val1 == 9 )//Oblivion Curse gives a 2nd success chance after the 1st one passes which is reduceable. [Rytech]
+ rate = 100 - tstatus->int_ * 4 / 5;
+ sc_start(src, bl,ssc->data[SC_POISONINGWEAPON]->val2,rate,ssc->data[SC_POISONINGWEAPON]->val1,skill->get_time2(GC_POISONINGWEAPON,1) - (tstatus->vit + tstatus->luk) / 2 * 1000);
+ status_change_end(src,SC_POISONINGWEAPON,-1);
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
}
}
@@ -2758,21 +2764,21 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
* Checking bl battle flag and display dammage
* then call func with source,target,skill_id,skill_lv,tick,flag
*------------------------------------------*/
-int skill_area_sub (struct block_list *bl, va_list ap) {
+int skill_area_sub(struct block_list *bl, va_list ap) {
struct block_list *src;
uint16 skill_id,skill_lv;
int flag;
- unsigned int tick;
+ int64 tick;
SkillFunc func;
nullpo_ret(bl);
- src=va_arg(ap,struct block_list *);
- skill_id=va_arg(ap,int);
- skill_lv=va_arg(ap,int);
- tick=va_arg(ap,unsigned int);
- flag=va_arg(ap,int);
- func=va_arg(ap,SkillFunc);
+ src = va_arg(ap,struct block_list *);
+ skill_id = va_arg(ap,int);
+ skill_lv = va_arg(ap,int);
+ tick = va_arg(ap,int64);
+ flag = va_arg(ap,int);
+ func = va_arg(ap,SkillFunc);
if(battle->check_target(src,bl,flag) > 0) {
// several splash skills need this initial dummy packet to display correctly
@@ -2807,7 +2813,8 @@ int skill_check_unit_range_sub (struct block_list *bl, va_list ap) {
case MG_SAFETYWALL:
case AL_PNEUMA:
case SC_MAELSTROM:
- if(g_skill_id != MH_STEINWAND && g_skill_id != MG_SAFETYWALL && g_skill_id != AL_PNEUMA && g_skill_id != SC_MAELSTROM)
+ case SO_ELEMENTAL_SHIELD:
+ if(g_skill_id != MH_STEINWAND && g_skill_id != MG_SAFETYWALL && g_skill_id != AL_PNEUMA && g_skill_id != SC_MAELSTROM && g_skill_id != SO_ELEMENTAL_SHIELD)
return 0;
break;
case AL_WARP:
@@ -2836,6 +2843,8 @@ int skill_check_unit_range_sub (struct block_list *bl, va_list ap) {
case RA_ICEBOUNDTRAP:
case SC_DIMENSIONDOOR:
case SC_BLOODYLUST:
+ case SC_CHAOSPANIC:
+ case GN_HELLS_PLANT:
//Non stackable on themselves and traps (including venom dust which does not has the trap inf2 set)
if (skill_id != g_skill_id && !(skill->get_inf2(g_skill_id)&INF2_TRAP) && g_skill_id != AS_VENOMDUST && g_skill_id != MH_POISON_MIST)
return 0;
@@ -2888,6 +2897,12 @@ int skill_check_unit_range2 (struct block_list *bl, int x, int y, uint16 skill_i
case WZ_ICEWALL:
range = 2;
break;
+ case SC_MANHOLE:
+ range = 0;
+ break;
+ case GN_HELLS_PLANT:
+ range = 0;
+ break;
default: {
int layout_type = skill->get_unit_layout_type(skill_id,skill_lv);
if (layout_type==-1 || layout_type>MAX_SQUARE_LAYOUT) {
@@ -3027,14 +3042,14 @@ int skill_check_condition_mercenary(struct block_list *bl, int skill_id, int lv,
/*==========================================
* what the hell it doesn't need to receive this many params, it doesn't do anything ~_~
*------------------------------------------*/
-int skill_area_sub_count (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) {
+int skill_area_sub_count(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
return 1;
}
/*==========================================
*
*------------------------------------------*/
-int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
+int skill_timerskill(int tid, int64 tick, int id, intptr_t data) {
struct block_list *src = map->id2bl(id),*target;
struct unit_data *ud = unit->bl2ud(src);
struct skill_timerskill *skl;
@@ -3059,8 +3074,23 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
break; // Target not on Map
if(src->m != target->m)
break; // Different Maps
- if(status->isdead(src))
- break; // Caster is Dead
+ if(status->isdead(src)){
+ // Exceptions
+ switch(skl->skill_id){
+ case WL_CHAINLIGHTNING_ATK:
+ case WL_TETRAVORTEX_FIRE:
+ case WL_TETRAVORTEX_WATER:
+ case WL_TETRAVORTEX_WIND:
+ case WL_TETRAVORTEX_GROUND:
+ case SR_FLASHCOMBO_ATK_STEP1:
+ case SR_FLASHCOMBO_ATK_STEP2:
+ case SR_FLASHCOMBO_ATK_STEP3:
+ case SR_FLASHCOMBO_ATK_STEP4:
+ break;
+ default:
+ continue; // Caster is Dead
+ }
+ }
if(status->isdead(target) && skl->skill_id != RG_INTIMIDATE && skl->skill_id != WZ_WATERBALL)
break;
@@ -3129,25 +3159,25 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
case WL_TETRAVORTEX_WIND:
case WL_TETRAVORTEX_GROUND:
clif->skill_nodamage(src, target, skl->skill_id, skl->skill_lv, 1);
- skill_attack(BF_MAGIC, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag);
+ skill->attack(BF_MAGIC, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag);
skill->toggle_magicpower(src, skl->skill_id); // only the first hit will be amplify
if( skl->type == 4 ){
const enum sc_type scs[] = { SC_BURNING, SC_BLOODING, SC_FROSTMISTY, SC_STUN }; // status inflicts are depend on what summoned element is used.
int rate = skl->y, index = skl->x-1;
- sc_start2(target, scs[index], rate, skl->skill_lv, src->id, skill->get_time(WL_TETRAVORTEX,index));
+ sc_start2(src,target, scs[index], rate, skl->skill_lv, src->id, skill->get_time(WL_TETRAVORTEX,index+1));
}
break;
case WM_REVERBERATION_MELEE:
case WM_REVERBERATION_MAGIC:
- skill->castend_damage_id(src, target, skl->skill_id, skl->skill_lv, tick, skl->flag|SD_LEVEL); // damage should split among targets
+ skill->attack(skill->get_type(skl->skill_id),src, src, target, skl->skill_id, skl->skill_lv, 0, SD_LEVEL);
break;
case SC_FATALMENACE:
if( src == target ) // Casters Part
- unit->warp(src, -1, skl->x, skl->y, 3);
+ unit->warp(src, -1, skl->x, skl->y, CLR_TELEPORT);
else { // Target's Part
short x = skl->x, y = skl->y;
map->search_freecell(NULL, target->m, &x, &y, 2, 2, 1);
- unit->warp(target,-1,x,y,3);
+ unit->warp(target,-1,x,y,CLR_TELEPORT);
}
break;
case LG_MOONSLASHER:
@@ -3161,19 +3191,12 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
}
}
break;
- case LG_OVERBRAND_BRANDISH:
- case LG_OVERBRAND_PLUSATK:
- if( status->check_skilluse(src, target, skl->skill_id, 1) )
- skill->attack(BF_WEAPON, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag|SD_LEVEL);
- else
- clif->skill_damage(src, target, tick, status_get_amotion(src), status_get_dmotion(target), 0, 1, skl->skill_id, skl->skill_lv, skill->get_hit(skl->skill_id));
- break;
case SR_KNUCKLEARROW:
skill->attack(BF_WEAPON, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag|SD_LEVEL);
break;
case GN_SPORE_EXPLOSION:
map->foreachinrange(skill->area_sub, target, skill->get_splash(skl->skill_id, skl->skill_lv), BL_CHAR,
- src, skl->skill_id, skl->skill_lv, 0, skl->flag|1|BCT_ENEMY, skill->castend_damage_id);
+ src, skl->skill_id, skl->skill_lv, (int64)0, skl->flag|1|BCT_ENEMY, skill->castend_damage_id);
break;
case SR_FLASHCOMBO_ATK_STEP1:
case SR_FLASHCOMBO_ATK_STEP2:
@@ -3184,6 +3207,9 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
const enum e_skill combos[] = {SR_DRAGONCOMBO, SR_FALLENEMPIRE, SR_TIGERCANNON, SR_SKYNETBLOW};
if( (sd = ((TBL_PC*)src)) ){
uint16 cid = combos[skl->skill_id-SR_FLASHCOMBO_ATK_STEP1];
+ if( distance_xy(src->x, src->y, target->x, target->y) >= 3 )
+ break;
+ skill->consume_requirement(sd,cid,pc->checkskill(sd, cid),1);
skill->castend_damage_id(src, target, cid, pc->checkskill(sd, cid), tick, 0);
}
}
@@ -3195,6 +3221,14 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
skill->addtimerskill(src,tick+80,src->id,0,0,skl->skill_id,skl->skill_lv,skl->type+1,0);
}
break;
+ case RK_HUNDREDSPEAR:
+ if(src->type == BL_PC) {
+ int skill_lv = pc->checkskill((TBL_PC *)src, KN_SPEARBOOMERANG);
+ if(skill_lv > 0)
+ skill->attack(BF_WEAPON, src, src, target, KN_SPEARBOOMERANG, skill_lv, tick, skl->flag);
+ } else
+ skill->attack(BF_WEAPON, src, src, target, KN_SPEARBOOMERANG, 1, tick, skl->flag);
+ break;
case CH_PALMSTRIKE:
{
struct status_change* tsc = status->get_sc(target);
@@ -3225,15 +3259,30 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
else if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) )
skill->unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,skl->flag);
break;
- case GN_CRAZYWEED_ATK:
- {
- int dummy = 1, i = skill->get_unit_range(skl->skill_id,skl->skill_lv);
- map->foreachinarea(skill->cell_overlap, src->m, skl->x-i, skl->y-i, skl->x+i, skl->y+i, BL_SKILL, skl->skill_id, &dummy, src);
- }
- // FIXME: there's no 'break' here. If it was intended, please consider adding a comment (issue #160)
+ // fall through ...
case WL_EARTHSTRAIN:
skill->unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,(skl->type<<16)|skl->flag);
break;
+ case LG_OVERBRAND_BRANDISH:
+ {
+ short x2 = src->x, y2 = src->y, x = x2, y = y2;
+ switch( skl->type ){
+ case 0: case 1: case 7: x2 += 4; x -= 4; y2 += 4; break;
+ case 3: case 4: case 5: x2 += 4; x -= 4; y -= 4; break;
+ case 2: y2 += 4; y -= 4; x -= 4; break;
+ case 6: y2 += 4; y -= 4; x2 += 4; break;
+ }
+ map->foreachinarea(skill->area_sub, src->m, x, y, x2, y2, BL_CHAR, src, skl->skill_id, skl->skill_lv, tick, skl->flag|BCT_ENEMY|SD_ANIMATION|1,skill->castend_damage_id);
+ }
+ break;
+ case GN_CRAZYWEED:
+ if( skl->type >= 0 ) {
+ int x = skl->type>>16, y = skl->type&0xFFFF;
+ if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) )
+ skill->castend_pos2(src, x, y, GN_CRAZYWEED_ATK, skl->skill_lv, tick, skl->flag);
+ } else if( path->search_long(NULL, src->m, src->x, src->y, skl->x, skl->y, CELL_CHKWALL) )
+ skill->castend_pos2(src, skl->x, skl->y, GN_CRAZYWEED_ATK, skl->skill_lv, tick, skl->flag);
+ break;
}
}
} while (0);
@@ -3245,8 +3294,7 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
/*==========================================
*
*------------------------------------------*/
-int skill_addtimerskill (struct block_list *src, unsigned int tick, int target, int x,int y, uint16 skill_id, uint16 skill_lv, int type, int flag)
-{
+int skill_addtimerskill(struct block_list *src, int64 tick, int target, int x,int y, uint16 skill_id, uint16 skill_lv, int type, int flag) {
int i;
struct unit_data *ud;
nullpo_retr(1, src);
@@ -3285,6 +3333,17 @@ int skill_cleartimerskill (struct block_list *src)
for(i=0;i<MAX_SKILLTIMERSKILL;i++) {
if(ud->skilltimerskill[i]) {
+ switch(ud->skilltimerskill[i]->skill_id){
+ case WL_TETRAVORTEX_FIRE:
+ case WL_TETRAVORTEX_WATER:
+ case WL_TETRAVORTEX_WIND:
+ case WL_TETRAVORTEX_GROUND:
+ case SR_FLASHCOMBO_ATK_STEP1:
+ case SR_FLASHCOMBO_ATK_STEP2:
+ case SR_FLASHCOMBO_ATK_STEP3:
+ case SR_FLASHCOMBO_ATK_STEP4:
+ continue;
+ }
timer->delete(ud->skilltimerskill[i]->timer, skill->timerskill);
ers_free(skill->timer_ers, ud->skilltimerskill[i]);
ud->skilltimerskill[i]=NULL;
@@ -3292,14 +3351,16 @@ int skill_cleartimerskill (struct block_list *src)
}
return 1;
}
-int skill_activate_reverbetion( struct block_list *bl, va_list ap) {
+int skill_activate_reverberation(struct block_list *bl, va_list ap) {
struct skill_unit *su = (TBL_SKILL*)bl;
struct skill_unit_group *sg;
if( bl->type != BL_SKILL )
return 0;
- if( su->alive && (sg = su->group) && sg->skill_id == WM_REVERBERATION ) {
- map->foreachinrange(skill->trap_splash, bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, bl, timer->gettick());
- su->limit=DIFF_TICK(timer->gettick(),sg->tick);
+ if( su->alive && (sg = su->group) && sg->skill_id == WM_REVERBERATION && sg->unit_id == UNT_REVERBERATION ) {
+ int64 tick = timer->gettick();
+ clif->changetraplook(bl,UNT_USED_TRAPS);
+ map->foreachinrange(skill->trap_splash, bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, bl, tick);
+ su->limit = DIFF_TICK32(tick,sg->tick)+1500;
sg->unit_id = UNT_USED_TRAPS;
}
return 0;
@@ -3310,7 +3371,7 @@ int skill_reveal_trap (struct block_list *bl, va_list ap) {
if (su->alive && su->group && skill->get_inf2(su->group->skill_id)&INF2_TRAP) { //Reveal trap.
//Change look is not good enough, the client ignores it as an actual trap still. [Skotlex]
//clif->changetraplook(bl, su->group->unit_id);
- clif->skill_setunit(su);
+ clif->getareachar_skillunit(&su->bl,su,AREA);
return 1;
}
return 0;
@@ -3320,7 +3381,7 @@ int skill_reveal_trap (struct block_list *bl, va_list ap) {
*
*
*------------------------------------------*/
-int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag) {
+int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
struct map_session_data *sd = NULL;
struct status_data *tstatus;
struct status_change *sc;
@@ -3448,7 +3509,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case NPC_CRITICALWOUND:
case NPC_HELLPOWER:
case RK_SONICWAVE:
- case RK_HUNDREDSPEAR:
case RK_STORMBLAST:
case RK_CRUSHSTRIKE:
case AB_DUPLELIGHT_MELEE:
@@ -3470,10 +3530,13 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case SR_GENTLETOUCH_QUIET:
case WM_SEVERE_RAINSTORM_MELEE:
case WM_GREAT_ECHO:
+ case GN_CRAZYWEED_ATK:
case GN_SLINGITEM_RANGEMELEEATK:
case KO_JYUMONJIKIRI:
case KO_SETSUDAN:
case GC_DARKCROW:
+ case LG_OVERBRAND_BRANDISH:
+ case LG_OVERBRAND:
skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
break;
@@ -3482,9 +3545,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
**/
case NC_BOOSTKNUCKLE:
case NC_PILEBUNKER:
- case NC_VULCANARM:
case NC_COLDSLOWER:
- case NC_ARMSCANNON:
if (sd) pc->overheat(sd,1);
case RK_WINDCUTTER:
skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag|SD_ANIMATION);
@@ -3620,7 +3681,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
status_change_end(src, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
#ifdef RENEWAL
- sc_start(src,SC_EXTREMITYFIST2,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src, src,SC_EXTREMITYFIST2,100,skill_lv,skill->get_time(skill_id,skill_lv));
#endif // RENEWAL
} else {
status_change_end(src, SC_NJ_NEN, INVALID_TIMER);
@@ -3680,6 +3741,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case WL_JACKFROST:
case RA_ARROWSTORM:
case RA_WUGDASH:
+ case NC_VULCANARM:
+ case NC_ARMSCANNON:
case NC_SELFDESTRUCTION:
case NC_AXETORNADO:
case GC_ROLLINGCUTTER:
@@ -3691,9 +3754,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case SR_SKYNETBLOW:
case SR_WINDMILL:
case SR_RIDEINLIGHTNING:
- case WM_SOUND_OF_DESTRUCTION:
- case WM_REVERBERATION_MELEE:
- case WM_REVERBERATION_MAGIC:
+ case WM_REVERBERATION:
case SO_VARETYR_SPEAR:
case GN_CART_TORNADO:
case GN_CARTCANNON:
@@ -3744,8 +3805,10 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
skill->area_temp[4] = bl->x;
skill->area_temp[5] = bl->y;
}
- if( skill_id == WM_REVERBERATION_MELEE || skill_id == WM_REVERBERATION_MAGIC )
- skill->area_temp[1] = 0;
+
+ if( skill_id == NC_VULCANARM )
+ if (sd) pc->overheat(sd,1);
+
// if skill damage should be split among targets, count them
//SD_LEVEL -> Forced splash damage for Auto Blitz-Beat -> count targets
//special case: Venom Splasher uses a different range for searching than for splashing
@@ -3753,7 +3816,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
skill->area_temp[0] = map->foreachinrange(skill->area_sub, bl, (skill_id == AS_SPLASHER)?1:skill->get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, BCT_ENEMY, skill->area_sub_count);
// recursive invocation of skill->castend_damage_id() with flag|1
- map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), ( skill_id == WM_REVERBERATION_MELEE || skill_id == WM_REVERBERATION_MAGIC )?BL_CHAR:splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id);
+ map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id);
}
break;
@@ -3831,7 +3894,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
case CH_PALMSTRIKE: // Palm Strike takes effect 1sec after casting. [Skotlex]
// clif->skill_nodamage(src,bl,skill_id,skill_lv,0); //Can't make this one display the correct attack animation delay :/
- clif->damage(src,bl,tick,status_get_amotion(src),0,-1,1,4,0); //Display an absorbed damage attack.
+ clif->damage(src,bl,status_get_amotion(src),0,-1,1,4,0); //Display an absorbed damage attack.
skill->addtimerskill(src, tick + (1000+status_get_amotion(src)), bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag);
break;
@@ -3871,7 +3934,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case NPC_MAGICALATTACK:
skill->attack(BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag);
- sc_start(src,status->skill2sc(skill_id),100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src, src,status->skill2sc(skill_id),100,skill_lv,skill->get_time(skill_id,skill_lv));
break;
case HVAN_CAPRICE: //[blackhole89]
@@ -3933,7 +3996,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case SL_STIN:
case SL_STUN:
if (sd && !battle_config.allow_es_magic_pc && bl->type != BL_MOB) {
- status->change_start(src,SC_STUN,10000,skill_lv,0,0,0,500,10);
+ status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,500,10);
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
@@ -3966,7 +4029,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
if( (tsc = status->get_sc(bl)) && (tsc->data[SC_HIDING] )) {
clif->skill_nodamage(src,src,skill_id,skill_lv,1);
} else
- skill->attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag);
+ skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
}
break;
case NPC_SELFDESTRUCTION: {
@@ -4012,7 +4075,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case NJ_KASUMIKIRI:
if (skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag) > 0)
- sc_start(src,SC_HIDING,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,src,SC_HIDING,100,skill_lv,skill->get_time(skill_id,skill_lv));
break;
case NJ_KIRIKAGE:
if( !map_flag_gvg2(src->m) && !map->list[src->m].flag.battleground ) {
@@ -4025,13 +4088,28 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
status_change_end(src, SC_HIDING, INVALID_TIMER);
skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
break;
+ case RK_HUNDREDSPEAR:
+ skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
+ if(rnd()%100 < (10 + 3*skill_lv)) {
+ if( !sd || pc->checkskill(sd,KN_SPEARBOOMERANG) == 0 )
+ break; // Spear Boomerang auto cast chance only works if you have mastered Spear Boomerang.
+ skill->blown(src,bl,6,-1,0);
+ skill->addtimerskill(src,tick+800,bl->id,0,0,skill_id,skill_lv,BF_WEAPON,flag);
+ skill->castend_damage_id(src,bl,KN_SPEARBOOMERANG,1,tick,0);
+ }
+ break;
case RK_PHANTOMTHRUST:
+ {
+ struct map_session_data *tsd = BL_CAST(BL_PC, bl);
unit->setdir(src,map->calc_dir(src, bl->x, bl->y));
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
skill->blown(src,bl,distance_bl(src,bl)-1,unit->getdir(src),0);
- if( battle->check_target(src,bl,BCT_ENEMY) > 0 )
+ if( sd && tsd && sd->status.party_id && sd->status.party_id && sd->status.party_id == tsd->status.party_id ) // Don't damage party members.
+ ; // No damage to Members
+ else
skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
+ }
break;
case GC_DARKILLUSION:
@@ -4115,7 +4193,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
types[x][1] = 25; // 25% each for equal sharing
if( x == 3 ){
x = 0;
- sc_index = types[rand()%4][0];
+ sc_index = types[rnd()%4][0];
for(; x < 4; x++)
if(types[x][0] == sc_index)
rate += types[x][1];
@@ -4136,7 +4214,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
skill->toggle_magicpower(src, skill_id);
// Priority is to release SpellBook
if( sc && sc->data[SC_READING_SB] ) { // SpellBook
- uint16 skill_id, skill_lv, point, s = 0;
+ uint16 spell_skill_id, spell_skill_lv, point, s = 0;
int spell[SC_SPELLBOOK7-SC_SPELLBOOK1 + 1];
for(i = SC_SPELLBOOK7; i >= SC_SPELLBOOK1; i--) // List all available spell to be released
@@ -4145,10 +4223,10 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
if ( s == 0 )
break;
- i = spell[s==1?0:rand()%s];// Random select of spell to be released.
+ i = spell[s==1?0:rnd()%s];// Random select of spell to be released.
if( s && sc->data[i] ){// Now extract the data from the preserved spell
- skill_id = sc->data[i]->val1;
- skill_lv = sc->data[i]->val2;
+ spell_skill_id = sc->data[i]->val1;
+ spell_skill_lv = sc->data[i]->val2;
point = sc->data[i]->val3;
status_change_end(src, (sc_type)i, INVALID_TIMER);
}else //something went wrong :(
@@ -4159,36 +4237,35 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
else // Last spell to be released
status_change_end(src, SC_READING_SB, INVALID_TIMER);
- if( !skill->check_condition_castbegin(sd, skill_id, skill_lv) )
+ if( !skill->check_condition_castbegin(sd, spell_skill_id, spell_skill_lv) )
break;
- switch( skill->get_casttype(skill_id) ) {
+ switch( skill->get_casttype(spell_skill_id) ) {
case CAST_GROUND:
- skill->castend_pos2(src, bl->x, bl->y, skill_id, skill_lv, tick, 0);
+ skill->castend_pos2(src, bl->x, bl->y, spell_skill_id, spell_skill_lv, tick, 0);
break;
case CAST_NODAMAGE:
- skill->castend_nodamage_id(src, bl, skill_id, skill_lv, tick, 0);
+ skill->castend_nodamage_id(src, bl, spell_skill_id, spell_skill_lv, tick, 0);
break;
case CAST_DAMAGE:
- skill->castend_damage_id(src, bl, skill_id, skill_lv, tick, 0);
+ skill->castend_damage_id(src, bl, spell_skill_id, spell_skill_lv, tick, 0);
break;
}
- sd->ud.canact_tick = tick + skill->delay_fix(src, skill_id, skill_lv);
- clif->status_change(src, SI_POSTDELAY, 1, skill->delay_fix(src, skill_id, skill_lv), 0, 0, 0);
+ sd->ud.canact_tick = tick + skill->delay_fix(src, spell_skill_id, spell_skill_lv);
+ clif->status_change(src, SI_POSTDELAY, 1, skill->delay_fix(src, spell_skill_id, spell_skill_lv), 0, 0, 0);
- cooldown = skill_get_cooldown(skill_id, skill_lv);
+ cooldown = skill->get_cooldown(spell_skill_id, spell_skill_lv);
for (i = 0; i < ARRAYLENGTH(sd->skillcooldown) && sd->skillcooldown[i].id; i++) {
- if (sd->skillcooldown[i].id == skill_id){
+ if (sd->skillcooldown[i].id == spell_skill_id){
cooldown += sd->skillcooldown[i].val;
break;
}
}
if(cooldown)
- skill->blockpc_start(sd, skill_id, cooldown, false);
+ skill->blockpc_start(sd, spell_skill_id, cooldown);
}else if( sc ){ // Summon Balls
- int i = SC_SUMMON5;
- for(; i >= SC_SUMMON1; i--){
+ for(i = SC_SUMMON5; i >= SC_SUMMON1; i--){
if( sc->data[i] ){
int skillid = WL_SUMMON_ATK_FIRE + (sc->data[i]->val1 - WLS_FIRE);
skill->addtimerskill(src, tick + status_get_adelay(src) * (SC_SUMMON5 - i), bl->id, 0, 0, skillid, skill_lv, BF_MAGIC, flag);
@@ -4258,8 +4335,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case NC_INFRAREDSCAN:
if( flag&1 ) {
//TODO: Need a confirmation if the other type of hidden status is included to be scanned. [Jobbie]
- if( rnd()%100 < 50 )
- sc_start(bl, SC_INFRAREDSCAN, 10000, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, SC_INFRAREDSCAN, 10000, skill_lv, skill->get_time(skill_id, skill_lv));
status_change_end(bl, SC_HIDING, INVALID_TIMER);
status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER); // Need confirm it.
@@ -4271,7 +4347,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
case NC_MAGNETICFIELD:
- sc_start2(bl,SC_MAGNETICFIELD,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv));
+ sc_start2(src,bl,SC_MAGNETICFIELD,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv));
break;
case SC_FATALMENACE:
if( flag&1 )
@@ -4294,20 +4370,12 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
case LG_SHIELDSPELL:
- // flag&1: Phisycal Attack, flag&2: Magic Attack.
- skill->attack((flag&1)?BF_WEAPON:BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag);
- break;
-
- case LG_OVERBRAND:
- if( status->check_skilluse(src, bl, skill_id, 1) )
- skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag|SD_LEVEL);
- else
- clif->skill_damage(src, bl, tick, status_get_amotion(src), status_get_dmotion(bl), 0, 1, skill_id, skill_lv, skill->get_hit(skill_id));
+ if ( skill_lv == 1 )
+ skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
+ else if ( skill_lv == 2 )
+ skill->attack(BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag);
break;
- case LG_OVERBRAND_BRANDISH:
- skill->addtimerskill(src, tick + status_get_amotion(src)*8/10, bl->id, 0, 0, skill_id, skill_lv, BF_WEAPON, flag|SD_LEVEL);
- break;
case SR_DRAGONCOMBO:
skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
break;
@@ -4331,9 +4399,13 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER);
status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
+ status_change_end(bl, SC_SIREN, INVALID_TIMER);
+ status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER);
status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER);
- status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER);
+ status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
+ status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER);
status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER);
+ status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER);
status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER);
status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER);
@@ -4352,6 +4424,39 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
}
break;
+ case WM_SOUND_OF_DESTRUCTION:
+ {
+ struct status_change *tsc = status->get_sc(bl);
+ if( tsc && tsc->count && ( tsc->data[SC_SWING] || tsc->data[SC_SYMPHONY_LOVE] || tsc->data[SC_MOONLIT_SERENADE] ||
+ tsc->data[SC_RUSH_WINDMILL] || tsc->data[SC_ECHOSONG] || tsc->data[SC_HARMONIZE] ||
+ tsc->data[SC_SIREN] || tsc->data[SC_DEEP_SLEEP] || tsc->data[SC_SIRCLEOFNATURE] ||
+ tsc->data[SC_GLOOMYDAY] || tsc->data[SC_SONG_OF_MANA] ||
+ tsc->data[SC_DANCE_WITH_WUG] || tsc->data[SC_SATURDAY_NIGHT_FEVER] || tsc->data[SC_LERADS_DEW] ||
+ tsc->data[SC_MELODYOFSINK] || tsc->data[SC_BEYOND_OF_WARCRY] || tsc->data[SC_UNLIMITED_HUMMING_VOICE] ) &&
+ rnd()%100 < 4 * skill_lv + 2 * (sd ? pc->checkskill(sd,WM_LESSON) : 10) + 10 * battle->calc_chorusbonus(sd)) {
+ skill->attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag);
+ status->change_start(src,bl,SC_STUN,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),8);
+ status_change_end(bl, SC_SWING, INVALID_TIMER);
+ status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER);
+ status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER);
+ status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER);
+ status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
+ status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
+ status_change_end(bl, SC_SIREN, INVALID_TIMER);
+ status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER);
+ status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER);
+ status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
+ status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER);
+ status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER);
+ status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER);
+ status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER);
+ status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
+ status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER);
+ status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER);
+ }
+ }
+ break;
+
case SO_POISON_BUSTER:
{
struct status_change *tsc = status->get_sc(bl);
@@ -4365,10 +4470,10 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case GN_SPORE_EXPLOSION:
if( flag&1 )
- skill->attack(skill->get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
+ skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
else {
clif->skill_nodamage(src, bl, skill_id, 0, 1);
- skill->addtimerskill(src, timer->gettick() + skill->get_time(skill_id, skill_lv) - 1000, bl->id, 0, 0, skill_id, skill_lv, 0, 0);
+ skill->addtimerskill(src, timer->gettick() + skill->get_time(skill_id, skill_lv), bl->id, 0, 0, skill_id, skill_lv, 0, 0);
}
break;
@@ -4425,21 +4530,21 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case EL_TIDAL_WEAPON:
if( src->type == BL_ELEM ) {
struct elemental_data *ele = BL_CAST(BL_ELEM,src);
- struct status_change *sc = status->get_sc(&ele->bl);
+ struct status_change *esc = status->get_sc(&ele->bl);
struct status_change *tsc = status->get_sc(bl);
sc_type type = status->skill2sc(skill_id), type2;
type2 = type-1;
clif->skill_nodamage(src,battle->get_master(src),skill_id,skill_lv,1);
clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
- if( (sc && sc->data[type2]) || (tsc && tsc->data[type]) ) {
+ if( (esc && esc->data[type2]) || (tsc && tsc->data[type]) ) {
elemental->clean_single_effect(ele, skill_id);
}
if( rnd()%100 < 50 )
skill->attack(skill->get_type(skill_id),src,src,bl,skill_id,skill_lv,tick,flag);
else {
- sc_start(src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv));
- sc_start(battle->get_master(src),type,100,ele->bl.id,skill->get_time(skill_id,skill_lv));
+ sc_start(src, src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src, battle->get_master(src),type,100,ele->bl.id,skill->get_time(skill_id,skill_lv));
}
clif->skill_nodamage(src,src,skill_id,skill_lv,1);
}
@@ -4469,7 +4574,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
#endif
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start4(bl,SC_RG_CCONFINE_S,100,skill_lv,src->id,0,0,skill->get_time(skill_id,skill_lv)));
+ sc_start4(src,bl,SC_RG_CCONFINE_S,100,skill_lv,src->id,0,0,skill->get_time(skill_id,skill_lv)));
skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
break;
@@ -4522,8 +4627,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
/*==========================================
*
*------------------------------------------*/
-int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
-{
+int skill_castend_id(int tid, int64 tick, int id, intptr_t data) {
struct block_list *target, *src;
struct map_session_data *sd;
struct mob_data *md;
@@ -4667,6 +4771,9 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
else if (inf && battle->check_target(src, target, inf) <= 0){
if (sd) clif->skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0);
break;
+ } else if( ud->skill_id == RK_PHANTOMTHRUST && target->type != BL_MOB ) {
+ if( !map_flag_vs(src->m) && battle->check_target(src,target,BCT_PARTY) <= 0 )
+ break; // You can use Phantom Thurst on party members in normal maps too. [pakpil]
}
if( inf&BCT_ENEMY
@@ -4734,7 +4841,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
}
}
if(cooldown)
- skill->blockpc_start(sd, ud->skill_id, cooldown, false);
+ skill->blockpc_start(sd, ud->skill_id, cooldown);
}
if( battle_config.display_status_timers && sd )
clif->status_change(src, SI_POSTDELAY, 1, skill->delay_fix(src, ud->skill_id, ud->skill_lv), 0, 0, 0);
@@ -4752,7 +4859,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
if( td && td->func == status->change_timer && DIFF_TICK(td->tick,timer->gettick()+skill->get_time(ud->skill_id, ud->skill_lv)) > 0 )
break;
}
- sc_start2(src, SC_NOEQUIPSHIELD, 100, 0, 1, skill->get_time(ud->skill_id, ud->skill_lv));
+ sc_start2(src,src, SC_NOEQUIPSHIELD, 100, 0, 1, skill->get_time(ud->skill_id, ud->skill_lv));
break;
}
}
@@ -4767,8 +4874,11 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
// SC_MAGICPOWER needs to switch states before any damage is actually dealt
skill->toggle_magicpower(src, ud->skill_id);
+
+ /* On aegis damage skills are also increase by camouflage. Need confirmation on kRo.
if( ud->skill_id != RA_CAMOUFLAGE ) // only normal attack and auto cast skills benefit from its bonuses
status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER);
+ */
if (skill->get_casttype(ud->skill_id) == CAST_NODAMAGE)
skill->castend_nodamage_id(src,target,ud->skill_id,ud->skill_lv,tick,flag);
@@ -4785,7 +4895,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
sc->data[SC_SOULLINK]->val3 = 0; //Clear bounced spell check.
if( sc->data[SC_DANCING] && skill->get_inf2(ud->skill_id)&INF2_SONG_DANCE && sd )
- skill->blockpc_start(sd,BD_ADAPTATION,3000, false);
+ skill->blockpc_start(sd,BD_ADAPTATION,3000);
}
if( sd && ud->skill_id != SA_ABRACADABRA && ud->skill_id != WM_RANDOMIZESPELL ) // they just set the data so leave it as it is.[Inkfish]
@@ -4812,7 +4922,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
status_change_end(src, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
status_change_end(src, SC_BLADESTOP, INVALID_TIMER);
#ifdef RENEWAL
- sc_start(src, SC_EXTREMITYFIST2, 100, ud->skill_lv, skill->get_time(ud->skill_id, ud->skill_lv));
+ sc_start(src, src, SC_EXTREMITYFIST2, 100, ud->skill_lv, skill->get_time(ud->skill_id, ud->skill_lv));
#endif
}
if (target && target->m == src->m) {
@@ -4850,8 +4960,7 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
/*==========================================
*
*------------------------------------------*/
-int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag)
-{
+int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
struct map_session_data *sd, *dstsd;
struct mob_data *md, *dstmd;
struct homun_data *hd;
@@ -4860,7 +4969,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
struct status_change *tsc;
struct status_change_entry *tsce;
- int i = 0;
+ int element = 0;
enum sc_type type;
if(skill_id > 0 && !skill_lv) return 0; // celest
@@ -4930,11 +5039,47 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
- return skill->castend_damage_id (src, bl, skill_id, skill_lv, tick, flag);
+ return skill->castend_damage_id(src, bl, skill_id, skill_lv, tick, flag);
+ }
+ break;
+ case SO_ELEMENTAL_SHIELD:
+ {
+ struct party_data *p;
+ short ret = 0;
+ int x0, y0, x1, y1, range, i;
+
+ if(sd == NULL || !sd->ed)
+ break;
+ if((p = party->search(sd->status.party_id)) == NULL)
+ break;
+
+ range = skill_get_splash(skill_id,skill_lv);
+ x0 = sd->bl.x - range;
+ y0 = sd->bl.y - range;
+ x1 = sd->bl.x + range;
+ y1 = sd->bl.y + range;
+
+ elemental->delete(sd->ed,0);
+
+ if(!skill->check_unit_range(src,src->x,src->y,skill_id,skill_lv))
+ ret = skill->castend_pos2(src,src->x,src->y,skill_id,skill_lv,tick,flag);
+ for(i = 0; i < MAX_PARTY; i++) {
+ struct map_session_data *psd = p->data[i].sd;
+ if(!psd)
+ continue;
+ if(psd->bl.m != sd->bl.m || !psd->bl.prev)
+ continue;
+ if(range && (psd->bl.x < x0 || psd->bl.y < y0 ||
+ psd->bl.x > x1 || psd->bl.y > y1))
+ continue;
+ if(!skill->check_unit_range(bl,psd->bl.x,psd->bl.y,skill_id,skill_lv))
+ ret |= skill->castend_pos2(bl,psd->bl.x,psd->bl.y,skill_id,skill_lv,tick,flag);
+ }
+ return ret;
}
break;
case NPC_SMOKING: //Since it is a self skill, this one ends here rather than in damage_id. [Skotlex]
- return skill->castend_damage_id (src, bl, skill_id, skill_lv, tick, flag);
+ return skill->castend_damage_id(src, bl, skill_id, skill_lv, tick, flag);
case MH_STEINWAND: {
struct block_list *s_src = battle->get_master(src);
short ret = 0;
@@ -4957,7 +5102,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case RK_FIGHTINGSPIRIT:
case RK_ABUNDANCE:
if( sd && !pc->checkskill(sd, RK_RUNEMASTERY) ){
- if( status->change_start(&sd->bl, (sc_type)(rnd()%SC_CONFUSION), 1000, 1, 0, 0, 0, skill->get_time2(skill_id,skill_lv),8) ){
+ if( status->change_start(src,&sd->bl, (sc_type)(rnd()%SC_CONFUSION), 1000, 1, 0, 0, 0, skill->get_time2(skill_id,skill_lv),8) ){
skill->consume_requirement(sd,skill_id,skill_lv,2);
map->freeblock_unlock();
return 0;
@@ -4975,9 +5120,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
tsce = (tsc && type != -1)?tsc->data[type]:NULL;
if (src!=bl && type > -1 &&
- (i = skill->get_ele(skill_id, skill_lv)) > ELE_NEUTRAL &&
+ (element = skill->get_ele(skill_id, skill_lv)) > ELE_NEUTRAL &&
skill->get_inf(skill_id) != INF_SUPPORT_SKILL &&
- battle->attr_fix(NULL, NULL, 100, i, tstatus->def_ele, tstatus->ele_lv) <= 0)
+ battle->attr_fix(NULL, NULL, 100, element, tstatus->def_ele, tstatus->ele_lv) <= 0)
return 1; //Skills that cause an status should be blocked if the target element blocks its element.
map->freeblock_lock();
@@ -4991,9 +5136,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
{
int heal = skill->calc_heal(src, bl, (skill_id == AB_HIGHNESSHEAL)?AL_HEAL:skill_id, (skill_id == AB_HIGHNESSHEAL)?10:skill_lv, true);
int heal_get_jobexp;
- //Highness Heal: starts at 1.5 boost + 0.5 for each level
+ //Highness Heal: starts at 1.7 boost + 0.3 for each level
if( skill_id == AB_HIGHNESSHEAL ) {
- heal = heal * ( 15 + 5 * skill_lv ) / 10;
+ heal = heal * ( 17 + 3 * skill_lv ) / 10;
}
if( status->isimmune(bl) ||
(dstmd && (dstmd->class_ == MOBID_EMPERIUM || mob_is_battleground(dstmd))) )
@@ -5015,7 +5160,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
dstsd = sd;
}
}
- else if (tsc->data[SC_BERSERK] || tsc->data[SC_SATURDAY_NIGHT_FEVER])
+ else if (tsc->data[SC_BERSERK])
heal = 0; //Needed so that it actually displays 0 when healing.
}
clif->skill_nodamage (src, bl, skill_id, heal, 1);
@@ -5111,19 +5256,20 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case AL_DECAGI:
clif->skill_nodamage (src, bl, skill_id, skill_lv,
- sc_start(bl, type, (40 + skill_lv * 2 + (status->get_lv(src) + sstatus->int_)/5), skill_lv,
+ sc_start(src, bl, type, (40 + skill_lv * 2 + (status->get_lv(src) + sstatus->int_)/5), skill_lv,
/* monsters using lvl 48 get the rate benefit but the duration of lvl 10 */
( src->type == BL_MOB && skill_lv == 48 ) ? skill->get_time(skill_id,10) : skill->get_time(skill_id,skill_lv)));
break;
case MER_DECAGI:
- clif->skill_nodamage (src, bl, skill_id, skill_lv,
- sc_start(bl, type, (40 + skill_lv * 2 + (status->get_lv(src) + sstatus->int_)/5), skill_lv, skill->get_time(skill_id,skill_lv)));
+ if( tsc && !tsc->data[SC_ADORAMUS] ) //Prevent duplicate agi-down effect.
+ clif->skill_nodamage(src, bl, skill_id, skill_lv,
+ sc_start(src, bl, type, (40 + skill_lv * 2 + (status->get_lv(src) + sstatus->int_)/5), skill_lv, skill->get_time(skill_id,skill_lv)));
break;
case AL_CRUCIS:
if (flag&1)
- sc_start(bl,type, 23+skill_lv*4 +status->get_lv(src) -status->get_lv(bl), skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src, bl,type, 23+skill_lv*4 +status->get_lv(src) -status->get_lv(bl), skill_lv,skill->get_time(skill_id,skill_lv));
else {
map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id, skill_lv), BL_CHAR,
src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id);
@@ -5136,19 +5282,19 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( tsce )
status_change_end(bl,type, INVALID_TIMER);
else
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src, bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
clif->skill_nodamage (src, bl, skill_id, skill_lv, 1);
break;
case SA_ABRACADABRA:
{
- int abra_skill_id = 0, abra_skill_lv;
+ int abra_skill_id = 0, abra_skill_lv, abra_idx;
do {
- i = rnd() % MAX_SKILL_ABRA_DB;
- abra_skill_id = skill->abra_db[i].skill_id;
+ abra_idx = rnd() % MAX_SKILL_ABRA_DB;
+ abra_skill_id = skill->abra_db[abra_idx].skill_id;
} while (abra_skill_id == 0 ||
- skill->abra_db[i].req_lv > skill_lv || //Required lv for it to appear
- rnd()%10000 >= skill->abra_db[i].per
+ skill->abra_db[abra_idx].req_lv > skill_lv || //Required lv for it to appear
+ rnd()%10000 >= skill->abra_db[abra_idx].per
);
abra_skill_lv = min(skill_lv, skill->get_max(abra_skill_id));
clif->skill_nodamage (src, bl, skill_id, skill_lv, 1);
@@ -5193,7 +5339,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SA_COMA:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time2(skill_id,skill_lv)));
+ sc_start(src, bl,type,100,skill_lv,skill->get_time2(skill_id,skill_lv)));
break;
case SA_FULLRECOVERY:
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
@@ -5217,7 +5363,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case SA_SUMMONMONSTER:
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- if (sd) mob->once_spawn(sd, src->m, src->x, src->y," --ja--", -1, 1, "", SZ_SMALL, AI_NONE);
+ if (sd) mob->once_spawn(sd, src->m, src->x, src->y," --ja--", -1, 1, "", SZ_MEDIUM, AI_NONE);
break;
case SA_LEVELUP:
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
@@ -5246,6 +5392,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
mob->class_change(dstmd,class_);
if( tsc && dstmd->status.mode&MD_BOSS )
{
+ int i;
const enum sc_type scs[] = { SC_QUAGMIRE, SC_PROVOKE, SC_ROKISWEIL, SC_GRAVITATION, SC_NJ_SUITON, SC_NOEQUIPWEAPON, SC_NOEQUIPSHIELD, SC_NOEQUIPARMOR, SC_NOEQUIPHELM, SC_BLADESTOP };
for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++)
if (tsc->data[i]) status_change_end(bl, (sc_type)i, INVALID_TIMER);
@@ -5266,7 +5413,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SA_REVERSEORCISH:
case ALL_REVERSEORCISH:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv)));
+ sc_start(src, bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv)));
break;
case SA_FORTUNE:
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
@@ -5275,6 +5422,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SA_TAMINGMONSTER:
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
if (sd && dstmd) {
+ int i;
ARR_FIND( 0, MAX_PET_DB, i, dstmd->class_ == pet->db[i].class_ );
if( i < MAX_PET_DB )
pet->catch_process1(sd, dstmd->class_);
@@ -5290,7 +5438,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src, bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
break;
case CG_MARIONETTE:
@@ -5306,8 +5454,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( sc && tsc ) {
if( !sc->data[SC_MARIONETTE_MASTER] && !tsc->data[SC_MARIONETTE] ) {
- sc_start(src,SC_MARIONETTE_MASTER,100,bl->id,skill->get_time(skill_id,skill_lv));
- sc_start(bl,SC_MARIONETTE,100,src->id,skill->get_time(skill_id,skill_lv));
+ sc_start(src,src,SC_MARIONETTE_MASTER,100,bl->id,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,SC_MARIONETTE,100,src->id,skill->get_time(skill_id,skill_lv));
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
} else if( sc->data[SC_MARIONETTE_MASTER ] && sc->data[SC_MARIONETTE_MASTER ]->val1 == bl->id
&& tsc->data[SC_MARIONETTE] && tsc->data[SC_MARIONETTE]->val1 == src->id
@@ -5326,7 +5474,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case RG_CLOSECONFINE:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start4(bl,type,100,skill_lv,src->id,0,0,skill->get_time(skill_id,skill_lv)));
+ sc_start4(src,bl,type,100,skill_lv,src->id,0,0,skill->get_time(skill_id,skill_lv)));
break;
case SA_FLAMELAUNCHER: // added failure chance and chance to break weapon if turned on [Valaris]
case SA_FROSTWEAPON:
@@ -5351,7 +5499,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
}
// 100% success rate at lv4 & 5, but lasts longer at lv5
- if(!clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(bl,type,(60+skill_lv*10),skill_lv, skill->get_time(skill_id,skill_lv)))) {
+ if(!clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(src,bl,type,(60+skill_lv*10),skill_lv, skill->get_time(skill_id,skill_lv)))) {
if (sd)
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
if (skill->break_equip(bl, EQP_WEAPON, 10000, BCT_PARTY) && sd && sd != dstsd)
@@ -5365,12 +5513,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
break;
case ITEM_ENCHANTARMS:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start2(bl,type,100,skill_lv,
+ sc_start2(src,bl,type,100,skill_lv,
skill->get_ele(skill_id,skill_lv), skill->get_time(skill_id,skill_lv)));
break;
@@ -5385,16 +5533,16 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case ELE_HOLY : type = SC_ASPERSIO; break;
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
- sc_start2(bl,SC_TK_SEVENWIND,100,skill_lv,skill->get_ele(skill_id,skill_lv),skill->get_time(skill_id,skill_lv));
+ sc_start2(src,bl,SC_TK_SEVENWIND,100,skill_lv,skill->get_ele(skill_id,skill_lv),skill->get_time(skill_id,skill_lv));
break;
case PR_KYRIE:
case MER_KYRIE:
clif->skill_nodamage(bl,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
break;
//Passive Magnum, should had been casted on yourself.
case SM_MAGNUM:
@@ -5404,9 +5552,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
src,skill_id,skill_lv,tick, flag|BCT_ENEMY|1, skill->castend_damage_id);
clif->skill_nodamage (src,src,skill_id,skill_lv,1);
// Initiate 10% of your damage becomes fire element.
- sc_start4(src,SC_SUB_WEAPONPROPERTY,100,3,20,0,0,skill->get_time2(skill_id, skill_lv));
+ sc_start4(src,src,SC_SUB_WEAPONPROPERTY,100,3,20,0,0,skill->get_time2(skill_id, skill_lv));
if( sd )
- skill->blockpc_start(sd, skill_id, skill->get_time(skill_id, skill_lv), false);
+ skill->blockpc_start(sd, skill_id, skill->get_time(skill_id, skill_lv));
else if( bl->type == BL_MER )
skill->blockmerc_start((TBL_MER*)bl, skill_id, skill->get_time(skill_id, skill_lv));
break;
@@ -5492,6 +5640,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case NC_SHAPESHIFT:
case WL_RECOGNIZEDSPELL:
case GC_VENOMIMPRESS:
+ case SC_INVISIBILITY:
case SC_DEADLYINFECT:
case LG_EXEEDBREAK:
case LG_PRESTIGE:
@@ -5510,7 +5659,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case RK_CRUSHSTRIKE:
case ALL_ODINS_POWER:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
break;
case SO_STRIKING:
@@ -5519,7 +5668,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
bonus += (pc->checkskill(sd, SA_FLAMELAUNCHER)+pc->checkskill(sd, SA_FROSTWEAPON)+pc->checkskill(sd, SA_LIGHTNINGLOADER)+pc->checkskill(sd, SA_SEISMICWEAPON))*5;
clif->skill_nodamage( src, bl, skill_id, skill_lv,
battle->check_target(src,bl,BCT_PARTY) > 0 ?
- sc_start2(bl, type, 100, skill_lv, bonus, skill->get_time(skill_id,skill_lv)) :
+ sc_start2(src, bl, type, 100, skill_lv, bonus, skill->get_time(skill_id,skill_lv)) :
0
);
}
@@ -5527,15 +5676,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case NPC_STOP:
if( clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start2(bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv)) ) )
- sc_start2(src,type,100,skill_lv,bl->id,skill->get_time(skill_id,skill_lv));
+ sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv)) ) )
+ sc_start2(src,src,type,100,skill_lv,bl->id,skill->get_time(skill_id,skill_lv));
break;
case HP_ASSUMPTIO:
if( sd && dstmd )
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
else
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
break;
case MG_SIGHT:
case MER_SIGHT:
@@ -5545,23 +5694,25 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case NPC_STONESKIN:
case NPC_ANTIMAGIC:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start2(bl,type,100,skill_lv,skill_id,skill->get_time(skill_id,skill_lv)));
+ sc_start2(src,bl,type,100,skill_lv,skill_id,skill->get_time(skill_id,skill_lv)));
break;
case HLIF_AVOID:
case HAMI_DEFENCE:
- i = skill->get_time(skill_id,skill_lv);
- clif->skill_nodamage(bl,bl,skill_id,skill_lv,sc_start(bl,type,100,skill_lv,i)); // Master
- clif->skill_nodamage(src,src,skill_id,skill_lv,sc_start(src,type,100,skill_lv,i)); // Homunc
+ {
+ int duration = skill->get_time(skill_id,skill_lv);
+ clif->skill_nodamage(bl,bl,skill_id,skill_lv,sc_start(src,bl,type,100,skill_lv,duration)); // Master
+ clif->skill_nodamage(src,src,skill_id,skill_lv,sc_start(src,src,type,100,skill_lv,duration)); // Homunc
+ }
break;
case NJ_BUNSINJYUTSU:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
status_change_end(bl, SC_NJ_NEN, INVALID_TIMER);
break;
#if 0 /* Was modified to only affect targetted char. [Skotlex] */
case HP_ASSUMPTIO:
if (flag&1)
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
else {
map->foreachinrange(skill->area_sub, bl,
skill->get_splash(skill_id, skill_lv), BL_PC,
@@ -5573,15 +5724,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
#endif // 0
case SM_ENDURE:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
if (sd)
- skill->blockpc_start (sd, skill_id, skill->get_time2(skill_id,skill_lv), false);
+ skill->blockpc_start (sd, skill_id, skill->get_time2(skill_id,skill_lv));
break;
case ALL_ANGEL_PROTECT:
if( dstsd )
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
else if( sd )
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
@@ -5601,12 +5752,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
break;
case LK_TENSIONRELAX:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start4(bl,type,100,skill_lv,0,0,skill->get_time2(skill_id,skill_lv),
+ sc_start4(src,bl,type,100,skill_lv,0,0,skill->get_time2(skill_id,skill_lv),
skill->get_time(skill_id,skill_lv)));
break;
@@ -5629,7 +5780,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
sd->mission_mobid = id;
sd->mission_count = 0;
- pc_setglobalreg(sd,"TK_MISSION_ID", id);
+ pc_setglobalreg(sd,script->add_str("TK_MISSION_ID"), id);
clif->mission_info(sd, id, 0);
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
}
@@ -5638,7 +5789,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case AC_CONCENTRATION:
{
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
map->foreachinrange(status->change_timer_sub, src,
skill->get_splash(skill_id, skill_lv), BL_CHAR,
src,NULL,type,tick);
@@ -5648,14 +5799,16 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SM_PROVOKE:
case SM_SELFPROVOKE:
case MER_PROVOKE:
+ {
+ int failure;
if( (tstatus->mode&MD_BOSS) || battle->check_undead(tstatus->race,tstatus->def_ele) ) {
map->freeblock_unlock();
return 1;
}
//TODO: How much does base level affects? Dummy value of 1% per level difference used. [Skotlex]
clif->skill_nodamage(src,bl,skill_id == SM_SELFPROVOKE ? SM_PROVOKE : skill_id,skill_lv,
- (i = sc_start(bl,type, skill_id == SM_SELFPROVOKE ? 100:( 50 + 3*skill_lv + status->get_lv(src) - status->get_lv(bl)), skill_lv, skill->get_time(skill_id,skill_lv))));
- if( !i ) {
+ (failure = sc_start(src,bl,type, skill_id == SM_SELFPROVOKE ? 100:( 50 + 3*skill_lv + status->get_lv(src) - status->get_lv(bl)), skill_lv, skill->get_time(skill_id,skill_lv))));
+ if( !failure ) {
if( sd )
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
map->freeblock_unlock();
@@ -5677,12 +5830,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
dstmd->state.provoke_flag = src->id;
mob->target(dstmd, src, skill->get_range2(src,skill_id,skill_lv));
}
+ }
break;
case ML_DEVOTION:
case CR_DEVOTION:
{
- int count, lv;
+ int count, lv, i;
if( !dstsd || (!sd && !mer) )
{ // Only players can be devoted
if( sd )
@@ -5726,7 +5880,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
mer->devotion_flag = 1; // Mercenary Devoting Owner
clif->skill_nodamage(src, bl, skill_id, skill_lv,
- sc_start4(bl, type, 100, src->id, i, skill->get_range2(src,skill_id,skill_lv),0, skill->get_time2(skill_id, skill_lv)));
+ sc_start4(src, bl, type, 100, src->id, i, skill->get_range2(src,skill_id,skill_lv),0, skill->get_time2(skill_id, skill_lv)));
clif->devotion(src, NULL);
}
break;
@@ -5743,7 +5897,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case CH_SOULCOLLECT:
if(sd) {
- int limit = 5;
+ int limit = 5, i;
if( sd->sc.data[SC_RAISINGDRAGON] )
limit += sd->sc.data[SC_RAISINGDRAGON]->val1;
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
@@ -5767,18 +5921,20 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case MO_ABSORBSPIRITS:
- i = 0;
+ {
+ int sp = 0;
if (dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m)) && ((dstsd->class_&MAPID_BASEMASK)!=MAPID_GUNSLINGER || (dstsd->class_&MAPID_UPPERMASK)!=MAPID_REBELLION))
{ // split the if for readability, and included gunslingers in the check so that their coins cannot be removed [Reddozen]
- i = dstsd->spiritball * 7;
+ sp = dstsd->spiritball * 7;
pc->delspiritball(dstsd,dstsd->spiritball,0);
} else if (dstmd && !(tstatus->mode&MD_BOSS) && rnd() % 100 < 20)
{ // check if target is a monster and not a Boss, for the 20% chance to absorb 2 SP per monster's level [Reddozen]
- i = 2 * dstmd->level;
+ sp = 2 * dstmd->level;
mob->target(dstmd,src,0);
}
- if (i) status->heal(src, 0, i, 3);
- clif->skill_nodamage(src,bl,skill_id,skill_lv,i?1:0);
+ if (sp) status->heal(src, 0, sp, 3);
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,sp?1:0);
+ }
break;
case AC_MAKINGARROW:
@@ -5804,7 +5960,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case BS_HAMMERFALL:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,SC_STUN,(20 + 10 * skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv)));
+ sc_start(src,bl,SC_STUN,(20 + 10 * skill_lv),skill_lv,skill->get_time2(skill_id,skill_lv)));
break;
case RG_RAID:
skill->area_temp[1] = 0;
@@ -5825,12 +5981,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SR_RAMPAGEBLASTER:
case SR_HOWLINGOFLION:
case KO_HAPPOKUNAI:
+ {
+ int count = 0;
skill->area_temp[1] = 0;
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- i = map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src),
+ count = map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src),
src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill->castend_damage_id);
- if( !i && ( skill_id == NC_AXETORNADO || skill_id == SR_SKYNETBLOW || skill_id == KO_HAPPOKUNAI ) )
+ if( !count && ( skill_id == NC_AXETORNADO || skill_id == SR_SKYNETBLOW || skill_id == KO_HAPPOKUNAI ) )
clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ }
break;
case NC_EMERGENCYCOOL:
@@ -5878,18 +6037,20 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case HVAN_EXPLOSION: //[orn]
case NPC_SELFDESTRUCTION:
+ {
//Self Destruction hits everyone in range (allies+enemies)
//Except for Summoned Marine spheres on non-versus maps, where it's just enemy.
- i = ((!md || md->special_state.ai == 2) && !map_flag_vs(src->m))?
+ int targetmask = ((!md || md->special_state.ai == 2) && !map_flag_vs(src->m))?
BCT_ENEMY:BCT_ALL;
clif->skill_nodamage(src, src, skill_id, -1, 1);
map->delblock(src); //Required to prevent chain-self-destructions hitting back.
map->foreachinrange(skill->area_sub, bl,
skill->get_splash(skill_id, skill_lv), splash_target(src),
- src, skill_id, skill_lv, tick, flag|i,
+ src, skill_id, skill_lv, tick, flag|targetmask,
skill->castend_damage_id);
map->addblock(src);
status->damage(src, src, sstatus->max_hp,0,0,1);
+ }
break;
case AL_ANGELUS:
@@ -5901,18 +6062,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case CASH_ASSUMPTIO:
case WM_FRIGG_SONG:
if( sd == NULL || sd->status.party_id == 0 || (flag & 1) )
- clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
else if( sd )
party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
break;
case MER_MAGNIFICAT:
if( mer != NULL )
{
- clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
if( mer->master && mer->master->status.party_id != 0 && !(flag&1) )
party->foreachsamemap(skill->area_sub, mer->master, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
else if( mer->master && !(flag&1) )
- clif->skill_nodamage(src, &mer->master->bl, skill_id, skill_lv, sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ clif->skill_nodamage(src, &mer->master->bl, skill_id, skill_lv, sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
}
break;
@@ -5922,7 +6083,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case BS_OVERTHRUST:
if (sd == NULL || sd->status.party_id == 0 || (flag & 1)) {
clif->skill_nodamage(bl,bl,skill_id,skill_lv,
- sc_start2(bl,type,100,skill_lv,(src == bl)? 1:0,skill->get_time(skill_id,skill_lv)));
+ sc_start2(src,bl,type,100,skill_lv,(src == bl)? 1:0,skill->get_time(skill_id,skill_lv)));
} else if (sd) {
party->foreachsamemap(skill->area_sub,
sd,skill->get_splash(skill_id, skill_lv),
@@ -5951,7 +6112,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
map->freeblock_unlock();
return 0;
}
- clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
break;
case SL_KAITE:
case SL_KAAHI:
@@ -5966,21 +6127,24 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|| dstsd->status.char_id == sd->status.child
)
) {
- status->change_start(src,SC_STUN,10000,skill_lv,0,0,0,500,8);
+ status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,500,8);
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv)));
break;
case SM_AUTOBERSERK:
case MER_AUTOBERSERK:
+ {
+ int failure;
if( tsce )
- i = status_change_end(bl, type, INVALID_TIMER);
+ failure = status_change_end(bl, type, INVALID_TIMER);
else
- i = sc_start(bl,type,100,skill_lv,60000);
- clif->skill_nodamage(src,bl,skill_id,skill_lv,i);
+ failure = sc_start(src,bl,type,100,skill_lv,60000);
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,failure);
+ }
break;
case TF_HIDING:
case ST_CHASEWALK:
@@ -5995,7 +6159,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
map->freeblock_unlock();
return 0;
}
- clif->skill_nodamage(src,bl,skill_id,-1,sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ clif->skill_nodamage(src,bl,skill_id,-1,sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
break;
case TK_RUN:
if (tsce) {
@@ -6003,7 +6167,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
map->freeblock_unlock();
return 0;
}
- clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(bl,type,100,skill_lv,unit->getdir(bl),0,0,0));
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(src,bl,type,100,skill_lv,unit->getdir(bl),0,0,0));
if (sd) // If the client receives a skill-use packet inmediately before a walkok packet, it will discard the walk packet! [Skotlex]
clif->walkok(sd); // So aegis has to resend the walk ok.
break;
@@ -6011,22 +6175,25 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case GC_CLOAKINGEXCEED:
case LG_FORCEOFVANGUARD:
case SC_REPRODUCE:
- case SC_INVISIBILITY:
if (tsce) {
- i = status_change_end(bl, type, INVALID_TIMER);
- if( i )
- clif->skill_nodamage(src,bl,skill_id,( skill_id == LG_FORCEOFVANGUARD ) ? skill_lv : -1,i);
+ int failure = status_change_end(bl, type, INVALID_TIMER);
+ if( failure )
+ clif->skill_nodamage(src,bl,skill_id,( skill_id == LG_FORCEOFVANGUARD ) ? skill_lv : -1,failure);
else if( sd )
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ if ( skill_id == LG_FORCEOFVANGUARD )
+ break;
map->freeblock_unlock();
return 0;
}
case RA_CAMOUFLAGE:
- i = sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
- if( i )
- clif->skill_nodamage(src,bl,skill_id,( skill_id == LG_FORCEOFVANGUARD ) ? skill_lv : -1,i);
+ {
+ int failure = sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ if( failure )
+ clif->skill_nodamage(src,bl,skill_id,( skill_id == LG_FORCEOFVANGUARD ) ? skill_lv : -1,failure);
else if( sd )
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ }
break;
case BD_ADAPTATION:
@@ -6051,18 +6218,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case BA_PANGVOICE:
- clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(bl,SC_CONFUSION,50,7,skill->get_time(skill_id,skill_lv)));
+ clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(src,bl,SC_CONFUSION,50,7,skill->get_time(skill_id,skill_lv)));
break;
case DC_WINKCHARM:
if( dstsd )
- clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(bl,SC_CONFUSION,30,7,skill->get_time2(skill_id,skill_lv)));
+ clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start(src,bl,SC_CONFUSION,30,7,skill->get_time2(skill_id,skill_lv)));
else if( dstmd ) {
if( status->get_lv(src) > status->get_lv(bl)
&& (tstatus->race == RC_DEMON || tstatus->race == RC_DEMIHUMAN || tstatus->race == RC_ANGEL)
&& !(tstatus->mode&MD_BOSS)
) {
- clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start2(bl,type,70,skill_lv,src->id,skill->get_time(skill_id,skill_lv)));
+ clif->skill_nodamage(src,bl,skill_id,skill_lv, sc_start2(src,bl,type,70,skill_lv,src->id,skill->get_time(skill_id,skill_lv)));
} else {
clif->skill_nodamage(src,bl,skill_id,skill_lv,0);
if(sd) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
@@ -6081,15 +6248,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case RG_STEALCOIN:
if(sd) {
- if(pc->steal_coin(sd,bl))
- {
+ int amount = pc->steal_coin(sd, bl);
+ if( amount > 0 ) {
dstmd->state.provoke_flag = src->id;
- mob->target(dstmd, src, skill->get_range2(src,skill_id,skill_lv));
- clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
+ mob->target(dstmd, src, skill->get_range2(src, skill_id, skill_lv));
+ clif->skill_nodamage(src, bl, skill_id, amount, 1);
- }
- else
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ } else
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
}
break;
@@ -6111,7 +6277,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if (sd) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
- if (sc_start4(bl,SC_STONE,(skill_lv*4+20)+brate,
+ if (sc_start4(src,bl,SC_STONE,(skill_lv*4+20)+brate,
skill_lv, 0, 0, skill->get_time(skill_id, skill_lv),
skill->get_time2(skill_id,skill_lv)))
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
@@ -6163,7 +6329,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
//Is this equation really right? It looks so... special.
if( battle->check_undead(tstatus->race,tstatus->def_ele) ) {
- status->change_start(bl, SC_BLIND,
+ status->change_start(src, bl, SC_BLIND,
100*(100-(tstatus->int_/2+tstatus->vit/3+tstatus->luk/10)), 1,0,0,0,
skill->get_time2(skill_id, skill_lv) * (100-(tstatus->int_+tstatus->vit)/2)/100,0);
}
@@ -6257,7 +6423,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case MC_VENDING:
if(sd)
{ //Prevent vending of GMs with unnecessary Level to trade/drop. [Skotlex]
- if ( !pc->can_give_items(sd) )
+ if ( !pc_can_give_items(sd) )
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
else {
sd->state.prevend = sd->state.workinprogress = 3;
@@ -6344,18 +6510,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case GC_WEAPONCRUSH:
case SC_STRIPACCESSARY: {
unsigned short location = 0;
- int d = 0;
+ int d = 0, rate;
//Rate in percent
if ( skill_id == ST_FULLSTRIP ) {
- i = 5 + 2*skill_lv + (sstatus->dex - tstatus->dex)/5;
+ rate = 5 + 2*skill_lv + (sstatus->dex - tstatus->dex)/5;
} else if( skill_id == SC_STRIPACCESSARY ) {
- i = 12 + 2 * skill_lv + (sstatus->dex - tstatus->dex)/5;
+ rate = 12 + 2 * skill_lv + (sstatus->dex - tstatus->dex)/5;
} else {
- i = 5 + 5*skill_lv + (sstatus->dex - tstatus->dex)/5;
+ rate = 5 + 5*skill_lv + (sstatus->dex - tstatus->dex)/5;
}
- if (i < 5) i = 5; //Minimum rate 5%
+ if (rate < 5) rate = 5; //Minimum rate 5%
//Duration in ms
if( skill_id == GC_WEAPONCRUSH){
@@ -6399,11 +6565,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
//Attempts to strip at rate i and duration d
- if( (i = skill->strip_equip(bl, location, i, skill_lv, d)) || (skill_id != ST_FULLSTRIP && skill_id != GC_WEAPONCRUSH ) )
- clif->skill_nodamage(src,bl,skill_id,skill_lv,i);
+ if( (rate = skill->strip_equip(bl, location, rate, skill_lv, d)) || (skill_id != ST_FULLSTRIP && skill_id != GC_WEAPONCRUSH ) )
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,rate);
//Nothing stripped.
- if( sd && !i )
+ if( sd && !rate )
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
@@ -6529,14 +6695,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
}
break;
case AM_TWILIGHT1:
if (sd) {
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
//Prepare 200 White Potions.
- if (!skill->produce_mix(sd, skill_id, 504, 0, 0, 0, 200))
+ if (!skill->produce_mix(sd, skill_id, ITEMID_WHITE_POTION, 0, 0, 0, 200))
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
}
break;
@@ -6544,36 +6710,44 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if (sd) {
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
//Prepare 200 Slim White Potions.
- if (!skill->produce_mix(sd, skill_id, 547, 0, 0, 0, 200))
+ if (!skill->produce_mix(sd, skill_id, ITEMID_WHITE_SLIM_POTION, 0, 0, 0, 200))
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
}
break;
case AM_TWILIGHT3:
if (sd) {
- int ebottle = pc->search_inventory(sd,713);
+ int ebottle = pc->search_inventory(sd,ITEMID_EMPTY_BOTTLE);
if( ebottle >= 0 )
ebottle = sd->status.inventory[ebottle].amount;
//check if you can produce all three, if not, then fail:
- if (!skill->can_produce_mix(sd,970,-1, 100) //100 Alcohol
- || !skill->can_produce_mix(sd,7136,-1, 50) //50 Acid Bottle
- || !skill->can_produce_mix(sd,7135,-1, 50) //50 Flame Bottle
+ if (!skill->can_produce_mix(sd,ITEMID_ALCHOL,-1, 100) //100 Alcohol
+ || !skill->can_produce_mix(sd,ITEMID_ACID_BOTTLE,-1, 50) //50 Acid Bottle
+ || !skill->can_produce_mix(sd,ITEMID_FIRE_BOTTLE,-1, 50) //50 Flame Bottle
|| ebottle < 200 //200 empty bottle are required at total.
) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- skill->produce_mix(sd, skill_id, 970, 0, 0, 0, 100);
- skill->produce_mix(sd, skill_id, 7136, 0, 0, 0, 50);
- skill->produce_mix(sd, skill_id, 7135, 0, 0, 0, 50);
+ skill->produce_mix(sd, skill_id, ITEMID_ALCHOL, 0, 0, 0, 100);
+ skill->produce_mix(sd, skill_id, ITEMID_ACID_BOTTLE, 0, 0, 0, 50);
+ skill->produce_mix(sd, skill_id, ITEMID_FIRE_BOTTLE, 0, 0, 0, 50);
}
break;
case SA_DISPELL:
- if (flag&1 || (i = skill->get_splash(skill_id, skill_lv)) < 1)
- {
+ {
+ int splash;
+ if (flag&1 || (splash = skill->get_splash(skill_id, skill_lv)) < 1) {
+ int i;
+ if( sd && dstsd && !map_flag_vs(sd->bl.m)
+ && (sd->status.party_id == 0 || sd->status.party_id != dstsd->status.party_id) ) {
+ // Outside PvP it should only affect party members and no skill fail message.
+ break;
+ }
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
if((dstsd && (dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER)
|| (tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SL_ROGUE) //Rogue's spirit defends againt dispel.
+ || (dstsd && pc_ismadogear(dstsd))
|| rnd()%100 >= 50+10*skill_lv )
{
if (sd)
@@ -6582,14 +6756,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
if(status->isimmune(bl) || !tsc || !tsc->count)
break;
-
- if( sd && dstsd && !map_flag_vs(sd->bl.m)
- && (sd->status.party_id == 0 || sd->status.party_id != dstsd->status.party_id) ) {
- // Outside PvP it should only affect party members
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- break;
- }
-
for(i = 0; i < SC_MAX; i++) {
if ( !tsc->data[i] )
continue;
@@ -6624,11 +6790,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
status_change_end(bl, (sc_type)i, INVALID_TIMER);
}
break;
+ } else {
+ //Affect all targets on splash area.
+ map->foreachinrange(skill->area_sub, bl, splash, BL_CHAR,
+ src, skill_id, skill_lv, tick, flag|1,
+ skill->castend_damage_id);
}
- //Affect all targets on splash area.
- map->foreachinrange(skill->area_sub, bl, i, BL_CHAR,
- src, skill_id, skill_lv, tick, flag|1,
- skill->castend_damage_id);
+ }
break;
case TF_BACKSLIDING: //This is the correct implementation as per packet logging information. [Skotlex]
@@ -6666,7 +6834,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if(sd) {
int sp = skill->get_sp(sd->skill_id_old,sd->skill_lv_old);
if( skill_id == SO_SPELLFIST ){
- sc_start4(src,type,100,skill_lv+1,skill_lv,sd->skill_id_old,sd->skill_lv_old,skill->get_time(skill_id,skill_lv));
+ sc_start4(src,src,type,100,skill_lv+1,skill_lv,sd->skill_id_old,sd->skill_lv_old,skill->get_time(skill_id,skill_lv));
sd->skill_id_old = sd->skill_lv_old = 0;
break;
}
@@ -6721,7 +6889,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case SA_MAGICROD:
clif->skill_nodamage(src,src,SA_MAGICROD,skill_lv,1);
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
break;
case SA_AUTOSPELL:
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
@@ -6756,7 +6924,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
maxlv = 3;
}
if(spellid > 0)
- sc_start4(src,SC_AUTOSPELL,100,skill_lv,spellid,maxlv,0,
+ sc_start4(src,src,SC_AUTOSPELL,100,skill_lv,spellid,maxlv,0,
skill->get_time(SA_AUTOSPELL,skill_lv));
}
break;
@@ -6787,7 +6955,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case NPC_CHANGEDARKNESS:
case NPC_CHANGETELEKINESIS:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start2(bl, type, 100, skill_lv, skill->get_ele(skill_id,skill_lv),
+ sc_start2(src, bl, type, 100, skill_lv, skill->get_ele(skill_id,skill_lv),
skill->get_time(skill_id, skill_lv)));
break;
case NPC_CHANGEUNDEAD:
@@ -6795,7 +6963,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
//TO-DO This is ugly, fix it
if(tstatus->def_ele==ELE_UNDEAD || tstatus->def_ele==ELE_DARK) break;
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start2(bl, type, 100, skill_lv, skill->get_ele(skill_id,skill_lv),
+ sc_start2(src, bl, type, 100, skill_lv, skill->get_ele(skill_id,skill_lv),
skill->get_time(skill_id, skill_lv)));
break;
@@ -6810,7 +6978,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
int skill_time = skill->get_time(skill_id,skill_lv);
struct unit_data *ud = unit->bl2ud(bl);
if (clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill_time))
+ sc_start(src,bl,type,100,skill_lv,skill_time))
&& ud) { //Disable attacking/acting/moving for skill's duration.
ud->attackabletime =
ud->canact_tick =
@@ -6822,18 +6990,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case NPC_REBIRTH:
if( md && md->state.rebirth )
break; // only works once
- sc_start(bl,type,100,skill_lv,-1);
+ sc_start(src,bl,type,100,skill_lv,-1);
break;
case NPC_DARKBLESSING:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start2(bl,type,(50+skill_lv*5),skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)));
+ sc_start2(src,bl,type,(50+skill_lv*5),skill_lv,skill_lv,skill->get_time2(skill_id,skill_lv)));
break;
case NPC_LICK:
status_zap(bl, 0, 100);
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,(skill_lv*5),skill_lv,skill->get_time2(skill_id,skill_lv)));
+ sc_start(src,bl,type,(skill_lv*5),skill_lv,skill->get_time2(skill_id,skill_lv)));
break;
case NPC_SUICIDE:
@@ -6865,7 +7033,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if (i > SC_ATTHASTE_INFINITY)
i = SC_ATTHASTE_INFINITY;
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,(sc_type)i,100,skill_lv,skill_lv * 60000));
+ sc_start(src,bl,(sc_type)i,100,skill_lv,skill_lv * 60000));
}
break;
@@ -6920,7 +7088,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
mob->unlocktarget(md,tick);
if(md->db->skill[md->skill_idx].val[1] || md->db->skill[md->skill_idx].val[2])
- sc_start4(src, type, 100, skill_lv,
+ sc_start4(src, src, type, 100, skill_lv,
md->db->skill[md->skill_idx].val[1],
md->db->skill[md->skill_idx].val[2],
md->db->skill[md->skill_idx].val[3],
@@ -6929,21 +7097,21 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case NPC_POWERUP:
- sc_start(bl,SC_INCATKRATE,100,200,skill->get_time(skill_id, skill_lv));
+ sc_start(src,bl,SC_INCATKRATE,100,200,skill->get_time(skill_id, skill_lv));
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,100,skill->get_time(skill_id, skill_lv)));
+ sc_start(src,bl,type,100,100,skill->get_time(skill_id, skill_lv)));
break;
case NPC_AGIUP:
- sc_start(bl,SC_MOVHASTE_INFINITY,100,skill_lv,skill->get_time(skill_id, skill_lv));
+ sc_start(src,bl,SC_MOVHASTE_INFINITY,100,skill_lv,skill->get_time(skill_id, skill_lv));
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,100,skill->get_time(skill_id, skill_lv)));
+ sc_start(src,bl,type,100,100,skill->get_time(skill_id, skill_lv)));
break;
case NPC_INVISIBLE:
//Have val4 passed as 6 is for "infinite cloak" (do not end on attack/skill use).
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start4(bl,type,100,skill_lv,0,0,6,skill->get_time(skill_id,skill_lv)));
+ sc_start4(src,bl,type,100,skill_lv,0,0,6,skill->get_time(skill_id,skill_lv)));
break;
case NPC_SIEGEMODE:
@@ -6973,12 +7141,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
struct map_session_data *m_sd = pc->get_mother(sd);
bool we_baby_parents = false;
if(m_sd && check_distance_bl(bl,&m_sd->bl,AREA_SIZE)) {
- sc_start(&m_sd->bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,&m_sd->bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
clif->specialeffect(&m_sd->bl,408,AREA);
we_baby_parents = true;
}
if(f_sd && check_distance_bl(bl,&f_sd->bl,AREA_SIZE)) {
- sc_start(&f_sd->bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,&f_sd->bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
clif->specialeffect(&f_sd->bl,408,AREA);
we_baby_parents = true;
}
@@ -6987,7 +7155,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
map->freeblock_unlock();
return 0;
}
- else status->change_start(bl,SC_STUN,10000,skill_lv,0,0,0,skill->get_time2(skill_id,skill_lv),8);
+ else
+ status->change_start(src,bl,SC_STUN,10000,skill_lv,0,0,0,skill->get_time2(skill_id,skill_lv),8);
}
break;
@@ -7017,19 +7186,20 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( su && (sg = su->group) && (src->type == BL_MER || sg->src_id == src->id || map_flag_vs(bl->m)) && (skill->get_inf2(sg->skill_id)&INF2_TRAP) )
{
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
- if( sd && !(sg->unit_id == UNT_USED_TRAPS || (sg->unit_id == UNT_ANKLESNARE && sg->val2 != 0 )) ) {
+ if( sd && !(sg->unit_id == UNT_USED_TRAPS || (sg->unit_id == UNT_ANKLESNARE && sg->val2 != 0 )) && sg->unit_id != UNT_THORNS_TRAP ) {
// prevent picking up expired traps
if( battle_config.skill_removetrap_type ) {
+ int i;
// get back all items used to deploy the trap
for( i = 0; i < 10; i++ ) {
if( skill->db[su->group->skill_id].itemid[i] > 0 ) {
- int flag;
+ int success;
struct item item_tmp;
memset(&item_tmp,0,sizeof(item_tmp));
item_tmp.nameid = skill->db[su->group->skill_id].itemid[i];
item_tmp.identify = 1;
- if( item_tmp.nameid && (flag=pc->additem(sd,&item_tmp,skill->db[su->group->skill_id].amount[i],LOG_TYPE_OTHER)) ) {
- clif->additem(sd,0,0,flag);
+ if( item_tmp.nameid && (success=pc->additem(sd,&item_tmp,skill->db[su->group->skill_id].amount[i],LOG_TYPE_OTHER)) ) {
+ clif->additem(sd,0,0,success);
map->addflooritem(&item_tmp,skill->db[su->group->skill_id].amount[i],sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
}
}
@@ -7075,8 +7245,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case UNT_TALKIEBOX:
su->group->unit_id = UNT_USED_TRAPS;
clif->changetraplook(bl, UNT_USED_TRAPS);
- su->group->limit=DIFF_TICK(tick+1500,su->group->tick);
- su->limit=DIFF_TICK(tick+1500,su->group->tick);
+ su->group->limit=DIFF_TICK32(tick+1500,su->group->tick);
+ su->limit=DIFF_TICK32(tick+1500,su->group->tick);
}
}
}
@@ -7099,9 +7269,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
return 1;
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start4(bl,type,100,skill_lv,skill_id,src->id,skill->get_time(skill_id,skill_lv),1000));
+ sc_start4(src,bl,type,100,skill_lv,skill_id,src->id,skill->get_time(skill_id,skill_lv),1000));
#ifndef RENEWAL
- if (sd) skill->blockpc_start (sd, skill_id, skill->get_time(skill_id, skill_lv)+3000, false);
+ if (sd) skill->blockpc_start (sd, skill_id, skill->get_time(skill_id, skill_lv)+3000);
#endif
break;
@@ -7121,7 +7291,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
//Has a 55% + skill_lv*5% success chance.
if (!clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,55+5*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)))
+ sc_start(src,bl,type,55+5*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)))
) {
if (sd) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
map->freeblock_unlock();
@@ -7215,7 +7385,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
for (i=0 ; i<4; i++) {
if( bl->type != BL_PC || ( dstsd && pc->checkequip(dstsd,equip[i]) < 0 ) )
continue;
- sc_start(bl,(sc_type)(SC_PROTECTWEAPON + i),100,skill_lv,skilltime);
+ sc_start(src,bl,(sc_type)(SC_PROTECTWEAPON + i),100,skill_lv,skilltime);
s++;
}
if( sd && !s ){
@@ -7237,7 +7407,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
&& (tsce->val1&0xFFFF) != CG_MOONLIT) //Can't use Longing for Freedom while under Moonlight Petals. [Skotlex]
{
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
}
}
break;
@@ -7269,7 +7439,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
status_percent_damage(src, bl, 0, 100, false);
break;
case 1: // matk halved
- sc_start(bl,SC_INCMATKRATE,100,-50,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_INCMATKRATE,100,-50,skill->get_time2(skill_id,skill_lv));
break;
case 2: // all buffs removed
status->change_clear_buffs(bl,1);
@@ -7277,7 +7447,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case 3: // 1000 damage, random armor destroyed
{
status_fix_damage(src, bl, 1000, 0);
- clif->damage(src,bl,tick,0,0,1000,0,0,0);
+ clif->damage(src,bl,0,0,1000,0,0,0);
if( !status->isdead(bl) ) {
int where[] = { EQP_ARMOR, EQP_SHIELD, EQP_HELM, EQP_SHOES, EQP_GARMENT };
skill->break_equip(bl, where[rnd()%5], 10000, BCT_ENEMY);
@@ -7285,7 +7455,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
break;
case 4: // atk halved
- sc_start(bl,SC_INCATKRATE,100,-50,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_INCATKRATE,100,-50,skill->get_time2(skill_id,skill_lv));
break;
case 5: // 2000HP heal, random teleported
status->heal(src, 2000, 0, 0);
@@ -7301,38 +7471,38 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case 7: // stop freeze or stoned
{
enum sc_type sc[] = { SC_STOP, SC_FREEZE, SC_STONE };
- sc_start(bl,sc[rnd()%3],100,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,sc[rnd()%3],100,skill_lv,skill->get_time2(skill_id,skill_lv));
}
break;
case 8: // curse coma and poison
- sc_start(bl,SC_COMA,100,skill_lv,skill->get_time2(skill_id,skill_lv));
- sc_start(bl,SC_CURSE,100,skill_lv,skill->get_time2(skill_id,skill_lv));
- sc_start(bl,SC_POISON,100,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_COMA,100,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_CURSE,100,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_POISON,100,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case 9: // confusion
- sc_start(bl,SC_CONFUSION,100,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_CONFUSION,100,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case 10: // 6666 damage, atk matk halved, cursed
status_fix_damage(src, bl, 6666, 0);
- clif->damage(src,bl,tick,0,0,6666,0,0,0);
- sc_start(bl,SC_INCATKRATE,100,-50,skill->get_time2(skill_id,skill_lv));
- sc_start(bl,SC_INCMATKRATE,100,-50,skill->get_time2(skill_id,skill_lv));
- sc_start(bl,SC_CURSE,skill_lv,100,skill->get_time2(skill_id,skill_lv));
+ clif->damage(src,bl,0,0,6666,0,0,0);
+ sc_start(src,bl,SC_INCATKRATE,100,-50,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_INCMATKRATE,100,-50,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_CURSE,skill_lv,100,skill->get_time2(skill_id,skill_lv));
break;
case 11: // 4444 damage
status_fix_damage(src, bl, 4444, 0);
- clif->damage(src,bl,tick,0,0,4444,0,0,0);
+ clif->damage(src,bl,0,0,4444,0,0,0);
break;
case 12: // stun
- sc_start(bl,SC_STUN,100,skill_lv,5000);
+ sc_start(src,bl,SC_STUN,100,skill_lv,5000);
break;
case 13: // atk,matk,hit,flee,def reduced
- sc_start(bl,SC_INCATKRATE,100,-20,skill->get_time2(skill_id,skill_lv));
- sc_start(bl,SC_INCMATKRATE,100,-20,skill->get_time2(skill_id,skill_lv));
- sc_start(bl,SC_INCHITRATE,100,-20,skill->get_time2(skill_id,skill_lv));
- sc_start(bl,SC_INCFLEERATE,100,-20,skill->get_time2(skill_id,skill_lv));
- sc_start(bl,SC_INCDEFRATE,100,-20,skill->get_time2(skill_id,skill_lv));
- sc_start(bl,type,100,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_INCATKRATE,100,-20,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_INCMATKRATE,100,-20,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_INCHITRATE,100,-20,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_INCFLEERATE,100,-20,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_INCDEFRATE,100,-20,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
default:
break;
@@ -7365,13 +7535,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if (skill_id == SL_SUPERNOVICE && dstsd && dstsd->die_counter && !(rnd()%100))
{ //Erase death count 1% of the casts
dstsd->die_counter = 0;
- pc_setglobalreg(dstsd,"PC_DIE_COUNTER", 0);
+ pc_setglobalreg(dstsd,script->add_str("PC_DIE_COUNTER"), 0);
clif->specialeffect(bl, 0x152, AREA);
//SC_SOULLINK invokes status_calc_pc for us.
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start4(bl,SC_SOULLINK,100,skill_lv,skill_id,0,0,skill->get_time(skill_id,skill_lv)));
- sc_start(src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA,skill_lv));
+ sc_start4(src,bl,SC_SOULLINK,100,skill_lv,skill_id,0,0,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA,skill_lv));
break;
case SL_HIGH:
if (sd && !(dstsd && (dstsd->class_&JOBL_UPPER) && !(dstsd->class_&JOBL_2) && dstsd->status.base_level < 70)) {
@@ -7379,15 +7549,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start4(bl,type,100,skill_lv,skill_id,0,0,skill->get_time(skill_id,skill_lv)));
- sc_start(src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA,skill_lv));
+ sc_start4(src,bl,type,100,skill_lv,skill_id,0,0,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA,skill_lv));
break;
case SL_SWOO:
if (tsce) {
if(sd)
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- status->change_start(src,SC_STUN,10000,skill_lv,0,0,0,10000,8);
+ status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,10000,8);
status_change_end(bl, SC_SWOO, INVALID_TIMER);
break;
}
@@ -7395,19 +7565,19 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SL_SKE:
if (sd && !battle_config.allow_es_magic_pc && bl->type != BL_MOB) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- status->change_start(src,SC_STUN,10000,skill_lv,0,0,0,500,10);
+ status->change_start(src,src,SC_STUN,10000,skill_lv,0,0,0,500,10);
break;
}
- clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
if (skill_id == SL_SKE)
- sc_start(src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA,skill_lv));
+ sc_start(src,src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA,skill_lv));
break;
// New guild skills [Celest]
case GD_BATTLEORDER:
if(flag&1) {
if (status->get_guild_id(src) == status->get_guild_id(bl))
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv));
} else if (status->get_guild_id(src)) {
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
map->foreachinrange(skill->area_sub, src,
@@ -7421,7 +7591,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case GD_REGENERATION:
if(flag&1) {
if (status->get_guild_id(src) == status->get_guild_id(bl))
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id, skill_lv));
} else if (status->get_guild_id(src)) {
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
map->foreachinrange(skill->area_sub, src,
@@ -7450,7 +7620,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
{
int dx[9]={-1, 1, 0, 0,-1, 1,-1, 1, 0};
int dy[9]={ 0, 0, 1,-1, 1,-1,-1, 1, 0};
- int j = 0;
+ int i, j = 0;
struct guild *g;
// i don't know if it actually summons in a circle, but oh well. ;P
g = sd ? sd->guild : guild->search(status->get_guild_id(src));
@@ -7504,21 +7674,25 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
/* per official standards, this skill works on players and mobs. */
if (sd && (dstsd || dstmd))
{
- i =65 -5*distance_bl(src,bl); //Base rate
- if (i < 30) i = 30;
+ int rate = 65 -5*distance_bl(src,bl); //Base rate
+ if (rate < 30) rate = 30;
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- sc_start(bl,SC_STUN, i,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,bl,SC_STUN, rate,skill_lv,skill->get_time2(skill_id,skill_lv));
}
break;
case AM_CALLHOMUN: //[orn]
- if (sd && homun->call(sd))
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ if( sd ) {
+ if (homun->call(sd))
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
+ else
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ }
break;
case AM_REST:
if (sd) {
- if (homun->vaporize(sd,1))
+ if (homun->vaporize(sd,HOM_ST_REST))
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
else
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
@@ -7558,20 +7732,21 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
{
static const int per[5][2]={{20,50},{50,60},{25,75},{60,64},{34,67}};
int r = rnd()%100;
- i = (skill_lv-1)%5;
- if(r<per[i][0]) //Self
+ int target = (skill_lv-1)%5;
+ int hp;
+ if(r<per[target][0]) //Self
bl = src;
- else if(r<per[i][1]) //Master
+ else if(r<per[target][1]) //Master
bl = battle->get_master(src);
else //Enemy
bl = map->id2bl(battle->get_target(src));
if (!bl) bl = src;
- i = skill->calc_heal(src, bl, skill_id, 1+rnd()%skill_lv, true);
+ hp = skill->calc_heal(src, bl, skill_id, 1+rnd()%skill_lv, true);
//Eh? why double skill packet?
- clif->skill_nodamage(src,bl,AL_HEAL,i,1);
- clif->skill_nodamage(src,bl,skill_id,i,1);
- status->heal(bl, i, 0, 0);
+ clif->skill_nodamage(src,bl,AL_HEAL,hp,1);
+ clif->skill_nodamage(src,bl,skill_id,hp,1);
+ status->heal(bl, hp, 0, 0);
}
break;
//Homun single-target support skills [orn]
@@ -7582,7 +7757,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case MH_ANGRIFFS_MODUS:
case MH_GOLDENE_FERSE:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
if (hd)
skill->blockhomun_start(hd, skill_id, skill->get_time2(skill_id,skill_lv));
break;
@@ -7590,9 +7765,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case NPC_DRAGONFEAR:
if (flag&1) {
const enum sc_type sc[] = { SC_STUN, SC_SILENCE, SC_CONFUSION, SC_BLOODING };
- int j;
+ int i, j;
j = i = rnd()%ARRAYLENGTH(sc);
- while ( !sc_start2(bl,sc[i],100,skill_lv,src->id,skill->get_time2(skill_id,i+1)) ) {
+ while ( !sc_start2(src,bl,sc[i],100,skill_lv,src->id,skill->get_time2(skill_id,i+1)) ) {
i++;
if ( i == ARRAYLENGTH(sc) )
i = 0;
@@ -7620,13 +7795,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if (flag&1){
switch( type ){
case SC_BURNING:
- sc_start4(bl,type,100,skill_lv,0,src->id,0,skill->get_time2(skill_id,skill_lv));
+ sc_start4(src,bl,type,100,skill_lv,0,src->id,0,skill->get_time2(skill_id,skill_lv));
break;
case SC_SIREN:
- sc_start2(bl,type,100,skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
+ sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
break;
default:
- sc_start2(bl,type,100,skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
+ sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
}
} else {
skill->area_temp[2] = 0; //For SD_PREAMBLE
@@ -7660,7 +7835,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
}
else
- clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
break;
case NPC_TALK:
case ALL_WEWISH:
@@ -7676,11 +7851,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case RK_ENCHANTBLADE:
clif->skill_nodamage(src,bl,skill_id,skill_lv,// formula not confirmed
- sc_start2(bl,type,100,skill_lv,100+20*skill_lv/*+sstatus->int_/2+status->get_lv(bl)/10*/,skill->get_time(skill_id,skill_lv)));
+ sc_start2(src,bl,type,100,skill_lv,(100+20*skill_lv)*status->get_lv(src)/150+sstatus->int_,skill->get_time(skill_id,skill_lv)));
break;
case RK_DRAGONHOWLING:
if( flag&1)
- sc_start(bl,type,50 + 6 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,type,50 + 6 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
else {
skill->area_temp[2] = 0;
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
@@ -7692,20 +7867,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case RK_IGNITIONBREAK:
case LG_EARTHDRIVE:
+ {
+ int splash;
clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
- i = skill->get_splash(skill_id,skill_lv);
+ splash = skill->get_splash(skill_id,skill_lv);
if( skill_id == LG_EARTHDRIVE ) {
int dummy = 1;
- map->foreachinarea(skill->cell_overlap, src->m, src->x-i, src->y-i, src->x+i, src->y+i, BL_SKILL, LG_EARTHDRIVE, &dummy, src);
+ map->foreachinarea(skill->cell_overlap, src->m, src->x-splash, src->y-splash, src->x+splash, src->y+splash, BL_SKILL, LG_EARTHDRIVE, &dummy, src);
}
- map->foreachinrange(skill->area_sub, bl,i,BL_CHAR,
+ map->foreachinrange(skill->area_sub, bl,splash,BL_CHAR,
src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
+ }
break;
case RK_STONEHARDSKIN:
if( sd ) {
- int heal = sstatus->hp / 4; // 25% HP
+ int heal = sstatus->hp / 5; // 20% HP
if( status->charge(bl,heal,0) )
- clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start2(bl,type,100,skill_lv,heal,skill->get_time(skill_id,skill_lv)));
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start2(src,bl,type,100,skill_lv,heal,skill->get_time(skill_id,skill_lv)));
else
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
}
@@ -7714,36 +7892,43 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
{
int heal = status_get_max_hp(bl) * 25 / 100;
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
status->heal(bl,heal,0,1);
status->change_clear_buffs(bl,4);
}
break;
case RK_MILLENNIUMSHIELD:
- if( sd ){
- short shields = (rnd()%100<50) ? 4 : ((rnd()%100<80) ? 3 : 2);
- sc_start4(bl,type,100,skill_lv,shields,1000,0,skill->get_time(skill_id,skill_lv));
- clif->millenniumshield(sd,shields);
+ if( sd && pc->checkskill(sd,RK_RUNEMASTERY) >= 9 ) {
+ short chance = 0;
+ short num_shields = 0;
+ chance = rnd()%100 + 1;//Generates a random number between 1 - 100 which is then used to determine how many shields will generate.
+ if ( chance >= 1 && chance <= 20 )//20% chance for 4 shields.
+ num_shields = 4;
+ else if ( chance >= 21 && chance <= 50 )//30% chance for 3 shields.
+ num_shields = 3;
+ else if ( chance >= 51 && chance <= 100 )//50% chance for 2 shields.
+ num_shields = 2;
+ sc_start4(src,bl,type,100,skill_lv,num_shields,1000,0,skill->get_time(skill_id,skill_lv));
+ clif->millenniumshield(src,num_shields);
clif->skill_nodamage(src,bl,skill_id,1,1);
}
break;
case RK_FIGHTINGSPIRIT:
if( flag&1 ) {
+ int atkbonus = 7 * party->foreachsamemap(skill->area_sub,sd,skill->get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,BCT_PARTY,skill->area_sub_count);
if( src == bl )
- sc_start2(bl,type,100,skill->area_temp[5],10*(sd?pc->checkskill(sd,RK_RUNEMASTERY):10),skill->get_time(skill_id,skill_lv));
+ sc_start2(src,bl,type,100,atkbonus,10*(sd?pc->checkskill(sd,RK_RUNEMASTERY):10),skill->get_time(skill_id,skill_lv));
else
- sc_start(bl,type,100,skill->area_temp[5]/4,skill->get_time(skill_id,skill_lv));
- } else if( sd ) {
- if( sd->status.party_id ) {
- i = party->foreachsamemap(skill->area_sub,sd,skill->get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,BCT_PARTY,skill->area_sub_count);
- skill->area_temp[5] = 7 * i; // ATK
+ sc_start(src,bl,type,100,atkbonus / 4,skill->get_time(skill_id,skill_lv));
+ } else if( sd && pc->checkskill(sd,RK_RUNEMASTERY) >= 5 ) {
+ if( sd->status.party_id )
party->foreachsamemap(skill->area_sub,sd,skill->get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,flag|BCT_PARTY|1,skill->castend_nodamage_id);
- } else
- sc_start2(bl,type,100,7,5,skill->get_time(skill_id,skill_lv));
+ else
+ sc_start2(src,bl,type,100,7,10*(sd?pc->checkskill(sd,RK_RUNEMASTERY):10),skill->get_time(skill_id,skill_lv));
+ clif->skill_nodamage(src,bl,skill_id,1,1);
}
- clif->skill_nodamage(src,bl,skill_id,1,1);
break;
case RK_LUXANIMA:
@@ -7751,28 +7936,26 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( src == bl )
break;
while( skill->area_temp[5] >= 0x10 ){
+ int value = 0;
type = SC_NONE;
- i = 0;
if( skill->area_temp[5]&0x10 ){
- if( dstsd ){
- i = (rnd()%100<50) ? 4 : ((rnd()%100<80) ? 3 : 2);
- clif->millenniumshield(dstsd,i);
- skill->area_temp[5] &= ~0x10;
- type = SC_MILLENNIUMSHIELD;
- }
+ value = (rnd()%100<50) ? 4 : ((rnd()%100<80) ? 3 : 2);
+ clif->millenniumshield(bl,value);
+ skill->area_temp[5] &= ~0x10;
+ type = SC_MILLENNIUMSHIELD;
}else if( skill->area_temp[5]&0x20 ){
- i = status_get_max_hp(bl) * 25 / 100;
+ value = status_get_max_hp(bl) * 25 / 100;
status->change_clear_buffs(bl,4);
skill->area_temp[5] &= ~0x20;
- status->heal(bl,i,0,1);
+ status->heal(bl,value,0,1);
type = SC_REFRESH;
}else if( skill->area_temp[5]&0x40 ){
skill->area_temp[5] &= ~0x40;
type = SC_GIANTGROWTH;
}else if( skill->area_temp[5]&0x80 ){
if( dstsd ){
- i = sstatus->hp / 4;
- if( status->charge(bl,i,0) )
+ value = sstatus->hp / 4;
+ if( status->charge(bl,value,0) )
type = SC_STONEHARDSKIN;
skill->area_temp[5] &= ~0x80;
}
@@ -7785,7 +7968,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
if( type > SC_NONE )
clif->skill_nodamage(bl, bl, skill_id, skill_lv,
- sc_start4(bl, type, 100, skill_lv, i, 0, 1, skill->get_time(skill_id, skill_lv)));
+ sc_start4(src,bl, type, 100, skill_lv, value, 0, 1, skill->get_time(skill_id, skill_lv)));
}
}else if( sd ){
if( tsc && tsc->count ){
@@ -7821,7 +8004,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
count = 10; // Max coounter
status_change_end(bl, SC_ROLLINGCUTTER, INVALID_TIMER);
}
- sc_start(bl,SC_ROLLINGCUTTER,100,count,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,SC_ROLLINGCUTTER,100,count,skill->get_time(skill_id,skill_lv));
clif->skill_nodamage(src,src,skill_id,skill_lv,1);
}
break;
@@ -7830,7 +8013,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( tsc && tsc->data[SC_WEAPONBLOCKING] )
status_change_end(bl, SC_WEAPONBLOCKING, INVALID_TIMER);
else
- sc_start(bl,SC_WEAPONBLOCKING,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,SC_WEAPONBLOCKING,100,skill_lv,skill->get_time(skill_id,skill_lv));
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
break;
@@ -7865,15 +8048,20 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case GC_PHANTOMMENACE:
+ {
+ int r;
clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
+ r = skill->get_splash(skill_id, skill_lv);
map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),BL_CHAR,
- src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
+ src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
+ map->foreachinarea( status->change_timer_sub,
+ src->m, src->x-r, src->y-r, src->x+r, src->y+r, BL_CHAR, src, NULL, SC_SIGHT, tick);
+ }
break;
-
case GC_HALLUCINATIONWALK:
{
- int heal = status_get_max_hp(bl) / 10;
+ int heal = status_get_max_hp(bl) * ( 18 - 2 * skill_lv ) / 100;
if( status_get_hp(bl) < heal ) { // if you haven't enough HP skill fails.
if( sd ) clif->skill_fail(sd,skill_id,USESKILL_FAIL_HP_INSUFFICIENT,0);
break;
@@ -7882,7 +8070,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( sd ) clif->skill_fail(sd,skill_id,USESKILL_FAIL_HP_INSUFFICIENT,0);
break;
}
- clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
}
break;
/**
@@ -7897,46 +8085,64 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case AB_CLEMENTIA:
case AB_CANTO:
+ {
+ int level = 0;
if( sd )
- i = skill_id == AB_CLEMENTIA ? pc->checkskill(sd,AL_BLESSING) : pc->checkskill(sd,AL_INCAGI);
+ level = skill_id == AB_CLEMENTIA ? pc->checkskill(sd,AL_BLESSING) : pc->checkskill(sd,AL_INCAGI);
if( sd == NULL || sd->status.party_id == 0 || flag&1 )
- clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(bl, type, 100, i + (sd?(sd->status.job_level / 10):0), skill->get_time(skill_id,skill_lv)));
+ clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, level + (sd?(sd->status.job_level / 10):0), skill->get_time(skill_id,skill_lv)));
else if( sd ) {
- if( !i )
+ if( !level )
clif->skill_fail(sd,skill_id,USESKILL_FAIL,0);
else
party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
}
+ }
break;
case AB_PRAEFATIO:
- if( sd == NULL || sd->status.party_id == 0 || flag&1 )
- clif->skill_nodamage(bl, bl, skill_id, skill_lv, sc_start4(bl, type, 100, skill_lv, 0, 0, 1, skill->get_time(skill_id, skill_lv)));
- else if( sd )
+ if( (flag&1) || sd == NULL || sd->status.party_id == 0 ) {
+ int count = 1;
+
+ if( dstsd && dstsd->special_state.no_magic_damage )
+ break;
+
+ if ( sd && sd->status.party_id == 0 )
+ count = 1;
+ else
+ count = party->foreachsamemap(party->sub_count, sd, 0);
+
+ if (count > 0)
+ clif->skill_nodamage(bl, bl, skill_id, skill_lv,
+ sc_start4(src, bl, type, 100, skill_lv, 0, 0, count, skill->get_time(skill_id, skill_lv)));
+ } else
party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
break;
-
case AB_CHEAL:
if( sd == NULL || sd->status.party_id == 0 || flag&1 ) {
- if( sd && tstatus && !battle->check_undead(tstatus->race, tstatus->def_ele) ) {
- i = skill->calc_heal(src, bl, AL_HEAL, pc->checkskill(sd, AL_HEAL), true);
-
- if( (dstsd && pc_ismadogear(dstsd)) || status->isimmune(bl))
- i = 0; // Should heal by 0 or won't do anything?? in iRO it breaks the healing to members.. [malufett]
+ if( sd && tstatus && !battle->check_undead(tstatus->race, tstatus->def_ele) && !tsc->data[SC_BERSERK] ) {
+ int lv = pc->checkskill(sd, AL_HEAL);
+ int heal = skill_calc_heal(src, bl, AL_HEAL, lv, true);
+
+ if( sd->status.party_id ) {
+ int partycount = party->foreachsamemap(party->sub_count, sd, 0);
+ if (partycount > 1)
+ heal += ((heal / 100) * (partycount * 10) / 4);
+ }
+ if( status->isimmune(bl) || (dstsd && pc_ismadogear(dstsd)) )
+ heal = 0;
- clif->skill_nodamage(bl, bl, skill_id, i, 1);
- if( tsc && tsc->data[SC_AKAITSUKI] && i )
- i = ~i + 1;
- status->heal(bl, i, 0, 0);
+ clif->skill_nodamage(bl, bl, skill_id, heal, 1);
+ if( tsc && tsc->data[SC_AKAITSUKI] && heal )
+ heal = ~heal + 1;
+ status->heal(bl, heal, 0, 1);
}
- }
- else if( sd )
+ } else if( sd )
party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
break;
-
case AB_ORATIO:
if( flag&1 )
- sc_start(bl, type, 40 + 5 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, type, 40 + 5 * skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
else {
map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id, skill_lv), BL_CHAR,
src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id);
@@ -7958,7 +8164,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
status_change_end(bl, SC_COLD, INVALID_TIMER);
}else //Success rate only applies to the curing effect and not stat bonus. Bonus status only applies to non infected targets
clif->skill_nodamage(bl, bl, skill_id, skill_lv,
- sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
+ sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
} else if( sd )
party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv),
src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
@@ -7966,23 +8172,27 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case AB_LAUDARAMUS:
if( flag&1 || sd == NULL ) {
- if( tsc && (tsc->data[SC_SLEEP] || tsc->data[SC_STUN] || tsc->data[SC_MANDRAGORA] || tsc->data[SC_SILENCE]) ){
+ if( tsc && (tsc->data[SC_SLEEP] || tsc->data[SC_STUN] || tsc->data[SC_MANDRAGORA] || tsc->data[SC_SILENCE] || tsc->data[SC_DEEP_SLEEP]) ){
// Success Chance: (40 + 10 * Skill Level) %
if( rnd()%100 > 40+10*skill_lv ) break;
status_change_end(bl, SC_SLEEP, INVALID_TIMER);
status_change_end(bl, SC_STUN, INVALID_TIMER);
status_change_end(bl, SC_MANDRAGORA, INVALID_TIMER);
status_change_end(bl, SC_SILENCE, INVALID_TIMER);
+ status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER);
}else // Success rate only applies to the curing effect and not stat bonus. Bonus status only applies to non infected targets
clif->skill_nodamage(bl, bl, skill_id, skill_lv,
- sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
+ sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
} else if( sd )
party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv),
src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
break;
case AB_CLEARANCE:
- if( flag&1 || (i = skill->get_splash(skill_id, skill_lv)) < 1 ) {
+ {
+ int splash;
+ if( flag&1 || (splash = skill->get_splash(skill_id, skill_lv)) < 1 ) {
+ int i;
//As of the behavior in official server Clearance is just a super version of Dispell skill. [Jobbie]
if( bl->type != BL_MOB && battle->check_target(src,bl,BCT_PARTY) <= 0 ) // Only affect mob or party.
break;
@@ -8015,8 +8225,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
status_change_end(bl,(sc_type)i,INVALID_TIMER);
}
break;
+ } else {
+ map->foreachinrange(skill->area_sub, bl, splash, BL_CHAR, src, skill_id, skill_lv, tick, flag|1, skill->castend_damage_id);
}
- map->foreachinrange(skill->area_sub, bl, i, BL_CHAR, src, skill_id, skill_lv, tick, flag|1, skill->castend_damage_id);
+ }
break;
case AB_SILENTIUM:
@@ -8030,7 +8242,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
**/
case WL_STASIS:
if( flag&1 )
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
else {
map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id, skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,(map_flag_vs(src->m)?BCT_ALL:BCT_ENEMY|BCT_SELF)|flag|1,skill->castend_nodamage_id);
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
@@ -8046,10 +8258,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
else if(bl->type == BL_PC) rate += 20 + 10 * skill_lv; // On Players, (20 + 10 * Skill Level) %
else rate += 40 + 10 * skill_lv; // On Monsters, (40 + 10 * Skill Level) %
+ if( sd )
+ skill->blockpc_start(sd,skill_id,4000);
+
if( !(tsc && tsc->data[type]) ){
- i = sc_start2(bl,type,rate,skill_lv,src->id,(src == bl)?5000:(bl->type == BL_PC)?skill->get_time(skill_id,skill_lv):skill->get_time2(skill_id, skill_lv));
- clif->skill_nodamage(src,bl,skill_id,skill_lv,i);
- if( sd && !i )
+ int failure = sc_start2(src,bl,type,rate,skill_lv,src->id,(src == bl)?5000:(bl->type == BL_PC)?skill->get_time(skill_id,skill_lv):skill->get_time2(skill_id, skill_lv));
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,failure);
+ if( sd && !failure )
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
}
}else
@@ -8058,18 +8273,22 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case WL_FROSTMISTY:
+ if( tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK)))
+ break; // Doesn't hit/cause Freezing to invisible enemy // Really? [Rytech]
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
map->foreachinrange(skill->area_sub,bl,skill->get_splash(skill_id,skill_lv),BL_CHAR|BL_SKILL,src,skill_id,skill_lv,tick,flag|BCT_ENEMY,skill->castend_damage_id);
break;
case WL_JACKFROST:
+ if( tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK)))
+ break; // Do not hit invisible enemy
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
map->foreachinshootrange(skill->area_sub,bl,skill->get_splash(skill_id,skill_lv),BL_CHAR|BL_SKILL,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
break;
case WL_MARSHOFABYSS:
clif->skill_nodamage(src, bl, skill_id, skill_lv,
- sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
+ sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
break;
case WL_SIENNAEXECRATE:
@@ -8079,7 +8298,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( tsc && tsc->data[SC_STONE] )
status_change_end(bl,SC_STONE,INVALID_TIMER);
else
- status->change_start(bl,SC_STONE,10000,skill_lv,0,0,500,skill->get_time(skill_id, skill_lv),2);
+ status->change_start(src,bl,SC_STONE,10000,skill_lv,0,0,500,skill->get_time(skill_id, skill_lv),2);
} else {
int rate = 45 + 5 * skill_lv;
if( rnd()%100 < rate ){
@@ -8094,19 +8313,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case WL_SUMMONBL:
case WL_SUMMONWB:
case WL_SUMMONSTONE:
+ {
+ int i;
for( i = SC_SUMMON1; i <= SC_SUMMON5; i++ ){
if( tsc && !tsc->data[i] ){ // officially it doesn't work like a stack
int ele = WLS_FIRE + (skill_id - WL_SUMMONFB) - (skill_id == WL_SUMMONSTONE ? 4 : 0);
clif->skill_nodamage(src, bl, skill_id, skill_lv,
- sc_start(bl, (sc_type)i, 100, ele, skill->get_time(skill_id, skill_lv)));
+ sc_start(src, bl, (sc_type)i, 100, ele, skill->get_time(skill_id, skill_lv)));
break;
}
}
+ }
break;
case WL_READING_SB:
if( sd ) {
struct status_change *sc = status->get_sc(bl);
+ int i;
for( i = SC_SPELLBOOK1; i <= SC_SPELLBOOK7; i++)
if( sc && !sc->data[i] )
@@ -8116,7 +8339,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
}
- sc_start(bl, SC_STOP, 100, skill_lv, INVALID_TIMER); //Can't move while selecting a spellbook.
+ sc_start(src, bl, SC_STOP, 100, skill_lv, INVALID_TIMER); //Can't move while selecting a spellbook.
clif->spellbook_list(sd);
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
}
@@ -8126,7 +8349,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
**/
case RA_FEARBREEZE:
clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
- clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
break;
case RA_WUGMASTERY:
@@ -8159,7 +8382,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
return 0;
}
if( sd && pc_isridingwug(sd) ) {
- clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(bl,type,100,skill_lv,unit->getdir(bl),0,0,1));
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(src,bl,type,100,skill_lv,unit->getdir(bl),0,0,1));
clif->walkok(sd);
}
break;
@@ -8195,34 +8418,39 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case NC_ANALYZE:
clif->skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
clif->skill_nodamage(src, bl, skill_id, skill_lv,
- sc_start(bl,type, 30 + 12 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src,bl,type, 30 + 12 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv)));
if( sd ) pc->overheat(sd,1);
break;
case NC_MAGNETICFIELD:
- if( (i = sc_start2(bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv))) )
+ {
+ int failure;
+ if( (failure = sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv))) )
{
map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),splash_target(src),src,skill_id,skill_lv,tick,flag|BCT_ENEMY|SD_SPLASH|1,skill->castend_damage_id);;
clif->skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6);
if (sd) pc->overheat(sd,1);
}
- clif->skill_nodamage(src,src,skill_id,skill_lv,i);
+ clif->skill_nodamage(src,src,skill_id,skill_lv,failure);
+ }
break;
case NC_REPAIR:
- if( sd )
- {
- int heal;
- if( dstsd && pc_ismadogear(dstsd) )
- {
- heal = dstsd->status.max_hp * (3+3*skill_lv) / 100;
- status->heal(bl,heal,0,2);
- } else {
- heal = sd->status.max_hp * (3+3*skill_lv) / 100;
- status->heal(src,heal,0,2);
+ if( sd ) {
+ int heal, hp = 0; // % of max hp regen
+ if( !dstsd || !pc_ismadogear(dstsd) ) {
+ clif->skill_fail(sd, skill_id,USESKILL_FAIL_TOTARGET,0);
+ break;
}
-
- clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
+ switch (cap_value(skill_lv, 1, 5)) {
+ case 1: hp = 4; break;
+ case 2: hp = 7; break;
+ case 3: hp = 13; break;
+ case 4: hp = 17; break;
+ case 5: hp = 23; break;
+ }
+ heal = tstatus->max_hp * hp / 100;
+ status->heal(bl,heal,0,2);
clif->skill_nodamage(src, bl, skill_id, skill_lv, heal);
}
break;
@@ -8240,7 +8468,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( sd ) {
int idx1 = skill->get_index(sd->reproduceskill_id), idx2 = skill->get_index(sd->cloneskill_id);
if( sd->status.skill[idx1].id || sd->status.skill[idx2].id ) {
- sc_start(src,SC_STOP,100,skill_lv,-1);// The skill_lv is stored in val1 used in skill_select_menu to determine the used skill lvl [Xazax]
+ sc_start(src,src,SC_STOP,100,skill_lv,-1);// The skill_lv is stored in val1 used in skill_select_menu to determine the used skill lvl [Xazax]
clif->autoshadowspell_list(sd);
clif->skill_nodamage(src,bl,skill_id,1,1);
}
@@ -8251,7 +8479,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SC_SHADOWFORM:
if( sd && dstsd && src != bl && !dstsd->shadowform_id ) {
- if( clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(src,type,100,skill_lv,bl->id,4+skill_lv,0,skill->get_time(skill_id, skill_lv))) )
+ if( clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(src,src,type,100,skill_lv,bl->id,4+skill_lv,0,skill->get_time(skill_id, skill_lv))) )
dstsd->shadowform_id = src->id;
}
else if( sd )
@@ -8261,16 +8489,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SC_BODYPAINT:
if( flag&1 ) {
if( tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] ||
- tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKINGEXCEED] ||
- tsc->data[SC__INVISIBILITY]) ) {
+ tsc->data[SC_CHASEWALK] || 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);
- status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER);
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
- sc_start(bl,SC_BLIND,53 + 2 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,type,20 + 5 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,SC_BLIND,53 + 2 * skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
}
} else {
clif->skill_nodamage(src, bl, skill_id, 0, 1);
@@ -8281,34 +8507,44 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SC_ENERVATION:
case SC_GROOMY:
+ case SC_IGNORANCE:
case SC_LAZINESS:
case SC_UNLUCKY:
case SC_WEAKNESS:
if( !(tsc && tsc->data[type]) ) {
- //((rand(myDEX / 12, myDEX / 4) + myJobLevel + 10 * skLevel) + myLevel / 10) - (targetLevel / 10 + targetLUK / 10 + (targetMaxWeight - targetWeight) / 1000 + rand(targetAGI / 6, targetAGI / 3))
- int rate = rnd_value(sstatus->dex/12,sstatus->dex/4) + 10*skill_lv + (sd?sd->status.job_level:0) + status->get_lv(src)/10
- - status->get_lv(bl)/10 - tstatus->luk/10 - (dstsd?(dstsd->max_weight-dstsd->weight)/10000:0) - rnd_value(tstatus->agi/6,tstatus->agi/3);
- rate = cap_value(rate, skill_lv+sstatus->dex/20, 100);
- clif->skill_nodamage(src,bl,skill_id,0,sc_start(bl,type,rate,skill_lv,skill->get_time(skill_id,skill_lv)));
- } else if( sd )
- clif->skill_fail(sd,skill_id,0,0);
- break;
-
- case SC_IGNORANCE:
- if( !(tsc && tsc->data[type]) ) {
- int rate = rnd_value(sstatus->dex/12,sstatus->dex/4) + 10*skill_lv + (sd?sd->status.job_level:0)
- + status->get_lv(src)/10 - status->get_lv(bl)/10 - tstatus->luk/10
- - (dstsd?(dstsd->max_weight-dstsd->weight)/10000:0) - rnd_value(tstatus->agi/6,tstatus->agi/3);
- rate = cap_value(rate, skill_lv+sstatus->dex/20, 100);
- if (clif->skill_nodamage(src,bl,skill_id,0,sc_start(bl,type,rate,skill_lv,skill->get_time(skill_id,skill_lv)))) {
- int sp = 200 * skill_lv;
+ int joblvbonus = 0;
+ int rate = 0;
+ if (is_boss(bl)) break;
+ joblvbonus = ( sd ? sd->status.job_level : 50 );
+ //First we set the success chance based on the caster's build which increases the chance.
+ rate = 10 * skill_lv + rnd_value( sstatus->dex / 12, sstatus->dex / 4 ) + joblvbonus + status->get_lv(src) / 10;
+ // We then reduce the success chance based on the target's build.
+ rate -= rnd_value( tstatus->agi / 6, tstatus->agi / 3 ) - tstatus->luk / 10 - ( dstsd ? (dstsd->max_weight / 10 - dstsd->weight / 10 ) / 100 : 0 ) - status->get_lv(bl) / 10;
+ //Finally we set the minimum success chance cap based on the caster's skill level and DEX.
+ rate = cap_value( rate, skill_lv + sstatus->dex / 20, 100);
+ clif->skill_nodamage(src,bl,skill_id,0,sc_start(src,bl,type,rate,skill_lv,skill->get_time(skill_id,skill_lv)));
+ if ( tsc && tsc->data[SC__IGNORANCE] && skill_id == SC_IGNORANCE) {
+ //If the target was successfully inflected with the Ignorance status, drain some of the targets SP.
+ int sp = 100 * skill_lv;
if( dstmd ) sp = dstmd->level * 2;
if( status_zap(bl,0,sp) )
- status->heal(src,0,sp/2,3);
- } else if( sd )
- clif->skill_fail(sd,skill_id,0,0);
+ status->heal(src,0,sp/2,3);//What does flag 3 do? [Rytech]
+ }
+ if ( tsc && tsc->data[SC__UNLUCKY] && skill_id == SC_UNLUCKY) {
+ //If the target was successfully inflected with the Unlucky status, give 1 of 3 random status's.
+ switch(rnd()%3) {//Targets in the Unlucky status will be affected by one of the 3 random status's reguardless of resistance.
+ case 0:
+ status->change_start(src,bl,SC_POISON,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),10);
+ break;
+ case 1:
+ status->change_start(src,bl,SC_SILENCE,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),10);
+ break;
+ case 2:
+ status->change_start(src,bl,SC_BLIND,10000,skill_lv,0,0,0,skill->get_time(skill_id,skill_lv),10);
+ }
+ }
} else if( sd )
- clif->skill_fail(sd,skill_id,0,0);
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
break;
case LG_TRAMPLE:
@@ -8320,114 +8556,96 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( tsc && tsc->data[type] )
status_change_end(bl,type,INVALID_TIMER);
else
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
break;
case LG_SHIELDSPELL:
if( flag&1 ) {
- int duration = (sd) ? sd->bonus.shieldmdef * 2000 : 10000;
- sc_start(bl,SC_SILENCE,100,skill_lv,duration);
+ sc_start(src,bl,SC_SILENCE,100,skill_lv,sd->bonus.shieldmdef * 30000);
} else if( sd ) {
- int opt = skill_lv;
- int rate = rnd()%100;
- int val, brate;
+ int opt = 0, val = 0, splashrange = 0;
+ struct item_data *shield_data = sd->inventory_data[sd->equip_index[EQI_HAND_L]];
+ if( !shield_data || shield_data->type != IT_ARMOR ) {
+ //Skill will first check if a shield is equipped. If none is found on the caster the skill will fail.
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+ //Generates a number between 1 - 3. The number generated will determine which effect will be triggered.
+ opt = rnd()%3 + 1;
switch( skill_lv ) {
case 1:
- {
- struct item_data *shield_data = sd->inventory_data[sd->equip_index[EQI_HAND_L]];
- if( !shield_data || shield_data->type != IT_ARMOR ) { // No shield?
- clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
- break;
- }
- brate = shield_data->def * 10;
- if( rate < 50 )
- opt = 1;
- else if( rate < 75 )
- opt = 2;
+ if ( shield_data->def >= 0 && shield_data->def <= 40)
+ splashrange = 1;
+ else if ( shield_data->def >= 41 && shield_data->def <= 80)
+ splashrange = 2;
else
- opt = 3;
-
+ splashrange = 3;
switch( opt ) {
case 1:
- sc_start(bl,SC_SHIELDSPELL_DEF,100,opt,-1);
+ sc_start(src,bl,SC_SHIELDSPELL_DEF,100,opt,INVALID_TIMER); //Splash AoE ATK
clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
- if( rate < brate )
- map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
+ map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
status_change_end(bl,SC_SHIELDSPELL_DEF,INVALID_TIMER);
break;
case 2:
- val = shield_data->def / 10; // % Reflected damage.
- sc_start2(bl,SC_SHIELDSPELL_DEF,brate,opt,val,shield_data->def * 1000);
+ val = shield_data->def/10; //Damage Reflecting Increase.
+ sc_start2(src,bl,SC_SHIELDSPELL_DEF,100,opt,val,shield_data->def * 1000);
break;
case 3:
- val = shield_data->def; // Attack increase.
- sc_start2(bl,SC_SHIELDSPELL_DEF,brate,opt,val,shield_data->def * 3000);
+ //Weapon Attack Increase.
+ val = shield_data->def;
+ sc_start2(src,bl,SC_SHIELDSPELL_DEF,100,opt,val,shield_data->def * 3000);
break;
}
- }
break;
case 2:
- brate = sd->bonus.shieldmdef * 20;
- if( rate < 30 )
- opt = 1;
- else if( rate < 60 )
- opt = 2;
+ if ( sd->bonus.shieldmdef >= 1 && sd->bonus.shieldmdef <= 3 )
+ splashrange = 1;
+ else if ( sd->bonus.shieldmdef >= 4 && sd->bonus.shieldmdef <= 5 )
+ splashrange = 2;
else
- opt = 3;
+ splashrange = 3;
switch( opt ) {
case 1:
- sc_start(bl,SC_SHIELDSPELL_MDEF,100,opt,-1);
+ sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,INVALID_TIMER); //Splash AoE MATK
clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
- if( rate < brate )
- map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|2,skill->castend_damage_id);
+ map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
status_change_end(bl,SC_SHIELDSPELL_MDEF,INVALID_TIMER);
break;
case 2:
- sc_start(bl,SC_SHIELDSPELL_MDEF,100,opt,-1);
- clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
- if( rate < brate )
- map->foreachinrange(skill->area_sub,src,skill->get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_nodamage_id);
+ sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,sd->bonus.shieldmdef * 2000); //Splash AoE Lex Divina
+ clif->skill_damage(src,bl,tick,status_get_amotion(src),0,-30000,1,skill_id,skill_lv,6);
+ map->foreachinrange(skill->area_sub,src,splashrange,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_nodamage_id);
break;
case 3:
- if( sc_start(bl,SC_SHIELDSPELL_MDEF,brate,opt,sd->bonus.shieldmdef * 30000) )
+ if( sc_start(src,bl,SC_SHIELDSPELL_MDEF,100,opt,sd->bonus.shieldmdef * 30000) ) //Magnificat
clif->skill_nodamage(src,bl,PR_MAGNIFICAT,skill_lv,
- sc_start(bl,SC_MAGNIFICAT,100,1,sd->bonus.shieldmdef * 30000));
+ sc_start(src,bl,SC_MAGNIFICAT,100,1,sd->bonus.shieldmdef * 30000));
break;
}
break;
-
case 3:
{
- struct item *it = &sd->status.inventory[sd->equip_index[EQI_HAND_L]];
- if( !it ) { // No shield?
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- break;
- }
- brate = it->refine * 5;
- if( rate < 25 )
- opt = 1;
- else if( rate < 50 )
- opt = 2;
- else
- opt = 3;
+ struct item *shield = &sd->status.inventory[sd->equip_index[EQI_HAND_L]];
+ int rate = 0;
switch( opt ) {
case 1:
- val = 105 * it->refine / 10;
- sc_start2(bl,SC_SHIELDSPELL_REF,brate,opt,val,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,SC_SHIELDSPELL_REF,100,opt,shield->refine * 30000); //Now breaks Armor at 100% rate
break;
case 2:
- case 3:
- if( rate < brate ) {
- val = sstatus->max_hp * (11 + it->refine) / 100;
- status->heal(bl, val, 0, 3);
- }
+ val = shield->refine * 10 * status->get_lv(src) / 100; //DEF Increase
+ rate = (shield->refine * 2) + (status_get_luk(src) / 10); //Status Resistance Rate
+ if( sc_start2(src,bl,SC_SHIELDSPELL_REF,100,opt,val,shield->refine * 20000))
+ clif->skill_nodamage(src,bl,SC_SCRESIST,skill_lv,
+ sc_start(src,bl,SC_SCRESIST,100,rate,shield->refine * 30000));
break;
-#if 0 // TODO: I need confirm what effect should be here. Moved to case 2 to until we got it.
case 3:
- // Full protection.
+ sc_start(src,bl,SC_SHIELDSPELL_REF,100,opt,INVALID_TIMER); //HP Recovery
+ val = sstatus->max_hp * ((status->get_lv(src) / 10) + (shield->refine + 1)) / 100;
+ status->heal(bl, val, 0, 2);
+ status_change_end(bl,SC_SHIELDSPELL_REF,INVALID_TIMER);
break;
-#endif // 0
}
}
break;
@@ -8438,7 +8656,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case LG_PIETY:
if( flag&1 )
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
else {
skill->area_temp[2] = 0;
map->foreachinrange(skill->area_sub,bl,skill->get_splash(skill_id,skill_lv),BL_PC,src,skill_id,skill_lv,tick,flag|SD_PREAMBLE|BCT_PARTY|BCT_SELF|1,skill->castend_nodamage_id);
@@ -8447,7 +8665,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case LG_KINGS_GRACE:
if( flag&1 ){
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ int i;
+ sc_start(src,bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
for(i=0; i<SC_MAX; i++)
{
if (!tsc->data[i])
@@ -8459,9 +8678,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SC_BLOODING: case SC_CURSE:
case SC_CONFUSION: case SC_ILLUSION:
case SC_SILENCE: case SC_BURNING:
- case SC_COLD: case SC_FROSTMISTY:
+ case SC_COLD: case SC_FROSTMISTY:
case SC_DEEP_SLEEP: case SC_FEAR:
- case SC_MANDRAGORA:
+ case SC_MANDRAGORA: case SC__CHAOS:
status_change_end(bl, (sc_type)i, INVALID_TIMER);
}
}
@@ -8481,12 +8700,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
clif->updatestatus(sd,SP_JOBEXP);
}
clif->skill_nodamage(bl,src,skill_id,skill_lv,
- sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
+ sc_start(src,bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
break;
case SR_CURSEDCIRCLE:
if( flag&1 ) {
if( is_boss(bl) ) break;
- if( sc_start2(bl, type, 100, skill_lv, src->id, skill->get_time(skill_id, skill_lv))) {
+ if( sc_start2(src,bl, type, 100, skill_lv, src->id, skill->get_time(skill_id, skill_lv))) {
if( bl->type == BL_MOB )
mob->unlocktarget((TBL_MOB*)bl,timer->gettick());
unit->stop_attack(bl);
@@ -8501,30 +8720,31 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id);
if( sd ) pc->delspiritball(sd, count, 0);
clif->skill_nodamage(src, src, skill_id, skill_lv,
- sc_start2(src, SC_CURSEDCIRCLE_ATKER, 100, skill_lv, count, skill->get_time(skill_id,skill_lv)));
+ sc_start2(src, src, SC_CURSEDCIRCLE_ATKER, 100, skill_lv, count, skill->get_time(skill_id,skill_lv)));
}
break;
case SR_RAISINGDRAGON:
if( sd ) {
short max = 5 + skill_lv;
- sc_start(bl, SC_EXPLOSIONSPIRITS, 100, skill_lv, skill->get_time(skill_id, skill_lv));
+ int i;
+ sc_start(src, bl, SC_EXPLOSIONSPIRITS, 100, skill_lv, skill->get_time(skill_id, skill_lv));
for( i = 0; i < max; i++ ) // Don't call more than max available spheres.
pc->addspiritball(sd, skill->get_time(skill_id, skill_lv), max);
- clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(bl, type, 100, skill_lv,skill->get_time(skill_id, skill_lv)));
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv,skill->get_time(skill_id, skill_lv)));
}
break;
case SR_ASSIMILATEPOWER:
if( flag&1 ) {
- i = 0;
+ int sp = 0;
if( dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m)) && (dstsd->class_&MAPID_BASEMASK)!=MAPID_GUNSLINGER )
{
- i = dstsd->spiritball; //1%sp per spiritball.
+ sp = dstsd->spiritball; //1%sp per spiritball.
pc->delspiritball(dstsd, dstsd->spiritball, 0);
}
- if( i ) status_percent_heal(src, 0, i);
- clif->skill_nodamage(src, bl, skill_id, skill_lv, i ? 1:0);
+ if( sp ) status_percent_heal(src, 0, sp);
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, sp ? 1:0);
} else {
clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|BCT_SELF|SD_SPLASH|1, skill->castend_nodamage_id);
@@ -8535,6 +8755,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( !dstsd )
break;
if( sd && dstsd->spiritball <= 5 ) {
+ int i;
for(i = 0; i <= 5; i++) {
pc->addspiritball(dstsd, skill->get_time(MO_CALLSPIRITS, pc->checkskill(sd,MO_CALLSPIRITS)), i);
pc->delspiritball(sd, sd->spiritball, 0);
@@ -8573,38 +8794,32 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SR_GENTLETOUCH_CHANGE:
case SR_GENTLETOUCH_REVITALIZE:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start2(bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv)));
+ sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv)));
break;
case SR_FLASHCOMBO:
+ {
+ int i;
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
for(i = SR_FLASHCOMBO_ATK_STEP1; i <= SR_FLASHCOMBO_ATK_STEP4; i++)
- skill->addtimerskill(src, tick + 500 * (i - SR_FLASHCOMBO_ATK_STEP1), bl->id, 0, 0, i, skill_lv, BF_WEAPON, flag|SD_LEVEL);
+ skill->addtimerskill(src, tick + 400 * (i - SR_FLASHCOMBO_ATK_STEP1), bl->id, 0, 0, i, skill_lv, BF_WEAPON, flag|SD_LEVEL);
+ }
break;
case WA_SWING_DANCE:
- case WA_MOONLIT_SERENADE:
- if( sd == NULL || sd->status.party_id == 0 || (flag & 1) )
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
- else if( sd ) { // Only shows effects on caster.
- clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
- }
- break;
-
case WA_SYMPHONY_OF_LOVER:
+ case WA_MOONLIT_SERENADE:
case MI_RUSH_WINDMILL:
case MI_ECHOSONG:
- if( sd == NULL || sd->status.party_id == 0 || (flag & 1) )
- sc_start4(bl,type,100,skill_lv,6*skill_lv,(sd?pc->checkskill(sd,WM_LESSON):0),(sd?sd->status.job_level:0),skill->get_time(skill_id,skill_lv));
- else if( sd ) { // Only shows effects on caster.
+ if( flag&1 )
+ sc_start2(src,bl,type,100,skill_lv,(sd?pc->checkskill(sd,WM_LESSON):0),skill->get_time(skill_id,skill_lv));
+ else if( sd ) {
+ party->foreachsamemap(skill->area_sub,sd,skill->get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,flag|BCT_PARTY|1,skill->castend_nodamage_id);
+ sc_start2(src,bl,type,100,skill_lv,pc->checkskill(sd,WM_LESSON),skill->get_time(skill_id,skill_lv));
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
}
break;
case MI_HARMONIZE:
- if( src != bl )
- clif->skill_nodamage(src, src, skill_id, skill_lv, sc_start(src, type, 100, skill_lv, skill->get_time(skill_id,skill_lv)));
- clif->skill_nodamage(src, bl, skill_id, skill_lv, sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id,skill_lv)));
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start2(src,bl,type,100,skill_lv,(sd?pc->checkskill(sd,WM_LESSON):1),skill->get_time(skill_id,skill_lv)));
break;
case WM_DEADHILLHERE:
@@ -8613,107 +8828,115 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
if( rnd()%100 < 88 + 2 * skill_lv ) {
- int heal = tstatus->sp;
- if( heal <= 0 )
+ int heal = 0;
+ status_zap(bl, 0, tstatus->sp * (60 - 10 * skill_lv) / 100);
+ heal = tstatus->sp;
+ if ( heal <= 0 )
heal = 1;
- tstatus->hp = heal;
- tstatus->sp -= tstatus->sp * ( 120 - 20 * skill_lv ) / 100;
+ status->fixed_revive(bl, heal, 0);
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- pc->revive((TBL_PC*)bl,heal,0);
- clif->resurrection(bl,1);
+ status->set_sp(bl, 0, 0);
}
}
break;
+ case WM_LULLABY_DEEPSLEEP:
+ if ( flag&1 )
+ sc_start2(src,bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv));
+ else if ( sd ) {
+ int rate = 4 * skill_lv + 2 * (sd ? pc->checkskill(sd,WM_LESSON) : 1) + status->get_lv(src) / 15 + (sd? sd->status.job_level:0) / 5;
+ if ( rnd()%100 < rate ) {
+ flag |= BCT_PARTY|BCT_GUILD;
+ map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_CHAR|BL_NPC|BL_SKILL, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id);
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
+ status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER);
+ }
+ }
+ break;
case WM_SIRCLEOFNATURE:
flag |= BCT_SELF|BCT_PARTY|BCT_GUILD;
case WM_VOICEOFSIREN:
if( skill_id != WM_SIRCLEOFNATURE )
flag &= ~BCT_SELF;
if( flag&1 ) {
- sc_start2(bl,type,(skill_id==WM_VOICEOFSIREN)?20+10*skill_lv:100,skill_lv,(skill_id==WM_VOICEOFSIREN)?src->id:0,skill->get_time(skill_id,skill_lv));
- } else {
- map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),(skill_id==WM_VOICEOFSIREN)?BL_CHAR|BL_SKILL:BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id);
- clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
+ sc_start2(src,bl,type,100,skill_lv,(skill_id==WM_VOICEOFSIREN)?src->id:0,skill->get_time(skill_id,skill_lv));
+ } else if( sd ) {
+ int rate = 6 * skill_lv + (sd ? pc->checkskill(sd,WM_LESSON) : 1) + (sd? sd->status.job_level:0) / 2;
+ if ( rnd()%100 < rate ) {
+ flag |= BCT_PARTY|BCT_GUILD;
+ map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),(skill_id==WM_VOICEOFSIREN)?BL_CHAR|BL_NPC|BL_SKILL:BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id);
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
+ status_change_end(bl, SC_SIREN, INVALID_TIMER);
+ }
}
break;
case WM_GLOOMYDAY:
- clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- if( dstsd && ( pc->checkskill(dstsd,KN_BRANDISHSPEAR) || pc->checkskill(dstsd,LK_SPIRALPIERCE) ||
- pc->checkskill(dstsd,CR_SHIELDCHARGE) || pc->checkskill(dstsd,CR_SHIELDBOOMERANG) ||
- pc->checkskill(dstsd,PA_SHIELDCHAIN) || pc->checkskill(dstsd,LG_SHIELDPRESS) ) )
- {
- sc_start(bl,SC_GLOOMYDAY_SK,100,skill_lv,skill->get_time(skill_id,skill_lv));
- break;
- }
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
- break;
-
- case WM_SATURDAY_NIGHT_FEVER:
- if( flag&1 ) { // Affect to all targets arround the caster and caster too.
- if( !(tsc && tsc->data[type]) )
- sc_start(bl, type, 100, skill_lv,skill->get_time(skill_id, skill_lv));
- } else if( flag&2 ) {
- if( src->id != bl->id && battle->check_target(src,bl,BCT_ENEMY) > 0 )
- status_fix_damage(src,bl,9999,clif->damage(src,bl,tick,0,0,9999,0,0,0));
- } else if( sd ) {
- short chance = sstatus->int_/6 + sd->status.job_level/5 + skill_lv*4;
- if( !sd->status.party_id || (rnd()%100 > chance)) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_NEED_HELPER,0);
- break;
- }
- if( map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id,skill_lv),
- BL_PC, src, skill_id, skill_lv, tick, BCT_ENEMY, skill->area_sub_count) > 7 )
- flag |= 2;
- else
- flag |= 1;
- map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|BCT_SELF, skill->castend_nodamage_id);
- clif->skill_nodamage(src, bl, skill_id, skill_lv,
- sc_start(src,SC_STOP,100,skill_lv,skill->get_time2(skill_id,skill_lv)));
- if( flag&2 ) // Dealed here to prevent conflicts
- status_fix_damage(src,bl,9999,clif->damage(src,bl,tick,0,0,9999,0,0,0));
+ if ( tsc && tsc->data[type] ) {
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
+ break;
}
+ // val4 indicates caster's voice lesson level
+ sc_start4(src,bl,type,100,skill_lv, 0, 0, sd?pc->checkskill(sd,WM_LESSON):10, skill->get_time(skill_id,skill_lv));
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
break;
case WM_SONG_OF_MANA:
case WM_DANCE_WITH_WUG:
case WM_LERADS_DEW:
+ case WM_UNLIMITED_HUMMING_VOICE:
+ {
+ int chorusbonus = battle->calc_chorusbonus(sd);
+ if( flag&1 )
+ sc_start2(src,bl,type,100,skill_lv,chorusbonus,skill->get_time(skill_id,skill_lv));
+ else if( sd ) {
+ party->foreachsamemap(skill->area_sub,sd,skill->get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,flag|BCT_PARTY|1,skill->castend_nodamage_id);
+ sc_start2(src,bl,type,100,skill_lv,chorusbonus,skill->get_time(skill_id,skill_lv));
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
+ }
+ }
+ break;
+ case WM_SATURDAY_NIGHT_FEVER:
+ {
if( flag&1 ) {
- // These affect to to all party members near the caster.
- struct status_change *sc = status->get_sc(src);
- if( sc && sc->data[type] ) {
- sc_start2(bl,type,100,skill_lv,sc->data[type]->val2,skill->get_time(skill_id,skill_lv));
- }
+ int madnesscheck = 0;
+ if ( sd )//Required to check if the lord of madness effect will be applied.
+ madnesscheck = map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY, skill->area_sub_count);
+ sc_start(src, bl, type, 100, skill_lv,skill->get_time(skill_id, skill_lv));
+ if ( madnesscheck >= 8 )//The god of madness deals 9999 fixed unreduceable damage when 8 or more enemy players are affected.
+ status_fix_damage(src, bl, 9999, clif->damage(src, bl, 0, 0, 9999, 0, 0, 0));
+ //skill->attack(BF_MISC,src,src,bl,skillid,skilllv,tick,flag);//To renable when I can confirm it deals damage like this. Data shows its dealed as reflected damage which I dont have it coded like that yet. [Rytech]
} else if( sd ) {
- uint16 lv = skill_lv;
- int count = skill->check_pc_partner(sd,skill_id,&lv,skill->get_splash(skill_id,skill_lv),1);
- if( sc_start2(bl,type,100,skill_lv,count,skill->get_time(skill_id,skill_lv)) )
- party->foreachsamemap(skill->area_sub,sd,skill->get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,flag|BCT_PARTY|1,skill->castend_nodamage_id);
- clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
-
+ int rate = sstatus->int_ / 6 + (sd? sd->status.job_level:0) / 5 + skill_lv * 4;
+ if ( rnd()%100 < rate ) {
+ map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id);
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
+ }
}
+ }
break;
case WM_MELODYOFSINK:
case WM_BEYOND_OF_WARCRY:
- case WM_UNLIMITED_HUMMING_VOICE:
- if( flag&1 ) {
- sc_start2(bl,type,100,skill_lv,skill->area_temp[0],skill->get_time(skill_id,skill_lv));
- } else { // These affect to all targets arround the caster.
- uint16 lv = skill_lv;
- skill->area_temp[0] = (sd) ? skill->check_pc_partner(sd,skill_id,&lv,skill->get_splash(skill_id,skill_lv),1) : 50; // 50% chance in non BL_PC (clones).
- map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id);
- clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
+ {
+ int chorusbonus = battle->calc_chorusbonus(sd);
+ if( flag&1 )
+ sc_start2(src,bl,type,100,skill_lv,chorusbonus,skill->get_time(skill_id,skill_lv));
+ else if( sd ) {
+ if ( rnd()%100 < 15 + 5 * skill_lv + 5 * chorusbonus ) {
+ map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id);
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
+ }
}
+ }
break;
case WM_RANDOMIZESPELL: {
- int improv_skill_id = 0, improv_skill_lv;
+ int improv_skill_id = 0, improv_skill_lv, improv_idx;
do {
- i = rnd() % MAX_SKILL_IMPROVISE_DB;
- improv_skill_id = skill->improvise_db[i].skill_id;
- } while( improv_skill_id == 0 || rnd()%10000 >= skill->improvise_db[i].per );
+ improv_idx = rnd() % MAX_SKILL_IMPROVISE_DB;
+ improv_skill_id = skill->improvise_db[improv_idx].skill_id;
+ } while( improv_skill_id == 0 || rnd()%10000 >= skill->improvise_db[improv_idx].per );
improv_skill_lv = 4 + skill_lv;
clif->skill_nodamage (src, bl, skill_id, skill_lv, 1);
@@ -8758,28 +8981,25 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( sd )
{
short x, y; // Destiny position.
- unsigned short mapindex;
+ unsigned short map_index;
- if( skill_id == RETURN_TO_ELDICASTES)
- {
+ if( skill_id == RETURN_TO_ELDICASTES) {
x = 198;
y = 187;
- mapindex = mapindex_name2id(MAP_DICASTES);
- }
- else
- {
+ map_index = mapindex->name2id(MAP_DICASTES);
+ } else {
x = 44;
y = 151;
- mapindex = mapindex_name2id(MAP_MORA);
+ map_index = mapindex->name2id(MAP_MORA);
}
- if(!mapindex) {
+ if(!map_index) {
//Given map not found?
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
map->freeblock_unlock();
return 0;
}
- pc->setpos(sd, mapindex, x, y, CLR_TELEPORT);
+ pc->setpos(sd, map_index, x, y, CLR_TELEPORT);
}
break;
@@ -8797,23 +9017,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SO_ARRULLO:
{
// [(15 + 5 * Skill Level) + ( Caster?s INT / 5 ) + ( Caster?s Job Level / 5 ) - ( Target?s INT / 6 ) - ( Target?s LUK / 10 )] %
- int rate = (15 + 5 * skill_lv) + status_get_int(src)/5 + (sd ? sd->status.job_level : 0);
+ int rate = (15 + 5 * skill_lv) + status_get_int(src)/5 + (sd? sd->status.job_level:0)/5;
rate -= status_get_int(bl)/6 - status_get_luk(bl)/10;
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
- sc_start2(bl, type, rate, skill_lv, 1, skill->get_time(skill_id, skill_lv));
- }
- break;
-
- case WM_LULLABY_DEEPSLEEP:
- if( flag&1 ){
- //[(Skill Level x 4) + (Voice Lessons Skill Level x 2) + (Caster?s Base Level / 15) + (Caster?s Job Level / 5)] %
- int rate = (4 * skill_lv) + ( (sd) ? pc->checkskill(sd,WM_LESSON)*2 + sd->status.job_level/5 : 0 ) + status->get_lv(src) / 15;
- if( bl != src )
- sc_start(bl,type,rate,skill_lv,skill->get_time(skill_id,skill_lv));
- }else {
- clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
- map->foreachinrange(skill->area_sub, bl, skill->get_splash(skill_id, skill_lv), BL_CHAR,
- src, skill_id, skill_lv, tick, flag|BCT_ALL|1, skill->castend_nodamage_id);
+ sc_start2(src,bl, type, rate, skill_lv, 1, skill->get_time(skill_id, skill_lv));
}
break;
@@ -8830,7 +9037,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
// Summoning the new one.
if( !elemental->create(sd,elemental_class,skill->get_time(skill_id,skill_lv)) ) {
- clif->skill_fail(sd,skill_id,0,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
@@ -8876,7 +9083,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
duration = 9000;
break;
}
- skill->blockpc_start(sd, skill_id, duration, false);
+ skill->blockpc_start(sd, skill_id, duration);
}
break;
@@ -8898,16 +9105,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
break;
- case SO_ELEMENTAL_SHIELD:
- if( sd == NULL || !sd->ed )
- break;
- elemental->delete(sd->ed, 0);
- if( sd->status.party_id == 0 || flag&1 )
- skill->unitsetting(src,MG_SAFETYWALL,skill_lv,bl->x,bl->y,0);
- else
- party->foreachsamemap(skill->area_sub, sd, skill->get_splash(skill_id, skill_lv), src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill->castend_nodamage_id);
- break;
-
case GN_CHANGEMATERIAL:
case SO_EL_ANALYSIS:
if( sd ) {
@@ -8926,7 +9123,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
status_change_end(src, type, INVALID_TIMER); // the first one cancels and the last one will take effect resetting the timer
}
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
- sc_start2(bl, type, 100, skill_lv, src->id, skill->get_time(skill_id,skill_lv));
+ sc_start2(src,bl, type, 100, skill_lv, src->id, skill->get_time(skill_id,skill_lv));
(sc->bs_counter)++;
} else if( sd ) {
clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
@@ -8940,8 +9137,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
int chance = 25 + 10 * skill_lv - (status_get_vit(bl) + status_get_luk(bl)) / 5;
if ( chance < 10 )
chance = 10;//Minimal chance is 10%.
- if ( rand()%100 < chance ) {//Coded to both inflect the status and drain the target's SP only when successful. [Rytech]
- sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv));
+ if ( rnd()%100 < chance ) {//Coded to both inflect the status and drain the target's SP only when successful. [Rytech]
+ sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv));
status_zap(bl, 0, status_get_max_sp(bl) * (25 + 5 * skill_lv) / 100);
}
} else if ( sd ) {
@@ -8953,23 +9150,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case GN_SLINGITEM:
if( sd ) {
short ammo_id;
- i = sd->equip_index[EQI_AMMO];
- if( i <= 0 )
+ int equip_idx = sd->equip_index[EQI_AMMO];
+ if( equip_idx <= 0 )
break; // No ammo.
- ammo_id = sd->inventory_data[i]->nameid;
+ ammo_id = sd->inventory_data[equip_idx]->nameid;
if( ammo_id <= 0 )
break;
sd->itemid = ammo_id;
if( itemdb_is_GNbomb(ammo_id) ) {
if(battle->check_target(src,bl,BCT_ENEMY) > 0) {// Only attack if the target is an enemy.
- if( ammo_id == 13263 )
+ if( ammo_id == ITEMID_PINEAPPLE_BOMB )
map->foreachincell(skill->area_sub,bl->m,bl->x,bl->y,BL_CHAR,src,GN_SLINGITEM_RANGEMELEEATK,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
else
skill->attack(BF_WEAPON,src,src,bl,GN_SLINGITEM_RANGEMELEEATK,skill_lv,tick,flag);
} else //Otherwise, it fails, shows animation and removes items.
clif->skill_fail(sd,GN_SLINGITEM_RANGEMELEEATK,0xa,0);
} else if( itemdb_is_GNthrowable(ammo_id) ) {
- struct script_code *scriptroot = sd->inventory_data[i]->script;
+ struct script_code *scriptroot = sd->inventory_data[equip_idx]->script;
if( !scriptroot )
break;
if( dstsd )
@@ -9026,9 +9223,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
clif->skill_nodamage(src,src,skill_id,skill_lv,1);
clif->skill_damage(src, ( skill_id == EL_GUST || skill_id == EL_BLAST || skill_id == EL_WILD_STORM )?src:bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
if( skill_id == EL_WIND_STEP ) // There aren't teleport, just push the master away.
- skill->blown(src,bl,(rnd()%skill->get_blewcount(skill_id,skill_lv))+1,rand()%8,0);
- sc_start(src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv));
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ skill->blown(src,bl,(rnd()%skill->get_blewcount(skill_id,skill_lv))+1,rnd()%8,0);
+ sc_start(src, src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src, bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
}
}
}
@@ -9056,8 +9253,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
} else {
// This not heals at the end.
clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
- sc_start(src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv));
- sc_start(bl,type,100,src->id,skill->get_time(skill_id,skill_lv));
+ sc_start(src, src,type2,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ sc_start(src, bl,type,100,src->id,skill->get_time(skill_id,skill_lv));
}
}
}
@@ -9068,6 +9265,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case KO_KAZEHU_SEIRAN:
case KO_DOHU_KOUKAI:
if(sd) {
+ int i;
int ttype = skill->get_ele(skill_id, skill_lv);
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
ARR_FIND(1, 6, i, sd->charm[i] > 0 && ttype != i);
@@ -9079,16 +9277,16 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case KO_ZANZOU:
if(sd) {
- struct mob_data *md;
-
- md = mob->once_spawn_sub(src, src->m, src->x, src->y, status->get_name(src), 2308, "", SZ_SMALL, AI_NONE);
- if( md ) {
- md->master_id = src->id;
- md->special_state.ai = AI_ZANZOU;
- if( md->deletetimer != INVALID_TIMER )
- timer->delete(md->deletetimer, mob->timer_delete);
- md->deletetimer = timer->add (timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, md->bl.id, 0);
- mob->spawn( md );
+ struct mob_data *summon_md;
+
+ summon_md = mob->once_spawn_sub(src, src->m, src->x, src->y, status->get_name(src), 2308, "", SZ_MEDIUM, AI_NONE);
+ if( summon_md ) {
+ summon_md->master_id = src->id;
+ summon_md->special_state.ai = AI_ZANZOU;
+ if( summon_md->deletetimer != INVALID_TIMER )
+ timer->delete(summon_md->deletetimer, mob->timer_delete);
+ summon_md->deletetimer = timer->add(timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, summon_md->bl.id, 0);
+ mob->spawn( summon_md );
pc->setinvincibletimer(sd,500);// unlock target lock
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
skill->blown(src,bl,skill->get_blewcount(skill_id,skill_lv),unit->getdir(bl),0);
@@ -9105,7 +9303,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
if( dstsd && tsc && !tsc->data[type] && rand()%100 < rate ){
clif->skill_nodamage(src, bl, skill_id, skill_lv,
- sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
+ sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
}else if( sd )
clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
}
@@ -9116,10 +9314,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
&& rand()%100 < (10 * (5 * skill_lv - status_get_int(bl) / 2 + 45 + 5 * skill_lv))
) {
clif->skill_nodamage(src, bl, skill_id, skill_lv,
- status->change_start(bl, type, 10000, skill_lv, 0, 0, 0, skill->get_time(skill_id, skill_lv), 1));
+ status->change_start(src, bl, type, 10000, skill_lv, 0, 0, 0, skill->get_time(skill_id, skill_lv), 1));
status_zap(bl, tstatus->max_hp * skill_lv * 5 / 100 , 0);
if( status->get_lv(bl) <= status->get_lv(src) )
- status->change_start(bl, SC_COMA, skill_lv, skill_lv, 0, src->id, 0, 0, 0);
+ status->change_start(src, bl, SC_COMA, skill_lv, skill_lv, 0, src->id, 0, 0, 0);
} else if( sd )
clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
break;
@@ -9135,13 +9333,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if (unit->movepos(src, bl->x, bl->y, 0, 0)) {
clif->skill_nodamage(src, src, skill_id, skill_lv, 1);
clif->slide(src, bl->x, bl->y) ;
- sc_start(src, SC_CONFUSION, 25, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, src, SC_CONFUSION, 25, skill_lv, skill->get_time(skill_id, skill_lv));
if ( !is_boss(bl) && unit->stop_walking(&sd->bl, 1) && unit->movepos(bl, x, y, 0, 0) )
{
if( dstsd && pc_issit(dstsd) )
pc->setstand(dstsd);
clif->slide(bl, x, y) ;
- sc_start(bl, SC_CONFUSION, 75, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, SC_CONFUSION, 75, skill_lv, skill->get_time(skill_id, skill_lv));
}
}
}
@@ -9159,7 +9357,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case KG_KYOMU:
case KG_KAGEMUSYA:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
+ sc_start(src, bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
clif->skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
break;
@@ -9168,8 +9366,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if(tsc && ( tsc->option&(OPTION_CLOAK|OPTION_HIDE) ||
tsc->data[SC_CAMOUFLAGE] || tsc->data[SC__SHADOWFORM] ||
tsc->data[SC_MARIONETTE_MASTER] || tsc->data[SC_HARMONIZE])){
- sc_start(src, type, 100, skill_lv, skill->get_time(skill_id, skill_lv));
- sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, src, type, 100, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv));
status_change_end(bl, SC_HIDING, INVALID_TIMER);
status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
@@ -9180,7 +9378,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
if( skill->area_temp[2] == 1 ){
clif->skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
- sc_start(src, SC_STOP, 100, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, src, SC_STOP, 100, skill_lv, skill->get_time(skill_id, skill_lv));
}
} else {
skill->area_temp[2] = 0;
@@ -9197,22 +9395,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
};
int heal;
if(tsc){
+ int i;
for (i = 0; i < ARRAYLENGTH(scs); i++) {
if (tsc->data[scs[i]]) status_change_end(bl, scs[i], INVALID_TIMER);
}
if (!tsc->data[SC_SILENCE]) //put inavoidable silence on target
- status->change_start(bl, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8);
+ status->change_start(src, bl, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8);
}
heal = status_get_matk_min(src)*4;
status->heal(bl, heal, 0, 7);
//now inflict silence on everyone
if(ssc && !ssc->data[SC_SILENCE]) //put inavoidable silence on homun
- status->change_start(src, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8);
+ status->change_start(src, src, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8);
if(m_bl){
struct status_change *msc = status->get_sc(m_bl);
if(msc && !msc->data[SC_SILENCE]) //put inavoidable silence on master
- status->change_start(m_bl, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8);
+ status->change_start(src, m_bl, SC_SILENCE, 100, skill_lv, 0,0,0, skill->get_time(skill_id, skill_lv),1|2|8);
}
if (hd)
skill->blockhomun_start(hd, skill_id, skill->get_cooldown(skill_id, skill_lv));
@@ -9228,22 +9427,24 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if(s_bl && s_bl->type==BL_PC) {
status->set_sp(s_bl,status_get_max_sp(s_bl)/2,0); //master drain 50% sp
clif->send_homdata(((TBL_PC *)s_bl), SP_HUNGRY, hd->homunculus.hunger); //refresh hunger info
- sc_start(s_bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); //gene bonus
+ sc_start(src, s_bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)); //gene bonus
}
- sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv));
skill->blockhomun_start(hd, skill_id, skill->get_cooldown(skill_id, skill_lv));
}
break;
case MH_GRANITIC_ARMOR:
case MH_PYROCLASTIC:
- {
- struct block_list *s_bl = battle->get_master(src);
- if(s_bl)
- sc_start2(s_bl, type, 100, skill_lv, hd->homunculus.level, skill->get_time(skill_id, skill_lv)); //start on master
- sc_start2(bl, type, 100, skill_lv, hd->homunculus.level, skill->get_time(skill_id, skill_lv));
- if (hd)
+ if( hd ){
+ struct block_list *s_bl = battle->get_master(src);
+
+ if(s_bl)
+ sc_start2(src, s_bl, type, 100, skill_lv, hd->homunculus.level, skill->get_time(skill_id, skill_lv)); //start on master
+
+ sc_start2(src, bl, type, 100, skill_lv, hd->homunculus.level, skill->get_time(skill_id, skill_lv));
+
skill->blockhomun_start(hd, skill_id, skill->get_cooldown(skill_id, skill_lv));
- }
+ }
break;
case MH_LIGHT_OF_REGENE:
@@ -9254,7 +9455,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
//don't break need to start status and start block timer
case MH_MAGMA_FLOW:
case MH_PAIN_KILLER:
- sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv));
if (hd)
skill->blockhomun_start(hd, skill_id, skill->get_cooldown(skill_id, skill_lv));
break;
@@ -9262,22 +9463,22 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
{
int summons[5] = {1004, 1303, 1303, 1994, 1994};
int qty[5] = {3 , 3 , 4 , 4 , 5};
- struct mob_data *md;
+ struct mob_data *summon_md;
int i, dummy = 0;
- i = map->foreachinmap(skill->check_condition_mob_master_sub ,hd->bl.m, BL_MOB, hd->bl.id, summons[skill_lv-1], skill_id, &dummy);
+ i = map->foreachinmap(skill->check_condition_mob_master_sub, src->m, BL_MOB, src->id, summons[skill_lv-1], skill_id, &dummy);
if(i >= qty[skill_lv-1])
break;
for(i=0; i<qty[skill_lv - 1]; i++){ //easy way
- md = mob->once_spawn_sub(src, src->m, src->x, src->y, status->get_name(src), summons[skill_lv - 1], "", SZ_SMALL, AI_ATTACK);
- if (md) {
- md->master_id = src->id;
- if (md->deletetimer != INVALID_TIMER)
- timer->delete(md->deletetimer, mob->timer_delete);
- md->deletetimer = timer->add(timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, md->bl.id, 0);
- mob->spawn(md); //Now it is ready for spawning.
- sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_CANATTACK|MD_AGGRESSIVE, 0, 60000);
+ summon_md = mob->once_spawn_sub(src, src->m, src->x, src->y, status->get_name(src), summons[skill_lv - 1], "", SZ_MEDIUM, AI_ATTACK);
+ if (summon_md) {
+ summon_md->master_id = src->id;
+ if (summon_md->deletetimer != INVALID_TIMER)
+ timer->delete(summon_md->deletetimer, mob->timer_delete);
+ summon_md->deletetimer = timer->add(timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, summon_md->bl.id, 0);
+ mob->spawn(summon_md); //Now it is ready for spawning.
+ sc_start4(src,&summon_md->bl, SC_MODECHANGE, 100, 1, 0, MD_CANATTACK|MD_AGGRESSIVE, 0, 60000);
}
}
if (hd)
@@ -9310,7 +9511,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
skill->onskillusage(sd, bl, skill_id, tick);
// perform skill requirement consumption
- skill->consume_requirement(sd,skill_id,skill_lv,2);
+ if( skill_id != NC_SELFDESTRUCTION )
+ skill->consume_requirement(sd,skill_id,skill_lv,2);
}
map->freeblock_unlock();
@@ -9320,7 +9522,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
/*==========================================
*
*------------------------------------------*/
-int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) {
+int skill_castend_pos(int tid, int64 tick, int id, intptr_t data) {
struct block_list* src = map->id2bl(id);
int maxcount;
struct map_session_data *sd;
@@ -9433,7 +9635,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) {
}
}
if(cooldown)
- skill->blockpc_start(sd, ud->skill_id, cooldown, false);
+ skill->blockpc_start(sd, ud->skill_id, cooldown);
}
if( battle_config.display_status_timers && sd )
clif->status_change(src, SI_POSTDELAY, 1, skill->delay_fix(src, ud->skill_id, ud->skill_lv), 0, 0, 0);
@@ -9474,6 +9676,14 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data) {
return 0;
}
+static int check_npc_chaospanic(struct block_list* bl, va_list args) {
+ TBL_NPC* nd = (TBL_NPC*)bl;
+
+ if( nd->option&(OPTION_HIDE|OPTION_INVISIBLE) || nd->class_ != 45 )
+ return 0;
+
+ return 1;
+}
/* skill count without self */
static int skill_count_wos(struct block_list *bl,va_list ap) {
struct block_list* src = va_arg(ap, struct block_list*);
@@ -9490,7 +9700,7 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char
nullpo_ret(sd);
//Simplify skill_failed code.
-#define skill_failed(sd) { sd->menuskill_id = sd->menuskill_val = 0; }
+#define skill_failed(sd) ( (sd)->menuskill_id = (sd)->menuskill_val = 0 )
if(skill_id != sd->menuskill_id)
return 0;
@@ -9549,10 +9759,10 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char
int i, lv, wx, wy;
int maxcount=0;
int x,y;
- unsigned short mapindex;
+ unsigned short map_index;
- mapindex = mapindex_name2id(mapname);
- if(!mapindex) { //Given map not found?
+ map_index = mapindex->name2id(mapname);
+ if(!map_index) { //Given map not found?
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
skill_failed(sd);
return 0;
@@ -9582,7 +9792,7 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char
if( lv > 4 ) lv = 4; // crash prevention
// check if the chosen map exists in the memo list
- ARR_FIND( 0, lv, i, mapindex == p[i]->map );
+ ARR_FIND( 0, lv, i, map_index == p[i]->map );
if( i < lv ) {
x=p[i]->x;
y=p[i]->y;
@@ -9607,7 +9817,7 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char
group->val1 = (group->val1<<16)|(short)0;
// record the destination coordinates
group->val2 = (x<<16)|y;
- group->val3 = mapindex;
+ group->val3 = map_index;
}
break;
}
@@ -9620,14 +9830,13 @@ int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char
/*==========================================
*
*------------------------------------------*/
-int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag)
-{
+int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
struct map_session_data* sd;
struct status_change* sc;
struct status_change_entry *sce;
struct skill_unit_group* sg;
enum sc_type type;
- int i;
+ int r;
//if(skill_lv <= 0) return 0;
if(skill_id > 0 && !skill_lv) return 0; // celest
@@ -9663,47 +9872,46 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
switch(skill_id) {
case PR_BENEDICTIO:
+ r = skill->get_splash(skill_id, skill_lv);
skill->area_temp[1] = src->id;
- i = skill->get_splash(skill_id, skill_lv);
map->foreachinarea(skill->area_sub,
- src->m, x-i, y-i, x+i, y+i, BL_PC,
+ src->m, x-r, y-r, x+r, y+r, BL_PC,
src, skill_id, skill_lv, tick, flag|BCT_ALL|1,
skill->castend_nodamage_id);
map->foreachinarea(skill->area_sub,
- src->m, x-i, y-i, x+i, y+i, BL_CHAR,
+ src->m, x-r, y-r, x+r, y+r, BL_CHAR,
src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1,
skill->castend_damage_id);
break;
case BS_HAMMERFALL:
- i = skill->get_splash(skill_id, skill_lv);
+ r = skill->get_splash(skill_id, skill_lv);
map->foreachinarea(skill->area_sub,
- src->m, x-i, y-i, x+i, y+i, BL_CHAR,
+ src->m, x-r, y-r, x+r, y+r, BL_CHAR,
src, skill_id, skill_lv, tick, flag|BCT_ENEMY|2,
skill->castend_nodamage_id);
break;
case HT_DETECTING:
- i = skill->get_splash(skill_id, skill_lv);
+ r = skill->get_splash(skill_id, skill_lv);
map->foreachinarea(status->change_timer_sub,
- src->m, x-i, y-i, x+i,y+i,BL_CHAR,
+ src->m, x-r, y-r, x+r,y+r,BL_CHAR,
src,NULL,SC_SIGHT,tick);
if(battle_config.traps_setting&1)
map->foreachinarea(skill_reveal_trap,
- src->m, x-i, y-i, x+i,y+i,BL_SKILL);
+ src->m, x-r, y-r, x+r, y+r, BL_SKILL);
break;
case SR_RIDEINLIGHTNING:
- i = skill->get_splash(skill_id, skill_lv);
- map->foreachinarea(skill->area_sub, src->m, x-i, y-i, x+i, y+i, BL_CHAR,
+ r = skill->get_splash(skill_id, skill_lv);
+ map->foreachinarea(skill->area_sub, src->m, x-r, y-r, x+r, y+r, BL_CHAR,
src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_damage_id);
break;
case SA_VOLCANO:
case SA_DELUGE:
case SA_VIOLENTGALE:
- { //Does not consumes if the skill is already active. [Skotlex]
- struct skill_unit_group *sg;
+ //Does not consumes if the skill is already active. [Skotlex]
if ((sg= skill->locate_element_field(src)) != NULL && ( sg->skill_id == SA_VOLCANO || sg->skill_id == SA_DELUGE || sg->skill_id == SA_VIOLENTGALE ))
{
if (sg->limit - DIFF_TICK(timer->gettick(), sg->tick) > 0) {
@@ -9714,7 +9922,14 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
}
skill->unitsetting(src,skill_id,skill_lv,x,y,0);
break;
- }
+
+ case SC_CHAOSPANIC:
+ case SC_MAELSTROM:
+ if (sd && map->foreachinarea(&check_npc_chaospanic,src->m, x-3, y-3, x+3, y+3, BL_NPC) > 0 ) {
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+
case MG_SAFETYWALL:
case MG_FIREWALL:
case MG_THUNDERSTORM:
@@ -9795,8 +10010,6 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case RA_ICEBOUNDTRAP:
case SC_MANHOLE:
case SC_DIMENSIONDOOR:
- case SC_CHAOSPANIC:
- case SC_MAELSTROM:
case SC_BLOODYLUST:
case WM_REVERBERATION:
case WM_SEVERE_RAINSTORM:
@@ -9823,6 +10036,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case MH_STEINWAND:
case MH_XENO_SLASHER:
case NC_MAGMA_ERUPTION:
+ case SO_ELEMENTAL_SHIELD:
case RL_B_TRAP:
flag|=1;//Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete).
case GS_GROUNDDRIFT: //Ammo should be deleted right away.
@@ -9845,20 +10059,20 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
skill->clear_unitgroup(src);
if( skill->unitsetting(src,skill_id,skill_lv,x,y,0) )
- sc_start4(src,type,100,skill_lv,0,0,src->id,skill->get_time(skill_id,skill_lv));
+ sc_start4(src,src,type,100,skill_lv,0,0,src->id,skill->get_time(skill_id,skill_lv));
flag|=1;
}
break;
case CG_HERMODE:
skill->clear_unitgroup(src);
if ((sg = skill->unitsetting(src,skill_id,skill_lv,x,y,0)))
- sc_start4(src,SC_DANCING,100,
+ sc_start4(src,src,SC_DANCING,100,
skill_id,0,skill_lv,sg->group_id,skill->get_time(skill_id,skill_lv));
flag|=1;
break;
case RG_CLEANER: // [Valaris]
- i = skill->get_splash(skill_id, skill_lv);
- map->foreachinarea(skill->graffitiremover,src->m,x-i,y-i,x+i,y+i,BL_SKILL);
+ r = skill->get_splash(skill_id, skill_lv);
+ map->foreachinarea(skill->graffitiremover,src->m,x-r,y-r,x+r,y+r,BL_SKILL);
break;
case SO_WARMER:
@@ -9867,9 +10081,11 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
skill->unitsetting(src,skill_id,skill_lv,x,y,0);
break;
- case WZ_METEOR: {
+ case WZ_METEOR:
+ {
int area = skill->get_splash(skill_id, skill_lv);
short tmpx = 0, tmpy = 0, x1 = 0, y1 = 0;
+ int i;
for( i = 0; i < 2 + (skill_lv>>1); i++ ) {
// Creates a random Cell in the Splash Area
@@ -9911,7 +10127,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
clif->skill_poseffect(src,skill_id,skill_lv,src->x,src->y,tick);
#endif
if (sd)
- skill->blockpc_start (sd, MO_EXTREMITYFIST, 2000, false);
+ skill->blockpc_start (sd, MO_EXTREMITYFIST, 2000);
}
break;
case NJ_SHADOWJUMP:
@@ -9930,13 +10146,13 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
struct mob_data *md;
// Correct info, don't change any of this! [celest]
- md = mob->once_spawn_sub(src, src->m, x, y, status->get_name(src), class_, "", SZ_SMALL, AI_NONE);
+ md = mob->once_spawn_sub(src, src->m, x, y, status->get_name(src), class_, "", SZ_MEDIUM, AI_NONE);
if (md) {
md->master_id = src->id;
md->special_state.ai = (skill_id == AM_SPHEREMINE) ? AI_SPHERE : AI_FLORA;
if( md->deletetimer != INVALID_TIMER )
timer->delete(md->deletetimer, mob->timer_delete);
- md->deletetimer = timer->add (timer->gettick() + skill->get_time(skill_id,skill_lv), mob->timer_delete, md->bl.id, 0);
+ md->deletetimer = timer->add(timer->gettick() + skill->get_time(skill_id,skill_lv), mob->timer_delete, md->bl.id, 0);
mob->spawn (md); //Now it is ready for spawning.
}
}
@@ -10002,8 +10218,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
if (rnd()%100 < 80) {
int dummy = 1;
clif->skill_poseffect(src,skill_id,skill_lv,x,y,tick);
- i = skill->get_splash(skill_id, skill_lv);
- map->foreachinarea(skill->cell_overlap, src->m, x-i, y-i, x+i, y+i, BL_SKILL, HW_GANBANTEIN, &dummy, src);
+ r = skill->get_splash(skill_id, skill_lv);
+ map->foreachinarea(skill->cell_overlap, src->m, x-r, y-r, x+r, y+r, BL_SKILL, HW_GANBANTEIN, &dummy, src);
} else {
if (sd) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 1;
@@ -10012,7 +10228,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case HW_GRAVITATION:
if ((sg = skill->unitsetting(src,skill_id,skill_lv,x,y,0)))
- sc_start4(src,type,100,skill_lv,0,BCT_SELF,sg->group_id,skill->get_time(skill_id,skill_lv));
+ sc_start4(src,src,type,100,skill_lv,0,BCT_SELF,sg->group_id,skill->get_time(skill_id,skill_lv));
flag|=1;
break;
@@ -10027,14 +10243,14 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
if (rnd()%100 < 50) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
} else {
- TBL_MOB* md = mob->once_spawn_sub(src, src->m, x, y, "--ja--",(skill_lv < 2 ? 1084+rnd()%2 : 1078+rnd()%6),"", SZ_SMALL, AI_NONE);
+ TBL_MOB* md = mob->once_spawn_sub(src, src->m, x, y, "--ja--",(skill_lv < 2 ? 1084+rnd()%2 : 1078+rnd()%6),"", SZ_MEDIUM, AI_NONE);
int i;
if (!md) break;
if ((i = skill->get_time(skill_id, skill_lv)) > 0)
{
if( md->deletetimer != INVALID_TIMER )
timer->delete(md->deletetimer, mob->timer_delete);
- md->deletetimer = timer->add (tick + i, mob->timer_delete, md->bl.id, 0);
+ md->deletetimer = timer->add(tick + i, mob->timer_delete, md->bl.id, 0);
}
mob->spawn (md);
}
@@ -10046,7 +10262,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case SG_STAR_WARM:
skill->clear_unitgroup(src);
if ((sg = skill->unitsetting(src,skill_id,skill_lv,src->x,src->y,0)))
- sc_start4(src,type,100,skill_lv,0,0,sg->group_id,skill->get_time(skill_id,skill_lv));
+ sc_start4(src,src,type,100,skill_lv,0,0,sg->group_id,skill->get_time(skill_id,skill_lv));
flag|=1;
break;
@@ -10060,13 +10276,13 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
if (sce)
status_change_end(src, type, INVALID_TIMER); //Was under someone else's Gospel. [Skotlex]
status->change_clear_buffs(src,3);
- sc_start4(src,type,100,skill_lv,0,sg->group_id,BCT_SELF,skill->get_time(skill_id,skill_lv));
+ sc_start4(src,src,type,100,skill_lv,0,sg->group_id,BCT_SELF,skill->get_time(skill_id,skill_lv));
clif->skill_poseffect(src, skill_id, skill_lv, 0, 0, tick); // PA_GOSPEL music packet
}
break;
case NJ_TATAMIGAESHI:
if (skill->unitsetting(src,skill_id,skill_lv,src->x,src->y,0))
- sc_start(src,type,100,skill_lv,skill->get_time2(skill_id,skill_lv));
+ sc_start(src,src,type,100,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case AM_RESURRECTHOMUN: //[orn]
@@ -10081,17 +10297,32 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case RK_WINDCUTTER:
clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
case NC_COLDSLOWER:
- case NC_ARMSCANNON:
case RK_DRAGONBREATH:
case RK_DRAGONBREATH_WATER:
- i = skill->get_splash(skill_id,skill_lv);
- map->foreachinarea(skill->area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),
+ r = skill->get_splash(skill_id,skill_lv);
+ map->foreachinarea(skill->area_sub,src->m,x-r,y-r,x+r,y+r,splash_target(src),
src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
break;
+ case WM_GREAT_ECHO:
+ case WM_SOUND_OF_DESTRUCTION:
+ r = skill->get_splash(skill_id,skill_lv);
+ map->foreachinarea(skill->area_sub,src->m,x-r,y-r,x+r,y+r,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
+ break;
+ case WM_LULLABY_DEEPSLEEP:
+ r = skill->get_splash(skill_id,skill_lv);
+ map->foreachinarea(skill->area_sub,src->m,x-r,y-r,x+r,y+r,BL_CHAR,
+ src,skill_id,skill_lv,tick,flag|BCT_ALL|1,skill->castend_damage_id);
+ break;
+
+ case WM_VOICEOFSIREN:
+ r = skill->get_splash(skill_id,skill_lv);
+ map->foreachinarea(skill->area_sub,src->m,x-r,y-r,x+r,y+r,BL_CHAR,
+ src,skill_id,skill_lv,tick,flag|BCT_ALL|1,skill->castend_damage_id);
+ break;
case SO_ARRULLO:
- i = skill->get_splash(skill_id,skill_lv);
- map->foreachinarea(skill->area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),
+ r = skill->get_splash(skill_id,skill_lv);
+ map->foreachinarea(skill->area_sub,src->m,x-r,y-r,x+r,y+r,splash_target(src),
src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_nodamage_id);
break;
/**
@@ -10112,8 +10343,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
**/
case AB_EPICLESIS:
if( (sg = skill->unitsetting(src, skill_id, skill_lv, x, y, 0)) ) {
- i = sg->unit->range;
- map->foreachinarea(skill->area_sub, src->m, x - i, y - i, x + i, y + i, BL_CHAR, src, ALL_RESURRECTION, 1, tick, flag|BCT_NOENEMY|1,skill->castend_nodamage_id);
+ r = sg->unit->range;
+ map->foreachinarea(skill->area_sub, src->m, x - r, y - r, x + r, y + r, BL_CHAR, src, ALL_RESURRECTION, 1, tick, flag|BCT_NOENEMY|1,skill->castend_nodamage_id);
}
break;
@@ -10138,8 +10369,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
* Ranger
**/
case RA_DETONATOR:
- i = skill->get_splash(skill_id, skill_lv);
- map->foreachinarea(skill->detonator, src->m, x-i, y-i, x+i, y+i, BL_SKILL, src);
+ r = skill->get_splash(skill_id, skill_lv);
+ map->foreachinarea(skill->detonator, src->m, x-r, y-r, x+r, y+r, BL_SKILL, src);
clif->skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
break;
/**
@@ -10149,7 +10380,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case NC_STEALTHFIELD:
skill->clear_unitgroup(src); // To remove previous skills - cannot used combined
if( (sg = skill->unitsetting(src,skill_id,skill_lv,src->x,src->y,0)) != NULL ) {
- sc_start2(src,skill_id == NC_NEUTRALBARRIER ? SC_NEUTRALBARRIER_MASTER : SC_STEALTHFIELD_MASTER,100,skill_lv,sg->group_id,skill->get_time(skill_id,skill_lv));
+ sc_start2(src,src,skill_id == NC_NEUTRALBARRIER ? SC_NEUTRALBARRIER_MASTER : SC_STEALTHFIELD_MASTER,100,skill_lv,sg->group_id,skill->get_time(skill_id,skill_lv));
if( sd ) pc->overheat(sd,1);
}
break;
@@ -10159,13 +10390,13 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
int class_ = 2042;
struct mob_data *md;
- md = mob->once_spawn_sub(src, src->m, x, y, status->get_name(src), class_, "", SZ_SMALL, AI_NONE);
+ md = mob->once_spawn_sub(src, src->m, x, y, status->get_name(src), class_, "", SZ_MEDIUM, AI_NONE);
if( md ) {
md->master_id = src->id;
md->special_state.ai = AI_FLORA;
if( md->deletetimer != INVALID_TIMER )
timer->delete(md->deletetimer, mob->timer_delete);
- md->deletetimer = timer->add (timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, md->bl.id, 0);
+ md->deletetimer = timer->add(timer->gettick() + skill->get_time(skill_id, skill_lv), mob->timer_delete, md->bl.id, 0);
mob->spawn( md );
}
}
@@ -10178,8 +10409,9 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case SC_FEINTBOMB:
skill->unitsetting(src,skill_id,skill_lv,x,y,0); // Set bomb on current Position
clif->skill_nodamage(src,src,skill_id,skill_lv,1);
- if( skill->blown(src,src,6,unit->getdir(src),0) )
- skill->castend_nodamage_id(src,src,TF_HIDING,1,tick,0x2);
+ skill->blown(src,src,3*skill_lv,unit->getdir(src),0);
+ //After back sliding, the player goes into hiding. Hiding level used is throught to be the learned level.
+ sc_start(src,src,SC_HIDING,100,(sd?pc->checkskill(sd,TF_HIDING):10),skill->get_time(TF_HIDING,(sd?pc->checkskill(sd,TF_HIDING):10)));
break;
case SC_ESCAPE:
@@ -10190,13 +10422,16 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case LG_OVERBRAND:
{
- int width;//according to data from irowiki it actually is a square
- for( width = 0; width < 7; width++ )
- for( i = 0; i < 7; i++ )
- map->foreachincell(skill->area_sub, src->m, x-2+i, y-2+width, splash_target(src), src, LG_OVERBRAND_BRANDISH, skill_lv, tick, flag|BCT_ENEMY,skill->castend_damage_id);
- for( width = 0; width < 7; width++ )
- for( i = 0; i < 7; i++ )
- map->foreachincell(skill->area_sub, src->m, x-2+i, y-2+width, splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY,skill->castend_damage_id);
+ uint8 dir = map->calc_dir(src, x, y);
+ uint8 x2 = x = src->x, y2 = y = src->y;
+ switch( dir ){
+ case 0: case 1: case 7: x2++; x--; y2 += 7; break;
+ case 3: case 4: case 5: x2++; x--; y -= 7; break;
+ case 2: y2++; y--; x -= 7;break;
+ case 6: y2++; y--; x2 += 7;break;
+ }
+ map->foreachinarea(skill->area_sub, src->m, x, y, x2, y2, BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_ANIMATION|1,skill->castend_damage_id);
+ skill->addtimerskill(src,timer->gettick() + status_get_amotion(src), 0, 0, 0, LG_OVERBRAND_BRANDISH, skill_lv, dir, flag);
}
break;
@@ -10204,7 +10439,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
if( sc && sc->data[SC_BANDING] )
status_change_end(src,SC_BANDING,INVALID_TIMER);
else if( (sg = skill->unitsetting(src,skill_id,skill_lv,src->x,src->y,0)) != NULL ) {
- sc_start4(src,SC_BANDING,100,skill_lv,0,0,sg->group_id,skill->get_time(skill_id,skill_lv));
+ sc_start4(src,src,SC_BANDING,100,skill_lv,0,0,sg->group_id,skill->get_time(skill_id,skill_lv));
if( sd ) pc->banding(sd,skill_lv);
}
clif->skill_nodamage(src,src,skill_id,skill_lv,1);
@@ -10212,32 +10447,46 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case LG_RAYOFGENESIS:
if( status->charge(src,status_get_max_hp(src)*3*skill_lv / 100,0) ) {
- i = skill->get_splash(skill_id,skill_lv);
- map->foreachinarea(skill->area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),
+ r = skill->get_splash(skill_id,skill_lv);
+ map->foreachinarea(skill->area_sub,src->m,x-r,y-r,x+r,y+r,splash_target(src),
src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
} else if( sd )
clif->skill_fail(sd,skill_id,USESKILL_FAIL,0);
break;
case WM_DOMINION_IMPULSE:
- i = skill->get_splash(skill_id, skill_lv);
- map->foreachinarea( skill->activate_reverberation,
- src->m, x-i, y-i, x+i,y+i,BL_SKILL);
+ r = skill->get_splash(skill_id, skill_lv);
+ map->foreachinarea( skill->activate_reverberation,src->m, x-r, y-r, x+r,y+r,BL_SKILL);
break;
- case WM_GREAT_ECHO:
- flag|=1; // Should counsume 1 item per skill usage.
- map->foreachinrange(skill->area_sub, src, skill->get_splash(skill_id,skill_lv),splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY, skill->castend_damage_id);
- break;
- case GN_CRAZYWEED: {
- int area = skill->get_splash(GN_CRAZYWEED_ATK, skill_lv);
- short x1 = 0, y1 = 0;
+ case GN_CRAZYWEED:
+ {
+ int area = skill->get_splash(skill_id, skill_lv);
+ short tmpx = 0, tmpy = 0, x1 = 0, y1 = 0;
+
+ for( r = 0; r < 3 + (skill_lv>>1); r++ ) {
+ // Creates a random Cell in the Splash Area
+ tmpx = x - area + rnd()%(area * 2 + 1);
+ tmpy = y - area + rnd()%(area * 2 + 1);
- for( i = 0; i < 3 + (skill_lv/2); i++ ) {
- x1 = x - area + rnd()%(area * 2 + 1);
- y1 = y - area + rnd()%(area * 2 + 1);
- skill->addtimerskill(src,tick+i*150,0,x1,y1,GN_CRAZYWEED_ATK,skill_lv,-1,0);
+ if( r > 0 )
+ skill->addtimerskill(src,tick+r*250,0,tmpx,tmpy,GN_CRAZYWEED,skill_lv,(x1<<16)|y1,flag);
+
+ x1 = tmpx;
+ y1 = tmpy;
}
+
+ skill->addtimerskill(src,tick+r*250,0,tmpx,tmpy,GN_CRAZYWEED,skill_lv,-1,flag);
+ }
+ break;
+
+ case GN_CRAZYWEED_ATK: {
+ int dummy = 1;
+ //Enable if any unique animation gets added to this skill ID in the future. [Rytech]
+ //clif_skill_poseffect(src,skillid,skilllv,x,y,tick);
+ r = skill->get_splash(skill_id, skill_lv);
+ map->foreachinarea(skill->cell_overlap, src->m, x-r, y-r, x+r, y+r, BL_SKILL, skill_id, &dummy, src);
+ map->foreachinarea(skill->area_sub, src->m, x-r, y-r, x+r, y+r, BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill->castend_damage_id);
}
break;
case GN_FIRE_EXPANSION: {
@@ -10280,15 +10529,18 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
if( sc && sc->data[type] )
status_change_end(src,type,INVALID_TIMER);
clif->skill_nodamage(src, src ,skill_id, skill_lv,
- sc_start2(src, type, 100, skill_id, skill_lv, skill->get_time(skill_id, skill_lv)));
+ sc_start2(src,src, type, 100, skill_id, skill_lv, skill->get_time(skill_id, skill_lv)));
break;
case KO_MAKIBISHI:
+ {
+ int i;
for( i = 0; i < (skill_lv+2); i++ ) {
x = src->x - 1 + rnd()%3;
y = src->y - 1 + rnd()%3;
skill->unitsetting(src,skill_id,skill_lv,x,y,0);
}
+ }
break;
default:
@@ -10332,7 +10584,7 @@ int skill_dance_overlap_sub(struct block_list* bl, va_list ap) {
else //Remove dissonance
target->val2 &= ~UF_ENSEMBLE;
- clif->skill_setunit(target); //Update look of affected cell.
+ clif->getareachar_skillunit(&target->bl,target,AREA); //Update look of affected cell.
return 1;
}
@@ -10463,6 +10715,9 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
sc = status->get_sc(src); // for traps, firewall and fogwall - celest
switch( skill_id ) {
+ case SO_ELEMENTAL_SHIELD:
+ val2 = 300 * skill_lv + 65 * (st->int_ + status->get_lv(src)) + st->max_sp;
+ break;
case MH_STEINWAND:
val2 = 4 + skill_lv; //nb of attack blocked
break;
@@ -10515,6 +10770,8 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
case WZ_QUAGMIRE: //The target changes to "all" if used in a gvg map. [Skotlex]
case AM_DEMONSTRATION:
case GN_HELLS_PLANT:
+ if( skill_id == GN_HELLS_PLANT && map->getcell(src->m, x, y, CELL_CHKLANDPROTECTOR) )
+ return NULL;
if (map_flag_vs(src->m) && battle_config.vs_traps_bctall
&& (src->type&battle_config.vs_traps_bctall))
target = BCT_ALL;
@@ -10549,7 +10806,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
{
struct skill_condition req = skill->get_requirement(sd,skill_id,skill_lv);
ARR_FIND(0, MAX_SKILL_ITEM_REQUIRE, i, req.itemid[i] && (req.itemid[i] == ITEMID_TRAP || req.itemid[i] == ITEMID_TRAP_ALLOY));
- if( req.itemid[i] )
+ if( i != MAX_SKILL_ITEM_REQUIRE && req.itemid[i] )
req_item = req.itemid[i];
if( map_flag_gvg2(src->m) || map->list[src->m].flag.battleground )
limit *= 4; // longer trap times in WOE [celest]
@@ -10573,7 +10830,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
old_sg->skill_id == SA_VIOLENTGALE
) && old_sg->limit > 0)
{ //Use the previous limit (minus the elapsed time) [Skotlex]
- limit = old_sg->limit - DIFF_TICK(timer->gettick(), old_sg->tick);
+ limit = old_sg->limit - DIFF_TICK32(timer->gettick(), old_sg->tick);
if (limit < 0) //This can happen...
limit = skill->get_time(skill_id,skill_lv);
}
@@ -10743,7 +11000,9 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
limit = -1;
break;
case WM_REVERBERATION:
- interval = limit;
+ if( battle_config.vs_traps_bctall && map_flag_vs(src->m) && (src->type&battle_config.vs_traps_bctall) )
+ target = BCT_ALL;
+ val1 = skill_lv + 1;
val2 = 1;
case WM_POEMOFNETHERWORLD: // Can't be placed on top of Land Protector.
if( map->getcell(src->m, x, y, CELL_CHKLANDPROTECTOR) )
@@ -10755,9 +11014,6 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
case SO_WARMER:
skill->clear_group(src, 8);
break;
- case SO_VACUUM_EXTREME:
- range++;
- break;
case GN_WALLOFTHORN:
if( flag&1 )
limit = 3000;
@@ -10805,7 +11061,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
sd->skill_lv_dance = skill_lv;
}
if (
- sc_start4(src, SC_DANCING, 100, skill_id, group->group_id, skill_lv,
+ sc_start4(src,src, SC_DANCING, 100, skill_id, group->group_id, skill_lv,
(group->state.song_dance&2?BCT_SELF:0), limit+1000) &&
sd && group->state.song_dance&2 && skill_id != CG_HERMODE //Hermod is a encore with a warp!
)
@@ -10817,9 +11073,9 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
struct skill_unit *su;
int ux = x + layout->dx[i];
int uy = y + layout->dy[i];
- int val1 = skill_lv;
- int val2 = 0;
int alive = 1;
+ val1 = skill_lv;
+ val2 = 0;
if( !group->state.song_dance && !map->getcell(src->m,ux,uy,CELL_CHKREACH) )
continue; // don't place skill units on walls (except for songs/dances/encores)
@@ -10871,11 +11127,9 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
if (val1 < 1) val1 = 1;
val2 = 0;
break;
- case WM_REVERBERATION:
- val1 = 1 + skill_lv;
- break;
case GN_WALLOFTHORN:
- val1 = 1000 * skill_lv; // Need official value. [LimitLine]
+ val1 = 2000 + 2000 * skill_lv;
+ val2 = src->id;
break;
default:
if (group->state.song_dance&0x1)
@@ -10885,9 +11139,6 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
if (skill->get_unit_flag(skill_id) & UF_RANGEDSINGLEUNIT && i == (layout->count / 2))
val2 |= UF_RANGEDSINGLEUNIT; // center.
- if( sd && map->getcell(src->m, ux, uy, CELL_CHKMAELSTROM) ) //Does not recover SP from monster skills
- map->foreachincell(skill->maelstrom_suction,src->m,ux,uy,BL_SKILL,skill_id,skill_lv);
-
if( range <= 0 )
map->foreachincell(skill->cell_overlap,src->m,ux,uy,BL_SKILL,skill_id, &alive, src);
if( !alive )
@@ -10930,7 +11181,7 @@ struct skill_unit_group* skill_unitsetting(struct block_list *src, uint16 skill_
/*==========================================
*
*------------------------------------------*/
-int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned int tick) {
+int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick) {
struct skill_unit_group *sg;
struct block_list *ss;
struct status_change *sc;
@@ -10949,13 +11200,14 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
if( skill->get_type(sg->skill_id) == BF_MAGIC && map->getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR) && sg->skill_id != SA_LANDPROTECTOR )
return 0; //AoE skills are ineffective. [Skotlex]
- if( map->getcell(bl->m, bl->x, bl->y, CELL_CHKMAELSTROM) )
- return 0;
sc = status->get_sc(bl);
if (sc && sc->option&OPTION_HIDE && sg->skill_id != WZ_HEAVENDRIVE && sg->skill_id != WL_EARTHSTRAIN )
return 0; //Hidden characters are immune to AoE skills except to these. [Skotlex]
+ if (sc && sc->data[SC_VACUUM_EXTREME] && map->getcell(bl->m, bl->x, bl->y, CELL_CHKLANDPROTECTOR))
+ status_change_end(bl, SC_VACUUM_EXTREME, INVALID_TIMER);
+
type = status->skill2sc(sg->skill_id);
sce = (sc && type != -1)?sc->data[type]:NULL;
skill_id = sg->skill_id; //In case the group is deleted, we need to return the correct skill id, still.
@@ -10967,34 +11219,36 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
break;
} else if( sc && battle->check_target(&sg->unit->bl,bl,sg->target_flag) > 0 ) {
int sec = skill->get_time2(sg->skill_id,sg->skill_lv);
- if( status->change_start(bl,type,10000,sg->skill_lv,1,sg->group_id,0,sec,8) ) {
+ if( status->change_start(ss, bl,type,10000,sg->skill_lv,1,sg->group_id,0,sec,8) ) {
const struct TimerData* td = sc->data[type]?timer->get(sc->data[type]->timer):NULL;
if( td )
- sec = DIFF_TICK(td->tick, tick);
+ sec = DIFF_TICK32(td->tick, tick);
map->moveblock(bl, src->bl.x, src->bl.y, tick);
clif->fixpos(bl);
sg->val2 = bl->id;
}
else
sec = 3000; //Couldn't trap it?
- sg->limit = DIFF_TICK(tick,sg->tick)+sec;
+ sg->limit = DIFF_TICK32(tick,sg->tick)+sec;
}
break;
case UNT_SAFETYWALL:
if (!sce)
- sc_start4(bl,type,100,sg->skill_lv,sg->skill_id,sg->group_id,0,sg->limit);
+ sc_start4(ss,bl,type,100,sg->skill_lv,sg->skill_id,sg->group_id,0,sg->limit);
break;
-
case UNT_BLOODYLUST:
if (sg->src_id == bl->id)
break; //Does not affect the caster.
- if( !sce && sc_start4(bl,type,100,sg->skill_lv,0,SC__BLOODYLUST,0,sg->limit) )
- sc_start(bl,SC__BLOODYLUST,100,sg->skill_lv,sg->limit);
+ if (bl->type == BL_MOB)
+ break; //Does not affect the caster.
+ if( !sce && sc_start4(ss,bl,type,100,sg->skill_lv,0,SC__BLOODYLUST,0,sg->limit) )
+ sc_start(ss,bl,SC__BLOODYLUST,100,sg->skill_lv,sg->limit);
break;
case UNT_PNEUMA:
case UNT_CHAOSPANIC:
+ case UNT_MAELSTROM:
if (!sce)
- sc_start4(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit);
+ sc_start4(ss,bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit);
break;
case UNT_WARP_WAITING: {
@@ -11030,19 +11284,19 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
case UNT_QUAGMIRE:
if( !sce && battle->check_target(&sg->unit->bl,bl,sg->target_flag) > 0 )
- sc_start4(bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit);
+ sc_start4(ss,bl,type,100,sg->skill_lv,sg->group_id,0,0,sg->limit);
break;
case UNT_VOLCANO:
case UNT_DELUGE:
case UNT_VIOLENTGALE:
if(!sce)
- sc_start(bl,type,100,sg->skill_lv,sg->limit);
+ sc_start(ss,bl,type,100,sg->skill_lv,sg->limit);
break;
case UNT_SUITON:
if(!sce)
- sc_start4(bl,type,100,sg->skill_lv,
+ sc_start4(ss,bl,type,100,sg->skill_lv,
map_flag_vs(bl->m) || battle->check_target(&src->bl,bl,BCT_ENEMY)>0?1:0, //Send val3 =1 to reduce agi.
0,0,sg->limit);
break;
@@ -11061,7 +11315,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
if (sg->src_id==bl->id && !(sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_BARDDANCER))
return skill_id;
if (!sce)
- sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
+ sc_start4(ss,bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
break;
case UNT_WHISTLE:
case UNT_ASSASSINCROSS:
@@ -11076,7 +11330,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
if (!sc) return 0;
if (!sce)
- sc_start4(bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
+ sc_start4(ss,bl,type,100,sg->skill_lv,sg->val1,sg->val2,0,sg->limit);
else if (sce->val4 == 1) {
//Readjust timers since the effect will not last long.
sce->val4 = 0;
@@ -11088,7 +11342,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
case UNT_FOGWALL:
if (!sce)
{
- sc_start4(bl, type, 100, sg->skill_lv, sg->val1, sg->val2, sg->group_id, sg->limit);
+ sc_start4(ss, bl, type, 100, sg->skill_lv, sg->val1, sg->val2, sg->group_id, sg->limit);
if (battle->check_target(&src->bl,bl,BCT_ENEMY)>0)
skill->additional_effect (ss, bl, sg->skill_id, sg->skill_lv, BF_MISC, ATK_DEF, tick);
}
@@ -11096,14 +11350,14 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
case UNT_GRAVITATION:
if (!sce)
- sc_start4(bl,type,100,sg->skill_lv,0,BCT_ENEMY,sg->group_id,sg->limit);
+ sc_start4(ss,bl,type,100,sg->skill_lv,0,BCT_ENEMY,sg->group_id,sg->limit);
break;
// officially, icewall has no problems existing on occupied cells [ultramage]
// case UNT_ICEWALL: //Destroy the cell. [Skotlex]
// src->val1 = 0;
// if(src->limit + sg->tick > tick + 700)
- // src->limit = DIFF_TICK(tick+700,sg->tick);
+ // src->limit = DIFF_TICK32(tick+700,sg->tick);
// break;
case UNT_MOONLIT:
@@ -11122,9 +11376,16 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
skill->attack(skill->get_type(sg->skill_id), ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
break;
+ case UNT_REVERBERATION:
+ clif->changetraplook(&src->bl,UNT_USED_TRAPS);
+ map->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick);
+ sg->unit_id = UNT_USED_TRAPS;
+ sg->limit = DIFF_TICK32(tick,sg->tick) + 1500;
+ break;
+
case UNT_VOLCANIC_ASH:
if (!sce)
- sc_start(bl, SC_VOLCANIC_ASH, 100, sg->skill_lv, skill->get_time(MH_VOLCANIC_ASH, sg->skill_lv));
+ sc_start(ss, bl, SC_VOLCANIC_ASH, 100, sg->skill_lv, skill->get_time(MH_VOLCANIC_ASH, sg->skill_lv));
break;
case UNT_GD_LEADERSHIP:
@@ -11132,7 +11393,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
case UNT_GD_SOULCOLD:
case UNT_GD_HAWKEYES:
if ( !sce && battle->check_target(&sg->unit->bl,bl,sg->target_flag) > 0 )
- sc_start4(bl,type,100,sg->skill_lv,0,0,0,1000);
+ sc_start4(ss,bl,type,100,sg->skill_lv,0,0,0,1000);
break;
}
return skill_id;
@@ -11141,12 +11402,12 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
/*==========================================
*
*------------------------------------------*/
-int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, unsigned int tick) {
+int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int64 tick) {
struct skill_unit_group *sg;
struct block_list *ss;
TBL_PC* tsd;
struct status_data *tstatus;
- struct status_change *tsc;
+ struct status_change *tsc, *ssc;
struct skill_unit_group_tickset *ts;
enum sc_type type;
uint16 skill_id;
@@ -11162,10 +11423,15 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
nullpo_ret(ss=map->id2bl(sg->src_id));
tsd = BL_CAST(BL_PC, bl);
tsc = status->get_sc(bl);
+ ssc = status->get_sc(ss); // Status Effects for Unit caster.
if ( tsc && tsc->data[SC_HOVERING] )
return 0; //Under hovering characters are immune to trap and ground target skills.
+ // Maestro or Wanderer is unaffected by traps of trappers he or she charmed [SuperHulk]
+ if ( ssc && ssc->data[SC_SIREN] && ssc->data[SC_SIREN]->val2 == bl->id && (skill->get_inf2(sg->skill_id)&INF2_TRAP) )
+ return 0;
+
tstatus = status->get_status_data(bl);
type = status->skill2sc(sg->skill_id);
skill_id = sg->skill_id;
@@ -11185,7 +11451,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if ((ts = skill->unitgrouptickset_search(bl,sg,tick))) {
//Not all have it, eg: Traps don't have it even though they can be hit by Heaven's Drive [Skotlex]
- diff = DIFF_TICK(tick,ts->tick);
+ diff = DIFF_TICK32(tick,ts->tick);
if (diff < 0)
return 0;
ts->tick = tick+sg->interval;
@@ -11275,6 +11541,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
int count = 0;
const int x = bl->x, y = bl->y;
+ map->freeblock_lock();
//If target isn't knocked back it should hit every "interval" ms [Playtester]
do {
if( bl->type == BL_PC )
@@ -11285,11 +11552,12 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
status->charge(ss, 0, 8); //costs additional 8 SP if miss
} else { // mobs
//should end when out of sp.
- sg->limit = DIFF_TICK(tick,sg->tick);
+ sg->limit = DIFF_TICK32(tick,sg->tick);
break;
}
- } while( x == bl->x && y == bl->y
+ } while( x == bl->x && y == bl->y && sg->alive_count
&& ++count < SKILLUNITTIMER_INTERVAL/sg->interval && !status->isdead(bl) );
+ map->freeblock_unlock();
}
break;
/**
@@ -11307,12 +11575,6 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if (rnd()%100 < src->val1)
skill->attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
break;
- case GN_CRAZYWEED_ATK:
- if( bl->type == BL_SKILL ){
- struct skill_unit *su = (struct skill_unit *)bl;
- if( su && !(skill->get_inf2(su->group->skill_id)&INF2_TRAP) )
- break;
- }
default:
skill->attack(skill->get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
}
@@ -11328,7 +11590,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
skill->blown(&src->bl,bl,skill->get_blewcount(sg->skill_id,sg->skill_lv),unit->getdir(bl),0);
sg->unit_id = UNT_USED_TRAPS;
clif->changetraplook(&src->bl, UNT_USED_TRAPS);
- sg->limit=DIFF_TICK(tick,sg->tick)+1500;
+ sg->limit=DIFF_TICK32(tick,sg->tick)+1500;
}
break;
@@ -11336,10 +11598,10 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case UNT_MANHOLE:
if( sg->val2 == 0 && tsc && (sg->unit_id == UNT_ANKLESNARE || bl->id != sg->src_id) ) {
int sec = skill->get_time2(sg->skill_id,sg->skill_lv);
- if( status->change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,sec, 8) ) {
+ if( status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,sec, 8) ) {
const struct TimerData* td = tsc->data[type]?timer->get(tsc->data[type]->timer):NULL;
if( td )
- sec = DIFF_TICK(td->tick, tick);
+ sec = DIFF_TICK32(td->tick, tick);
if( sg->unit_id == UNT_MANHOLE || battle_config.skill_trap_type || !map_flag_gvg2(src->bl.m) ) {
unit->movepos(bl, src->bl.x, src->bl.y, 0, 0);
clif->fixpos(bl);
@@ -11356,7 +11618,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
**/
clif->changetraplook(&src->bl, UNT_ANKLESNARE);
}
- sg->limit = DIFF_TICK(tick,sg->tick)+sec;
+ sg->limit = DIFF_TICK32(tick,sg->tick)+sec;
sg->interval = -1;
src->range = 0;
}
@@ -11366,7 +11628,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if( bl->id != ss->id ) {
if( status_get_mode(bl)&MD_BOSS )
break;
- if( status->change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id, sg->skill_lv), 8) ) {
+ if( status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id, sg->skill_lv), 8) ) {
map->moveblock(bl, src->bl.x, src->bl.y, tick);
clif->fixpos(bl);
@@ -11379,7 +11641,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case UNT_VENOMDUST:
if(tsc && !tsc->data[type])
- status->change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id,sg->skill_lv),0);
+ status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id,sg->skill_lv),0);
break;
@@ -11408,7 +11670,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
map->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick);
if (sg->unit_id != UNT_FIREPILLAR_ACTIVE)
clif->changetraplook(&src->bl, sg->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS);
- sg->limit=DIFF_TICK(tick,sg->tick)+1500 +
+ sg->limit=DIFF_TICK32(tick,sg->tick)+1500 +
(sg->unit_id== UNT_CLUSTERBOMB || sg->unit_id== UNT_ICEBOUNDTRAP?1000:0);// Cluster Bomb/Icebound has 1s to disappear once activated.
sg->unit_id = UNT_USED_TRAPS; //Changed ID so it does not invoke a for each in area again.
break;
@@ -11420,7 +11682,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
clif->talkiebox(&src->bl, sg->valstr);
sg->unit_id = UNT_USED_TRAPS;
clif->changetraplook(&src->bl, UNT_USED_TRAPS);
- sg->limit = DIFF_TICK(tick, sg->tick) + 5000;
+ sg->limit = DIFF_TICK32(tick, sg->tick) + 5000;
sg->val2 = -1;
}
break;
@@ -11482,46 +11744,46 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if (tsd) clif->gospel_info(tsd, 0x15);
break;
case 2: // Immunity to all status
- sc_start(bl,SC_SCRESIST,100,100,time);
+ sc_start(ss,bl,SC_SCRESIST,100,100,time);
if (tsd) clif->gospel_info(tsd, 0x16);
break;
case 3: // MaxHP +100%
- sc_start(bl,SC_INCMHPRATE,100,100,time);
+ sc_start(ss,bl,SC_INCMHPRATE,100,100,time);
if (tsd) clif->gospel_info(tsd, 0x17);
break;
case 4: // MaxSP +100%
- sc_start(bl,SC_INCMSPRATE,100,100,time);
+ sc_start(ss,bl,SC_INCMSPRATE,100,100,time);
if (tsd) clif->gospel_info(tsd, 0x18);
break;
case 5: // All stats +20
- sc_start(bl,SC_INCALLSTATUS,100,20,time);
+ sc_start(ss,bl,SC_INCALLSTATUS,100,20,time);
if (tsd) clif->gospel_info(tsd, 0x19);
break;
case 6: // Level 10 Blessing
- sc_start(bl,SC_BLESSING,100,10,time);
+ sc_start(ss,bl,SC_BLESSING,100,10,time);
break;
case 7: // Level 10 Increase AGI
- sc_start(bl,SC_INC_AGI,100,10,time);
+ sc_start(ss,bl,SC_INC_AGI,100,10,time);
break;
case 8: // Enchant weapon with Holy element
- sc_start(bl,SC_ASPERSIO,100,1,time);
+ sc_start(ss,bl,SC_ASPERSIO,100,1,time);
if (tsd) clif->gospel_info(tsd, 0x1c);
break;
case 9: // Enchant armor with Holy element
- sc_start(bl,SC_BENEDICTIO,100,1,time);
+ sc_start(ss,bl,SC_BENEDICTIO,100,1,time);
if (tsd) clif->gospel_info(tsd, 0x1d);
break;
case 10: // DEF +25%
- sc_start(bl,SC_INCDEFRATE,100,25,time);
+ sc_start(ss,bl,SC_INCDEFRATE,100,25,time);
if (tsd) clif->gospel_info(tsd, 0x1e);
break;
case 11: // ATK +100%
- sc_start(bl,SC_INCATKRATE,100,100,time);
+ sc_start(ss,bl,SC_INCATKRATE,100,100,time);
if (tsd) clif->gospel_info(tsd, 0x1f);
break;
case 12: // HIT/Flee +50
- sc_start(bl,SC_INCHIT,100,50,time);
- sc_start(bl,SC_INCFLEE,100,50,time);
+ sc_start(ss,bl,SC_INCHIT,100,50,time);
+ sc_start(ss,bl,SC_INCFLEE,100,50,time);
if (tsd) clif->gospel_info(tsd, 0x20);
break;
}
@@ -11536,28 +11798,28 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
skill->attack(BF_MISC,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
break;
case 1: // Curse
- sc_start(bl,SC_CURSE,100,1,time);
+ sc_start(ss,bl,SC_CURSE,100,1,time);
break;
case 2: // Blind
- sc_start(bl,SC_BLIND,100,1,time);
+ sc_start(ss,bl,SC_BLIND,100,1,time);
break;
case 3: // Poison
- sc_start(bl,SC_POISON,100,1,time);
+ sc_start(ss,bl,SC_POISON,100,1,time);
break;
case 4: // Level 10 Provoke
- sc_start(bl,SC_PROVOKE,100,10,time);
+ sc_start(ss,bl,SC_PROVOKE,100,10,time);
break;
case 5: // DEF -100%
- sc_start(bl,SC_INCDEFRATE,100,-100,time);
+ sc_start(ss,bl,SC_INCDEFRATE,100,-100,time);
break;
case 6: // ATK -100%
- sc_start(bl,SC_INCATKRATE,100,-100,time);
+ sc_start(ss,bl,SC_INCATKRATE,100,-100,time);
break;
case 7: // Flee -100%
- sc_start(bl,SC_INCFLEERATE,100,-100,time);
+ sc_start(ss,bl,SC_INCFLEERATE,100,-100,time);
break;
case 8: // Speed/ASPD -25%
- sc_start4(bl,SC_GOSPEL,100,1,0,0,BCT_ENEMY,time);
+ sc_start4(ss,bl,SC_GOSPEL,100,1,0,0,BCT_ENEMY,time);
break;
}
}
@@ -11573,7 +11835,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
}
if( sg->src_id != bl->id && i <= 0 )
- sc_start4(bl, type, 100, 0, 0, 0, src->bl.id, sg->interval + 100);
+ sc_start4(ss, bl, type, 100, 0, 0, 0, src->bl.id, sg->interval + 100);
}
break;
@@ -11597,14 +11859,18 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
&src->bl,tick);
sg->unit_id = UNT_USED_TRAPS;
//clif->changetraplook(&src->bl, UNT_FIREPILLAR_ACTIVE);
- sg->limit=DIFF_TICK(tick,sg->tick)+1500;
+ sg->limit=DIFF_TICK32(tick,sg->tick)+1500;
break;
/**
* 3rd stuff
**/
case UNT_POISONSMOKE:
- if( battle->check_target(ss,bl,BCT_ENEMY) > 0 && !(tsc && tsc->data[sg->val2]) && rnd()%100 < 20 )
- sc_start(bl,sg->val2,100,sg->val3,skill->get_time2(GC_POISONINGWEAPON, 1));
+ if( battle->check_target(ss,bl,BCT_ENEMY) > 0 && !(tsc && tsc->data[sg->val2]) && rnd()%100 < 50 ) {
+ short rate = 100;
+ if ( sg->val1 == 9 )//Oblivion Curse gives a 2nd success chance after the 1st one passes which is reduceable. [Rytech]
+ rate = 100 - tstatus->int_ * 4 / 5 ;
+ sc_start(ss,bl,sg->val2,rate,sg->val1,skill->get_time2(GC_POISONINGWEAPON,1) - (tstatus->vit + tstatus->luk) / 2 * 1000);
+ }
break;
case UNT_EPICLESIS:
@@ -11619,13 +11885,14 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
hp = tstatus->max_hp * hp / 100;
sp = tstatus->max_sp * sp / 100;
status->heal(bl, hp, sp, 2);
- sc_start(bl, type, 100, sg->skill_lv, (sg->interval * 3) + 100);
+ sc_start(ss, bl, type, 100, sg->skill_lv, (sg->interval * 3) + 100);
}
// Reveal hidden players every 5 seconds.
if( sg->val2 % 5 == 0 ) {
// TODO: check if other hidden status can be removed.
status_change_end(bl,SC_HIDING,INVALID_TIMER);
status_change_end(bl,SC_CLOAKING,INVALID_TIMER);
+ status_change_end(bl,SC_CLOAKINGEXCEED,INVALID_TIMER);
}
}
/* Enable this if kRO fix the current skill. Currently no damage on undead and demon monster. [Jobbie]
@@ -11637,7 +11904,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if( bl->id == sg->src_id )
break; // Dont work on Self (video shows that)
case UNT_NEUTRALBARRIER:
- sc_start(bl,type,100,sg->skill_lv,sg->interval + 100);
+ sc_start(ss,bl,type,100,sg->skill_lv,sg->interval + 100);
break;
case UNT_DIMENSIONDOOR:
@@ -11650,20 +11917,18 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case UNT_REVERBERATION:
clif->changetraplook(&src->bl,UNT_USED_TRAPS);
map->foreachinrange(skill->trap_splash,&src->bl, skill->get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, &src->bl,tick);
- sg->limit = DIFF_TICK(tick,sg->tick)+1000;
+ sg->limit = DIFF_TICK32(tick,sg->tick)+1500;
sg->unit_id = UNT_USED_TRAPS;
break;
case UNT_SEVERE_RAINSTORM:
- if( battle->check_target(&src->bl, bl, BCT_ENEMY) > 0 )
+ if( battle->check_target(&src->bl, bl, BCT_ENEMY))
skill->attack(BF_WEAPON,ss,&src->bl,bl,WM_SEVERE_RAINSTORM_MELEE,sg->skill_lv,tick,0);
break;
case UNT_NETHERWORLD:
- if( !(status_get_mode(bl)&MD_BOSS) && ss != bl && battle->check_target(&src->bl, bl, BCT_PARTY) > 0 ) {
+ if( !(status_get_mode(bl)&MD_BOSS)) {
if( !(tsc && tsc->data[type]) ){
- sc_start(bl, type, 100, sg->skill_lv, skill->get_time2(sg->skill_id,sg->skill_lv));
- sg->limit = DIFF_TICK(tick,sg->tick);
- sg->unit_id = UNT_USED_TRAPS;
+ sc_start(ss, bl, type, 100, sg->skill_lv, skill->get_time2(sg->skill_id,sg->skill_lv));
}
}
break;
@@ -11671,16 +11936,16 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if( tsc ) {
if( !sg->val2 ) {
int sec = skill->get_time2(sg->skill_id, sg->skill_lv);
- if( sc_start(bl, type, 100, sg->skill_lv, sec) ) {
+ if( sc_start(ss, bl, type, 100, sg->skill_lv, sec) ) {
const struct TimerData* td = tsc->data[type]?timer->get(tsc->data[type]->timer):NULL;
if( td )
- sec = DIFF_TICK(td->tick, tick);
+ sec = DIFF_TICK32(td->tick, tick);
///map->moveblock(bl, src->bl.x, src->bl.y, tick); // in official server it doesn't behave like this. [malufett]
clif->fixpos(bl);
sg->val2 = bl->id;
} else
sec = 3000; // Couldn't trap it?
- sg->limit = DIFF_TICK(tick, sg->tick) + sec;
+ sg->limit = DIFF_TICK32(tick, sg->tick) + sec;
} else if( tsc->data[SC_THORNS_TRAP] && bl->id == sg->val2 )
skill->attack(skill->get_type(GN_THORNS_TRAP), ss, ss, bl, sg->skill_id, sg->skill_lv, tick, SD_LEVEL|SD_ANIMATION);
}
@@ -11692,7 +11957,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case 1:
case 2:
default:
- sc_start4(bl, SC_BURNING, 4 + 4 * sg->skill_lv, sg->skill_lv, 0, ss->id, 0,
+ sc_start4(ss, bl, SC_BURNING, 4 + 4 * sg->skill_lv, sg->skill_lv, 0, ss->id, 0,
skill->get_time2(sg->skill_id, sg->skill_lv));
skill->attack(skill->get_type(sg->skill_id), ss, &src->bl, bl,
sg->skill_id, sg->skill_lv + 10 * sg->val2, tick, 0);
@@ -11707,38 +11972,40 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
break;
case UNT_FIRE_EXPANSION_SMOKE_POWDER:
- sc_start(bl, status->skill2sc(GN_FIRE_EXPANSION_SMOKE_POWDER), 100, sg->skill_lv, 1000);
+ sc_start(ss, bl, status->skill2sc(GN_FIRE_EXPANSION_SMOKE_POWDER), 100, sg->skill_lv, 1000);
break;
case UNT_FIRE_EXPANSION_TEAR_GAS:
- sc_start(bl, status->skill2sc(GN_FIRE_EXPANSION_TEAR_GAS), 100, sg->skill_lv, 1000);
+ sc_start(ss, bl, status->skill2sc(GN_FIRE_EXPANSION_TEAR_GAS), 100, sg->skill_lv, 1000);
break;
case UNT_HELLS_PLANT:
if( battle->check_target(&src->bl,bl,BCT_ENEMY) > 0 )
skill->attack(skill->get_type(GN_HELLS_PLANT_ATK), ss, &src->bl, bl, GN_HELLS_PLANT_ATK, sg->skill_lv, tick, 0);
if( ss != bl) //The caster is the only one who can step on the Plants, without destroying them
- sg->limit = DIFF_TICK(tick, sg->tick) + 100;
+ sg->limit = DIFF_TICK32(tick, sg->tick) + 100;
break;
case UNT_CLOUD_KILL:
if(tsc && !tsc->data[type])
- status->change_start(bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id,sg->skill_lv),8);
+ status->change_start(ss,bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill->get_time2(sg->skill_id,sg->skill_lv),8);
skill->attack(skill->get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
break;
case UNT_WARMER:
if( bl->type == BL_PC && !battle->check_undead(tstatus->race, tstatus->def_ele) && tstatus->race != RC_DEMON ) {
- int hp = 125 * sg->skill_lv; // Officially is 125 * skill_lv.
- struct status_change *ssc = status->get_sc(ss);
+ int hp = 0;
if( ssc && ssc->data[SC_HEATER_OPTION] )
- hp += hp * ssc->data[SC_HEATER_OPTION]->val3 / 100;
+ hp = tstatus->max_hp * 3 * sg->skill_lv / 100;
+ else
+ hp = tstatus->max_hp * sg->skill_lv / 100;
+ status->heal(bl, hp, 0, 0);
if( tstatus->hp != tstatus->max_hp )
clif->skill_nodamage(&src->bl, bl, AL_HEAL, hp, 0);
if( tsc && tsc->data[SC_AKAITSUKI] && hp )
hp = ~hp + 1;
status->heal(bl, hp, 0, 0);
- sc_start(bl, SC_WARMER, 100, sg->skill_lv, skill->get_time2(sg->skill_id,sg->skill_lv));
+ sc_start(ss, bl, SC_WARMER, 100, sg->skill_lv, skill->get_time2(sg->skill_id,sg->skill_lv));
}
break;
@@ -11747,7 +12014,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case UNT_WIND_INSIGNIA:
case UNT_EARTH_INSIGNIA:
case UNT_ZEPHYR:
- sc_start(bl,type, 100, sg->skill_lv, sg->interval);
+ sc_start(ss, bl,type, 100, sg->skill_lv, sg->interval);
if (sg->unit_id != UNT_ZEPHYR && !battle->check_undead(tstatus->race, tstatus->def_ele)) {
int hp = tstatus->max_hp / 100; //+1% each 5s
if ((sg->val3) % 5) { //each 5s
@@ -11767,31 +12034,11 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
break;
case UNT_VACUUM_EXTREME:
- {// TODO: official behavior in gvg area. [malufett]
- int sec = sg->limit - DIFF_TICK(tick, sg->tick);
- int range = skill->get_unit_range(sg->skill_id, sg->skill_lv);
-
- if( tsc && !tsc->data[type] &&
- distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) <= range)// don't consider outer bounderies
- sc_start(bl, type, 100, sg->skill_lv, sec);
-
- if( unit->is_walking(bl) && // wait until target stop walking
- ( tsc && tsc->data[type] && tsc->data[type]->val4 >= tsc->data[type]->val3-range ))
- break;
-
- if( tsc && ( !tsc->data[type] || (tsc->data[type] && tsc->data[type]->val4 < 1 ) ) )
- break;
-
- if( unit->is_walking(bl) &&
- distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) > range )// going outside of boundaries? then force it to stop
- unit->stop_walking(bl,1);
-
- if( !unit->is_walking(bl) &&
- distance_xy(src->bl.x, src->bl.y, bl->x, bl->y) <= range && // only snap if the target is inside the range or
- src->bl.x != bl->x && src->bl.y != bl->y){// diagonal position parallel to VE's center
- unit->movepos(bl, src->bl.x, src->bl.y, 0, 0);
- clif->fixpos(bl);
- }
+ if ( tsc && tsc->data[SC_HALLUCINATIONWALK] ) {
+ return 0;
+ } else {
+ sg->limit -= 100 * tstatus->str/20;
+ sc_start(ss, bl, SC_VACUUM_EXTREME, 100, sg->skill_lv, sg->limit);
}
break;
@@ -11807,36 +12054,36 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if( battle->check_target(&src->bl,bl,BCT_ENEMY) > 0 ){
switch( sg->unit_id ){
case UNT_ZENKAI_WATER:
- sc_start(bl, SC_COLD, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
- sc_start(bl, SC_FREEZE, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
- sc_start(bl, SC_FROSTMISTY, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(ss, bl, SC_COLD, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(ss, bl, SC_FREEZE, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(ss, bl, SC_FROSTMISTY, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
break;
case UNT_ZENKAI_LAND:
- sc_start(bl, SC_STONE, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
- sc_start(bl, SC_POISON, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(ss, bl, SC_STONE, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(ss, bl, SC_POISON, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
break;
case UNT_ZENKAI_FIRE:
- sc_start4(bl, SC_BURNING, sg->val1*5, sg->skill_lv, 0, ss->id, 0, skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start4(ss, bl, SC_BURNING, sg->val1*5, sg->skill_lv, 0, ss->id, 0, skill->get_time2(sg->skill_id, sg->skill_lv));
break;
case UNT_ZENKAI_WIND:
- sc_start(bl, SC_SILENCE, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
- sc_start(bl, SC_SLEEP, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
- sc_start(bl, SC_DEEP_SLEEP, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(ss, bl, SC_SILENCE, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(ss, bl, SC_SLEEP, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(ss, bl, SC_DEEP_SLEEP, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
break;
}
}else
- sc_start2(bl,type,100,sg->val1,sg->val2,skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start2(ss, bl,type,100,sg->val1,sg->val2,skill->get_time2(sg->skill_id, sg->skill_lv));
break;
case UNT_LAVA_SLIDE:
skill->attack(BF_WEAPON, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
if(++sg->val1 > 4) //after 5 stop hit and destroy me
- sg->limit = DIFF_TICK(tick, sg->tick);
+ sg->limit = DIFF_TICK32(tick, sg->tick);
break;
case UNT_POISON_MIST:
skill->attack(BF_MAGIC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
- status->change_start(bl, SC_BLIND, rnd() % 100 > sg->skill_lv * 10, sg->skill_lv, sg->skill_id, 0, 0, skill->get_time2(sg->skill_id, sg->skill_lv), 2|8);
+ status->change_start(ss, bl, SC_BLIND, rnd() % 100 > sg->skill_lv * 10, sg->skill_lv, sg->skill_id, 0, 0, skill->get_time2(sg->skill_id, sg->skill_lv), 2|8);
break;
}
@@ -11848,7 +12095,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
/*==========================================
* Triggered when a char steps out of a skill cell
*------------------------------------------*/
-int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned int tick) {
+int skill_unit_onout(struct skill_unit *src, struct block_list *bl, int64 tick) {
struct skill_unit_group *sg;
struct status_change *sc;
struct status_change_entry *sce;
@@ -11862,7 +12109,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
sce = (sc && type != -1)?sc->data[type]:NULL;
if( bl->prev == NULL
- || (status->isdead(bl) && sg->unit_id != UNT_ANKLESNARE && sg->unit_id != UNT_SPIDERWEB)
+ || (status->isdead(bl) && sg->unit_id != UNT_ANKLESNARE && sg->unit_id != UNT_SPIDERWEB && sg->unit_id != UNT_THORNS_TRAP)
) //Need to delete the trap if the source died.
return 0;
@@ -11872,6 +12119,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
case UNT_EPICLESIS://Arch Bishop
case UNT_NEUTRALBARRIER:
case UNT_STEALTHFIELD:
+ case UNT_WARMER:
if (sce)
status_change_end(bl, type, INVALID_TIMER);
break;
@@ -11885,13 +12133,14 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
status_change_end(bl, type, INVALID_TIMER);
break;
+ case UNT_THORNS_TRAP:
case UNT_SPIDERWEB:
{
struct block_list *target = map->id2bl(sg->val2);
if (target && target==bl) {
if (sce && sce->val3 == sg->group_id)
status_change_end(bl, type, INVALID_TIMER);
- sg->limit = DIFF_TICK(tick,sg->tick)+1000;
+ sg->limit = DIFF_TICK32(tick,sg->tick)+1000;
}
}
break;
@@ -11902,7 +12151,7 @@ int skill_unit_onout (struct skill_unit *src, struct block_list *bl, unsigned in
/*==========================================
* Triggered when a char steps out of a skill group (entirely) [Skotlex]
*------------------------------------------*/
-int skill_unit_onleft (uint16 skill_id, struct block_list *bl, unsigned int tick) {
+int skill_unit_onleft(uint16 skill_id, struct block_list *bl, int64 tick) {
struct status_change *sc;
struct status_change_entry *sce;
enum sc_type type;
@@ -11956,6 +12205,7 @@ int skill_unit_onleft (uint16 skill_id, struct block_list *bl, unsigned int tick
case SO_WATER_INSIGNIA:
case SO_WIND_INSIGNIA:
case SO_EARTH_INSIGNIA:
+ case SO_ELEMENTAL_SHIELD:
case SC_BLOODYLUST:
if (sce)
status_change_end(bl, type, INVALID_TIMER);
@@ -12008,10 +12258,10 @@ int skill_unit_onleft (uint16 skill_id, struct block_list *bl, unsigned int tick
* flag&1: Invoke onplace function (otherwise invoke onout)
* flag&4: Invoke a onleft call (the unit might be scheduled for deletion)
*------------------------------------------*/
-int skill_unit_effect (struct block_list* bl, va_list ap) {
+int skill_unit_effect(struct block_list* bl, va_list ap) {
struct skill_unit* su = va_arg(ap,struct skill_unit*);
struct skill_unit_group* group = su->group;
- unsigned int tick = va_arg(ap,unsigned int);
+ int64 tick = va_arg(ap,int64);
unsigned int flag = va_arg(ap,unsigned int);
uint16 skill_id;
bool dissonance;
@@ -12047,8 +12297,7 @@ int skill_unit_effect (struct block_list* bl, va_list ap) {
/*==========================================
*
*------------------------------------------*/
-int skill_unit_ondamaged (struct skill_unit *src, struct block_list *bl, int64 damage, unsigned int tick)
-{
+int skill_unit_ondamaged(struct skill_unit *src, struct block_list *bl, int64 damage, int64 tick) {
struct skill_unit_group *sg;
nullpo_ret(src);
@@ -12066,10 +12315,12 @@ int skill_unit_ondamaged (struct skill_unit *src, struct block_list *bl, int64 d
case UNT_TALKIEBOX:
case UNT_ANKLESNARE:
case UNT_ICEWALL:
- case UNT_REVERBERATION:
case UNT_WALLOFTHORN:
src->val1 -= (int)cap_value(damage,INT_MIN,INT_MAX);
break;
+ case UNT_REVERBERATION:
+ src->val1--;
+ break;
default:
damage = 0;
break;
@@ -12173,7 +12424,7 @@ int skill_check_pc_partner (struct map_session_data *sd, uint16 skill_id, uint16
int i;
bool is_chorus = ( skill->get_inf2(skill_id)&INF2_CHORUS_SKILL );
- if (!battle_config.player_skill_partner_check || pc->has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL))
+ if (!battle_config.player_skill_partner_check || pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL))
return is_chorus ? MAX_PARTY : 99; //As if there were infinite partners.
if (cast_flag) { //Execute the skill on the partners.
@@ -12191,18 +12442,12 @@ int skill_check_pc_partner (struct map_session_data *sd, uint16 skill_id, uint16
status->charge(&tsd->bl, 0, i);
}
break;
- case WM_GREAT_ECHO:
- for( i = 0; i < c; i++ ) {
- if( (tsd = map->id2sd(p_sd[i])) != NULL )
- status_zap(&tsd->bl,0,skill->get_sp(skill_id,*skill_lv)/c);
- }
- break;
default: //Warning: Assuming Ensemble skills here (for speed)
if( is_chorus )
break;//Chorus skills are not to be parsed as ensambles
if (c > 0 && sd->sc.data[SC_DANCING] && (tsd = map->id2sd(p_sd[0])) != NULL) {
sd->sc.data[SC_DANCING]->val4 = tsd->bl.id;
- sc_start4(&tsd->bl,SC_DANCING,100,skill_id,sd->sc.data[SC_DANCING]->val2,*skill_lv,sd->bl.id,skill->get_time(skill_id,*skill_lv)+1000);
+ sc_start4(&tsd->bl,&tsd->bl,SC_DANCING,100,skill_id,sd->sc.data[SC_DANCING]->val2,*skill_lv,sd->bl.id,skill->get_time(skill_id,*skill_lv)+1000);
clif->skill_nodamage(&tsd->bl, &sd->bl, skill_id, *skill_lv, 1);
tsd->skill_id_dance = skill_id;
tsd->skill_lv_dance = *skill_lv;
@@ -12264,13 +12509,12 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
struct status_data *st;
struct status_change *sc;
struct skill_condition require;
- int i;
nullpo_ret(sd);
if (sd->chatID) return 0;
- if( pc->has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill_id )
+ if( pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill_id )
{ //GMs don't override the skillItem check, otherwise they can use items without them being consumed! [Skotlex]
sd->state.arrow_atk = skill->get_ammotype(skill_id)?1:0; //Need to do arrow state check.
sd->spiritball_old = sd->spiritball; //Need to do Spiritball check.
@@ -12306,6 +12550,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
if( sd->state.abra_flag ) // Hocus-Pocus was used. [Inkfish]
sd->state.abra_flag = 0;
else {
+ int i;
// When a target was selected, consume items that were skipped in pc_use_item [Skotlex]
if( (i = sd->itemindex) == -1 ||
sd->status.inventory[i].nameid != sd->itemid ||
@@ -12459,34 +12704,38 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
return 0;
if(sc->data[SC_BLADESTOP])
break;
- if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == MO_TRIPLEATTACK )
- break;
- if( i )
+ if( sc && sc->data[SC_COMBOATTACK] ) {
+ if( sc->data[SC_COMBOATTACK]->val1 == MO_TRIPLEATTACK )
+ break;
clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, MO_TRIPLEATTACK);
+ }
return 0;
case MO_COMBOFINISH:
if(!sc)
return 0;
- if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == MO_CHAINCOMBO )
- break;
- if( i )
+ if( sc && sc->data[SC_COMBOATTACK] ) {
+ if ( sc->data[SC_COMBOATTACK]->val1 == MO_CHAINCOMBO )
+ break;
clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, MO_CHAINCOMBO);
+ }
return 0;
case CH_TIGERFIST:
if(!sc)
return 0;
- if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == MO_COMBOFINISH )
- break;
- if( i )
+ if( sc && sc->data[SC_COMBOATTACK] ) {
+ if ( sc->data[SC_COMBOATTACK]->val1 == MO_COMBOFINISH )
+ break;
clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, MO_COMBOFINISH);
+ }
return 0;
case CH_CHAINCRUSH:
if(!sc)
return 0;
- if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == CH_TIGERFIST )
- break;
- if( i )
+ if( sc && sc->data[SC_COMBOATTACK] ) {
+ if( sc->data[SC_COMBOATTACK]->val1 == CH_TIGERFIST )
+ break;
clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, CH_TIGERFIST);
+ }
return 0;
case MO_EXTREMITYFIST:
// if(sc && sc->data[SC_EXTREMITYFIST]) //To disable Asura during the 5 min skill block uncomment this...
@@ -12634,8 +12883,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case SG_STAR_WARM:
if (sc && sc->data[SC_MIRACLE])
break;
- i = skill_id-SG_SUN_WARM;
- if (sd->bl.m == sd->feel_map[i].m)
+ if (sd->bl.m == sd->feel_map[skill_id-SG_SUN_WARM].m)
break;
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
@@ -12645,9 +12893,8 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case SG_STAR_COMFORT:
if (sc && sc->data[SC_MIRACLE])
break;
- i = skill_id-SG_SUN_COMFORT;
- if (sd->bl.m == sd->feel_map[i].m &&
- (battle_config.allow_skill_without_day || pc->sg_info[i].day_func()))
+ if (sd->bl.m == sd->feel_map[skill_id-SG_SUN_COMFORT].m &&
+ (battle_config.allow_skill_without_day || pc->sg_info[skill_id-SG_SUN_COMFORT].day_func()))
break;
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
@@ -12728,7 +12975,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
**/
case AB_ANCILLA:
{
- int count = 0;
+ int count = 0, i;
for( i = 0; i < MAX_INVENTORY; i ++ )
if( sd->status.inventory[i].nameid == ITEMID_ANCILLA )
count += sd->status.inventory[i].amount;
@@ -12755,12 +13002,15 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
* Warlock
**/
case WL_COMET:
- if( skill->check_pc_partner(sd,skill_id,&skill_lv,1,0) <= 0 && ((i = pc->search_inventory(sd,require.itemid[0])) < 0 || sd->status.inventory[i].amount < require.amount[0]) )
+ {
+ int idx;
+ if( skill->check_pc_partner(sd,skill_id,&skill_lv,1,0) <= 0 && ((idx = pc->search_inventory(sd,require.itemid[0])) < 0 || sd->status.inventory[idx].amount < require.amount[0]) )
{
//clif->skill_fail(sd,skill_id,USESKILL_FAIL_NEED_ITEM,require.amount[0],require.itemid[0]);
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
+ }
break;
case WL_SUMMONFB:
case WL_SUMMONBL:
@@ -12769,10 +13019,9 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case WL_TETRAVORTEX:
case WL_RELEASE:
{
- int x = SC_SUMMON1;
- i = 0;
- for(; x <= SC_SUMMON5; x++)
- if( sc && sc->data[x] )
+ int j, i = 0;
+ for(j = SC_SUMMON1; j <= SC_SUMMON5; j++)
+ if( sc && sc->data[j] )
i++;
switch(skill_id){
@@ -12783,8 +13032,8 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
}
break;
case WL_RELEASE:
- for(x = SC_SPELLBOOK7; x >= SC_SPELLBOOK1; x--)
- if( sc && sc->data[x] )
+ for(j = SC_SPELLBOOK7; j >= SC_SPELLBOOK1; j--)
+ if( sc && sc->data[j] )
i++;
if( i == 0 ){
clif->skill_fail(sd,skill_id,USESKILL_FAIL_SUMMON_NONE,0);
@@ -12857,13 +13106,6 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
return 0;
}
break;
- case LG_RAGEBURST:
- if( sd->spiritball == 0 ) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_SKILLINTERVAL,0);
- return 0;
- }
- sd->spiritball_old = require.spiritball = sd->spiritball;
- break;
case LG_RAYOFGENESIS:
if( sc && sc->data[SC_INSPIRATION] )
return 1; // Don't check for partner.
@@ -12880,12 +13122,11 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
}
break;
case SR_FALLENEMPIRE:
- if( !sc )
- return 0;
- if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == SR_DRAGONCOMBO )
- break;
- if( i )
+ if( sc && sc->data[SC_COMBOATTACK] ) {
+ if( sc->data[SC_COMBOATTACK]->val1 == SR_DRAGONCOMBO )
+ break;
clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, SR_DRAGONCOMBO);
+ }
return 0;
case SR_CRESCENTELBOW:
if( sc && sc->data[SC_CRESCENTELBOW] ) {
@@ -12898,7 +13139,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
if (map->foreachinrange(mob->count_sub, &sd->bl, skill->get_splash(skill_id, skill_lv), BL_MOB,
MOBID_EMPERIUM, MOBID_GUARIDAN_STONE1, MOBID_GUARIDAN_STONE2)) {
char output[128];
- sprintf(output, "You're too close to a stone or emperium to do this skill");
+ sprintf(output, "You're too close to a stone or emperium to do this skill"); /* TODO official response? or message.conf it */
clif->colormes(sd->fd, COLOR_RED, output);
return 0;
}
@@ -12906,7 +13147,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
if( sd->spiritball > 0 )
sd->spiritball_old = require.spiritball = sd->spiritball;
else {
- clif->skill_fail(sd,skill_id,0,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
break;
@@ -12917,7 +13158,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case SC_MANHOLE:
case SC_DIMENSIONDOOR:
if( sc && sc->data[SC_MAGNETICFIELD] ) {
- clif->skill_fail(sd,skill_id,0,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
break;
@@ -12931,11 +13172,17 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
require.sp -= require.sp * 20 * count / 100; // -20% each W/M in the party.
}
break;
+ case NC_PILEBUNKER:
+ if ( sd->equip_index[EQI_HAND_R] < 0 || sd->status.inventory[sd->equip_index[EQI_HAND_R]].nameid != ITEMID_PILEBUNCKER ) {
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ return 0;
+ }
+ break;
case SO_FIREWALK:
case SO_ELECTRICWALK: // Can't be casted until you've walked all cells.
if( sc && sc->data[SC_PROPERTYWALK] &&
sc->data[SC_PROPERTYWALK]->val3 < skill->get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2) ) {
- clif->skill_fail(sd,skill_id,0x0,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
break;
@@ -12951,9 +13198,8 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
return 0;
}
break;
- case LG_REFLECTDAMAGE:
case CR_REFLECTSHIELD:
- if( sc && sc->data[SC_KYOMU] && rand()%100 < 5 * sc->data[SC_KYOMU]->val1 ){
+ if( sc && sc->data[SC_KYOMU] && rnd()%100 < 5 * sc->data[SC_KYOMU]->val1 ){
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
@@ -12972,11 +13218,14 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
break;
case KO_KAIHOU:
case KO_ZENKAI:
- ARR_FIND(1, 6, i, sd->charm[i] > 0);
+ {
+ int i;
+ ARR_FIND(1, 6, i, sd->charm[i] > 0); // FIXME: 4 or 6?
if( i > 4 ) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_SUMMON,0);
return 0;
}
+ }
break;
}
@@ -13187,7 +13436,7 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
if( sd->chatID )
return 0;
- if( pc->has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill_id ) {
+ if( pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill_id ) {
//GMs don't override the skillItem check, otherwise they can use items without them being consumed! [Skotlex]
sd->state.arrow_atk = skill->get_ammotype(skill_id)?1:0; //Need to do arrow state check.
sd->spiritball_old = sd->spiritball; //Need to do Spiritball check.
@@ -13534,7 +13783,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
if( sc->data[SC__LAZINESS] )
req.sp += req.sp + sc->data[SC__LAZINESS]->val1 * 10;
if( sc->data[SC_UNLIMITED_HUMMING_VOICE] )
- req.sp += req.sp * sc->data[SC_UNLIMITED_HUMMING_VOICE]->val2 / 100;
+ req.sp += req.sp * sc->data[SC_UNLIMITED_HUMMING_VOICE]->val3 / 100;
if( sc->data[SC_RECOGNIZEDSPELL] )
req.sp += req.sp / 4;
if( sc->data[SC_TELEKINESIS_INTENSE] && skill->get_ele(skill_id, skill_lv) == ELE_GHOST)
@@ -13652,6 +13901,22 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
req.amount[skill_lv-1] = skill->db[idx].amount[skill_lv-1];
break;
}
+ if (skill_id == NC_REPAIR) {
+ switch(skill_lv) {
+ case 1:
+ case 2:
+ req.itemid[1] = ITEMID_REPAIR_A;
+ break;
+ case 3:
+ case 4:
+ req.itemid[1] = ITEMID_REPAIR_B;
+ break;
+ case 5:
+ req.itemid[1] = ITEMID_REPAIR_C;
+ break;
+ }
+ req.amount[1] = 1;
+ }
// Check for cost reductions due to skills & SCs
switch(skill_id) {
@@ -13728,7 +13993,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
req.sp -= req.sp * (5 + 5 * pc->checkskill(sd,SO_EL_SYMPATHY)) / 100;
break;
case SO_PSYCHIC_WAVE:
- if( sc && sc->data[SC_BLAST_OPTION] )
+ if( sc && (sc->data[SC_HEATER_OPTION] || sc->data[SC_COOLER_OPTION] || sc->data[SC_BLAST_OPTION] || sc->data[SC_CURSED_SOIL_OPTION] ))
req.sp += req.sp * 150 / 100;
break;
}
@@ -13913,13 +14178,15 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16
// Fixed cast reduction bonuses
if( sc->data[SC__LAZINESS] )
fixcast_r = max(fixcast_r, sc->data[SC__LAZINESS]->val2);
+ if( sc->data[SC_DANCE_WITH_WUG])
+ fixcast_r = max(fixcast_r, sc->data[SC_DANCE_WITH_WUG]->val4);
if( sc->data[SC_SECRAMENT] )
fixcast_r = max(fixcast_r, sc->data[SC_SECRAMENT]->val2);
if( sd && ( skill_lv = pc->checkskill(sd, WL_RADIUS) ) && (skill_id >= WL_WHITEIMPRISON && skill_id < WL_FREEZE_SP) )
fixcast_r = max(fixcast_r, (status_get_int(bl) + status->get_lv(bl)) / 15 + skill_lv * 5); // [{(Caster?s INT / 15) + (Caster?s Base Level / 15) + (Radius Skill Level x 5)}] %
// Fixed cast non percentage bonuses
if( sc->data[SC_MANDRAGORA] )
- fixed += sc->data[SC_MANDRAGORA]->val1 * 1000 / 2;
+ fixed += sc->data[SC_MANDRAGORA]->val1 * 500;
if( sc->data[SC_IZAYOI] )
fixed = 0;
if( sc->data[SC_GUST_OPTION] || sc->data[SC_BLAST_OPTION] || sc->data[SC_WILD_STORM_OPTION] )
@@ -13929,6 +14196,12 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16
if( sd && !(skill->get_castnodex(skill_id, skill_lv)&4) ){
VARCAST_REDUCTION( max(sd->bonus.varcastrate, 0) + max(i, 0) );
fixcast_r = max(fixcast_r, sd->bonus.fixcastrate) + min(sd->bonus.fixcastrate,0);
+ for( i = 0; i < ARRAYLENGTH(sd->skillcast) && sd->skillcast[i].id; i++ )
+ if( sd->skillcast[i].id == skill_id ){ // bonus2 bVariableCastrate
+ if( (i=sd->skillcast[i].val) > 0)
+ VARCAST_REDUCTION(i);
+ break;
+ }
}
if( varcast_r < 0 ) // now compute overall factors
@@ -14155,8 +14428,7 @@ void skill_brandishspear_dir (struct square* tc, uint8 dir, int are) {
}
}
-void skill_brandishspear(struct block_list* src, struct block_list* bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag)
-{
+void skill_brandishspear(struct block_list* src, struct block_list* bl, uint16 skill_id, uint16 skill_lv, int64 tick, int flag) {
int c,n=4;
uint8 dir = map->calc_dir(src,bl->x,bl->y);
struct square tc;
@@ -14188,7 +14460,7 @@ void skill_brandishspear(struct block_list* src, struct block_list* bl, uint16 s
src,skill_id,skill_lv,tick, flag|BCT_ENEMY|n,
skill->castend_damage_id);
if(skill_lv > 6 && n==3 && c==4) {
- skill_brandishspear_dir(&tc,dir,-1);
+ skill->brandishspear_dir(&tc,dir,-1);
n--;c=-1;
}
}
@@ -14207,7 +14479,12 @@ void skill_brandishspear(struct block_list* src, struct block_list* bl, uint16 s
*------------------------------------------*/
void skill_repairweapon (struct map_session_data *sd, int idx) {
int material;
- int materials[4] = { 1002, 998, 999, 756 };
+ int materials[4] = {
+ ITEMID_IRON_ORE,
+ ITEMID_IRON,
+ ITEMID_STEEL,
+ ITEMID_ORIDECON_STONE,
+ };
struct item *item;
struct map_session_data *target_sd;
@@ -14231,9 +14508,9 @@ void skill_repairweapon (struct map_session_data *sd, int idx) {
}
if ( target_sd->inventory_data[idx]->type == IT_WEAPON )
- material = materials [ target_sd->inventory_data[idx]->wlv - 1 ]; // Lv1/2/3/4 weapons consume 1 Iron Ore/Iron/Steel/Rough Oridecon
+ material = materials[ target_sd->inventory_data[idx]->wlv - 1 ]; // Lv1/2/3/4 weapons consume 1 Iron Ore/Iron/Steel/Rough Oridecon
else
- material = materials [2]; // Armors consume 1 Steel
+ material = materials[2]; // Armors consume 1 Steel
if ( pc->search_inventory(sd,material) < 0 ) {
clif->skill_fail(sd,sd->menuskill_id,USESKILL_FAIL_LEVEL,0);
return;
@@ -14281,7 +14558,13 @@ void skill_weaponrefine (struct map_session_data *sd, int idx)
if (idx >= 0 && idx < MAX_INVENTORY)
{
int i = 0, ep = 0, per;
- int material[5] = { 0, 1010, 1011, 984, 984 };
+ int material[5] = {
+ 0,
+ ITEMID_PHRACON,
+ ITEMID_EMVERETARCON,
+ ITEMID_ORIDECON,
+ ITEMID_ORIDECON,
+ };
struct item *item;
struct item_data *ditem = sd->inventory_data[idx];
item = &sd->status.inventory[idx];
@@ -14296,8 +14579,8 @@ void skill_weaponrefine (struct map_session_data *sd, int idx)
clif->upgrademessage(sd->fd, 2, item->nameid);
return;
}
- if( (i = pc->search_inventory(sd, material [ditem->wlv])) < 0 ){
- clif->upgrademessage(sd->fd, 3, material [ditem->wlv]);
+ if( (i = pc->search_inventory(sd, material[ditem->wlv])) < 0 ){
+ clif->upgrademessage(sd->fd, 3, material[ditem->wlv]);
return;
}
@@ -14392,7 +14675,7 @@ int skill_autospell (struct map_session_data *sd, uint16 skill_id)
if(maxlv > lv)
maxlv = lv;
- sc_start4(&sd->bl,SC_AUTOSPELL,100,skill_lv,skill_id,maxlv,0,
+ sc_start4(&sd->bl,&sd->bl,SC_AUTOSPELL,100,skill_lv,skill_id,maxlv,0,
skill->get_time(SA_AUTOSPELL,skill_lv));
return 0;
}
@@ -14493,10 +14776,10 @@ int skill_sit (struct map_session_data *sd, int type)
/*==========================================
*
*------------------------------------------*/
-int skill_frostjoke_scream (struct block_list *bl, va_list ap) {
+int skill_frostjoke_scream(struct block_list *bl, va_list ap) {
struct block_list *src;
uint16 skill_id,skill_lv;
- unsigned int tick;
+ int64 tick;
nullpo_ret(bl);
nullpo_ret(src=va_arg(ap,struct block_list*));
@@ -14504,7 +14787,7 @@ int skill_frostjoke_scream (struct block_list *bl, va_list ap) {
skill_id=va_arg(ap,int);
skill_lv=va_arg(ap,int);
if(!skill_lv) return 0;
- tick=va_arg(ap,unsigned int);
+ tick=va_arg(ap,int64);
if (src == bl || status->isdead(bl))
return 0;
@@ -14537,22 +14820,22 @@ void skill_unitsetmapcell (struct skill_unit *src, uint16 skill_id, uint16 skill
/*==========================================
*
*------------------------------------------*/
-int skill_attack_area (struct block_list *bl, va_list ap) {
+int skill_attack_area(struct block_list *bl, va_list ap) {
struct block_list *src,*dsrc;
int atk_type,skill_id,skill_lv,flag,type;
- unsigned int tick;
+ int64 tick;
if(status->isdead(bl))
return 0;
atk_type = va_arg(ap,int);
- src=va_arg(ap,struct block_list*);
- dsrc=va_arg(ap,struct block_list*);
- skill_id=va_arg(ap,int);
- skill_lv=va_arg(ap,int);
- tick=va_arg(ap,unsigned int);
- flag=va_arg(ap,int);
- type=va_arg(ap,int);
+ src = va_arg(ap,struct block_list*);
+ dsrc = va_arg(ap,struct block_list*);
+ skill_id = va_arg(ap,int);
+ skill_lv = va_arg(ap,int);
+ tick = va_arg(ap,int64);
+ flag = va_arg(ap,int);
+ type = va_arg(ap,int);
if (skill->area_temp[1] == bl->id) //This is the target of the skill, do a full attack and skip target checks.
@@ -14600,6 +14883,10 @@ int skill_clear_group (struct block_list *bl, int flag)
if (flag&1)
group[count++]= ud->skillunit[i];
break;
+ case SO_CLOUD_KILL:
+ if( flag&4 )
+ group[count++]= ud->skillunit[i];
+ break;
case SO_WARMER:
if( flag&8 )
group[count++]= ud->skillunit[i];
@@ -14632,6 +14919,7 @@ struct skill_unit_group *skill_locate_element_field(struct block_list *bl) {
case SA_VIOLENTGALE:
case SA_LANDPROTECTOR:
case NJ_SUITON:
+ case SO_CLOUD_KILL:
case SO_WARMER:
return ud->skillunit[i];
}
@@ -14707,7 +14995,7 @@ int skill_detonator(struct block_list *bl, va_list ap) {
map->foreachinrange(skill->trap_splash,bl,skill->get_splash(su->group->skill_id,su->group->skill_lv),su->group->bl_flag,bl,su->group->tick);
}
clif->changetraplook(bl, UNT_USED_TRAPS);
- su->group->limit = DIFF_TICK(timer->gettick(),su->group->tick) +
+ su->group->limit = DIFF_TICK32(timer->gettick(),su->group->tick) +
(unit_id == UNT_TALKIEBOX ? 5000 : (unit_id == UNT_CLUSTERBOMB || unit_id == UNT_ICEBOUNDTRAP? 2500 : (unit_id == UNT_FIRINGTRAP ? 0 : 1500)) );
su->group->unit_id = UNT_USED_TRAPS;
break;
@@ -14730,6 +15018,9 @@ int skill_cell_overlap(struct block_list *bl, va_list ap) {
if( su == NULL || su->group == NULL || (*alive) == 0 )
return 0;
+ if( su->group->state.guildaura ) /* guild auras are not cancelled! */
+ return 0;
+
switch (skill_id) {
case SA_LANDPROTECTOR:
if( su->group->skill_id == SA_LANDPROTECTOR ) {//Check for offensive Land Protector to delete both. [Skotlex]
@@ -14737,13 +15028,14 @@ int skill_cell_overlap(struct block_list *bl, va_list ap) {
skill->delunit(su);
return 1;
}
- if( !(skill->get_inf2(su->group->skill_id)&(INF2_SONG_DANCE|INF2_TRAP)) || su->group->skill_id == WZ_FIREPILLAR ) { //It deletes everything except songs/dances and traps
+ if( !(skill->get_inf2(su->group->skill_id)&(INF2_SONG_DANCE|INF2_TRAP)) || su->group->skill_id == WZ_FIREPILLAR || su->group->skill_id == GN_HELLS_PLANT) { //It deletes everything except songs/dances and traps
skill->delunit(su);
return 1;
}
break;
case HW_GANBANTEIN:
case LG_EARTHDRIVE:
+ case GN_CRAZYWEED_ATK:
if( !(su->group->state.song_dance&0x1) ) {// Don't touch song/dance.
skill->delunit(su);
return 1;
@@ -14790,25 +15082,6 @@ int skill_cell_overlap(struct block_list *bl, va_list ap) {
return 1;
}
break;
- case GN_CRAZYWEED_ATK:
- switch(su->group->unit_id) {
- //TODO: look for other ground skills that are affected.
- case UNT_WALLOFTHORN:
- case UNT_THORNS_TRAP:
- case UNT_BLOODYLUST:
- case UNT_CHAOSPANIC:
- case UNT_MAELSTROM:
- case UNT_FIREPILLAR_ACTIVE:
- case UNT_LANDPROTECTOR:
- case UNT_VOLCANO:
- case UNT_DELUGE:
- case UNT_VIOLENTGALE:
- case UNT_SAFETYWALL:
- case UNT_PNEUMA:
- skill->delunit(su);
- return 1;
- }
- break;
}
if (su->group->skill_id == SA_LANDPROTECTOR && !(skill->get_inf2(skill_id)&(INF2_SONG_DANCE|INF2_TRAP))) {
@@ -14844,20 +15117,20 @@ int skill_chastle_mob_changetarget(struct block_list *bl,va_list ap)
/*==========================================
*
*------------------------------------------*/
-int skill_trap_splash (struct block_list *bl, va_list ap) {
+int skill_trap_splash(struct block_list *bl, va_list ap) {
struct block_list *src;
- int tick;
- struct skill_unit *su;
+ int64 tick;
+ struct skill_unit *src_su;
struct skill_unit_group *sg;
struct block_list *ss;
src = va_arg(ap,struct block_list *);
- su = (struct skill_unit *)src;
- tick = va_arg(ap,int);
+ src_su = (struct skill_unit *)src;
+ tick = va_arg(ap,int64);
- if( !su->alive || bl->prev == NULL )
+ if( !src_su->alive || bl->prev == NULL )
return 0;
- nullpo_ret(sg = su->group);
+ nullpo_ret(sg = src_su->group);
nullpo_ret(ss = map->id2bl(sg->src_id));
if(battle->check_target(src,bl,sg->target_flag) <= 0)
@@ -14871,19 +15144,19 @@ int skill_trap_splash (struct block_list *bl, va_list ap) {
break;
case UNT_GROUNDDRIFT_WIND:
if(skill->attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
- sc_start(bl,SC_STUN,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(src,bl,SC_STUN,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv));
break;
case UNT_GROUNDDRIFT_DARK:
if(skill->attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
- sc_start(bl,SC_BLIND,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(src,bl,SC_BLIND,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv));
break;
case UNT_GROUNDDRIFT_POISON:
if(skill->attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
- sc_start(bl,SC_POISON,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(src,bl,SC_POISON,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv));
break;
case UNT_GROUNDDRIFT_WATER:
if(skill->attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
- sc_start(bl,SC_FREEZE,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start(src,bl,SC_FREEZE,5,sg->skill_lv,skill->get_time2(sg->skill_id, sg->skill_lv));
break;
case UNT_GROUNDDRIFT_FIRE:
if(skill->attack(BF_WEAPON,ss,src,bl,sg->skill_id,sg->skill_lv,tick,sg->val1))
@@ -14897,11 +15170,13 @@ int skill_trap_splash (struct block_list *bl, va_list ap) {
case UNT_MAIZETRAP:
case UNT_VERDURETRAP:
if( bl->type != BL_PC && !is_boss(bl) )
- sc_start2(bl,SC_ARMOR_PROPERTY,100,sg->skill_lv,skill->get_ele(sg->skill_id,sg->skill_lv),skill->get_time2(sg->skill_id,sg->skill_lv));
+ sc_start2(ss,bl,SC_ARMOR_PROPERTY,100,sg->skill_lv,skill->get_ele(sg->skill_id,sg->skill_lv),skill->get_time2(sg->skill_id,sg->skill_lv));
break;
case UNT_REVERBERATION:
- skill->addtimerskill(ss,tick+50,bl->id,0,0,WM_REVERBERATION_MELEE,sg->skill_lv,BF_WEAPON,0); // for proper skill delay animation when use with Dominion Impulse
- skill->addtimerskill(ss,tick+250,bl->id,0,0,WM_REVERBERATION_MAGIC,sg->skill_lv,BF_MAGIC,0);
+ if( battle->check_target(src,bl,BCT_ENEMY) > 0 ) {
+ skill->attack(BF_WEAPON,ss,src,bl,WM_REVERBERATION_MELEE,sg->skill_lv,tick,0);
+ skill->addtimerskill(ss,tick+200,bl->id,0,0,WM_REVERBERATION_MAGIC,sg->skill_lv,BF_MAGIC,SD_LEVEL);
+ }
break;
case UNT_FIRINGTRAP:
case UNT_ICEBOUNDTRAP:
@@ -14930,7 +15205,7 @@ int skill_trap_splash (struct block_list *bl, va_list ap) {
case UNT_FIRINGTRAP:
case UNT_ICEBOUNDTRAP:
clif->changetraplook(bl, UNT_USED_TRAPS);
- su->group->limit = DIFF_TICK(timer->gettick(),su->group->tick) + 1500;
+ su->group->limit = DIFF_TICK32(timer->gettick(),su->group->tick) + 1500;
su->group->unit_id = UNT_USED_TRAPS;
}
break;
@@ -14942,39 +15217,12 @@ int skill_trap_splash (struct block_list *bl, va_list ap) {
return 1;
}
-int skill_maelstrom_suction(struct block_list *bl, va_list ap) {
- uint16 skill_id, skill_lv;
- struct skill_unit *su;
-
- skill_id = va_arg(ap,int);
- skill_lv = va_arg(ap,int);
- su = (struct skill_unit *)bl;
-
- if( su == NULL || su->group == NULL )
- return 0;
-
- if( skill->get_inf2(skill_id)&INF2_TRAP )
- return 0;
-
- if( su->group->skill_id == SC_MAELSTROM ) {
- struct block_list *src;
- if( (src = map->id2bl(su->group->src_id)) ) {
- int sp = su->group->skill_lv * skill_lv;
- if( src->type == BL_PC )
- sp += ((TBL_PC*)src)->status.job_level / 5;
- status->heal(src, 0, sp/2, 1);
- }
- }
-
- return 0;
-}
-
/*==========================================
*
*------------------------------------------*/
int skill_enchant_elemental_end (struct block_list *bl, int type) {
struct status_change *sc;
- const enum sc_type scs[] = { SC_ENCHANTPOISON, SC_ASPERSIO, SC_PROPERTYFIRE, SC_PROPERTYWATER, SC_PROPERTYWIND, SC_PROPERTYGROUND, SC_PROPERTYDARK, SC_PROPERTYTELEKINESIS, SC_ENCHANTARMS, SC_EXEEDBREAK };
+ const enum sc_type scs[] = { SC_ENCHANTPOISON, SC_ASPERSIO, SC_PROPERTYFIRE, SC_PROPERTYWATER, SC_PROPERTYWIND, SC_PROPERTYGROUND, SC_PROPERTYDARK, SC_PROPERTYTELEKINESIS, SC_ENCHANTARMS };
int i;
nullpo_ret(bl);
nullpo_ret(sc = status->get_sc(bl));
@@ -15049,6 +15297,39 @@ bool skill_check_camouflage(struct block_list *bl, struct status_change_entry *s
return wall;
}
+bool skill_check_shadowform(struct block_list *bl, int64 damage, int hit){
+ struct status_change *sc;
+ struct block_list *src;
+
+ nullpo_retr(false, bl);
+
+ sc = status->get_sc(bl);
+
+ if( sc && sc->data[SC__SHADOWFORM] && damage ) {
+ src = map->id2bl(sc->data[SC__SHADOWFORM]->val2);
+
+ if( !src || src->m != bl->m ) {
+ status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
+ return false;
+ }
+
+ if( src && (status->isdead(src) || !battle->check_target(bl,src,BCT_ENEMY)) ){
+ if( src->type == BL_PC )
+ ((TBL_PC*)src)->shadowform_id = 0;
+ status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
+ return false;
+ }
+
+ status->damage(bl, src, damage, 0, clif->damage(src, src, 500, 500, damage, hit, (hit > 1 ? 8 : 0), 0), 0);
+ if( (--sc->data[SC__SHADOWFORM]->val3) <= 0 ) {
+ status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
+ if( src->type == BL_PC )
+ ((TBL_PC*)src)->shadowform_id = 0;
+ }
+ return true;
+ }
+ return false;
+}
/*==========================================
*
*------------------------------------------*/
@@ -15059,9 +15340,6 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int
nullpo_retr(NULL, group->unit); // crash-protection against poor coding
nullpo_retr(NULL, su=&group->unit[idx]);
- if( map->getcell(map->id2bl(group->src_id)->m, x, y, CELL_CHKMAELSTROM) )
- return su;
-
if(!su->alive)
group->alive_count++;
@@ -15093,16 +15371,13 @@ struct skill_unit *skill_initunit (struct skill_unit_group *group, int idx, int
case HP_BASILICA:
skill->unitsetmapcell(su,HP_BASILICA,group->skill_lv,CELL_BASILICA,true);
break;
- case SC_MAELSTROM:
- skill->unitsetmapcell(su,SC_MAELSTROM,group->skill_lv,CELL_MAELSTROM,true);
- break;
default:
if (group->state.song_dance&0x1) //Check for dissonance.
skill->dance_overlap(su, 1);
break;
}
- clif->skill_setunit(su);
+ clif->getareachar_skillunit(&su->bl,su,AREA);
return su;
}
@@ -15154,9 +15429,6 @@ int skill_delunit (struct skill_unit* su) {
status_change_end(target, SC_ELECTRICSHOCKER, INVALID_TIMER);
}
break;
- case SC_MAELSTROM:
- skill->unitsetmapcell(su,SC_MAELSTROM,group->skill_lv,CELL_MAELSTROM,false);
- break;
case SC_MANHOLE: // Note : Removing the unit don't remove the status (official info)
if( group->val2 ) { // Someone Traped
struct status_change *tsc = status->get_sc(map->id2bl(group->val2));
@@ -15223,11 +15495,11 @@ struct skill_unit_group* skill_initunitgroup (struct block_list* src, int count,
if(i == MAX_SKILLUNITGROUP) {
// array is full, make room by discarding oldest group
int j=0;
- unsigned maxdiff=0,x,tick=timer->gettick();
+ int64 maxdiff = 0, x, tick = timer->gettick();
for(i=0;i<MAX_SKILLUNITGROUP && ud->skillunit[i];i++)
- if((x=DIFF_TICK(tick,ud->skillunit[i]->tick))>maxdiff){
- maxdiff=x;
- j=i;
+ if( (x=DIFF_TICK(tick,ud->skillunit[i]->tick)) > maxdiff ) {
+ maxdiff = x;
+ j = i;
}
skill->del_unitgroup(ud->skillunit[j],ALC_MARK);
//Since elements must have shifted, we use the last slot.
@@ -15414,7 +15686,7 @@ int skill_clear_unitgroup (struct block_list *src)
/*==========================================
*
*------------------------------------------*/
-struct skill_unit_group_tickset *skill_unitgrouptickset_search (struct block_list *bl, struct skill_unit_group *group, int tick) {
+struct skill_unit_group_tickset *skill_unitgrouptickset_search(struct block_list *bl, struct skill_unit_group *group, int64 tick) {
int i,j=-1,k,s,id;
struct unit_data *ud;
struct skill_unit_group_tickset *set;
@@ -15454,10 +15726,10 @@ struct skill_unit_group_tickset *skill_unitgrouptickset_search (struct block_lis
/*==========================================
*
*------------------------------------------*/
-int skill_unit_timer_sub_onplace (struct block_list* bl, va_list ap) {
+int skill_unit_timer_sub_onplace(struct block_list* bl, va_list ap) {
struct skill_unit* su = va_arg(ap,struct skill_unit *);
struct skill_unit_group* group = su->group;
- unsigned int tick = va_arg(ap,unsigned int);
+ int64 tick = va_arg(ap,int64);
if( !su->alive || bl->prev == NULL )
return 0;
@@ -15481,7 +15753,7 @@ int skill_unit_timer_sub_onplace (struct block_list* bl, va_list ap) {
int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
struct skill_unit* su = DB->data2ptr(data);
struct skill_unit_group* group = su->group;
- unsigned int tick = va_arg(ap,unsigned int);
+ int64 tick = va_arg(ap,int64);
bool dissonance;
struct block_list* bl = &su->bl;
@@ -15505,8 +15777,8 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
case UNT_GROUNDDRIFT_FIRE:
group->unit_id = UNT_USED_TRAPS;
//clif->changetraplook(bl, UNT_FIREPILLAR_ACTIVE);
- group->limit=DIFF_TICK(tick+1500,group->tick);
- su->limit=DIFF_TICK(tick+1500,group->tick);
+ group->limit=DIFF_TICK32(tick+1500,group->tick);
+ su->limit=DIFF_TICK32(tick+1500,group->tick);
break;
case UNT_ANKLESNARE:
@@ -15585,15 +15857,15 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
}
clif->changetraplook(bl,UNT_USED_TRAPS);
map->foreachinrange(skill->trap_splash, bl, skill->get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick);
- group->limit = DIFF_TICK(tick,group->tick)+1000;
- su->limit = DIFF_TICK(tick,group->tick)+1000;
+ group->limit = DIFF_TICK32(tick,group->tick)+1500;
+ su->limit = DIFF_TICK32(tick,group->tick)+1500;
group->unit_id = UNT_USED_TRAPS;
break;
case UNT_FEINTBOMB: {
struct block_list *src = map->id2bl(group->src_id);
if( src )
- map->foreachinrange(skill->area_sub, &group->unit->bl, su->range, splash_target(src), src, SC_FEINTBOMB, group->skill_lv, tick, BCT_ENEMY|SD_ANIMATION|1, skill->castend_damage_id);
+ map->foreachinrange(skill->area_sub, &group->unit->bl, su->range, splash_target(src), src, SC_FEINTBOMB, group->skill_lv, tick, BCT_ENEMY|1, skill->castend_damage_id);
skill->delunit(su);
break;
}
@@ -15607,8 +15879,8 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
break;
}
// This unit isn't removed while SC_BANDING is active.
- group->limit = DIFF_TICK(tick+group->interval,group->tick);
- su->limit = DIFF_TICK(tick+group->interval,group->tick);
+ group->limit = DIFF_TICK32(tick+group->interval,group->tick);
+ su->limit = DIFF_TICK32(tick+group->interval,group->tick);
}
break;
@@ -15621,7 +15893,7 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
// icewall loses 50 hp every second
su->val1 -= SKILLUNITTIMER_INTERVAL/20; // trap's hp
if( su->val1 <= 0 && su->limit + group->tick > tick + 700 )
- su->limit = DIFF_TICK(tick+700,group->tick);
+ su->limit = DIFF_TICK32(tick+700,group->tick);
break;
case UNT_BLASTMINE:
case UNT_SKIDTRAP:
@@ -15638,24 +15910,19 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
skill->delunit(su);
else {
clif->changetraplook(bl, group->unit_id==UNT_LANDMINE?UNT_FIREPILLAR_ACTIVE:UNT_USED_TRAPS);
- group->limit = DIFF_TICK(tick, group->tick) + 1500;
+ group->limit = DIFF_TICK32(tick, group->tick) + 1500;
group->unit_id = UNT_USED_TRAPS;
}
}
break;
case UNT_REVERBERATION:
- if( su->val1 <= 0 ) {
- clif->changetraplook(bl,UNT_USED_TRAPS);
- map->foreachinrange(skill->trap_splash, bl, skill->get_splash(group->skill_id, group->skill_lv), group->bl_flag, bl, tick);
- group->limit = DIFF_TICK(tick,group->tick)+1000;
- su->limit = DIFF_TICK(tick,group->tick)+1000;
- group->unit_id = UNT_USED_TRAPS;
- }
+ if( su->val1 <= 0 )
+ su->limit = DIFF_TICK32(tick + 700,group->tick);
break;
case UNT_WALLOFTHORN:
if( su->val1 <= 0 ) {
group->unit_id = UNT_USED_TRAPS;
- group->limit = DIFF_TICK(tick, group->tick) + 1500;
+ group->limit = DIFF_TICK32(tick, group->tick) + 1500;
}
break;
}
@@ -15692,7 +15959,7 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
/*==========================================
* Executes on all skill units every SKILLUNITTIMER_INTERVAL miliseconds.
*------------------------------------------*/
-int skill_unit_timer(int tid, unsigned int tick, int id, intptr_t data) {
+int skill_unit_timer(int tid, int64 tick, int id, intptr_t data) {
map->freeblock_lock();
skill->unit_db->foreach(skill->unit_db, skill->unit_timer_sub, tick);
@@ -15705,12 +15972,12 @@ int skill_unit_timer(int tid, unsigned int tick, int id, intptr_t data) {
/*==========================================
*
*------------------------------------------*/
-int skill_unit_move_sub (struct block_list* bl, va_list ap) {
+int skill_unit_move_sub(struct block_list* bl, va_list ap) {
struct skill_unit* su = (struct skill_unit *)bl;
struct skill_unit_group* group = su->group;
struct block_list* target = va_arg(ap,struct block_list*);
- unsigned int tick = va_arg(ap,unsigned int);
+ int64 tick = va_arg(ap,int64);
int flag = va_arg(ap,int);
bool dissonance;
@@ -15802,7 +16069,7 @@ int skill_unit_move_sub (struct block_list* bl, va_list ap) {
* units to figure out when they have left a group.
* flag&4: Force a onleft event (triggered when the bl is killed, for example)
*------------------------------------------*/
-int skill_unit_move (struct block_list *bl, unsigned int tick, int flag) {
+int skill_unit_move(struct block_list *bl, int64 tick, int flag) {
nullpo_ret(bl);
if( bl->prev == NULL )
@@ -15827,10 +16094,9 @@ int skill_unit_move (struct block_list *bl, unsigned int tick, int flag) {
/*==========================================
*
*------------------------------------------*/
-int skill_unit_move_unit_group (struct skill_unit_group *group, int16 m, int16 dx, int16 dy)
-{
+int skill_unit_move_unit_group(struct skill_unit_group *group, int16 m, int16 dx, int16 dy) {
int i,j;
- unsigned int tick = timer->gettick();
+ int64 tick = timer->gettick();
int *m_flag;
struct skill_unit *su1;
struct skill_unit *su2;
@@ -15906,7 +16172,7 @@ int skill_unit_move_unit_group (struct skill_unit_group *group, int16 m, int16 d
if (!(m_flag[i]&0x2)) { //We only moved the cell in 0-1
if (group->state.song_dance&0x1) //Check for dissonance effect.
skill->dance_overlap(su1, 1);
- clif->skill_setunit(su1);
+ clif->getareachar_skillunit(&su1->bl,su1,AREA);
map->foreachincell(skill->unit_effect,su1->bl.m,su1->bl.x,su1->bl.y,group->bl_flag,&su1->bl,tick,1);
}
}
@@ -16017,11 +16283,11 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
j = pc->search_inventory(sd,slot[i]);
if(j < 0)
continue;
- if(slot[i]==1000){ /* Star Crumb */
+ if( slot[i]==ITEMID_STAR_CRUMB ) {
pc->delitem(sd,j,1,1,0,LOG_TYPE_PRODUCE);
sc++;
}
- if(slot[i]>=994 && slot[i]<=997 && ele==0){ /* Flame Heart . . . Great Nature */
+ if( slot[i] >= ITEMID_FLAME_HEART && slot[i] <= ITEMID_GREAT_NATURE && ele == 0 ) {
static const int ele_table[4]={3,1,4,2};
pc->delitem(sd,j,1,1,0,LOG_TYPE_PRODUCE);
ele=ele_table[slot[i]-994];
@@ -16029,11 +16295,11 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
}
if( skill_id == RK_RUNEMASTERY ) {
- int temp_qty, skill_lv = pc->checkskill(sd,skill_id);
+ int temp_qty, rune_skill_lv = pc->checkskill(sd,skill_id);
data = itemdb->search(nameid);
- if( skill_lv == 10 ) temp_qty = 1 + rnd()%3;
- else if( skill_lv > 5 ) temp_qty = 1 + rnd()%2;
+ if( rune_skill_lv == 10 ) temp_qty = 1 + rnd()%3;
+ else if( rune_skill_lv > 5 ) temp_qty = 1 + rnd()%2;
else temp_qty = 1;
if (data->stack.inventory) {
@@ -16088,13 +16354,13 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
i = pc->checkskill(sd,skill_id);
make_per = sd->status.job_level*20 + st->dex*10 + st->luk*10; //Base chance
switch(nameid){
- case 998: // Iron
+ case ITEMID_IRON:
make_per += 4000+i*500; // Temper Iron bonus: +26/+32/+38/+44/+50
break;
- case 999: // Steel
+ case ITEMID_STEEL:
make_per += 3000+i*500; // Temper Steel bonus: +35/+40/+45/+50/+55
break;
- case 1000: //Star Crumb
+ case ITEMID_STAR_CRUMB:
make_per = 100000; // Star Crumbs are 100% success crafting rate? (made 1000% so it succeeds even after penalties) [Skotlex]
break;
default: // Enchanted Stones
@@ -16125,32 +16391,32 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
make_per += skill2_lv*100; //+1% bonus per level
}
switch(nameid){
- case 501: // Red Potion
- case 503: // Yellow Potion
- case 504: // White Potion
+ case ITEMID_RED_POTION:
+ case ITEMID_YELLOW_POTION:
+ case ITEMID_WHITE_POTION:
make_per += (1+rnd()%100)*10 + 2000;
break;
- case 970: // Alcohol
+ case ITEMID_ALCHOL:
make_per += (1+rnd()%100)*10 + 1000;
break;
- case 7135: // Bottle Grenade
- case 7136: // Acid Bottle
- case 7137: // Plant Bottle
- case 7138: // Marine Sphere Bottle
+ case ITEMID_FIRE_BOTTLE:
+ case ITEMID_ACID_BOTTLE:
+ case ITEMID_MENEATER_PLANT_BOTTLE:
+ case ITEMID_MINI_BOTTLE:
make_per += (1+rnd()%100)*10;
break;
- case 546: // Condensed Yellow Potion
+ case ITEMID_YELLOW_SLIM_POTION:
make_per -= (1+rnd()%50)*10;
break;
- case 547: // Condensed White Potion
- case 7139: // Glistening Coat
+ case ITEMID_WHITE_SLIM_POTION:
+ case ITEMID_COATING_BOTTLE:
make_per -= (1+rnd()%100)*10;
break;
//Common items, recieve no bonus or penalty, listed just because they are commonly produced
- case 505: // Blue Potion
- case 545: // Condensed Red Potion
- case 605: // Anodyne
- case 606: // Aloevera
+ case ITEMID_BLUE_POTION:
+ case ITEMID_RED_SLIM_POTION:
+ case ITEMID_ANODYNE:
+ case ITEMID_ALOEBERA:
default:
break;
}
@@ -16170,18 +16436,18 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
int C = 100 * cap_value(sd->itemid,0,100); //itemid depend on makerune()
int D = 2500;
switch (nameid) { //rune rank it_diff 9 craftable rune
- case ITEMID_RAIDO:
- case ITEMID_THURISAZ:
- case ITEMID_HAGALAZ:
- case ITEMID_OTHILA:
+ case ITEMID_RAIDO:
+ case ITEMID_THURISAZ:
+ case ITEMID_HAGALAZ:
+ case ITEMID_OTHILA:
D -= 500; //Rank C
- case ITEMID_ISA:
- case ITEMID_WYRD:
+ case ITEMID_ISA:
+ case ITEMID_WYRD:
D -= 500; //Rank B
- case ITEMID_NAUTHIZ:
- case ITEMID_URUZ:
+ case ITEMID_NAUTHIZ:
+ case ITEMID_URUZ:
D -= 500; //Rank A
- case ITEMID_BERKANA:
+ case ITEMID_BERKANA:
case ITEMID_LUX_ANIMA:
D -= 500; //Rank S
}
@@ -16197,7 +16463,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
const int max[10] = {4, 5, 5, 6, 6, 7, 7, 8, 8, 9};
int lv = max(0, pc->checkskill(sd,GC_RESEARCHNEWPOISON) - 1);
qty = min[lv] + rnd()%(max[lv] - min[lv]);
- make_per = 3000 + 500 * (lv+1);
+ make_per = 3000 + 500 * lv + st->dex / 3 * 10 + st->luk * 10 + sd->status.job_level * 10;
}
break;
case GN_CHANGEMATERIAL:
@@ -16217,22 +16483,28 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
(sd->status.base_level-100) + pc->checkskill(sd, AM_LEARNINGPOTION) + pc->checkskill(sd, CR_FULLPROTECTION)*(4+rnd()%6); // (Caster?s Base Level - 100) + (Potion Research x 5) + (Full Chemical Protection Skill Level) x (Random number between 4 ~ 10)
switch(nameid){// difficulty factor
- case 12422: case 12425:
- case 12428:
+ case ITEMID_HP_INCREASE_POTIONS:
+ case ITEMID_SP_INCREASE_POTIONS:
+ case ITEMID_ENRICH_WHITE_POTIONZ:
difficulty += 10;
break;
- case 6212: case 12426:
+ case ITEMID_BOMB_MUSHROOM_SPORE:
+ case ITEMID_SP_INCREASE_POTIONM:
difficulty += 15;
break;
- case 13264: case 12423:
- case 12427: case 12436:
+ case ITEMID_BANANA_BOMB:
+ case ITEMID_HP_INCREASE_POTIONM:
+ case ITEMID_SP_INCREASE_POTIONL:
+ case ITEMID_VITATA500:
difficulty += 20;
break;
- case 6210: case 6211:
- case 12437:
+ case ITEMID_SEED_OF_HORNY_PLANT:
+ case ITEMID_BLOODSUCK_PLANT_SEED:
+ case ITEMID_ENRICH_CELERMINE_JUICE:
difficulty += 30;
break;
- case 12424: case 12475:
+ case ITEMID_HP_INCREASE_POTIONL:
+ case ITEMID_CURE_FREE:
difficulty += 40;
break;
}
@@ -16259,18 +16531,23 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
qty = ~(5 + rnd()%5) + 1;
switch(nameid){// difficulty factor
- case 13260:
+ case ITEMID_APPLE_BOMB:
difficulty += 5;
break;
- case 13261: case 13262:
+ case ITEMID_COCONUT_BOMB:
+ case ITEMID_MELON_BOMB:
difficulty += 10;
break;
- case 12429: case 12430: case 12431:
- case 12432: case 12433: case 12434:
- case 13263:
+ case ITEMID_SAVAGE_BBQ:
+ case ITEMID_WUG_BLOOD_COCKTAIL:
+ case ITEMID_MINOR_BRISKET:
+ case ITEMID_SIROMA_ICETEA:
+ case ITEMID_DROCERA_HERB_STEW:
+ case ITEMID_PETTI_TAIL_NOODLE:
+ case ITEMID_PINEAPPLE_BOMB:
difficulty += 15;
break;
- case 13264:
+ case ITEMID_BANANA_BOMB:
difficulty += 20;
break;
}
@@ -16404,7 +16681,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
}
if (rnd()%10000 < make_per || qty == 1) { //Success
tmp_item.amount++;
- if(nameid < 545 || nameid > 547)
+ if(nameid < ITEMID_RED_SLIM_POTION || nameid > ITEMID_WHITE_SLIM_POTION)
continue;
if( skill_id != AM_PHARMACY &&
skill_id != AM_TWILIGHT1 &&
@@ -16459,7 +16736,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
{ //Cooking items.
clif->specialeffect(&sd->bl, 608, AREA);
if( sd->cook_mastery < 1999 )
- pc_setglobalreg(sd, "COOK_MASTERY",sd->cook_mastery + ( 1 << ( (skill->produce_db[idx].itemlv - 11) / 2 ) ) * 5);
+ pc_setglobalreg(sd, script->add_str("COOK_MASTERY"),sd->cook_mastery + ( 1 << ( (skill->produce_db[idx].itemlv - 11) / 2 ) ) * 5);
}
break;
}
@@ -16527,7 +16804,13 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
break;
case GN_MIX_COOKING: {
struct item tmp_item;
- const int compensation[5] = {13265, 13266, 13267, 12435, 13268};
+ const int compensation[5] = {
+ ITEMID_BLACK_LUMP,
+ ITEMID_BLACK_HARD_LUMP,
+ ITEMID_VERY_HARD_LUMP,
+ ITEMID_BLACK_THING,
+ ITEMID_MYSTERIOUS_POWDER,
+ };
int rate = rnd()%500;
memset(&tmp_item,0,sizeof(tmp_item));
if( rate < 50) i = 4;
@@ -16554,7 +16837,7 @@ int skill_produce_mix(struct map_session_data *sd, uint16 skill_id, int nameid,
{ //Cooking items.
clif->specialeffect(&sd->bl, 609, AREA);
if( sd->cook_mastery > 0 )
- pc_setglobalreg(sd, "COOK_MASTERY", sd->cook_mastery - ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) - ( ( ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) >> 1 ) * 3 ));
+ pc_setglobalreg(sd, script->add_str("COOK_MASTERY"), sd->cook_mastery - ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) - ( ( ( 1 << ((skill->produce_db[idx].itemlv - 11) / 2) ) >> 1 ) * 3 ));
}
}
}
@@ -16612,21 +16895,22 @@ int skill_poisoningweapon( struct map_session_data *sd, int nameid) {
}
switch( nameid )
{ // t_lv used to take duration from skill->get_time2
- case PO_PARALYSE: type = SC_PARALYSE; break;
- case PO_PYREXIA: type = SC_PYREXIA; break;
- case PO_DEATHHURT: type = SC_DEATHHURT; break;
- case PO_LEECHESEND: type = SC_LEECHESEND; break;
- case PO_VENOMBLEED: type = SC_VENOMBLEED; break;
- case PO_TOXIN: type = SC_TOXIN; break;
- case PO_MAGICMUSHROOM: type = SC_MAGICMUSHROOM; break;
- case PO_OBLIVIONCURSE: type = SC_OBLIVIONCURSE; break;
+ case ITEMID_POISON_PARALYSIS: type = SC_PARALYSE; break;
+ case ITEMID_POISON_FEVER: type = SC_PYREXIA; break;
+ case ITEMID_POISON_CONTAMINATION: type = SC_DEATHHURT; break;
+ case ITEMID_POISON_LEECH: type = SC_LEECHESEND; break;
+ case ITEMID_POISON_FATIGUE: type = SC_VENOMBLEED; break;
+ case ITEMID_POISON_NUMB: type = SC_TOXIN; break;
+ case ITEMID_POISON_LAUGHING: type = SC_MAGICMUSHROOM; break;
+ case ITEMID_POISON_OBLIVION: type = SC_OBLIVIONCURSE; break;
default:
clif->skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_LEVEL,0);
return 0;
}
+ status_change_end(&sd->bl, SC_POISONINGWEAPON, -1);//Status must be forced to end so that a new poison will be applied if a player decides to change poisons. [Rytech]
chance = 2 + 2 * sd->menuskill_val; // 2 + 2 * skill_lv
- sc_start4(&sd->bl, SC_POISONINGWEAPON, 100, pc->checkskill(sd, GC_RESEARCHNEWPOISON), //in Aegis it store the level of GC_RESEARCHNEWPOISON in val1
+ sc_start4(&sd->bl, &sd->bl, SC_POISONINGWEAPON, 100, pc->checkskill(sd, GC_RESEARCHNEWPOISON), //in Aegis it store the level of GC_RESEARCHNEWPOISON in val1
type, chance, 0, skill->get_time(GC_POISONINGWEAPON, sd->menuskill_val));
return 0;
@@ -16675,16 +16959,16 @@ int skill_magicdecoy(struct map_session_data *sd, int nameid) {
sd->sc.comet_x = sd->sc.comet_y = 0;
sd->menuskill_val = 0;
- class_ = (nameid == 990 || nameid == 991) ? 2043 + nameid - 990 : (nameid == 992) ? 2046 : 2045;
+ class_ = (nameid == ITEMID_BOODY_RED || nameid == ITEMID_CRYSTAL_BLUE) ? 2043 + nameid - ITEMID_BOODY_RED : (nameid == ITEMID_WIND_OF_VERDURE) ? 2046 : 2045;
- md = mob->once_spawn_sub(&sd->bl, sd->bl.m, x, y, sd->status.name, class_, "", SZ_SMALL, AI_NONE);
+ md = mob->once_spawn_sub(&sd->bl, sd->bl.m, x, y, sd->status.name, class_, "", SZ_MEDIUM, AI_NONE);
if( md ) {
md->master_id = sd->bl.id;
md->special_state.ai = AI_FLORA;
if( md->deletetimer != INVALID_TIMER )
timer->delete(md->deletetimer, mob->timer_delete);
- md->deletetimer = timer->add (timer->gettick() + skill->get_time(NC_MAGICDECOY,skill_id), mob->timer_delete, md->bl.id, 0);
+ md->deletetimer = timer->add(timer->gettick() + skill->get_time(NC_MAGICDECOY,skill_id), mob->timer_delete, md->bl.id, 0);
mob->spawn(md);
md->status.matk_min = md->status.matk_max = 250 + (50 * skill_id);
}
@@ -16714,7 +16998,7 @@ int skill_spellbook (struct map_session_data *sd, int nameid) {
if( !pc->checkskill(sd, (skill_id = skill->spellbook_db[i].skill_id)) )
{ // User don't know the skill
- sc_start(&sd->bl, SC_SLEEP, 100, 1, skill->get_time(WL_READING_SB, pc->checkskill(sd,WL_READING_SB)));
+ sc_start(&sd->bl, &sd->bl, SC_SLEEP, 100, 1, skill->get_time(WL_READING_SB, pc->checkskill(sd,WL_READING_SB)));
clif->skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_DIFFICULT_SLEEP, 0);
return 0;
}
@@ -16730,13 +17014,13 @@ int skill_spellbook (struct map_session_data *sd, int nameid) {
for(i = SC_SPELLBOOK7; i >= SC_SPELLBOOK1; i--){ // This is how official saves spellbook. [malufett]
if( !sc->data[i] ){
sc->data[SC_READING_SB]->val2 += point; // increase points
- sc_start4(&sd->bl, (sc_type)i, 100, skill_id, pc->checkskill(sd,skill_id), point, 0, INVALID_TIMER);
+ sc_start4(&sd->bl,&sd->bl, (sc_type)i, 100, skill_id, pc->checkskill(sd,skill_id), point, 0, INVALID_TIMER);
break;
}
}
}else{
- sc_start2(&sd->bl, SC_READING_SB, 100, 0, point, INVALID_TIMER);
- sc_start4(&sd->bl, SC_SPELLBOOK7, 100, skill_id, pc->checkskill(sd,skill_id), point, 0, INVALID_TIMER);
+ sc_start2(&sd->bl,&sd->bl, SC_READING_SB, 100, 0, point, INVALID_TIMER);
+ sc_start4(&sd->bl,&sd->bl, SC_SPELLBOOK7, 100, skill_id, pc->checkskill(sd,skill_id), point, 0, INVALID_TIMER);
}
return 1;
@@ -16761,7 +17045,7 @@ int skill_select_menu(struct map_session_data *sd,uint16 skill_id) {
lv = (aslvl + 1) / 2; // The level the skill will be autocasted
lv = min(lv,sd->status.skill[idx].lv);
prob = (aslvl == 10) ? 15 : (32 - 2 * aslvl); // Probability at level 10 was increased to 15.
- sc_start4(&sd->bl,SC__AUTOSHADOWSPELL,100,id,lv,prob,0,skill->get_time(SC_AUTOSHADOWSPELL,aslvl));
+ sc_start4(&sd->bl,&sd->bl,SC__AUTOSHADOWSPELL,100,id,lv,prob,0,skill->get_time(SC_AUTOSHADOWSPELL,aslvl));
return 0;
}
int skill_elementalanalysis(struct map_session_data* sd, int n, uint16 skill_lv, unsigned short* item_list) {
@@ -16791,15 +17075,15 @@ int skill_elementalanalysis(struct map_session_data* sd, int n, uint16 skill_lv,
switch( nameid ) {
// Level 1
- case 994: product = 990; break; // Flame Heart -> Red Blood.
- case 995: product = 991; break; // Mystic Frozen -> Crystal Blue.
- case 996: product = 992; break; // Rough Wind -> Wind of Verdure.
- case 997: product = 993; break; // Great Nature -> Green Live.
+ case ITEMID_FLAME_HEART: product = ITEMID_BOODY_RED; break;
+ case ITEMID_MISTIC_FROZEN: product = ITEMID_CRYSTAL_BLUE; break;
+ case ITEMID_ROUGH_WIND: product = ITEMID_WIND_OF_VERDURE; break;
+ case ITEMID_GREAT_NATURE: product = ITEMID_YELLOW_LIVE; break;
// Level 2
- case 990: product = 994; break; // Red Blood -> Flame Heart.
- case 991: product = 995; break; // Crystal Blue -> Mystic Frozen.
- case 992: product = 996; break; // Wind of Verdure -> Rough Wind.
- case 993: product = 997; break; // Green Live -> Great Nature.
+ case ITEMID_BOODY_RED: product = ITEMID_FLAME_HEART; break;
+ case ITEMID_CRYSTAL_BLUE: product = ITEMID_MISTIC_FROZEN; break;
+ case ITEMID_WIND_OF_VERDURE: product = ITEMID_ROUGH_WIND; break;
+ case ITEMID_YELLOW_LIVE: product = ITEMID_GREAT_NATURE; break;
default:
clif->skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0);
return 1;
@@ -16882,13 +17166,13 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite
/**
* for Royal Guard's LG_TRAMPLE
**/
-int skill_destroy_trap( struct block_list *bl, va_list ap ) {
+int skill_destroy_trap(struct block_list *bl, va_list ap) {
struct skill_unit *su = (struct skill_unit *)bl;
struct skill_unit_group *sg;
- unsigned int tick;
+ int64 tick;
nullpo_ret(su);
- tick = va_arg(ap, unsigned int);
+ tick = va_arg(ap, int64);
if (su->alive && (sg = su->group) && skill->get_inf2(sg->skill_id)&INF2_TRAP) {
switch( sg->unit_id ) {
@@ -16915,13 +17199,14 @@ int skill_destroy_trap( struct block_list *bl, va_list ap ) {
/*==========================================
*
*------------------------------------------*/
-int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) {
+int skill_blockpc_end(int tid, int64 tick, int id, intptr_t data) {
struct map_session_data *sd = map->id2sd(id);
struct skill_cd * cd = NULL;
if (data <= 0 || data >= MAX_SKILL)
return 0;
- if (!sd) return 0;
+ if (!sd || !sd->blockskill[data])
+ return 0;
if( ( cd = idb_get(skill->cd_db,sd->status.char_id) ) ) {
int i;
@@ -16955,22 +17240,21 @@ int skill_blockpc_end(int tid, unsigned int tick, int id, intptr_t data) {
}
}
- if (sd->blockskill[data] != (0x1|(tid&0xFE))) return 0;
-
- sd->blockskill[data] = 0;
+ sd->blockskill[data] = false;
return 1;
}
/**
* flags a singular skill as being blocked from persistent usage.
* @param sd the player the skill delay affects
- * @param skill_id the skill which should be delayed
+ * @param skill_id the skill which should be delayed
* @param tick the length of time the delay should last
- * @param load whether this assignment is being loaded upon player login
* @return 0 if successful, -1 otherwise
*/
-int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick, bool load) {
+int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick) {
+ struct skill_cd* cd = NULL;
uint16 idx = skill->get_index(skill_id);
+ int64 now = timer->gettick();
nullpo_retr (-1, sd);
@@ -16978,53 +17262,60 @@ int skill_blockpc_start_(struct map_session_data *sd, uint16 skill_id, int tick,
return -1;
if (tick < 1) {
- sd->blockskill[idx] = 0;
+ sd->blockskill[idx] = false;
return -1;
}
- if( !load && battle_config.display_status_timers )
+ if( battle_config.display_status_timers )
clif->skill_cooldown(sd, skill_id, tick);
-
- if( !load ) {// not being loaded initially so ensure the skill delay is recorded
- struct skill_cd* cd = NULL;
+
+ if( !(cd = idb_get(skill->cd_db,sd->status.char_id)) ) {// create a new skill cooldown object for map storage
+ cd = ers_alloc(skill->cd_ers, struct skill_cd);
+
+ idb_put( skill->cd_db, sd->status.char_id, cd );
+ } else {
int i;
- if( !(cd = idb_get(skill->cd_db,sd->status.char_id)) ) {// create a new skill cooldown object for map storage
- cd = ers_alloc(skill->cd_ers, struct skill_cd);
-
- cd->cursor = 0;
- memset(cd->entry, 0, sizeof(cd->entry));
-
- idb_put( skill->cd_db, sd->status.char_id, cd );
- }
-
for(i = 0; i < MAX_SKILL_TREE; i++) {
- if( !cd->entry[i] )
+ if( cd->entry[i] && cd->entry[i]->skidx == idx )
break;
}
-
- if( i == MAX_SKILL_TREE ) {
- ShowError("skill_blockpc_start: '%s' got over '%d' skill cooldowns, no room to save!\n",sd->status.name,MAX_SKILL_TREE);
- } else {
- cd->entry[cd->cursor] = ers_alloc(skill->cd_entry_ers,struct skill_cd_entry);
-
- cd->entry[cd->cursor]->duration = tick;
+
+ if( i != MAX_SKILL_TREE ) {/* duplicate, update necessary */
+ cd->entry[i]->duration = tick;
#if PACKETVER >= 20120604
- cd->entry[cd->cursor]->total = tick;
+ cd->entry[i]->total = tick;
#endif
- cd->entry[cd->cursor]->skidx = idx;
- cd->entry[cd->cursor]->skill_id = skill_id;
- cd->entry[cd->cursor]->started = timer->gettick();
-
- cd->cursor++;
+ cd->entry[i]->started = now;
+ timer->settick(cd->entry[i]->timer,now+tick);
+ return 0;
}
+
}
+
+ if( cd->cursor == MAX_SKILL_TREE ) {
+ ShowError("skill_blockpc_start: '%s' got over '%d' skill cooldowns, no room to save!\n",sd->status.name,MAX_SKILL_TREE);
+ return -1;
+ }
+
+ cd->entry[cd->cursor] = ers_alloc(skill->cd_entry_ers,struct skill_cd_entry);
+
+ cd->entry[cd->cursor]->duration = tick;
+#if PACKETVER >= 20120604
+ cd->entry[cd->cursor]->total = tick;
+#endif
+ cd->entry[cd->cursor]->skidx = idx;
+ cd->entry[cd->cursor]->skill_id = skill_id;
+ cd->entry[cd->cursor]->started = now;
+ cd->entry[cd->cursor]->timer = timer->add(now+tick,skill->blockpc_end,sd->bl.id,idx);
+
+ cd->cursor++;
- sd->blockskill[idx] = 0x1|(0xFE&timer->add(timer->gettick()+tick,skill->blockpc_end,sd->bl.id,idx));
+ sd->blockskill[idx] = true;
return 0;
}
-int skill_blockhomun_end(int tid, unsigned int tick, int id, intptr_t data) { //[orn]
+int skill_blockhomun_end(int tid, int64 tick, int id, intptr_t data) { //[orn]
struct homun_data *hd = (TBL_HOM*)map->id2bl(id);
if (data <= 0 || data >= MAX_SKILL)
return 0;
@@ -17049,7 +17340,7 @@ int skill_blockhomun_start(struct homun_data *hd, uint16 skill_id, int tick) { /
return timer->add(timer->gettick() + tick, skill->blockhomun_end, hd->bl.id, idx);
}
-int skill_blockmerc_end(int tid, unsigned int tick, int id, intptr_t data) {//[orn]
+int skill_blockmerc_end(int tid, int64 tick, int id, intptr_t data) {//[orn]
struct mercenary_data *md = (TBL_MER*)map->id2bl(id);
if( data <= 0 || data >= MAX_SKILL )
return 0;
@@ -17446,7 +17737,7 @@ int skill_block_check(struct block_list *bl, sc_type type , uint16 skill_id) {
switch(type){
case SC_STASIS:
inf = skill->get_inf2(skill_id);
- if( inf == INF2_SONG_DANCE || /*skill->get_inf2(skill_id) == INF2_CHORUS_SKILL ||*/ inf == INF2_SPIRIT_SKILL )
+ if( inf == INF2_SONG_DANCE || skill->get_inf2(skill_id) == INF2_CHORUS_SKILL || inf == INF2_SPIRIT_SKILL )
return 1; // Can't do it.
switch( skill_id ) {
case NV_FIRSTAID: case TF_HIDING: case AS_CLOAKING: case WZ_SIGHTRASHER:
@@ -17517,7 +17808,7 @@ int skill_get_elemental_type( uint16 skill_id , uint16 skill_lv ) {
void skill_cooldown_save(struct map_session_data * sd) {
int i;
struct skill_cd* cd = NULL;
- unsigned int now = 0;
+ int64 now = 0;
// always check to make sure the session properly exists
nullpo_retv(sd);
@@ -17530,7 +17821,11 @@ void skill_cooldown_save(struct map_session_data * sd) {
// process each individual cooldown associated with the character
for( i = 0; i < cd->cursor; i++ ) {
- cd->entry[i]->duration = DIFF_TICK(cd->entry[i]->started+cd->entry[i]->duration,now);
+ cd->entry[i]->duration = DIFF_TICK32(cd->entry[i]->started+cd->entry[i]->duration,now);
+ if( cd->entry[i]->timer != INVALID_TIMER ) {
+ timer->delete(cd->entry[i]->timer,skill->blockpc_end);
+ cd->entry[i]->timer = INVALID_TIMER;
+ }
}
}
@@ -17541,7 +17836,7 @@ void skill_cooldown_save(struct map_session_data * sd) {
void skill_cooldown_load(struct map_session_data * sd) {
int i;
struct skill_cd* cd = NULL;
- unsigned int now = 0;
+ int64 now = 0;
// always check to make sure the session properly exists
nullpo_retv(sd);
@@ -17557,8 +17852,8 @@ void skill_cooldown_load(struct map_session_data * sd) {
// process each individual cooldown associated with the character
for( i = 0; i < cd->cursor; i++ ) {
cd->entry[i]->started = now;
- // block the skill from usage but ensure it is not recorded (load = true)
- skill->blockpc_start( sd, cd->entry[i]->skill_id, cd->entry[i]->duration, true );
+ cd->entry[i]->timer = timer->add(timer->gettick()+cd->entry[i]->duration,skill->blockpc_end,sd->bl.id,cd->entry[i]->skidx);
+ sd->blockskill[cd->entry[i]->skidx] = true;
}
}
@@ -17611,6 +17906,7 @@ bool skill_parse_row_skilldb(char* split[], int columns, int current) {
safestrncpy(skill->db[idx].name, trim(split[15]), sizeof(skill->db[idx].name));
safestrncpy(skill->db[idx].desc, trim(split[16]), sizeof(skill->db[idx].desc));
strdb_iput(skill->name2id_db, skill->db[idx].name, skill_id);
+ script->set_constant2(skill->db[idx].name,(int)skill_id,0);
return true;
}
@@ -17740,8 +18036,8 @@ bool skill_parse_row_unitdb(char* split[], int columns, int current) {
if( !idx ) // invalid skill id
return false;
- skill->db[idx].unit_id[0] = strtol(split[1],NULL,16);
- skill->db[idx].unit_id[1] = strtol(split[2],NULL,16);
+ skill->db[idx].unit_id[0] = (int)strtol(split[1],NULL,16);
+ skill->db[idx].unit_id[1] = (int)strtol(split[2],NULL,16);
skill->split_atoi(split[3],skill->db[idx].unit_layout_type);
skill->split_atoi(split[4],skill->db[idx].unit_range);
skill->db[idx].unit_interval = atoi(split[5]);
@@ -17756,9 +18052,9 @@ bool skill_parse_row_unitdb(char* split[], int columns, int current) {
else if( strcmpi(split[6],"self")==0 ) skill->db[idx].unit_target = BCT_SELF;
else if( strcmpi(split[6],"sameguild")==0 ) skill->db[idx].unit_target = BCT_GUILD|BCT_SAMEGUILD;
else if( strcmpi(split[6],"noone")==0 ) skill->db[idx].unit_target = BCT_NOONE;
- else skill->db[idx].unit_target = strtol(split[6],NULL,16);
+ else skill->db[idx].unit_target = (int)strtol(split[6],NULL,16);
- skill->db[idx].unit_flag = strtol(split[7],NULL,16);
+ skill->db[idx].unit_flag = (int)strtol(split[7],NULL,16);
if (skill->db[idx].unit_flag&UF_DEFNOTENEMY && battle_config.defnotenemy)
skill->db[idx].unit_target = BCT_NOENEMY;
@@ -17954,7 +18250,7 @@ bool skill_parse_row_changematerialdb(char* split[], int columns, int current) {
* create_arrow_db.txt
* abra_db.txt
*------------------------------*/
-void skill_readdb(void) {
+void skill_readdb(bool minimal) {
// init skill db structures
db_clear(skill->name2id_db);
@@ -17976,7 +18272,17 @@ void skill_readdb(void) {
safestrncpy(skill->db[0].name, "UNKNOWN_SKILL", sizeof(skill->db[0].name));
safestrncpy(skill->db[0].desc, "Unknown Skill", sizeof(skill->db[0].desc));
+#ifdef ENABLE_CASE_CHECK
+ script->parser_current_file = DBPATH"skill_db.txt";
+#endif // ENABLE_CASE_CHECK
sv->readdb(map->db_path, DBPATH"skill_db.txt", ',', 17, 17, MAX_SKILL_DB, skill->parse_row_skilldb);
+#ifdef ENABLE_CASE_CHECK
+ script->parser_current_file = NULL;
+#endif // ENABLE_CASE_CHECK
+
+ if (minimal)
+ return;
+
sv->readdb(map->db_path, DBPATH"skill_require_db.txt", ',', 32, 32, MAX_SKILL_DB, skill->parse_row_requiredb);
#ifdef RENEWAL_CAST
sv->readdb(map->db_path, "re/skill_cast_db.txt", ',', 8, 8, MAX_SKILL_DB, skill->parse_row_castdb);
@@ -18004,7 +18310,7 @@ void skill_reload (void) {
struct map_session_data *sd;
int i,c,k;
- skill->read_db();
+ skill->read_db(false);
//[Ind/Hercules] refresh index cache
for(c = 0; c < CLASS_COUNT; c++) {
@@ -18030,22 +18336,27 @@ void skill_reload (void) {
/*==========================================
*
*------------------------------------------*/
-int do_init_skill (void) {
+int do_init_skill(bool minimal) {
skill->name2id_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, MAX_SKILL_NAME_LENGTH);
- skill->read_db();
+ skill->read_db(minimal);
+
+ if (minimal)
+ return 0;
skill->group_db = idb_alloc(DB_OPT_BASE);
skill->unit_db = idb_alloc(DB_OPT_BASE);
skill->cd_db = idb_alloc(DB_OPT_BASE);
skill->usave_db = idb_alloc(DB_OPT_RELEASE_DATA);
- skill->unit_ers = ers_new(sizeof(struct skill_unit_group),"skill.c::skill_unit_ers",ERS_OPT_NONE);
- skill->timer_ers = ers_new(sizeof(struct skill_timerskill),"skill.c::skill_timer_ers",ERS_OPT_NONE);
- skill->cd_ers = ers_new(sizeof(struct skill_cd),"skill.c::skill_cd_ers",ERS_OPT_CLEAR);
- skill->cd_entry_ers = ers_new(sizeof(struct skill_cd_entry),"skill.c::skill_cd_entry_ers",ERS_OPT_CLEAR);
+ skill->unit_ers = ers_new(sizeof(struct skill_unit_group),"skill.c::skill_unit_ers",ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK);
+ skill->timer_ers = ers_new(sizeof(struct skill_timerskill),"skill.c::skill_timer_ers",ERS_OPT_NONE|ERS_OPT_FLEX_CHUNK);
+ skill->cd_ers = ers_new(sizeof(struct skill_cd),"skill.c::skill_cd_ers",ERS_OPT_CLEAR|ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK);
+ skill->cd_entry_ers = ers_new(sizeof(struct skill_cd_entry),"skill.c::skill_cd_entry_ers",ERS_OPT_CLEAR|ERS_OPT_FLEX_CHUNK);
ers_chunk_size(skill->cd_ers, 25);
ers_chunk_size(skill->cd_entry_ers, 100);
+ ers_chunk_size(skill->unit_ers, 150);
+ ers_chunk_size(skill->timer_ers, 150);
timer->add_func_list(skill->unit_timer,"skill_unit_timer");
timer->add_func_list(skill->castend_id,"skill_castend_id");
@@ -18235,7 +18546,7 @@ void skill_defaults(void) {
skill->check_condition_mercenary = skill_check_condition_mercenary;
skill->locate_element_field = skill_locate_element_field;
skill->graffitiremover = skill_graffitiremover;
- skill->activate_reverberation = skill_activate_reverbetion;
+ skill->activate_reverberation = skill_activate_reverberation;
skill->dance_overlap = skill_dance_overlap;
skill->dance_overlap_sub = skill_dance_overlap_sub;
skill->get_unit_layout = skill_get_unit_layout;
@@ -18292,6 +18603,6 @@ void skill_defaults(void) {
skill->changematerial = skill_changematerial;
skill->get_elemental_type = skill_get_elemental_type;
skill->cooldown_save = skill_cooldown_save;
- skill->maelstrom_suction = skill_maelstrom_suction;
skill->get_new_group_id = skill_get_new_group_id;
+ skill->check_shadowform = skill_check_shadowform;
}