summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.c26
-rw-r--r--src/map/battle.c698
-rw-r--r--src/map/battle.h2
-rw-r--r--src/map/chrif.c7
-rw-r--r--src/map/clif.c28
-rw-r--r--src/map/guild.c2
-rw-r--r--src/map/intif.c2
-rw-r--r--src/map/itemdb.h4
-rw-r--r--src/map/map.c3
-rw-r--r--src/map/map.h3
-rw-r--r--src/map/mercenary.c2
-rw-r--r--src/map/mob.c19
-rw-r--r--src/map/party.c21
-rw-r--r--src/map/party.h1
-rw-r--r--src/map/pc.c47
-rw-r--r--src/map/script.c44
-rw-r--r--src/map/skill.c1938
-rw-r--r--src/map/skill.h1
-rw-r--r--src/map/status.c967
-rw-r--r--src/map/status.h104
-rw-r--r--src/map/unit.c21
21 files changed, 2255 insertions, 1685 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 2849ada0b..c5460eb47 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -4416,7 +4416,7 @@ ACMD(jail) {
}
//Duration of INT_MAX to specify infinity.
- sc_start4(&pl_sd->bl,SC_JAILED,100,INT_MAX,m_index,x,y,1000);
+ sc_start4(NULL,&pl_sd->bl,SC_JAILED,100,INT_MAX,m_index,x,y,1000);
clif->message(pl_sd->fd, msg_txt(117)); // GM has send you in jails.
clif->message(fd, msg_txt(118)); // Player warped in jails.
return true;
@@ -4454,7 +4454,7 @@ ACMD(unjail) {
}
//Reset jail time to 1 sec.
- sc_start(&pl_sd->bl,SC_JAILED,100,1,1000);
+ sc_start(NULL,&pl_sd->bl,SC_JAILED,100,1,1000);
clif->message(pl_sd->fd, msg_txt(120)); // A GM has discharged you from jail.
clif->message(fd, msg_txt(121)); // Player unjailed.
return true;
@@ -4565,7 +4565,7 @@ ACMD(jailfor) {
break;
}
- sc_start4(&pl_sd->bl,SC_JAILED,100,jailtime,m_index,x,y,jailtime?60000:1000); //jailtime = 0: Time was reset to 0. Wait 1 second to warp player out (since it's done in status->change_timer).
+ sc_start4(NULL,&pl_sd->bl,SC_JAILED,100,jailtime,m_index,x,y,jailtime?60000:1000); //jailtime = 0: Time was reset to 0. Wait 1 second to warp player out (since it's done in status->change_timer).
return true;
}
@@ -5477,7 +5477,7 @@ ACMD(autotrade) {
sd->state.autotrade = 1;
if( battle_config.at_timeout ) {
int timeout = atoi(message);
- status->change_start(&sd->bl, SC_AUTOTRADE, 10000, 0, 0, 0, 0, ((timeout > 0) ? min(timeout,battle_config.at_timeout) : battle_config.at_timeout) * 60000, 0);
+ status->change_start(NULL,&sd->bl, SC_AUTOTRADE, 10000, 0, 0, 0, 0, ((timeout > 0) ? min(timeout,battle_config.at_timeout) : battle_config.at_timeout) * 60000, 0);
}
clif->chsys_quit(sd);
@@ -6072,7 +6072,7 @@ ACMD(npctalk)
unsigned int color = 0;
if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] ||
+ (sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) ||
(sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
return false;
@@ -6121,7 +6121,7 @@ ACMD(pettalk)
}
if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] ||
+ (sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) ||
(sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
return false;
@@ -6263,7 +6263,7 @@ ACMD(summon)
md->deletetimer=timer->add(tick+(duration*60000),mob->timer_delete,md->bl.id,0);
clif->specialeffect(&md->bl,344,AREA);
mob->spawn(md);
- sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000);
+ sc_start4(NULL,&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000);
clif->skill_poseffect(&sd->bl,AM_CALLHOMUN,1,md->bl.x,md->bl.y,tick);
clif->message(fd, msg_txt(39)); // All monster summoned!
@@ -6433,7 +6433,7 @@ ACMD(mute) {
if( pl_sd->status.manner < manner ) {
pl_sd->status.manner -= manner;
- sc_start(&pl_sd->bl,SC_NOCHAT,100,0,0);
+ sc_start(NULL,&pl_sd->bl,SC_NOCHAT,100,0,0);
} else {
pl_sd->status.manner = 0;
status_change_end(&pl_sd->bl, SC_NOCHAT, INVALID_TIMER);
@@ -6912,7 +6912,7 @@ ACMD(homtalk)
}
if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] ||
+ (sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) ||
(sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
return false;
@@ -7228,7 +7228,7 @@ int atcommand_mutearea_sub(struct block_list *bl,va_list ap)
if (id != bl->id && !pc_get_group_level(pl_sd)) {
pl_sd->status.manner -= time;
if (pl_sd->status.manner < 0)
- sc_start(&pl_sd->bl,SC_NOCHAT,100,0,0);
+ sc_start(NULL,&pl_sd->bl,SC_NOCHAT,100,0,0);
else
status_change_end(&pl_sd->bl, SC_NOCHAT, INVALID_TIMER);
}
@@ -7287,7 +7287,7 @@ ACMD(me)
memset(atcmd_output, '\0', sizeof(atcmd_output));
if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] ||
+ (sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) ||
(sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
return false;
@@ -8366,7 +8366,7 @@ ACMD(mount2) {
clif->message(sd->fd,msg_txt(1362)); // NOTICE: If you crash with mount your LUA is outdated.
if( !(sd->sc.data[SC_ALL_RIDING]) ) {
clif->message(sd->fd,msg_txt(1363)); // You have mounted.
- sc_start(&sd->bl,SC_ALL_RIDING,100,0,-1);
+ sc_start(NULL,&sd->bl,SC_ALL_RIDING,100,0,-1);
} else {
clif->message(sd->fd,msg_txt(1364)); // You have released your mount.
status_change_end(&sd->bl, SC_ALL_RIDING, INVALID_TIMER);
@@ -9339,7 +9339,7 @@ ACMD(costume){
return false;
}
- sc_start(&sd->bl, name2id[k], 100, 0, -1);
+ sc_start(NULL,&sd->bl, name2id[k], 100, 0, -1);
return true;
}
diff --git a/src/map/battle.c b/src/map/battle.c
index 1a04aeff9..ce861aa7e 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -366,8 +366,6 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
}
if( tsc->data[SC_THORNS_TRAP])
status_change_end(target, SC_THORNS_TRAP, INVALID_TIMER);
- if( tsc->data[SC_FIRE_CLOAK_OPTION])
- damage -= damage * tsc->data[SC_FIRE_CLOAK_OPTION]->val2 / 100;
if( tsc->data[SC_COLD] && target->type != BL_MOB)
status_change_end(target, SC_COLD, INVALID_TIMER);
if( tsc->data[SC_EARTH_INSIGNIA]) damage += damage/2;
@@ -377,7 +375,7 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
if( tsc->data[SC_ORATIO]) ratio += tsc->data[SC_ORATIO]->val1 * 2;
break;
case ELE_POISON:
- if( tsc->data[SC_VENOMIMPRESS]) ratio += tsc->data[SC_VENOMIMPRESS]->val2;
+ if( tsc->data[SC_VENOMIMPRESS] && atk_elem == ELE_POISON ) ratio += tsc->data[SC_VENOMIMPRESS]->val2;
break;
case ELE_WIND:
if( tsc->data[SC_COLD] && target->type != BL_MOB) damage += damage/2;
@@ -446,8 +444,8 @@ int64 battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, u
eatk += 200;
#ifdef RENEWAL_EDP
if( sc->data[SC_EDP] && skill_id != AS_GRIMTOOTH && skill_id != AS_VENOMKNIFE && skill_id != ASC_BREAKER ){
- eatk = eatk * sc->data[SC_EDP]->val4 / 100;
- damage += damage * sc->data[SC_EDP]->val3 / 100;
+ eatk = eatk * (sc->data[SC_EDP]->val4 / 100 - 1);
+ damage = damage * (sc->data[SC_EDP]->val4 / 100);
}
#endif
}
@@ -611,7 +609,7 @@ int64 battle_addmastery(struct map_session_data *sd,struct block_list *target,in
if( (skill_lv = pc->checkskill(sd,NC_RESEARCHFE)) > 0 && (st->def_ele == ELE_FIRE || st->def_ele == ELE_EARTH) )
damage += (skill_lv * 10);
if( pc_ismadogear(sd) )
- damage += 20 + 20 * pc->checkskill(sd, NC_MADOLICENCE);
+ damage += 15 * pc->checkskill(sd, NC_MADOLICENCE);
#ifdef RENEWAL
if( (skill_lv = pc->checkskill(sd,BS_WEAPONRESEARCH)) > 0 )
damage += (skill_lv * 2);
@@ -788,6 +786,8 @@ int64 battle_calc_masteryfix(struct block_list *src, struct block_list *target,
// general skill masteries
#ifdef RENEWAL
+ if( div < 0 ) // div fix
+ div = 1;
if( skill_id == MO_FINGEROFFENSIVE )//The finger offensive spheres on moment of attack do count. [Skotlex]
damage += div * sd->spiritball_old * 3;
else
@@ -849,6 +849,10 @@ int64 battle_calc_elefix(struct block_list *src, struct block_list *target, uint
damage=battle->attr_fix(src, target, damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
if( skill_id == MC_CARTREVOLUTION ) //Cart Revolution applies the element fix once more with neutral element
damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
+ if( skill_id == NC_ARMSCANNON )
+ damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
+ if( skill_id == GN_CARTCANNON )
+ damage = battle->attr_fix(src,target,damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
if( skill_id == GS_GROUNDDRIFT ) //Additional 50*lv Neutral damage.
damage += battle->attr_fix(src,target,50*skill_lv,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
}
@@ -1364,6 +1368,22 @@ int64 battle_calc_defense(int attack_type, struct block_list *src, struct block_
return damage;
}
+// Minstrel/Wanderer number check for chorus skills.
+int battle_calc_chorusbonus(struct map_session_data *sd) {
+ int members = 0;
+
+ if (!sd || !sd->status.party_id)
+ return 0;
+
+ members = party->foreachsamemap(party->sub_count_chorus, sd, 0);
+
+ if (members < 3)
+ return 0; // Bonus remains 0 unless 3 or more Minstrel's/Wanderer's are in the party.
+ if (members > 7)
+ return 5; // Maximum effect possiable from 7 or more Minstrel's/Wanderer's
+ return members - 2; // Effect bonus from additional Minstrel's/Wanderer's if not above the max possible
+}
+
int battle_calc_skillratio(int attack_type, struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int skillratio, int flag){
int i;
struct status_change *sc, *tsc;
@@ -1500,25 +1520,24 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
* Arch Bishop
**/
case AB_JUDEX:
- skillratio += 180 + 20 * skill_lv;
- if (skill_lv > 4) skillratio += 20;
+ skillratio = 300 + 20 * skill_lv;
RE_LVL_DMOD(100);
break;
case AB_ADORAMUS:
- skillratio += 400 + 100 * skill_lv;
+ skillratio = 500 + 100 * skill_lv;
RE_LVL_DMOD(100);
break;
case AB_DUPLELIGHT_MAGIC:
- skillratio += 100 + 20 * skill_lv;
+ skillratio = 200 + 20 * skill_lv;
break;
/**
* Warlock
**/
- case WL_SOULEXPANSION: // MATK [{( Skill Level + 4 ) x 100 ) + ( Caster?s INT )} x ( Caster?s Base Level / 100 )] %
- skillratio += 300 + 100 * skill_lv + status_get_int(src);
+ case WL_SOULEXPANSION: // MATK [{( Skill Level + 4 ) x 100 ) + ( Caster's INT )} x ( Caster's Base Level / 100 )] %
+ skillratio = 100 * (skill_lv + 4) + st->int_;
RE_LVL_DMOD(100);
break;
- case WL_FROSTMISTY: // MATK [{( Skill Level x 100 ) + 200 } x ( Caster?s Base Level / 100 )] %
+ case WL_FROSTMISTY: // MATK [{( Skill Level x 100 ) + 200 } x ( Caster's Base Level / 100 )] %
skillratio += 100 + 100 * skill_lv;
RE_LVL_DMOD(100);
break;
@@ -1566,7 +1585,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
c = 0;
memset (p_sd, 0, sizeof(p_sd));
party->foreachsamemap(skill->check_condition_char_sub, sd, 3, &sd->bl, &c, &p_sd, skill_id);
- c = ( c > 1 ? rand()%c : 0 );
+ c = ( c > 1 ? rnd()%c : 0 );
if( (psd = map->id2sd(p_sd[c])) && pc->checkskill(psd,WL_COMET) > 0 ){
skillratio = skill_lv * 400; //MATK [{( Skill Level x 400 ) x ( Caster's Base Level / 120 )} + 2500 ] %
@@ -1583,7 +1602,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
skillratio += 100 * flag;
break;
case WL_EARTHSTRAIN:
- skillratio += 1900 + 100 * skill_lv;
+ skillratio = 2000 + 100 * skill_lv;
RE_LVL_DMOD(100);
break;
case WL_TETRAVORTEX_FIRE:
@@ -1596,7 +1615,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
case WL_SUMMON_ATK_WATER:
case WL_SUMMON_ATK_WIND:
case WL_SUMMON_ATK_GROUND:
- skillratio = skill_lv * (status->get_lv(src) + ( sd ? sd->status.job_level : 50 ));// This is close to official, but lacking a little info to finalize. [Rytech]
+ skillratio = (1 + skill_lv) / 2 * (status->get_lv(src) + (sd ? sd->status.job_level : 50));
RE_LVL_DMOD(100);
break;
case LG_RAYOFGENESIS:
@@ -1607,82 +1626,68 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
bandingBonus = 200 * (sd ? skill->check_pc_partner(sd,skill_id,&lv,skill->get_splash(skill_id,skill_lv),0) : 1);
skillratio = ((300 * skill_lv) + bandingBonus) * (sd ? sd->status.job_level : 1) / 25;
}
- break;
- case LG_SHIELDSPELL:// [(Casters Base Level x 4) + (Shield MDEF x 100) + (Casters INT x 2)] %
- if( sd ) {
- skillratio = status->get_lv(src) * 4 + sd->bonus.shieldmdef * 100 + status_get_int(src) * 2;
- } else
- skillratio += 1900; //2000%
break;
- case WM_METALICSOUND:
- skillratio += 120 * skill_lv + 60 * ( sd? pc->checkskill(sd, WM_LESSON) : 10 ) - 100;
+ case LG_SHIELDSPELL:
+ if ( sd && skill_lv == 2 ) // [(Casters Base Level x 4) + (Shield MDEF x 100) + (Casters INT x 2)] %
+ skillratio = 4 * status->get_lv(src) + 100 * sd->bonus.shieldmdef + 2 * st->int_;
+ else
+ skillratio = 0;
break;
- /*case WM_SEVERE_RAINSTORM:
- skillratio += 50 * skill_lv;
+ case WM_METALICSOUND:
+ skillratio = 120 * skill_lv + 60 * ( sd? pc->checkskill(sd, WM_LESSON) : 10 );
+ RE_LVL_DMOD(100);
break;
-
- WM_SEVERE_RAINSTORM just set a unit place,
- refer to WM_SEVERE_RAINSTORM_MELEE to set the formula.
- */
case WM_REVERBERATION_MAGIC:
- // MATK [{(Skill Level x 100) + 100} x Casters Base Level / 100] %
- skillratio += 100 * (sd ? pc->checkskill(sd, WM_REVERBERATION) : 1);
+ skillratio = 100 * skill_lv + 100;
RE_LVL_DMOD(100);
break;
case SO_FIREWALK:
- skillratio = 300;
+ skillratio = 60 * skill_lv;
RE_LVL_DMOD(100);
if( sc && sc->data[SC_HEATER_OPTION] )
- skillratio += sc->data[SC_HEATER_OPTION]->val3;
+ skillratio += sc->data[SC_HEATER_OPTION]->val3 / 2;
break;
case SO_ELECTRICWALK:
- skillratio = 300;
+ skillratio = 60 * skill_lv;
RE_LVL_DMOD(100);
if( sc && sc->data[SC_BLAST_OPTION] )
- skillratio += sd ? sd->status.job_level / 2 : 0;
+ skillratio += sc->data[SC_BLAST_OPTION]->val2 / 2;
break;
case SO_EARTHGRAVE:
- skillratio = ( 200 * ( sd ? pc->checkskill(sd, SA_SEISMICWEAPON) : 10 ) + status_get_int(src) * skill_lv );
+ skillratio = st->int_ * skill_lv + 200 * (sd ? pc->checkskill(sd,SA_SEISMICWEAPON) : 1);
RE_LVL_DMOD(100);
if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
- skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
+ skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val3 * 5;
break;
case SO_DIAMONDDUST:
- skillratio = ( 200 * ( sd ? pc->checkskill(sd, SA_FROSTWEAPON) : 10 ) + status_get_int(src) * skill_lv );
- RE_LVL_DMOD(100);
+ skillratio = (st->int_ * skill_lv + 200 * (sd ? pc->checkskill(sd, SA_FROSTWEAPON) : 1)) * status->get_lv(src) / 100;
if( sc && sc->data[SC_COOLER_OPTION] )
- skillratio += sc->data[SC_COOLER_OPTION]->val3;
+ skillratio += sc->data[SC_COOLER_OPTION]->val3 * 5;
break;
case SO_POISON_BUSTER:
- skillratio += 1100 + 300 * skill_lv;
+ skillratio += 900 + 300 * skill_lv;
+ RE_LVL_DMOD(100);
if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
- skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
+ skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val3 * 5;
break;
case SO_PSYCHIC_WAVE:
- skillratio += -100 + skill_lv * 70 + (status_get_int(src) * 3);
+ skillratio = 70 * skill_lv + 3 * st->int_;
RE_LVL_DMOD(100);
- if( sc ){
- if( sc->data[SC_HEATER_OPTION] )
- skillratio += sc->data[SC_HEATER_OPTION]->val3;
- else if(sc->data[SC_COOLER_OPTION] )
- skillratio += sc->data[SC_COOLER_OPTION]->val3;
- else if(sc->data[SC_BLAST_OPTION] )
- skillratio += sc->data[SC_BLAST_OPTION]->val2;
- else if(sc->data[SC_CURSED_SOIL_OPTION] )
- skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val3;
- }
+ if( sc && ( sc->data[SC_HEATER_OPTION] || sc->data[SC_COOLER_OPTION]
+ || sc->data[SC_BLAST_OPTION] || sc->data[SC_CURSED_SOIL_OPTION] ) )
+ skillratio += skillratio * 20 / 100;
break;
- case SO_VARETYR_SPEAR: //MATK [{( Endow Tornado skill level x 50 ) + ( Caster INT x Varetyr Spear Skill level )} x Caster Base Level / 100 ] %
+ case SO_VARETYR_SPEAR:
skillratio = status_get_int(src) * skill_lv + ( sd ? pc->checkskill(sd, SA_LIGHTNINGLOADER) * 50 : 0 );
RE_LVL_DMOD(100);
if( sc && sc->data[SC_BLAST_OPTION] )
- skillratio += sd ? sd->status.job_level * 5 : 0;
+ skillratio += sc->data[SC_BLAST_OPTION]->val2 * 5;
break;
case SO_CLOUD_KILL:
- skillratio += -100 + skill_lv * 40;
+ skillratio = 40 * skill_lv;
RE_LVL_DMOD(100);
if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
- skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
+ skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val3;
break;
case GN_DEMONIC_FIRE:
if( skill_lv > 20)
@@ -2073,7 +2078,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
skillratio += ((skill_lv-1)%5+1) * 100;
break;
case RK_SONICWAVE:
- skillratio += -100 + 100 * (skill_lv + 5);
+ skillratio = (skill_lv + 5) * 100;
skillratio = skillratio * (100 + (status->get_lv(src)-100) / 2) / 100;
break;
case RK_HUNDREDSPEAR:
@@ -2087,20 +2092,20 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
}
break;
case RK_WINDCUTTER:
- skillratio += -100 + 50 * (skill_lv + 2);
+ skillratio = (skill_lv + 2) * 50;
RE_LVL_DMOD(100);
break;
case RK_IGNITIONBREAK:
- i = distance_bl(src,target);
- if( i < 2 )
- skillratio += 300 * skill_lv;
- else if( i < 4 )
- skillratio += 250 * skill_lv;
- else
- skillratio += 200 * skill_lv;
- skillratio = (skillratio - 100) * (100 + (status->get_lv(src)-100)) / 100;
- if( st->rhw.ele == ELE_FIRE )
- skillratio += 100 * skill_lv;
+ i = distance_bl(src,target);
+ if( i < 2 )
+ skillratio = 300 * skill_lv;
+ else if( i < 4 )
+ skillratio = 250 * skill_lv;
+ else
+ skillratio = 200 * skill_lv;
+ skillratio = skillratio * status->get_lv(src) / 100;
+ if( st->rhw.ele == ELE_FIRE )
+ skillratio += 100 * skill_lv;
break;
case RK_CRUSHSTRIKE:
if( sd )
@@ -2112,10 +2117,10 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
}
break;
case RK_STORMBLAST:
- skillratio += -100 + 100 *(sd ? pc->checkskill(sd,RK_RUNEMASTERY) : 1) + status_get_int(src) / 8;
+ skillratio = ((sd ? pc->checkskill(sd,RK_RUNEMASTERY) : 1) + status_get_int(src) / 8) * 100;
break;
case RK_PHANTOMTHRUST:
- skillratio += -100 + 50 * skill_lv + 10 * ( sd ? pc->checkskill(sd,KN_SPEARMASTERY) : 10);
+ skillratio = 50 * skill_lv + 10 * (sd ? pc->checkskill(sd,KN_SPEARMASTERY) : 10);
RE_LVL_DMOD(150);
break;
/**
@@ -2134,7 +2139,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
RE_LVL_DMOD(120);
break;
case GC_ROLLINGCUTTER:
- skillratio += -50 + 50 * skill_lv;
+ skillratio = 50 + 50 * skill_lv;
RE_LVL_DMOD(100);
break;
case GC_CROSSRIPPERSLASHER:
@@ -2167,88 +2172,99 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
skillratio += 100 + 100 * skill_lv;
break;
case RA_WUGDASH:// ATK 300%
- skillratio += 200;
+ skillratio = 300;
+ if( sc && sc->data[SC_DANCE_WITH_WUG] )
+ skillratio += 10 * sc->data[SC_DANCE_WITH_WUG]->val1 * (2 + battle->calc_chorusbonus(sd));
break;
case RA_WUGSTRIKE:
- skillratio += -100 + 200 * skill_lv;
+ skillratio = 200 * skill_lv;
+ if( sc && sc->data[SC_DANCE_WITH_WUG] )
+ skillratio += 10 * sc->data[SC_DANCE_WITH_WUG]->val1 * (2 + battle->calc_chorusbonus(sd));
break;
case RA_WUGBITE:
skillratio += 300 + 200 * skill_lv;
if ( skill_lv == 5 ) skillratio += 100;
break;
case RA_SENSITIVEKEEN:
- skillratio += 50 * skill_lv;
+ skillratio = 150 * skill_lv;
break;
/**
* Mechanic
**/
case NC_BOOSTKNUCKLE:
- skillratio += 100 + 100 * skill_lv + status_get_dex(src);
- RE_LVL_DMOD(100);
+ skillratio = skill_lv * 100 + 200 + st->dex;
+ RE_LVL_DMOD(120);
break;
case NC_PILEBUNKER:
- skillratio += 200 + 100 * skill_lv + status_get_str(src);
+ skillratio = skill_lv*100 + 300 + status_get_str(src);
RE_LVL_DMOD(100);
break;
case NC_VULCANARM:
- skillratio += -100 + 70 * skill_lv + status_get_dex(src);
+ skillratio = 70 * skill_lv + status_get_dex(src);
RE_LVL_DMOD(100);
break;
case NC_FLAMELAUNCHER:
case NC_COLDSLOWER:
- skillratio += 200 + 300 * skill_lv;
+ skillratio += 200 + 100 * skill_lv + status_get_str(src);
RE_LVL_DMOD(100);
break;
case NC_ARMSCANNON:
switch( tst->size ) {
- case SZ_MEDIUM: skillratio += 100 + 500 * skill_lv; break;// Medium
- case SZ_SMALL: skillratio += 100 + 400 * skill_lv; break;// Small
- case SZ_BIG: skillratio += 100 + 300 * skill_lv; break;// Large
+ case SZ_MEDIUM: skillratio = 300 + 350 * skill_lv; break; // Medium
+ case SZ_SMALL: skillratio = 300 + 400 * skill_lv; break; // Small
+ case SZ_BIG: skillratio = 300 + 300 * skill_lv; break; // Large
}
- RE_LVL_DMOD(100);
- //NOTE: Their's some other factors that affects damage, but not sure how exactly. Will recheck one day. [Rytech]
+ RE_LVL_DMOD(120);
break;
case NC_AXEBOOMERANG:
- skillratio += 60 + 40 * skill_lv;
+ skillratio = 250 + 50 * skill_lv;
if( sd ) {
short index = sd->equip_index[EQI_HAND_R];
if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON )
- skillratio += sd->inventory_data[index]->weight / 10;// Weight is divided by 10 since 10 weight in coding make 1 whole actural weight. [Rytech]
+ skillratio += sd->inventory_data[index]->weight / 10;
}
RE_LVL_DMOD(100);
break;
case NC_POWERSWING:
- skillratio += 80 + 20 * skill_lv + status_get_str(src) + status_get_dex(src);
- RE_LVL_DMOD(100);
+ skillratio = 300 + 100*skill_lv + ( status_get_str(src)+status_get_dex(src) ) * status->get_lv(src) / 100;
break;
case NC_AXETORNADO:
- skillratio += 100 + 100 * skill_lv + status_get_vit(src);
+ skillratio = 200 + 100 * skill_lv + st->vit;
RE_LVL_DMOD(100);
+ if( st->rhw.ele == ELE_WIND )
+ skillratio = skillratio * 125 / 100;
+ if ( distance_bl(src, target) > 2 ) // Will deal 75% damage outside of 5x5 area.
+ skillratio = skillratio * 75 / 100;
break;
case SC_FATALMENACE:
- skillratio += 100 * skill_lv;
+ skillratio = 100 * (skill_lv+1) * status->get_lv(src) / 100;
break;
case SC_TRIANGLESHOT:
- skillratio += 270 + 30 * skill_lv;
+ skillratio = ( 300 + (skill_lv-1) * status_get_agi(src)/2 ) * status->get_lv(src) / 120;
break;
case SC_FEINTBOMB:
- skillratio += 100 + 100 * skill_lv;
+ skillratio = (skill_lv+1) * (st->dex/2) * (sd?sd->status.job_level:50)/10 * status->get_lv(src) / 120;
break;
case LG_CANNONSPEAR:
- skillratio += -100 + (50 + status_get_str(src)) * skill_lv;
+ skillratio = (50 + st->str) * skill_lv;
RE_LVL_DMOD(100);
break;
case LG_BANISHINGPOINT:
- skillratio += -100 + ((50 * skill_lv) + (30 * ((sd)?pc->checkskill(sd,SM_BASH):1)));
+ skillratio = 50 * skill_lv + 30 * (sd ? pc->checkskill(sd,SM_BASH) : 10);
RE_LVL_DMOD(100);
break;
case LG_SHIELDPRESS:
- skillratio += 60 + 43 * skill_lv;
+ skillratio = 150 * skill_lv + st->str;
+ if( sd ) {
+ short index = sd->equip_index[EQI_HAND_L];
+ if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR )
+ skillratio += sd->inventory_data[index]->weight / 10;
+ }
RE_LVL_DMOD(100);
break;
case LG_PINPOINTATTACK:
- skillratio += -100 + ((100 * skill_lv) + (10 * status_get_agi(src)) );
- RE_LVL_DMOD(100);
+ skillratio = 100 * skill_lv + 5 * st->agi;
+ RE_LVL_DMOD(120);
break;
case LG_RAGEBURST:
if( sc ){
@@ -2257,17 +2273,17 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
}
RE_LVL_DMOD(100);
break;
- case LG_SHIELDSPELL:// [(Casters Base Level x 4) + (Shield DEF x 10) + (Casters VIT x 2)] %
- if( sd ) {
+ case LG_SHIELDSPELL:
+ if ( sd && skill_lv == 1 ) {
struct item_data *shield_data = sd->inventory_data[sd->equip_index[EQI_HAND_L]];
- skillratio += -100 + status->get_lv(src) * 4 + status_get_vit(src) * 2;
if( shield_data )
- skillratio += shield_data->def * 10;
- } else
- skillratio += 2400; //2500%
+ skillratio = 4 * status->get_lv(src) + 10 * shield_data->def + 2 * st->vit;
+ }
+ else
+ skillratio = 0; // Prevents ATK damage from being done on LV 2 usage since LV 2 us MATK. [Rytech]
break;
case LG_MOONSLASHER:
- skillratio += -100 + (120 * skill_lv + ((sd) ? pc->checkskill(sd,LG_OVERBRAND) : 5) * 80);
+ skillratio = 120 * skill_lv + 80 * (sd ? pc->checkskill(sd,LG_OVERBRAND) : 5);
RE_LVL_DMOD(100);
break;
case LG_OVERBRAND:
@@ -2283,11 +2299,15 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
RE_LVL_DMOD(100);
break;
case LG_RAYOFGENESIS:
- skillratio += 200 + 300 * skill_lv;
+ skillratio = 300 + 300 * skill_lv;
RE_LVL_DMOD(100);
break;
case LG_EARTHDRIVE:
- skillratio = (skillratio + 100) * skill_lv;
+ if( sd ) {
+ short index = sd->equip_index[EQI_HAND_L];
+ if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR )
+ skillratio = (1 + skill_lv) * sd->inventory_data[index]->weight / 10;
+ }
RE_LVL_DMOD(100);
break;
case LG_HESPERUSLIT:
@@ -2341,8 +2361,9 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
}
break;
case SR_KNUCKLEARROW:
- if( flag&4 ){ // ATK [(Skill Level x 150) + (1000 x Target current weight / Maximum weight) + (Target Base Level x 5) x (Caster Base Level / 150)] %
- skillratio += -100 + 150 * skill_lv + status->get_lv(target) * 5 * (status->get_lv(src) / 100) ;
+ if ( flag&4 || map->list[src->m].flag.gvg_castle || tst->mode&MD_BOSS ) {
+ // ATK [(Skill Level x 150) + (1000 x Target current weight / Maximum weight) + (Target Base Level x 5) x (Caster Base Level / 150)] %
+ skillratio = 150 * skill_lv + status->get_lv(target) * 5 * (status->get_lv(src) / 100) ;
if( tsd && tsd->weight )
skillratio += 100 * (tsd->weight / tsd->max_weight);
}else // ATK [(Skill Level x 100 + 500) x Caster Base Level / 100] %
@@ -2350,7 +2371,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
RE_LVL_DMOD(100);
break;
case SR_WINDMILL: // ATK [(Caster Base Level + Caster DEX) x Caster Base Level / 100] %
- skillratio += -100 + status->get_lv(src) + status_get_dex(src);
+ skillratio = status->get_lv(src) + status_get_dex(src);
RE_LVL_DMOD(100);
break;
case SR_GATEOFHELL:
@@ -2376,40 +2397,36 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
RE_LVL_DMOD(100);
break;
case WM_REVERBERATION_MELEE:
- // ATK [{(Skill Level x 100) + 300} x Caster Base Level / 100]
- skillratio += 200 + 100 * pc->checkskill(sd, WM_REVERBERATION);
+ skillratio += 200 + 100 * skill_lv;
RE_LVL_DMOD(100);
break;
case WM_SEVERE_RAINSTORM_MELEE:
- //ATK [{(Caster DEX + AGI) x (Skill Level / 5)} x Caster Base Level / 100] %
- skillratio += -100 + (status_get_dex(src) + status_get_agi(src)) * (skill_lv * 2);
+ skillratio = (st->agi + st->dex) * skill_lv / 5;
RE_LVL_DMOD(100);
- skillratio /= 10;
break;
case WM_GREAT_ECHO:
- skillratio += 800 + 100 * skill_lv;
- if( sd ) { // Still need official value [pakpil]
- uint16 lv = skill_lv;
- skillratio += 100 * skill->check_pc_partner(sd,skill_id,&lv,skill->get_splash(skill_id,skill_lv),0);
- }
- break;
- case WM_SOUND_OF_DESTRUCTION:
- skillratio += 400;
+ {
+ int chorusbonus = battle->calc_chorusbonus(sd);
+ skillratio += 300 + 200 * skill_lv;
+ //Chorus bonus dont count the first 2 Minstrel's/Wanderer's and only increases when their's 3 or more. [Rytech]
+ if (chorusbonus >= 1 && chorusbonus <= 5)
+ skillratio += 100<<(chorusbonus-1); // 1->100; 2->200; 3->400; 4->800; 5->1600
+ RE_LVL_DMOD(100);
+ }
break;
case GN_CART_TORNADO:
- // ATK [( Skill Level x 50 ) + ( Cart Weight / ( 150 - Caster Base STR ))] + ( Cart Remodeling Skill Level x 50 )] %
- skillratio += -100 + 50 * skill_lv;
- if( sd && sd->cart_weight)
- skillratio += sd->cart_weight/10 / max(150-status_get_str(src),1) + pc->checkskill(sd, GN_REMODELING_CART) * 50;
+ {
+ int strbonus = st->str; // FIXME Supposed to take only base STR, but current code wont allow that. So well just take STR for now. [Rytech]
+ if ( strbonus > 130 ) // Max base stat limit on official is 130. So well allow no higher then 125 STR here. This limit prevents
+ strbonus = 130; // the division from going any lower then 30 so the server wont divide by 0 if someone has 150 STR.
+ skillratio = 50 * skill_lv + (sd ? sd->cart_weight : battle_config.max_cart_weight) / 10 / (150 - strbonus) + 50 * (sd ? pc->checkskill(sd, GN_REMODELING_CART) : 5);
+ }
break;
case GN_CARTCANNON:
- // ATK [{( Cart Remodeling Skill Level x 50 ) x ( INT / 40 )} + ( Cart Cannon Skill Level x 60 )] %
- skillratio += -100 + 60 * skill_lv;
- if( sd ) skillratio += pc->checkskill(sd, GN_REMODELING_CART) * 50 * (status_get_int(src) / 40);
+ skillratio = 50 * (sd ? pc->checkskill(sd, GN_REMODELING_CART) : 5) * (st->int_ / 40) + 60 * skill_lv;
break;
case GN_SPORE_EXPLOSION:
- skillratio += 200 + 100 * skill_lv;
- break;
+ skillratio = 100 * skill_lv + (200 + st->int_) * status->get_lv(src) / 100;
case GN_CRAZYWEED_ATK:
skillratio += 400 + 100 * skill_lv;
break;
@@ -2417,25 +2434,32 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
if( sd ) {
switch( sd->itemid ) {
case ITEMID_APPLE_BOMB:
- case ITEMID_COCONUT_BOMB:
+ skillratio = st->str + st->dex + 300;
+ break;
case ITEMID_MELON_BOMB:
+ skillratio = st->str + st->dex + 500;
+ break;
+ case ITEMID_COCONUT_BOMB:
case ITEMID_PINEAPPLE_BOMB:
- skillratio += 400; // Unconfirmed
+ case ITEMID_BANANA_BOMB:
+ skillratio = st->str + st->dex + 800;
break;
- case ITEMID_BANANA_BOMB: // 2000%
- skillratio += 1900;
+ case ITEMID_BLACK_LUMP:
+ skillratio = (st->str + st->agi + st->dex) / 3; // Black Lump
+ break;
+ case ITEMID_BLACK_HARD_LUMP:
+ skillratio = (st->str + st->agi + st->dex) / 2; // Hard Black Lump
+ break;
+ case ITEMID_VERY_HARD_LUMP:
+ skillratio = st->str + st->agi + st->dex; // Extremely Hard Black Lump
break;
- case ITEMID_BLACK_LUMP: skillratio -= 75; break; // 25%
- case ITEMID_BLACK_HARD_LUMP: skillratio -= 25; break; // 75%
- case ITEMID_VERY_HARD_LUMP: skillratio += 100; break; // 200%
}
- } else
- skillratio += 300; // Bombs
+ }
break;
case SO_VARETYR_SPEAR://ATK [{( Striking Level x 50 ) + ( Varetyr Spear Skill Level x 50 )} x Caster Base Level / 100 ] %
skillratio += -100 + 50 * skill_lv + ( sd ? pc->checkskill(sd, SO_STRIKING) * 50 : 0 );
if( sc && sc->data[SC_BLAST_OPTION] )
- skillratio += sd ? sd->status.job_level * 5 : 0;
+ skillratio += (sd ? sd->status.job_level * 5 : 0);
break;
// Physical Elemantal Spirits Attack Skills
case EL_CIRCLE_OF_FIRE:
@@ -2510,7 +2534,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
skillratio += sc->data[SC_OVERTHRUST]->val3;
if(sc->data[SC_OVERTHRUSTMAX])
skillratio += sc->data[SC_OVERTHRUSTMAX]->val2;
- if(sc->data[SC_BERSERK] || sc->data[SC_SATURDAY_NIGHT_FEVER])
+ if(sc->data[SC_BERSERK])
#ifndef RENEWAL
skillratio += 100;
#else
@@ -2535,7 +2559,7 @@ int battle_calc_skillratio(int attack_type, struct block_list *src, struct block
*------------------------------------------*/
int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damage *d,int64 damage,uint16 skill_id,uint16 skill_lv) {
struct map_session_data *sd = NULL;
- struct status_change *sc;
+ struct status_change *sc, *tsc;
struct status_change_entry *sce;
int div_ = d->div_, flag = d->flag;
@@ -2545,9 +2569,6 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
return 0;
if( battle_config.ksprotection && mob->ksprotected(src, bl) )
return 0;
- if( map->getcell(bl->m, bl->x, bl->y, CELL_CHKMAELSTROM) && skill->get_type(skill_id) != BF_MISC
- && skill->get_casttype(skill_id) == CAST_GROUND )
- return 0;
if (bl->type == BL_PC) {
sd=(struct map_session_data *)bl;
//Special no damage states
@@ -2564,6 +2585,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
}
sc = status->get_sc(bl);
+ tsc = status->get_sc(src);
if( sc && sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
return 1;
@@ -2608,9 +2630,20 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
if (group) {
d->dmg_lv = ATK_BLOCK;
if(src_skill_id == MH_STEINWAND){
- if (--group->val2<=0)
- skill->del_unitgroup(group,ALC_MARK);
- return 0;
+ if (--group->val2<=0)
+ skill->del_unitgroup(group,ALC_MARK);
+ if( (group->val3 - damage) > 0 )
+ group->val3 -= (int)cap_value(damage, INT_MIN, INT_MAX);
+ else
+ skill->del_unitgroup(group,ALC_MARK);
+ return 0;
+ }
+ if( skill_id == SO_ELEMENTAL_SHIELD ) {
+ if ( ( group->val2 - damage) > 0 ) {
+ group->val2 -= (int)cap_value(damage,INT_MIN,INT_MAX);
+ } else
+ skill->del_unitgroup(group,ALC_MARK);
+ return 0;
}
/**
* in RE, SW possesses a lifetime equal to 3 times the caster's health
@@ -2633,11 +2666,26 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
d->dmg_lv = ATK_BLOCK;
return 0;
}
+ if( sc->data[SC_NEUTRALBARRIER] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG && skill_id != CR_ACIDDEMONSTRATION ) {
+ d->dmg_lv = ATK_BLOCK;
+ return 0;
+ }
+ if( sc->data[SC__MAELSTROM] && (flag&BF_MAGIC) && skill_id && (skill->get_inf(skill_id)&INF_GROUND_SKILL) ) {
+ // {(Maelstrom Skill LevelxAbsorbed Skill Level)+(Caster's Job/5)}/2
+ int sp = (sc->data[SC__MAELSTROM]->val1 * skill_lv + sd->status.job_level / 5) / 2;
+ status->heal(bl, 0, sp, 3);
+ d->dmg_lv = ATK_BLOCK;
+ return 0;
+ }
if( sc->data[SC_WEAPONBLOCKING] && flag&(BF_SHORT|BF_WEAPON) && rnd()%100 < sc->data[SC_WEAPONBLOCKING]->val2 )
{
clif->skill_nodamage(bl,src,GC_WEAPONBLOCKING,1,1);
d->dmg_lv = ATK_BLOCK;
- sc_start2(bl,SC_COMBOATTACK,100,GC_WEAPONBLOCKING,src->id,2000);
+ sc_start2(src,bl,SC_COMBOATTACK,100,GC_WEAPONBLOCKING,src->id,2000);
+ return 0;
+ }
+ if( sc->data[SC_HOVERING] && skill_id && (skill->get_inf(skill_id)&INF_GROUND_SKILL || skill_id == SR_WINDMILL) ) {
+ d->dmg_lv = ATK_BLOCK;
return 0;
}
if( (sce=sc->data[SC_AUTOGUARD]) && flag&BF_WEAPON && !(skill->get_nk(skill_id)&NK_NO_CARDFIX_ATK) && rnd()%100 < sce->val2 )
@@ -2663,7 +2711,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
clif->skill_nodamage(bl, bl, RK_MILLENNIUMSHIELD, 1, 1);
sce->val3 -= (int)cap_value(damage,INT_MIN,INT_MAX); // absorb damage
d->dmg_lv = ATK_BLOCK;
- sc_start(bl,SC_STUN,15,0,skill->get_time2(RK_MILLENNIUMSHIELD,sce->val1)); // There is a chance to be stuned when one shield is broken.
+ sc_start(src,bl,SC_STUN,15,0,skill->get_time2(RK_MILLENNIUMSHIELD,sce->val1)); // There is a chance to be stuned when one shield is broken.
if( sce->val3 <= 0 ) { // Shield Down
sce->val2--;
if( sce->val2 > 0 ) {
@@ -2688,21 +2736,16 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
if (sd && pc_issit(sd)) pc->setstand(sd); //Stand it to dodge.
clif->skill_nodamage(bl,bl,TK_DODGE,1,1);
if (!sc->data[SC_COMBOATTACK])
- sc_start4(bl, SC_COMBOATTACK, 100, TK_JUMPKICK, src->id, 1, 0, 2000);
+ sc_start4(src, bl, SC_COMBOATTACK, 100, TK_JUMPKICK, src->id, 1, 0, 2000);
return 0;
}
- if(sc->data[SC_HERMODE] && flag&BF_MAGIC)
+ if((sc->data[SC_HERMODE] || sc->data[SC_HOVERING]) && flag&BF_MAGIC)
return 0;
if(sc->data[SC_NJ_TATAMIGAESHI] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG)
return 0;
- if( sc->data[SC_NEUTRALBARRIER] && (flag&(BF_MAGIC|BF_LONG)) == (BF_MAGIC|BF_LONG) ) {
- d->dmg_lv = ATK_MISS;
- return 0;
- }
-
if((sce=sc->data[SC_KAUPE]) && rnd()%100 < sce->val2)
{ //Kaupe blocks damage (skill or otherwise) from players, mobs, homuns, mercenaries.
clif->specialeffect(bl, 462, AREA);
@@ -2810,7 +2853,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
(flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
damage -= damage * 20 / 100;
- if(sc->data[SC_FOGWALL] && skill_id != RK_DRAGONBREATH && skill_id != RK_DRAGONBREATH_WATER) {
+ if(sc->data[SC_FOGWALL]) {
if(flag&BF_SKILL) //25% reduction
damage -= damage * 25 / 100;
else if ((flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
@@ -2838,11 +2881,13 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
sce->val3&flag && sce->val4&flag)
damage -= damage * sc->data[SC_ARMOR]->val2 / 100;
+ if( sc->data[SC_ENERGYCOAT] && (skill_id == GN_HELLS_PLANT_ATK ||
#ifdef RENEWAL
- if(sc->data[SC_ENERGYCOAT] && (flag&BF_WEAPON || flag&BF_MAGIC) && skill_id != WS_CARTTERMINATION)
+ ((flag&BF_WEAPON || flag&BF_MAGIC) && skill_id != WS_CARTTERMINATION)
#else
- if(sc->data[SC_ENERGYCOAT] && (flag&BF_WEAPON && skill_id != WS_CARTTERMINATION))
+ (flag&BF_WEAPON && skill_id != WS_CARTTERMINATION)
#endif
+ ) )
{
struct status_data *sstatus = status->get_status_data(bl);
int per = 100*sstatus->sp / sstatus->max_sp -1; //100% should be counted as the 80~99% interval
@@ -2863,6 +2908,9 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
skill->castend_damage_id(bl,src,MH_MAGMA_FLOW,sce->val1,timer->gettick(),0);
}
+ if( sc->data[SC_DARKCROW] && (flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT )
+ damage += damage * sc->data[SC_DARKCROW]->val2 / 100;
+
if( (sce = sc->data[SC_STONEHARDSKIN]) && flag&(BF_SHORT|BF_WEAPON) && damage > 0 ) {
sce->val2 -= (int)cap_value(damage,INT_MIN,INT_MAX);
if( src->type == BL_PC ) {
@@ -2873,7 +2921,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
skill->break_equip(src, EQP_WEAPON, 3000, BCT_SELF);
// 30% chance to reduce monster's ATK by 25% for 10 seconds.
if( src->type == BL_MOB )
- sc_start(src, SC_NOEQUIPWEAPON, 30, 0, skill->get_time2(RK_STONEHARDSKIN, sce->val1));
+ sc_start(bl,src, SC_NOEQUIPWEAPON, 30, 0, skill->get_time2(RK_STONEHARDSKIN, sce->val1));
if( sce->val2 <= 0 )
status_change_end(bl, SC_STONEHARDSKIN, INVALID_TIMER);
}
@@ -2942,7 +2990,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
if (hd) homun->addspiritball(hd, 10); //add a sphere
}
- if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
+ if( sc->data[SC__DEADLYINFECT] && flag&BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * sc->data[SC__DEADLYINFECT]->val1 && !is_boss(src) )
status->change_spread(bl, src); // Deadly infect attacked side
}
@@ -2973,10 +3021,19 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
break;
}
}
- if( sc->data[SC_POISONINGWEAPON] && skill_id != GC_VENOMPRESSURE && (flag&BF_WEAPON) && damage > 0 && rnd()%100 < sc->data[SC_POISONINGWEAPON]->val3 )
- sc_start(bl,sc->data[SC_POISONINGWEAPON]->val2,100,sc->data[SC_POISONINGWEAPON]->val1,skill->get_time2(GC_POISONINGWEAPON, 1));
- if( sc->data[SC__DEADLYINFECT] && damage > 0 && rnd()%100 < 65 + 5 * sc->data[SC__DEADLYINFECT]->val1 )
+ if( tsc->data[SC_POISONINGWEAPON] ) {
+ short rate = 100;
+ struct status_data *tstatus = status->get_status_data(bl);
+ if ( !(flag&BF_SKILL) && (flag&BF_WEAPON) && damage > 0 && rnd()%100 < tsc->data[SC_POISONINGWEAPON]->val3 ) {
+ if ( tsc->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,tsc->data[SC_POISONINGWEAPON]->val2,rate,tsc->data[SC_POISONINGWEAPON]->val1,skill->get_time2(GC_POISONINGWEAPON,1) - (tstatus->vit + tstatus->luk) / 2 * 1000);
+ }
+ }
+ if( sc->data[SC__DEADLYINFECT] && flag&BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * sc->data[SC__DEADLYINFECT]->val1 && !is_boss(src) )
status->change_spread(src, bl);
+ if (sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 && damage > 0)
+ skill->break_equip(bl,EQP_ARMOR,10000,BCT_ENEMY );
if (sc->data[SC_STYLE_CHANGE] && rnd()%2) {
TBL_HOM *hd = BL_CAST(BL_HOM,bl);
if (hd) homun->addspiritball(hd, 10);
@@ -3104,6 +3161,7 @@ int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64
case HW_GRAVITATION:
case NJ_ZENYNAGE:
case KO_MUCHANAGE:
+ case NC_SELFDESTRUCTION:
break;
default:
/* Uncomment if you want god-mode Emperiums at 100 defense. [Kisuka]
@@ -3264,11 +3322,8 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
//Skill Range Criteria
ad.flag |= battle->range_type(src, target, skill_id, skill_lv);
flag.infdef=(tstatus->mode&MD_PLANT?1:0);
- if( target->type == BL_SKILL){
- TBL_SKILL *su = (TBL_SKILL*)target;
- if( su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) )
- flag.infdef = 1;
- }
+ if( !flag.infdef && target->type == BL_SKILL && ((TBL_SKILL*)target)->group->unit_id == UNT_REVERBERATION )
+ flag.infdef = 1; // Reberberation takes 1 damage
switch(skill_id) {
case MG_FIREWALL:
@@ -3317,11 +3372,13 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
case AL_HEAL:
case PR_BENEDICTIO:
case PR_SANCTUARY:
+ ad.damage = skill->calc_heal(src, target, skill_id, skill_lv, false);
+ break;
/**
* Arch Bishop
**/
case AB_HIGHNESSHEAL:
- ad.damage = skill->calc_heal(src, target, skill_id, skill_lv, false);
+ ad.damage = skill->calc_heal(src, target, AL_HEAL, 10, false) * ( 17 + 3 * skill_lv ) / 10;
break;
case PR_ASPERSIO:
ad.damage = 40;
@@ -3336,7 +3393,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
ad.damage = tstatus->hp;
else {
#ifdef RENEWAL
- MATK_ADD(status->get_matk(src, 2));
+ MATK_ADD(status->get_matk(src, 2));
#else
ad.damage = status->get_lv(src) + sstatus->int_ + skill_lv * 10;
#endif
@@ -3350,9 +3407,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
**/
case AB_RENOVATIO:
//Damage calculation from iRO wiki. [Jobbie]
- ad.damage = (int)((15 * status->get_lv(src)) + (1.5 * sstatus->int_));
+ ad.damage = status->get_lv(src) * 10 + sstatus->int_;
break;
- default: {
+ default: {
MATK_ADD( status->get_matk(src, 2) );
if (nk&NK_SPLASHSPLIT) { // Divide MATK in case of multiple targets skill
@@ -3364,14 +3421,14 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
if (sc){
if( sc->data[SC_TELEKINESIS_INTENSE] && s_ele == ELE_GHOST )
- skillratio += sc->data[SC_TELEKINESIS_INTENSE]->val3;
+ ad.damage += sc->data[SC_TELEKINESIS_INTENSE]->val3;
}
switch(skill_id){
case MG_FIREBOLT:
case MG_COLDBOLT:
case MG_LIGHTNINGBOLT:
if ( sc && sc->data[SC_SPELLFIST] && mflag&BF_SHORT ) {
- skillratio += (sc->data[SC_SPELLFIST]->val4 * 100) + (sc->data[SC_SPELLFIST]->val2 * 100) - 100;// val4 = used bolt level, val2 = used spellfist level. [Rytech]
+ skillratio = sc->data[SC_SPELLFIST]->val2 * 50 + sc->data[SC_SPELLFIST]->val4 * 100;// val4 = used bolt level, val2 = used spellfist level. [Rytech]
ad.div_ = 1;// ad mods, to make it work similar to regular hits [Xazax]
ad.flag = BF_WEAPON|BF_SHORT;
ad.type = 0;
@@ -3741,7 +3798,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
case RK_DRAGONBREATH_WATER:
md.damage = ((status_get_hp(src) / 50) + (status_get_max_sp(src) / 4)) * skill_lv;
RE_LVL_MDMOD(150);
- if (sd) md.damage = md.damage * (100 + 5 * (pc->checkskill(sd,RK_DRAGONTRAINING) - 1)) / 100;
+ if (sd) md.damage = md.damage * (95 + 5 * pc->checkskill(sd,RK_DRAGONTRAINING)) / 100;
md.flag |= BF_LONG|BF_WEAPON;
break;
/**
@@ -3763,6 +3820,10 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
md.damage = md.damage * 200 / (skill_id == RA_CLUSTERBOMB?50:100);
break;
+ case WM_SOUND_OF_DESTRUCTION:
+ md.damage = 1000 * skill_lv + sstatus->int_ * (sd ? pc->checkskill(sd,WM_LESSON) : 10);
+ md.damage += md.damage * 10 * battle->calc_chorusbonus(sd) / 100;
+ break;
/**
* Mechanic
**/
@@ -3785,8 +3846,8 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
md.damage = 100 + 200 * skill_lv + sstatus->int_;
break;
case GN_HELLS_PLANT_ATK:
- //[{( Hell Plant Skill Level x Casters Base Level ) x 10 } + {( Casters INT x 7 ) / 2 } x { 18 + ( Casters Job Level / 4 )] x ( 5 / ( 10 - Summon Flora Skill Level ))
- md.damage = ( skill_lv * status->get_lv(src) * 10 ) + ( sstatus->int_ * 7 / 2 ) * ( 18 + (sd?sd->status.job_level:0) / 4 ) * ( 5 / (10 - (sd?pc->checkskill(sd,AM_CANNIBALIZE):0)) );
+ md.damage = skill_lv * status->get_lv(src) * 10 + sstatus->int_ * 7 / 2 * (18 + (sd ? sd->status.job_level : 0) / 4) * (5 / (10 - (sd ? pc->checkskill(sd, AM_CANNIBALIZE) : 0)));
+ md.damage = md.damage*(1000 + tstatus->mdef) / (1000 + tstatus->mdef * 10) - tstatus->mdef2;
break;
case KO_HAPPOKUNAI:
{
@@ -3906,10 +3967,6 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
default:
md.damage = 1;
}
- }else if( target->type == BL_SKILL ){
- TBL_SKILL *su = (TBL_SKILL*)target;
- if( su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) )
- md.damage = 1;
}
if(!(nk&NK_NO_ELEFIX))
@@ -3992,11 +4049,8 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
&& skill_id != HT_FREEZINGTRAP
#endif
?1:0);
- if( target->type == BL_SKILL){
- TBL_SKILL *su = (TBL_SKILL*)target;
- if( su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) )
- flag.infdef = 1;
- }
+ if( !flag.infdef && target->type == BL_SKILL && ((TBL_SKILL*)target)->group->unit_id == UNT_REVERBERATION )
+ flag.infdef = 1; // Reberberation takes 1 damage
//Initial Values
wd.type=0; //Normal attack
@@ -4180,7 +4234,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
else if(sc && sc->data[SC_FEARBREEZE] && sd->weapontype1==W_BOW
&& (i = sd->equip_index[EQI_AMMO]) >= 0 && sd->inventory_data[i] && sd->status.inventory[i].amount > 1){
- int chance = rand()%100;
+ int chance = rnd()%100;
wd.type = 0x08;
switch(sc->data[SC_FEARBREEZE]->val1){
case 5:
@@ -4364,6 +4418,9 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
case GC_VENOMPRESSURE:
hitrate += 10 + 4 * skill_lv;
break;
+ case SC_FATALMENACE:
+ hitrate -= 35 - 5 * skill_lv;
+ break;
case LG_BANISHINGPOINT:
hitrate += 3 * skill_lv;
break;
@@ -4486,16 +4543,14 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
#endif
case CR_SHIELDBOOMERANG:
case PA_SHIELDCHAIN:
- case LG_SHIELDPRESS:
- case LG_EARTHDRIVE:
wd.damage = sstatus->batk;
if (sd) {
+ int damagevalue = 0;
short index = sd->equip_index[EQI_HAND_L];
- if (index >= 0 &&
- sd->inventory_data[index] &&
- sd->inventory_data[index]->type == IT_ARMOR)
- ATK_ADD(sd->inventory_data[index]->weight/10);
+ if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR )
+ damagevalue = sd->inventory_data[index]->weight/10;
+ ATK_ADD(damagevalue);
} else
ATK_ADD(sstatus->rhw.atk2); //Else use Atk2
break;
@@ -4568,14 +4623,15 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
} //End default case
} //End switch(skill_id)
- if( sc && skill_id != PA_SACRIFICE ){
- if( sc->data[SC_UNLIMIT] && wd.flag&BF_LONG )
- ATK_ADD( 50 * sc->data[SC_UNLIMIT]->val1 );
- }
-
- if( tsc && skill_id != PA_SACRIFICE ){
- if( tsc->data[SC_DARKCROW] && wd.flag&BF_SHORT )
- ATK_ADD( 30 * tsc->data[SC_DARKCROW]->val1 );
+ if( sc && skill_id != PA_SACRIFICE && sc->data[SC_UNLIMIT] && (wd.flag&(BF_LONG|BF_MAGIC)) == BF_LONG) {
+ switch(skill_id) {
+ case RA_WUGDASH:
+ case RA_WUGSTRIKE:
+ case RA_WUGBITE:
+ break;
+ default:
+ ATK_ADD( 50 * sc->data[SC_UNLIMIT]->val1 );
+ }
}
if ( sc && !skill_id && sc->data[SC_EXEEDBREAK] ) {
@@ -4654,12 +4710,40 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
case GC_COUNTERSLASH:
ATK_ADD( status_get_agi(src) * 2 + (sd?sd->status.job_level:0) * 4 );
break;
- case SR_TIGERCANNON: // (Tiger Cannon skill level x 240) + (Target Base Level x 40)
+ case RA_WUGDASH:
+ if( sc && sc->data[SC_DANCE_WITH_WUG] )
+ ATK_ADD(2 * sc->data[SC_DANCE_WITH_WUG]->val1 * (2 + battle->calc_chorusbonus(sd)));
+ break;
+ case SR_TIGERCANNON:
ATK_ADD( skill_lv * 240 + status->get_lv(target) * 40 );
if( sc && sc->data[SC_COMBOATTACK]
- && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE ) // (Tiger Cannon skill level x 500) + (Target Base Level x 40)
+ && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE )
ATK_ADD( skill_lv * 500 + status->get_lv(target) * 40 );
break;
+ case RA_WUGSTRIKE:
+ case RA_WUGBITE:
+ if(sd)
+ ATK_ADD(30*pc->checkskill(sd, RA_TOOTHOFWUG));
+ if( sc && sc->data[SC_DANCE_WITH_WUG] )
+ ATK_ADD(2 * sc->data[SC_DANCE_WITH_WUG]->val1 * (2 + battle->calc_chorusbonus(sd)));
+ break;
+ case LG_SHIELDPRESS:
+ if( sd ) {
+ int damagevalue = 0;
+ short index = sd->equip_index[EQI_HAND_L];
+ if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_ARMOR )
+ damagevalue = sstatus->vit * sd->status.inventory[index].refine;
+ ATK_ADD(damagevalue);
+ }
+ break;
+ case SR_GATEOFHELL:
+ ATK_ADD (sstatus->max_hp - status_get_hp(src));
+ if(sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE) {
+ ATK_ADD( (sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status->get_lv(src) );
+ } else {
+ ATK_ADD( (sstatus->sp * (1 + skill_lv * 2 / 10)) + 10 * status->get_lv(src) );
+ }
+ break;
case SR_FALLENEMPIRE:// [(Target Size value + Skill Level - 1) x Caster STR] + [(Target current weight x Caster DEX / 120)]
ATK_ADD( ((tstatus->size+1)*2 + skill_lv - 1) * sstatus->str);
if( tsd && tsd->weight ){
@@ -4688,12 +4772,6 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if( sc->data[SC_TRUESIGHT] )
ATK_ADDRATE(2*sc->data[SC_TRUESIGHT]->val1);
#endif
- if( sc->data[SC_GLOOMYDAY_SK] &&
- ( skill_id == LK_SPIRALPIERCE || skill_id == KN_BRANDISHSPEAR ||
- skill_id == CR_SHIELDBOOMERANG || skill_id == PA_SHIELDCHAIN ||
- skill_id == LG_SHIELDPRESS || skill_id == RK_HUNDREDSPEAR ||
- skill_id == CR_SHIELDCHARGE ) )
- ATK_ADDRATE(sc->data[SC_GLOOMYDAY_SK]->val2);
#ifndef RENEWAL_EDP
if( sc->data[SC_EDP] ){
@@ -4728,10 +4806,6 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
sc->data[SC_SOULLINK]->val2 == SL_CRUSADER)
ATK_ADDRATE(100);
break;
- case NC_AXETORNADO:
- if( (sstatus->rhw.ele) == ELE_WIND || (sstatus->lhw.ele) == ELE_WIND )
- ATK_ADDRATE(50);
- break;
}
if( skill_id ){
uint16 rskill;/* redirect skill id */
@@ -5033,6 +5107,19 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if(!flag.lh && wd.damage2)
wd.damage2=0;
+ if( sc && sc->data[SC_GLOOMYDAY] ) {
+ switch( skill_id ) {
+ case KN_BRANDISHSPEAR:
+ case LK_SPIRALPIERCE:
+ case CR_SHIELDCHARGE:
+ case CR_SHIELDBOOMERANG:
+ case PA_SHIELDCHAIN:
+ case RK_HUNDREDSPEAR:
+ case LG_SHIELDPRESS:
+ wd.damage += wd.damage * sc->data[SC_GLOOMYDAY]->val2 / 100;
+ }
+ }
+
if( sc ) {
//SG_FUSION hp penalty [Komurka]
if (sc->data[SC_FUSION]) {
@@ -5055,14 +5142,6 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
wd.damage += md.damage;
break;
}
- case SR_GATEOFHELL:
- ATK_ADD (sstatus->max_hp - status_get_hp(src));
- if(sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE){
- ATK_ADD ( (sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status->get_lv(src) );
- }else{
- ATK_ADD ( (sstatus->sp * (1 + skill_lv * 2 / 10)) + 10 * status->get_lv(src) );
- }
- break;
}
if( wd.damage + wd.damage2 ) { //There is a total damage value
@@ -5194,30 +5273,31 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
int64 damage = wd->damage + wd->damage2, rdamage = 0, trdamage = 0;
struct map_session_data *sd, *tsd;
struct status_change *sc;
+ struct status_change *ssc;
int64 tick = timer->gettick();
int delay = 50, rdelay = 0;
#ifdef RENEWAL
int max_reflect_damage;
-
+
max_reflect_damage = max(status_get_max_hp(target), status_get_max_hp(target) * status->get_lv(target) / 100);
#endif
-
+
sd = BL_CAST(BL_PC, src);
-
+
tsd = BL_CAST(BL_PC, target);
sc = status->get_sc(target);
-
+
#ifdef RENEWAL
- #define NORMALIZE_RDAMAGE(d) ( trdamage += rdamage = max(1, min(max_reflect_damage, (d))) )
+#define NORMALIZE_RDAMAGE(d) ( trdamage += rdamage = max(1, min(max_reflect_damage, (d))) )
#else
- #define NORMALIZE_RDAMAGE(d) ( trdamage += rdamage = max(1, (d)) )
+#define NORMALIZE_RDAMAGE(d) ( trdamage += rdamage = max(1, (d)) )
#endif
-
+
if( sc && !sc->count )
sc = NULL;
-
+
if( sc ) {
-
+
if( sc->data[SC_CRESCENTELBOW] && !is_boss(src) && rnd()%100 < sc->data[SC_CRESCENTELBOW]->val2 ){
//ATK [{(Target HP / 100) x Skill Level} x Caster Base Level / 125] % + [Received damage x {1 + (Skill Level x 0.2)}]
int ratio = (status_get_hp(src) / 100) * sc->data[SC_CRESCENTELBOW]->val1 * status->get_lv(target) / 125;
@@ -5225,31 +5305,31 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
rdamage = rdamage * ratio / 100 + (damage) * (10 + sc->data[SC_CRESCENTELBOW]->val1 * 20 / 10) / 10;
skill->blown(target, src, skill->get_blewcount(SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1), unit->getdir(src), 0);
clif->skill_damage(target, src, tick, status_get_amotion(src), 0, rdamage,
- 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does
+ 1, SR_CRESCENTELBOW_AUTOSPELL, sc->data[SC_CRESCENTELBOW]->val1, 6); // This is how official does
clif->delay_damage(tick + delay, src, target,status_get_amotion(src)+1000,0, rdamage/10, 1, 0);
status->damage(src, target, status->damage(target, src, rdamage, 0, 0, 1)/10, 0, 0, 1);
status_change_end(target, SC_CRESCENTELBOW, INVALID_TIMER);
/* shouldn't this trigger skill->additional_effect? */
return; // Just put here to minimize redundancy
}
-
+
if( wd->flag & BF_SHORT ) {
if( !is_boss(src) ) {
if( sc->data[SC_DEATHBOUND] && skill_id != WS_CARTTERMINATION ) {
uint8 dir = map->calc_dir(target,src->x,src->y),
- t_dir = unit->getdir(target);
-
+ t_dir = unit->getdir(target);
+
if( !map->check_dir(dir,t_dir) ) {
int64 rd1 = damage * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage.
-
+
trdamage += rdamage = rd1 - (damage = rd1 * 30 / 100); // not normalized as intended.
rdelay = clif->skill_damage(src, target, tick, status_get_amotion(src), status_get_dmotion(src), -3000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1, 6);
skill->blown(target, src, skill->get_blewcount(RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1), unit->getdir(src), 0);
-
+
if( tsd ) /* is this right? rdamage as both left and right? */
battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0);
battle->delay_damage(tick, wd->amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true);
-
+
delay += 100;/* gradual increase so the numbers don't clip in the client */
}
wd->damage = wd->damage + wd->damage2;
@@ -5258,85 +5338,103 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
}
}
}
-
+
if( sc->data[SC_KYOMU] ){
// Nullify reflecting ability of the conditions onwards
return;
}
-
+
}
-
+
if( wd->flag & BF_SHORT ) {
if ( tsd && tsd->bonus.short_weapon_damage_return ) {
NORMALIZE_RDAMAGE(damage * tsd->bonus.short_weapon_damage_return / 100);
rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
-
+
/* is this right? rdamage as both left and right? */
battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0);
battle->delay_damage(tick, wd->amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true);
-
+
delay += 100;/* gradual increase so the numbers don't clip in the client */
}
-
- if( sc && wd->dmg_lv >= ATK_BLOCK ) {/* yes block still applies, somehow gravity thinks it makes sense. */
- if( sc->data[SC_REFLECTSHIELD] && skill_id != WS_CARTTERMINATION ) {
- NORMALIZE_RDAMAGE(damage * sc->data[SC_REFLECTSHIELD]->val2 / 100);
-
+
+ if( wd->dmg_lv >= ATK_BLOCK ) {/* yes block still applies, somehow gravity thinks it makes sense. */
+ if( sc ) {
+ if( sc->data[SC_REFLECTSHIELD] && skill_id != WS_CARTTERMINATION ) {
+ NORMALIZE_RDAMAGE(damage * sc->data[SC_REFLECTSHIELD]->val2 / 100);
+
#ifndef RENEWAL
- rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
+ rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
#else
- rdelay = clif->skill_damage(src, src, tick, delay, status_get_dmotion(src), rdamage, 1, CR_REFLECTSHIELD, 1, 4);
+ rdelay = clif->skill_damage(src, src, tick, delay, status_get_dmotion(src), rdamage, 1, CR_REFLECTSHIELD, 1, 4);
#endif
- /* is this right? rdamage as both left and right? */
- if( tsd )
- battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0);
- battle->delay_damage(tick, wd->amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true);
-
- delay += 100;/* gradual increase so the numbers don't clip in the client */
- }
- if( sc->data[SC_LG_REFLECTDAMAGE] && rand()%100 < (30 + 10*sc->data[SC_LG_REFLECTDAMAGE]->val1) ) {
- bool change = false;
+ /* is this right? rdamage as both left and right? */
+ if( tsd )
+ battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0);
+ battle->delay_damage(tick, wd->amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true);
- NORMALIZE_RDAMAGE(damage * sc->data[SC_LG_REFLECTDAMAGE]->val2 / 100);
-
- trdamage -= rdamage;/* wont count towards total */
-
- if( sd && !sd->state.autocast ) {
- change = true;
- sd->state.autocast = 1;
+ delay += 100;/* gradual increase so the numbers don't clip in the client */
+ }
+ if( sc->data[SC_LG_REFLECTDAMAGE] && rand()%100 < (30 + 10*sc->data[SC_LG_REFLECTDAMAGE]->val1) ) {
+ bool change = false;
+
+ NORMALIZE_RDAMAGE(damage * sc->data[SC_LG_REFLECTDAMAGE]->val2 / 100);
+
+ trdamage -= rdamage;/* wont count towards total */
+
+ if( sd && !sd->state.autocast ) {
+ change = true;
+ sd->state.autocast = 1;
+ }
+
+ map->foreachinshootrange(battle->damage_area,target,skill->get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,delay,wd->dmotion,rdamage,status_get_race(target));
+
+ if( change )
+ sd->state.autocast = 0;
+
+ delay += 150;/* gradual increase so the numbers don't clip in the client */
+
+ if( (--sc->data[SC_LG_REFLECTDAMAGE]->val3) <= 0 )
+ status_change_end(target, SC_LG_REFLECTDAMAGE, INVALID_TIMER);
+ }
+ if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 ){
+ NORMALIZE_RDAMAGE(damage * sc->data[SC_SHIELDSPELL_DEF]->val2 / 100);
+
+ rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
+
+ /* is this right? rdamage as both left and right? */
+ if( tsd )
+ battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0);
+ battle->delay_damage(tick, wd->amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true);
+
+ delay += 100;/* gradual increase so the numbers don't clip in the client */
}
-
- map->foreachinshootrange(battle->damage_area,target,skill->get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,delay,wd->dmotion,rdamage,status_get_race(target));
-
- if( change )
- sd->state.autocast = 0;
-
- delay += 150;/* gradual increase so the numbers don't clip in the client */
}
- if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 ){
- NORMALIZE_RDAMAGE(damage * sc->data[SC_SHIELDSPELL_DEF]->val2 / 100);
-
- rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
+ if( ( ssc = status->get_sc(src) ) ) {
+ if( ssc->data[SC_INSPIRATION] ) {
+ NORMALIZE_RDAMAGE(damage / 100);
+
+ rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
- /* is this right? rdamage as both left and right? */
- if( tsd )
+ /* is this right? rdamage as both left and right? */
battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0);
- battle->delay_damage(tick, wd->amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true);
-
- delay += 100;/* gradual increase so the numbers don't clip in the client */
+ battle->delay_damage(tick, wd->amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true);
+
+ delay += 100;/* gradual increase so the numbers don't clip in the client */
+ }
}
}
} else {/* long */
if ( tsd && tsd->bonus.long_weapon_damage_return ) {
NORMALIZE_RDAMAGE(damage * tsd->bonus.long_weapon_damage_return / 100);
-
+
rdelay = clif->delay_damage(tick+delay,src, src, status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4);
-
+
/* is this right? rdamage as both left and right? */
battle->drain(tsd, src, rdamage, rdamage, status_get_race(src), 0);
battle->delay_damage(tick, wd->amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true);
-
+
delay += 100;/* gradual increase so the numbers don't clip in the client */
}
}
@@ -5345,12 +5443,12 @@ void battle_reflect_damage(struct block_list *target, struct block_list *src, st
// Tell Clang's static analyzer that we want to += it even the value is currently unused (it'd be used if we added new checks)
(void)delay;
#endif // __clang_analyzer
-
+
/* something caused reflect */
if( trdamage ) {
skill->additional_effect(target, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
}
-
+
return;
#undef NORMALIZE_RDAMAGE
}
@@ -5529,11 +5627,11 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
uint16 skill_lv = tsc->data[SC_BLADESTOP_WAIT]->val1;
int duration = skill->get_time2(MO_BLADESTOP,skill_lv);
status_change_end(target, SC_BLADESTOP_WAIT, INVALID_TIMER);
- if(sc_start4(src, SC_BLADESTOP, 100, sd?pc->checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration)) {
+ if(sc_start4(target, src, SC_BLADESTOP, 100, sd?pc->checkskill(sd, MO_BLADESTOP):5, 0, 0, target->id, duration)) {
//Target locked.
clif->damage(src, target, sstatus->amotion, 1, 0, 1, 0, 0); //Display MISS.
clif->bladestop(target, src->id, 1);
- sc_start4(target, SC_BLADESTOP, 100, skill_lv, 0, 0, src->id, duration);
+ sc_start4(target, target, SC_BLADESTOP, 100, skill_lv, 0, 0, src->id, duration);
return ATK_BLOCK;
}
}
@@ -5596,7 +5694,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
}
if( tsc && tsc->data[SC_MTF_MLEATKED] && rnd()%100 < 20 )
clif->skill_nodamage(target, target, SM_ENDURE, 5,
- sc_start(target, SC_ENDURE, 100, 5, skill->get_time(SM_ENDURE, 5)));
+ sc_start(target,target, SC_ENDURE, 100, 5, skill->get_time(SM_ENDURE, 5)));
}
if(tsc && tsc->data[SC_KAAHI] && tsc->data[SC_KAAHI]->val4 == INVALID_TIMER && tstatus->hp < tstatus->max_hp)
@@ -5958,12 +6056,9 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
case MS_MAGNUM:
case RA_DETONATOR:
case RA_SENSITIVEKEEN:
- case GN_CRAZYWEED_ATK:
case RK_STORMBLAST:
- case RK_PHANTOMTHRUST:
case SR_RAMPAGEBLASTER:
case NC_COLDSLOWER:
- case NC_SELFDESTRUCTION:
#ifdef RENEWAL
case KN_BOWLINGBASH:
case KN_SPEARSTAB:
@@ -5985,14 +6080,10 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
strip_enemy = 0;
break;
default:
- if(su->group->skill_id == WM_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD){
- state |= BCT_ENEMY;
- strip_enemy = 0;
- }else
- return 0;
+ return 0;
}
} else if (su->group->skill_id==WZ_ICEWALL ||
- su->group->skill_id == GN_WALLOFTHORN) {
+ su->group->skill_id == GN_WALLOFTHORN) {
state |= BCT_ENEMY;
strip_enemy = 0;
} else //Excepting traps and icewall, you should not be able to target skills.
@@ -6957,6 +7048,7 @@ void battle_defaults(void) {
battle->calc_cardfix = battle_calc_cardfix;
battle->calc_elefix = battle_calc_elefix;
battle->calc_masteryfix = battle_calc_masteryfix;
+ battle->calc_chorusbonus = battle_calc_chorusbonus;
battle->calc_skillratio = battle_calc_skillratio;
battle->calc_sizefix = battle_calc_sizefix;
battle->calc_weapon_damage = battle_calc_weapon_damage;
diff --git a/src/map/battle.h b/src/map/battle.h
index 0fcef7292..b57476cb4 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -540,6 +540,8 @@ struct battle_interface {
int64 (*calc_elefix) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 damage, int nk, int n_ele, int s_ele, int s_ele_, bool left, int flag);
/* applies mastery modifiers */
int64 (*calc_masteryfix) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int64 damage, int div, bool left, bool weapon);
+ /* calculates chorus bonus */
+ int (*calc_chorusbonus) (struct map_session_data *sd);
/* applies skill modifiers */
int (*calc_skillratio) (int attack_type, struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int skillratio, int flag);
/* applies size modifiers */
diff --git a/src/map/chrif.c b/src/map/chrif.c
index c55b241e6..d6f0e5ef8 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -457,7 +457,6 @@ int chrif_reconnect(DBKey key, DBData *data, va_list ap) {
chrif->changemapserver(sd, ip, port);
else //too much lag/timeout is the closest explanation for this error.
clif->authfail_fd(sd->fd, 3);
-
break;
}
}
@@ -1206,7 +1205,7 @@ bool chrif_load_scdata(int fd) {
for (i = 0; i < count; i++) {
data = (struct status_change_data*)RFIFOP(fd,14 + i*sizeof(struct status_change_data));
- status->change_start(&sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 15);
+ status->change_start(NULL, &sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 15);
}
pc->scdata_received(sd);
@@ -1565,7 +1564,7 @@ void chrif_send_report(char* buf, int len) {
**/
void chrif_save_scdata_single(int account_id, int char_id, short type, struct status_change_entry *sce) {
- if( !chrif->fd )
+ if( !chrif->isconnected() )
return;
WFIFOHEAD(chrif->fd, 28);
@@ -1587,7 +1586,7 @@ void chrif_save_scdata_single(int account_id, int char_id, short type, struct st
**/
void chrif_del_scdata_single(int account_id, int char_id, short type) {
- if( !chrif->fd ) {
+ if( !chrif->isconnected() ) {
ShowError("MAYDAY! failed to delete status %d from CID:%d/AID:%d\n",type,char_id,account_id);
return;
}
diff --git a/src/map/clif.c b/src/map/clif.c
index 83a3c37bd..e87276d4f 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -9424,14 +9424,14 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
clif->status_change(&sd->bl, SI_WUGRIDER, 1, 0, 0, 0, 0);
if(sd->status.manner < 0)
- sc_start(&sd->bl,SC_NOCHAT,100,0,0);
+ sc_start(NULL,&sd->bl,SC_NOCHAT,100,0,0);
//Auron reported that This skill only triggers when you logon on the map o.O [Skotlex]
if ((lv = pc->checkskill(sd,SG_KNOWLEDGE)) > 0) {
if(sd->bl.m == sd->feel_map[0].m
|| sd->bl.m == sd->feel_map[1].m
|| sd->bl.m == sd->feel_map[2].m)
- sc_start(&sd->bl, SC_KNOWLEDGE, 100, lv, skill->get_time(SG_KNOWLEDGE, lv));
+ sc_start(NULL,&sd->bl, SC_KNOWLEDGE, 100, lv, skill->get_time(SG_KNOWLEDGE, lv));
}
if(sd->pd && sd->pd->pet.intimate > 900)
@@ -9753,7 +9753,7 @@ void clif_disconnect_ack(struct map_session_data* sd, short result)
void clif_parse_QuitGame(int fd, struct map_session_data *sd)
{
/* Rovert's prevent logout option fixed [Valaris] */
- if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] &&
+ if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC__INVISIBILITY] &&
(!battle_config.prevent_logout || DIFF_TICK(timer->gettick(), sd->canlog_tick) > battle_config.prevent_logout) )
{
set_eof(fd);
@@ -9832,7 +9832,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
if( atcommand->exec(fd, sd, message, true) )
return;
- if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
+ if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
return;
if( battle_config.min_chat_delay ) { //[Skotlex]
@@ -9864,7 +9864,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
sd->state.snovice_call_flag = 3;
break;
case 3:
- sc_start(&sd->bl, status->skill2sc(MO_EXPLOSIONSPIRITS), 100, 17, skill->get_time(MO_EXPLOSIONSPIRITS, 5)); //Lv17-> +50 critical (noted by Poki) [Skotlex]
+ sc_start(NULL,&sd->bl, status->skill2sc(MO_EXPLOSIONSPIRITS), 100, 17, skill->get_time(MO_EXPLOSIONSPIRITS, 5)); //Lv17-> +50 critical (noted by Poki) [Skotlex]
clif->skill_nodamage(&sd->bl, &sd->bl, MO_EXPLOSIONSPIRITS, 5, 1); // prayer always shows successful Lv5 cast and disregards noskill restrictions
sd->state.snovice_call_flag = 0;
break;
@@ -10081,6 +10081,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
(sd->sc.data[SC_TRICKDEAD] ||
sd->sc.data[SC_AUTOCOUNTER] ||
sd->sc.data[SC_BLADESTOP] ||
+ sd->sc.data[SC_DEEP_SLEEP] ||
sd->sc.data[SC__MANHOLE] ||
sd->sc.data[SC_CURSEDCIRCLE_ATKER] ||
sd->sc.data[SC_CURSEDCIRCLE_TARGET] ))
@@ -10102,7 +10103,8 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
if( sd->sc.option&(OPTION_WEDDING|OPTION_XMAS|OPTION_SUMMER|OPTION_HANBOK|OPTION_OKTOBERFEST) )
return;
- if( sd->sc.data[SC_BASILICA] || sd->sc.data[SC__SHADOWFORM] )
+ if( sd->sc.data[SC_BASILICA] || sd->sc.data[SC__SHADOWFORM] ||
+ (sd->sc.data[SC_SIREN] && sd->sc.data[SC_SIREN]->val2 == target_id) )
return;
if (!battle_config.sdelay_attack_enable && pc->checkskill(sd, SA_FREECAST) <= 0) {
@@ -10307,7 +10309,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd) {
break;
case 0x01:
/* Rovert's Prevent logout option - Fixed [Valaris] */
- if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] &&
+ if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC__INVISIBILITY] &&
(!battle_config.prevent_logout || DIFF_TICK(timer->gettick(), sd->canlog_tick) > battle_config.prevent_logout) )
{ //Send to char-server for character selection.
chrif->charselectreq(sd, session[fd]->client_addr);
@@ -10336,7 +10338,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
if ( atcommand->exec(fd, sd, message, true) )
return;
- if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))
+ if (sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))
return;
if (battle_config.min_chat_delay) { //[Skotlex]
@@ -12157,7 +12159,7 @@ void clif_parse_PartyMessage(int fd, struct map_session_data* sd)
if( atcommand->exec(fd, sd, message, true) )
return;
- if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
+ if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
return;
if( battle_config.min_chat_delay )
@@ -13221,7 +13223,7 @@ void clif_parse_GuildMessage(int fd, struct map_session_data* sd)
if( atcommand->exec(fd, sd, message, true) )
return;
- if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
+ if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
return;
if( battle_config.min_chat_delay )
@@ -13675,7 +13677,7 @@ void clif_parse_GMReqNoChat(int fd,struct map_session_data *sd) {
if (dstsd->status.manner < value) {
dstsd->status.manner -= value;
- sc_start(&dstsd->bl,SC_NOCHAT,100,0,0);
+ sc_start(NULL,&dstsd->bl,SC_NOCHAT,100,0,0);
} else {
dstsd->status.manner = 0;
@@ -13904,7 +13906,7 @@ void clif_parse_NoviceExplosionSpirits(int fd, struct map_session_data *sd)
int percent = (int)( ( (float)sd->status.base_exp/(float)next )*1000. );
if( percent && ( percent%100 ) == 0 ) {// 10.0%, 20.0%, ..., 90.0%
- sc_start(&sd->bl, status->skill2sc(MO_EXPLOSIONSPIRITS), 100, 17, skill->get_time(MO_EXPLOSIONSPIRITS, 5)); //Lv17-> +50 critical (noted by Poki) [Skotlex]
+ sc_start(NULL,&sd->bl, status->skill2sc(MO_EXPLOSIONSPIRITS), 100, 17, skill->get_time(MO_EXPLOSIONSPIRITS, 5)); //Lv17-> +50 critical (noted by Poki) [Skotlex]
clif->skill_nodamage(&sd->bl, &sd->bl, MO_EXPLOSIONSPIRITS, 5, 1); // prayer always shows successful Lv5 cast and disregards noskill restrictions
}
}
@@ -16211,7 +16213,7 @@ void clif_parse_BattleChat(int fd, struct map_session_data* sd)
if( atcommand->exec(fd, sd, message, true) )
return;
- if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
+ if( sd->sc.data[SC_BERSERK] || (sd->sc.data[SC_DEEP_SLEEP] && sd->sc.data[SC_DEEP_SLEEP]->val2) || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
return;
if( battle_config.min_chat_delay ) {
diff --git a/src/map/guild.c b/src/map/guild.c
index d13c681bb..7989fb070 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -1360,7 +1360,7 @@ void guild_guildaura_refresh(struct map_session_data *sd, uint16 skill_id, uint1
}
group = skill->unitsetting(&sd->bl,skill_id,skill_lv,sd->bl.x,sd->bl.y,0);
if( group ) {
- sc_start4(&sd->bl,type,100,(battle_config.guild_aura&16)?0:skill_lv,0,0,group->group_id,600000);//duration doesn't matter these status never end with val4
+ sc_start4(NULL,&sd->bl,type,100,(battle_config.guild_aura&16)?0:skill_lv,0,0,group->group_id,600000);//duration doesn't matter these status never end with val4
}
return;
}
diff --git a/src/map/intif.c b/src/map/intif.c
index 49fbe4721..f04ec4015 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -273,7 +273,7 @@ int intif_saveregistry(struct map_session_data *sd) {
int plen = 0;
size_t len;
- if (intif->CheckForCharServer())
+ if (intif->CheckForCharServer() || !sd->var_db)
return -1;
WFIFOHEAD(inter_fd, 60000 + 300);
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index c399a0442..eebcd5d4d 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -70,6 +70,7 @@ enum item_itemid {
ITEMID_PHRACON = 1010,
ITEMID_EMVERETARCON = 1011,
ITEMID_TRAP = 1065,
+ ITEMID_PILEBUNCKER = 1549,
ITEMID_ANGRA_MANYU = 1599,
ITEMID_STRANGE_EMBRYO = 6415,
ITEMID_FACE_PAINT = 6120,
@@ -108,6 +109,9 @@ enum item_itemid {
ITEMID_BULGING_HEAD = 12309,
ITEMID_THICK_MANUAL50 = 12312,
ITEMID_ANCILLA = 12333,
+ ITEMID_REPAIR_A = 12392,
+ ITEMID_REPAIR_B = 12393,
+ ITEMID_REPAIR_C = 12394,
ITEMID_BLACK_THING = 12435,
ITEMID_REINS_OF_MOUNT = 12622,
ITEMID_NOBLE_NAMEPLATE = 12705,
diff --git a/src/map/map.c b/src/map/map.c
index 96595caae..4bc272035 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -2563,8 +2563,6 @@ int map_getcellp(struct map_data* m,int16 x,int16 y,cell_chk cellchk) {
return (cell.novending);
case CELL_CHKNOCHAT:
return (cell.nochat);
- case CELL_CHKMAELSTROM:
- return (cell.maelstrom);
case CELL_CHKICEWALL:
return (cell.icewall);
@@ -2625,7 +2623,6 @@ void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag) {
case CELL_LANDPROTECTOR: map->list[m].cell[j].landprotector = flag; break;
case CELL_NOVENDING: map->list[m].cell[j].novending = flag; break;
case CELL_NOCHAT: map->list[m].cell[j].nochat = flag; break;
- case CELL_MAELSTROM: map->list[m].cell[j].maelstrom = flag; break;
case CELL_ICEWALL: map->list[m].cell[j].icewall = flag; break;
default:
ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell);
diff --git a/src/map/map.h b/src/map/map.h
index a4e9499b3..438027917 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -443,7 +443,6 @@ typedef enum {
CELL_LANDPROTECTOR,
CELL_NOVENDING,
CELL_NOCHAT,
- CELL_MAELSTROM,
CELL_ICEWALL,
} cell_t;
@@ -467,7 +466,6 @@ typedef enum {
CELL_CHKLANDPROTECTOR,
CELL_CHKNOVENDING,
CELL_CHKNOCHAT,
- CELL_CHKMAELSTROM,
CELL_CHKICEWALL,
} cell_chk;
@@ -486,7 +484,6 @@ struct mapcell {
landprotector : 1,
novending : 1,
nochat : 1,
- maelstrom : 1,
icewall : 1;
#ifdef CELL_NOSTACK
diff --git a/src/map/mercenary.c b/src/map/mercenary.c
index 87e7d2f3c..495621014 100644
--- a/src/map/mercenary.c
+++ b/src/map/mercenary.c
@@ -360,7 +360,7 @@ int mercenary_killbonus(struct mercenary_data *md)
const enum sc_type scs[] = { SC_MER_FLEE, SC_MER_ATK, SC_MER_HP, SC_MER_SP, SC_MER_HIT };
int index = rnd() % ARRAYLENGTH(scs);
- sc_start(&md->bl, scs[index], 100, rnd() % 5, 600000);
+ sc_start(NULL,&md->bl, scs[index], 100, rnd() % 5, 600000);
return 0;
}
diff --git a/src/map/mob.c b/src/map/mob.c
index 30658051c..b1fb99859 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -415,7 +415,7 @@ bool mob_ksprotected(struct block_list *src, struct block_list *target) {
return true;
} while(0);
- status->change_start(target, SC_KSPROTECTED, 10000, sd->bl.id, sd->state.noks, sd->status.party_id, sd->status.guild_id, battle_config.ksprotection, 0);
+ status->change_start(NULL, target, SC_KSPROTECTED, 10000, sd->bl.id, sd->state.noks, sd->status.party_id, sd->status.guild_id, battle_config.ksprotection, 0);
return false;
}
@@ -506,7 +506,7 @@ int mob_once_spawn(struct map_session_data* sd, int16 m, int16 x, int16 y, const
if (class_ < 0 && battle_config.dead_branch_active) {
//Behold Aegis's masterful decisions yet again...
//"I understand the "Aggressive" part, but the "Can Move" and "Can Attack" is just stupid" - Poki#3
- sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE|MD_CANATTACK|MD_CANMOVE|MD_ANGRY, 0, 60000);
+ sc_start4(NULL, &md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE|MD_CANATTACK|MD_CANMOVE|MD_ANGRY, 0, 60000);
}
}
@@ -1412,7 +1412,8 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
// Abnormalities
if(( md->sc.opt1 > 0 && md->sc.opt1 != OPT1_STONEWAIT && md->sc.opt1 != OPT1_BURNING && md->sc.opt1 != OPT1_CRYSTALIZE )
- || md->sc.data[SC_BLADESTOP] || md->sc.data[SC__MANHOLE] || md->sc.data[SC_CURSEDCIRCLE_TARGET]) {//Should reset targets.
+ || md->sc.data[SC_DEEP_SLEEP] || md->sc.data[SC_BLADESTOP] || md->sc.data[SC__MANHOLE] || md->sc.data[SC_CURSEDCIRCLE_TARGET]) {
+ //Should reset targets.
md->target_id = md->attacked_id = 0;
return false;
}
@@ -1465,7 +1466,7 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
}
}
else
- if( (abl = map->id2bl(md->attacked_id)) && (!tbl || mob->can_changetarget(md, abl, mode)) ) {
+ if( (abl = map->id2bl(md->attacked_id)) && (!tbl || mob->can_changetarget(md, abl, mode) || (md->sc.count && md->sc.data[SC__CHAOS]))) {
int dist;
if( md->bl.m != abl->m || abl->prev == NULL
|| (dist = distance_bl(&md->bl, abl)) >= MAX_MINCHASE // Attacker longer than visual area
@@ -1528,7 +1529,7 @@ bool mob_ai_sub_hard(struct mob_data *md, int64 tick) {
if ((!tbl && mode&MD_AGGRESSIVE) || md->state.skillstate == MSS_FOLLOW) {
map->foreachinrange (mob->ai_sub_hard_activesearch, &md->bl, view_range, DEFAULT_ENEMY_TYPE(md), md, &tbl, mode);
- } else if (mode&MD_CHANGECHASE && (md->state.skillstate == MSS_RUSH || md->state.skillstate == MSS_FOLLOW)) {
+ } else if ((mode&MD_CHANGECHASE && (md->state.skillstate == MSS_RUSH || md->state.skillstate == MSS_FOLLOW)) || (md->sc.count && md->sc.data[SC__CHAOS])) {
int search_size;
search_size = view_range<md->status.rhw.range ? view_range:md->status.rhw.range;
map->foreachinrange (mob->ai_sub_hard_changechase, &md->bl, search_size, DEFAULT_ENEMY_TYPE(md), md, &tbl);
@@ -2927,17 +2928,17 @@ int mob_summonslave(struct mob_data *md2,int *value,int amount,uint16 skill_id)
switch (battle_config.slaves_inherit_mode) {
case 1: //Always aggressive
if (!(md->status.mode&MD_AGGRESSIVE))
- sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, MD_AGGRESSIVE, 0, 0);
+ sc_start4(NULL, &md->bl, SC_MODECHANGE, 100,1,0, MD_AGGRESSIVE, 0, 0);
break;
case 2: //Always passive
if (md->status.mode&MD_AGGRESSIVE)
- sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, 0, MD_AGGRESSIVE, 0);
+ sc_start4(NULL, &md->bl, SC_MODECHANGE, 100,1,0, 0, MD_AGGRESSIVE, 0);
break;
default: //Copy master.
if (md2->status.mode&MD_AGGRESSIVE)
- sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, MD_AGGRESSIVE, 0, 0);
+ sc_start4(NULL, &md->bl, SC_MODECHANGE, 100,1,0, MD_AGGRESSIVE, 0, 0);
else
- sc_start4(&md->bl, SC_MODECHANGE, 100,1,0, 0, MD_AGGRESSIVE, 0);
+ sc_start4(NULL, &md->bl, SC_MODECHANGE, 100,1,0, 0, MD_AGGRESSIVE, 0);
break;
}
}
diff --git a/src/map/party.c b/src/map/party.c
index 9f144297d..cf5e7bbe3 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -841,7 +841,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id
case TK_COUNTER: //Increase Triple Attack rate of Monks.
if((p_sd->class_&MAPID_UPPERMASK) == MAPID_MONK
&& pc->checkskill(p_sd,MO_TRIPLEATTACK)) {
- sc_start4(&p_sd->bl,SC_SKILLRATE_UP,100,MO_TRIPLEATTACK,
+ sc_start4(&p_sd->bl,&p_sd->bl,SC_SKILLRATE_UP,100,MO_TRIPLEATTACK,
50+50*skill_lv, //+100/150/200% rate
0,0,skill->get_time(SG_FRIEND, 1));
}
@@ -850,7 +850,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id
if((p_sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR
&& sd->sc.data[SC_COUNTERKICK_READY]
&& pc->checkskill(p_sd,SG_FRIEND)) {
- sc_start4(&p_sd->bl,SC_SKILLRATE_UP,100,TK_COUNTER,
+ sc_start4(&p_sd->bl,&p_sd->bl,SC_SKILLRATE_UP,100,TK_COUNTER,
50+50*pc->checkskill(p_sd,SG_FRIEND), //+100/150/200% rate
0,0,skill->get_time(SG_FRIEND, 1));
}
@@ -1108,6 +1108,22 @@ int party_vforeachsamemap(int (*func)(struct block_list*,va_list), struct map_se
return total;
}
+// Special check for Minstrel's and Wanderer's chorus skills.
+int party_sub_count_chorus(struct block_list *bl, va_list ap) {
+ struct map_session_data *sd = (TBL_PC *)bl;
+
+ if (sd->state.autotrade)
+ return 0;
+
+ if (battle_config.idle_no_share && pc_isidle(sd))
+ return 0;
+
+ if ( (sd->class_&MAPID_THIRDMASK) != MAPID_MINSTRELWANDERER )
+ return 0;
+
+ return 1;
+}
+
/**
* Executes 'func' for each party member on the same map and within a 'range' cells area
* @param func Function to execute
@@ -1393,6 +1409,7 @@ void party_defaults(void) {
party->share_loot = party_share_loot;
party->send_dot_remove = party_send_dot_remove;
party->sub_count = party_sub_count;
+ party->sub_count_chorus = party_sub_count_chorus;
party->booking_register = party_booking_register;
party->booking_update = party_booking_update;
party->booking_search = party_booking_search;
diff --git a/src/map/party.h b/src/map/party.h
index 05b5309e6..ed8289af6 100644
--- a/src/map/party.h
+++ b/src/map/party.h
@@ -115,6 +115,7 @@ struct party_interface {
int (*share_loot) (struct party_data* p, struct map_session_data* sd, struct item* item_data, int first_charid);
int (*send_dot_remove) (struct map_session_data *sd);
int (*sub_count) (struct block_list *bl, va_list ap);
+ int (*sub_count_chorus) (struct block_list *bl, va_list ap);
/*==========================================
* Party Booking in KRO [Spiria]
*------------------------------------------*/
diff --git a/src/map/pc.c b/src/map/pc.c
index 3c0fca33a..394a08d75 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -1450,7 +1450,6 @@ int pc_calc_skilltree(struct map_session_data *sd)
case WL_SUMMON_ATK_GROUND:
case LG_OVERBRAND_BRANDISH:
case LG_OVERBRAND_PLUSATK:
- case WM_SEVERE_RAINSTORM_MELEE:
continue;
default:
break;
@@ -1720,9 +1719,9 @@ int pc_updateweightstatus(struct map_session_data *sd)
// start new status change
if( new_overweight == 1 )
- sc_start(&sd->bl, SC_WEIGHTOVER50, 100, 0, 0);
+ sc_start(NULL,&sd->bl, SC_WEIGHTOVER50, 100, 0, 0);
else if( new_overweight == 2 )
- sc_start(&sd->bl, SC_WEIGHTOVER90, 100, 0, 0);
+ sc_start(NULL,&sd->bl, SC_WEIGHTOVER90, 100, 0, 0);
// update overweight status
sd->regen.state.overweight = new_overweight;
@@ -4265,7 +4264,7 @@ int pc_isUseitem(struct map_session_data *sd,int n)
case ITEMID_M_BERSERK_POTION:
if( sd->md == NULL || sd->md->db == NULL )
return 0;
- if (sd->md->sc.data[SC_BERSERK] || sd->md->sc.data[SC_SATURDAY_NIGHT_FEVER])
+ if (sd->md->sc.data[SC_BERSERK])
return 0;
if( nameid == ITEMID_M_AWAKENING_POTION && sd->md->db->lv < 40 )
return 0;
@@ -4389,9 +4388,12 @@ int pc_useitem(struct map_session_data *sd,int n) {
sd->sc.data[SC_TRICKDEAD] ||
sd->sc.data[SC_HIDING] ||
sd->sc.data[SC__SHADOWFORM] ||
+ sd->sc.data[SC__INVISIBILITY] ||
sd->sc.data[SC__MANHOLE] ||
sd->sc.data[SC_KG_KAGEHUMI] ||
sd->sc.data[SC_WHITEIMPRISON] ||
+ sd->sc.data[SC_DEEP_SLEEP] ||
+ sd->sc.data[SC_SATURDAY_NIGHT_FEVER] ||
(sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOITEM)
))
return 0;
@@ -4945,6 +4947,10 @@ int pc_setpos(struct map_session_data* sd, unsigned short map_index, int x, int
status_change_end(&sd->bl, SC_MOON_COMFORT, INVALID_TIMER);
status_change_end(&sd->bl, SC_STAR_COMFORT, INVALID_TIMER);
status_change_end(&sd->bl, SC_MIRACLE, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_NEUTRALBARRIER_MASTER, INVALID_TIMER);//Will later check if this is needed. [Rytech]
+ status_change_end(&sd->bl, SC_NEUTRALBARRIER, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STEALTHFIELD_MASTER, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STEALTHFIELD, INVALID_TIMER);
if (sd->sc.data[SC_KNOWLEDGE]) {
struct status_change_entry *sce = sd->sc.data[SC_KNOWLEDGE];
if (sce->timer != INVALID_TIMER)
@@ -5862,16 +5868,16 @@ int pc_checkbaselevelup(struct map_session_data *sd) {
status_percent_heal(&sd->bl,100,100);
if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE) {
- sc_start(&sd->bl,status->skill2sc(PR_KYRIE),100,1,skill->get_time(PR_KYRIE,1));
- sc_start(&sd->bl,status->skill2sc(PR_IMPOSITIO),100,1,skill->get_time(PR_IMPOSITIO,1));
- sc_start(&sd->bl,status->skill2sc(PR_MAGNIFICAT),100,1,skill->get_time(PR_MAGNIFICAT,1));
- sc_start(&sd->bl,status->skill2sc(PR_GLORIA),100,1,skill->get_time(PR_GLORIA,1));
- sc_start(&sd->bl,status->skill2sc(PR_SUFFRAGIUM),100,1,skill->get_time(PR_SUFFRAGIUM,1));
+ sc_start(NULL,&sd->bl,status->skill2sc(PR_KYRIE),100,1,skill->get_time(PR_KYRIE,1));
+ sc_start(NULL,&sd->bl,status->skill2sc(PR_IMPOSITIO),100,1,skill->get_time(PR_IMPOSITIO,1));
+ sc_start(NULL,&sd->bl,status->skill2sc(PR_MAGNIFICAT),100,1,skill->get_time(PR_MAGNIFICAT,1));
+ sc_start(NULL,&sd->bl,status->skill2sc(PR_GLORIA),100,1,skill->get_time(PR_GLORIA,1));
+ sc_start(NULL,&sd->bl,status->skill2sc(PR_SUFFRAGIUM),100,1,skill->get_time(PR_SUFFRAGIUM,1));
if (sd->state.snovice_dead_flag)
sd->state.snovice_dead_flag = 0; //Reenable steelbody resurrection on dead.
} else if( (sd->class_&MAPID_BASEMASK) == MAPID_TAEKWON ) {
- sc_start(&sd->bl,status->skill2sc(AL_INCAGI),100,10,600000);
- sc_start(&sd->bl,status->skill2sc(AL_BLESSING),100,10,600000);
+ sc_start(NULL,&sd->bl,status->skill2sc(AL_INCAGI),100,10,600000);
+ sc_start(NULL,&sd->bl,status->skill2sc(AL_BLESSING),100,10,600000);
}
clif->misceffect(&sd->bl,0);
npc->script_event(sd, NPCE_BASELVUP); //LORDALFA - LVLUPEVENT
@@ -6953,7 +6959,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
if (battle_config.pk_mode&2) {
ssd->status.manner -= 5;
if(ssd->status.manner < 0)
- sc_start(src,SC_NOCHAT,100,0,0);
+ sc_start(NULL,src,SC_NOCHAT,100,0,0);
#if 0
// PK/Karma system code (not enabled yet) [celest]
// originally from Kade Online, so i don't know if any of these is correct ^^;
@@ -7005,7 +7011,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
clif->resurrection(&sd->bl, 1);
if(battle_config.pc_invincible_time)
pc->setinvincibletimer(sd, battle_config.pc_invincible_time);
- sc_start(&sd->bl,status->skill2sc(MO_STEELBODY),100,1,skill->get_time(MO_STEELBODY,1));
+ sc_start(NULL,&sd->bl,status->skill2sc(MO_STEELBODY),100,1,skill->get_time(MO_STEELBODY,1));
if(map_flag_gvg2(sd->bl.m))
pc->respawn_timer(INVALID_TIMER, timer->gettick(), sd->bl.id, 0);
return 0;
@@ -7549,6 +7555,11 @@ int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp)
sp -= sp * sd->sc.data[SC_CRITICALWOUND]->val2 / 100;
}
+ if( sd->sc.data[SC_VITALITYACTIVATION] ){
+ hp += hp / 2; // 1.5 times
+ sp -= sp / 2;
+ }
+
if ( sd->sc.data[SC_DEATHHURT] ) {
hp -= hp * 20 / 100;
sp -= sp * 20 / 100;
@@ -8017,7 +8028,7 @@ int pc_setcart(struct map_session_data *sd,int type) {
if( !sd->sc.data[SC_PUSH_CART] ) /* first time, so fill cart data */
clif->cartlist(sd);
clif->updatestatus(sd, SP_CARTINFO);
- sc_start(&sd->bl, SC_PUSH_CART, 100, type, 0);
+ sc_start(NULL,&sd->bl, SC_PUSH_CART, 100, type, 0);
clif->sc_load(&sd->bl, sd->bl.id, AREA, SI_ON_PUSH_CART, type, 0, 0);
if( sd->sc.data[SC_PUSH_CART] )/* forcefully update */
sd->sc.data[SC_PUSH_CART]->val1 = type;
@@ -8629,7 +8640,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
return 0;
}
- if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAY_NIGHT_FEVER])
+ if (sd->sc.data[SC_BERSERK])
{
clif->equipitemack(sd,n,0,EIA_FAIL); // fail
return 0;
@@ -8833,7 +8844,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
}
// if player is berserk then cannot unequip
- if (!(flag & 2) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAY_NIGHT_FEVER]))
+ if (!(flag & 2) && sd->sc.count && (sd->sc.data[SC_BERSERK]))
{
clif->unequipitemack(sd,n,0,UIA_FAIL);
return 0;
@@ -9431,9 +9442,9 @@ void pc_overheat(struct map_session_data *sd, int val) {
heat = max(0,heat); // Avoid negative HEAT
if( heat >= limit[skill_lv] )
- sc_start(&sd->bl,SC_OVERHEAT,100,0,1000);
+ sc_start(NULL,&sd->bl,SC_OVERHEAT,100,0,1000);
else
- sc_start(&sd->bl,SC_OVERHEAT_LIMITPOINT,100,heat,30000);
+ sc_start(NULL,&sd->bl,SC_OVERHEAT_LIMITPOINT,100,heat,30000);
return;
}
diff --git a/src/map/script.c b/src/map/script.c
index be346cb92..1dff4c202 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -2609,7 +2609,7 @@ void* get_val2(struct script_state* st, int64 uid, struct DBMap** ref) {
**/
void script_array_ensure_zero(struct script_state *st, struct map_session_data *sd, int64 uid, struct DBMap** ref) {
const char *name = script->get_str(script_getvarid(uid));
- struct DBMap *src = script->array_src(st, sd ? sd : st->rid ? map->id2sd(st->rid) : NULL, name, ref);\
+ struct DBMap *src = script->array_src(st, sd ? sd : st->rid ? map->id2sd(st->rid) : NULL, name, ref);
struct script_array *sa = NULL;
bool insert = false;
@@ -4847,8 +4847,17 @@ BUILDIN(callfunc)
const char* name = reference_getname(data);
if( name[0] == '.' ) {
if( !ref ) {
- ref = (struct DBMap**)aCalloc(sizeof(struct DBMap*), 1);
+ ref = (struct DBMap**)aCalloc(sizeof(struct DBMap*), 2);
ref[0] = (name[1] == '@' ? st->stack->var_function : st->script->script_vars);
+ if( name[1] == '@' ) {
+ if( !st->stack->array_function_db )
+ st->stack->array_function_db = idb_alloc(DB_OPT_BASE);
+ ref[1] = st->stack->array_function_db;
+ } else {
+ if( !st->script->script_arrays_db )
+ st->script->script_arrays_db = idb_alloc(DB_OPT_BASE);
+ ref[1] = st->script->script_arrays_db;
+ }
}
data->ref = ref;
}
@@ -4897,8 +4906,11 @@ BUILDIN(callsub)
const char* name = reference_getname(data);
if( name[0] == '.' && name[1] == '@' ) {
if ( !ref ) {
- ref = (struct DBMap**)aCalloc(sizeof(struct DBMap*), 1);
+ ref = (struct DBMap**)aCalloc(sizeof(struct DBMap*), 2);
ref[0] = st->stack->var_function;
+ if( !st->stack->array_function_db )
+ st->stack->array_function_db = idb_alloc(DB_OPT_BASE);
+ ref[1] = st->stack->array_function_db;
}
data->ref = ref;
}
@@ -4971,12 +4983,16 @@ BUILDIN(return)
const char* name = reference_getname(data);
if( name[0] == '.' && name[1] == '@' )
{// scope variable
- if( !data->ref || data->ref == (DBMap**)&st->stack->var_function )
+ if( !data->ref || data->ref[0] == st->stack->var_function )
script->get_val(st, data);// current scope, convert to value
}
else if( name[0] == '.' && !data->ref )
{// script variable, link to current script
- data->ref = &st->script->script_vars;
+ data->ref = (struct DBMap**)aCalloc(sizeof(struct DBMap*), 2);
+ data->ref[0] = st->script->script_vars;
+ if( !st->script->script_arrays_db )
+ st->script->script_arrays_db = idb_alloc(DB_OPT_BASE);
+ data->ref[1] = st->script->script_arrays_db;
}
}
}
@@ -9868,7 +9884,7 @@ BUILDIN(sc_start) {
}
if( bl )
- status->change_start(bl, type, 10000, val1, 0, 0, val4, tick, 2);
+ status->change_start(NULL, bl, type, 10000, val1, 0, 0, val4, tick, 2);
return true;
}
@@ -9906,7 +9922,7 @@ BUILDIN(sc_start2) {
}
if( bl )
- status->change_start(bl, type, rate, val1, 0, 0, val4, tick, 2);
+ status->change_start(NULL, bl, type, rate, val1, 0, 0, val4, tick, 2);
return true;
}
@@ -9946,7 +9962,7 @@ BUILDIN(sc_start4) {
}
if( bl )
- status->change_start(bl, type, 10000, val1, val2, val3, val4, tick, 2);
+ status->change_start(NULL, bl, type, 10000, val1, val2, val3, val4, tick, 2);
return true;
}
@@ -10013,7 +10029,7 @@ BUILDIN(getscrate) {
bl = map->id2bl(st->rid);
if (bl)
- rate = status->get_sc_def(bl, (sc_type)type, 10000, 10000, 0);
+ rate = status->get_sc_def(bl, bl, (sc_type)type, 10000, 10000, 0);
script_pushint(st,rate);
return true;
@@ -13259,7 +13275,7 @@ BUILDIN(summon)
md->deletetimer = timer->add(tick+(timeout>0?timeout*1000:60000),mob->timer_delete,md->bl.id,0);
mob->spawn (md); //Now it is ready for spawning.
clif->specialeffect(&md->bl,344,AREA);
- sc_start4(&md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000);
+ sc_start4(NULL, &md->bl, SC_MODECHANGE, 100, 1, 0, MD_AGGRESSIVE, 0, 60000);
}
return true;
}
@@ -15812,7 +15828,7 @@ BUILDIN(mercenary_sc_start) {
tick = script_getnum(st,3);
val1 = script_getnum(st,4);
- status->change_start(&sd->md->bl, type, 10000, val1, 0, 0, 0, tick, 2);
+ status->change_start(NULL, &sd->md->bl, type, 10000, val1, 0, 0, 0, tick, 2);
return true;
}
@@ -17044,7 +17060,7 @@ BUILDIN(setmounting) {
if( sd->sc.data[SC_ALL_RIDING] )
status_change_end(&sd->bl, SC_ALL_RIDING, INVALID_TIMER);
else
- sc_start(&sd->bl, SC_ALL_RIDING, 100, 0, -1);
+ sc_start(NULL,&sd->bl, SC_ALL_RIDING, 100, 0, -1);
script_pushint(st,1);//in both cases, return 1.
}
return true;
@@ -17595,8 +17611,8 @@ BUILDIN(montransform) {
sprintf(msg, msg_txt(1485), monster->name); // Traaaansformation-!! %s form!!
clif->ShowScript(&sd->bl, msg);
status_change_end(bl, SC_MONSTER_TRANSFORM, INVALID_TIMER); // Clear previous
- sc_start2(bl, SC_MONSTER_TRANSFORM, 100, mob_id, type, tick);
- sc_start4(bl, type, 100, val1, val2, val3, val4, tick);
+ sc_start2(NULL, bl, SC_MONSTER_TRANSFORM, 100, mob_id, type, tick);
+ sc_start4(NULL, bl, type, 100, val1, val2, val3, val4, tick);
}
return true;
}
diff --git a/src/map/skill.c b/src/map/skill.c
index 2c2ed0d6c..37ee297ca 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -374,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]
@@ -384,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
@@ -426,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)] )
@@ -554,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;
@@ -702,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);
}
}
@@ -720,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);
}
}
}
@@ -756,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]
@@ -773,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));
}
}
@@ -785,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));
}
}
@@ -797,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:
@@ -810,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:
@@ -828,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
@@ -844,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
@@ -859,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:
@@ -886,32 +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));
+ 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;
@@ -921,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:
@@ -929,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:
@@ -961,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;
@@ -976,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:
{
@@ -1009,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;
@@ -1042,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:
@@ -1065,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:
@@ -1082,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;
@@ -1105,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-1], 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;
@@ -1219,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 ITEMID_COCONUT_BOMB:
- 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));
+ 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 ITEMID_MELON_BOMB:
- sc_start(bl, SC_MELON_BOMB, 100, skill_lv, skill->get_time(GN_SLINGITEM, skill_lv)); // Reduces ASPD and moviment speed
+ sc_start(src, bl, SC_MELON_BOMB, 100, skill_lv, 60000); // Reduces ASPD and moviment speed
break;
case ITEMID_BANANA_BOMB:
- 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.
+ 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;
}
@@ -1364,7 +1356,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
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
@@ -1701,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:
@@ -1732,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))
@@ -1937,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.
@@ -2002,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;
@@ -2044,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;
}
@@ -2325,7 +2317,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
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;
@@ -2339,7 +2331,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
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]
@@ -2360,7 +2352,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
} //Switch End
if (combo) { //Possible to chain
if ( (combo = DIFF_TICK32(sd->ud.canact_tick, tick)) < 50 ) combo = 50;/* less is a waste. */
- sc_start2(src,SC_COMBOATTACK,100,skill_id,bl->id,combo);
+ sc_start2(NULL,src,SC_COMBOATTACK,100,skill_id,bl->id,combo);
clif->combo_delay(src, combo);
}
}
@@ -2428,18 +2420,23 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
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:
@@ -2514,6 +2511,9 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
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;
@@ -2594,7 +2594,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
}
// 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;
@@ -2614,7 +2614,7 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
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]);
@@ -2641,11 +2641,6 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
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 ){
@@ -2729,8 +2724,11 @@ int skill_attack(int attack_type, struct block_list* src, struct block_list *dsr
{
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);
}
}
@@ -2815,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:
@@ -2844,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;
@@ -2896,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) {
@@ -3157,20 +3164,20 @@ int skill_timerskill(int tid, int64 tick, int id, intptr_t data) {
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+1));
+ 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:
@@ -3200,6 +3207,9 @@ int skill_timerskill(int tid, int64 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);
}
}
@@ -3211,6 +3221,14 @@ int skill_timerskill(int tid, int64 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);
@@ -3241,11 +3259,6 @@ int skill_timerskill(int tid, int64 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);
- }
// fall through ...
case WL_EARTHSTRAIN:
skill->unitsetting(src,skl->skill_id,skl->skill_lv,skl->x,skl->y,(skl->type<<16)|skl->flag);
@@ -3262,6 +3275,14 @@ int skill_timerskill(int tid, int64 tick, int id, intptr_t data) {
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);
@@ -3330,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_TICK32(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;
@@ -3486,7 +3509,6 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
case NPC_CRITICALWOUND:
case NPC_HELLPOWER:
case RK_SONICWAVE:
- case RK_HUNDREDSPEAR:
case RK_STORMBLAST:
case RK_CRUSHSTRIKE:
case AB_DUPLELIGHT_MELEE:
@@ -3508,6 +3530,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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:
@@ -3522,9 +3545,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
**/
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);
@@ -3660,7 +3681,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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);
@@ -3720,6 +3741,8 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
case WL_JACKFROST:
case RA_ARROWSTORM:
case RA_WUGDASH:
+ case NC_VULCANARM:
+ case NC_ARMSCANNON:
case NC_SELFDESTRUCTION:
case NC_AXETORNADO:
case GC_ROLLINGCUTTER:
@@ -3731,9 +3754,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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:
@@ -3784,8 +3805,10 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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
@@ -3793,7 +3816,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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;
@@ -3911,7 +3934,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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]
@@ -3973,7 +3996,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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;
}
@@ -4006,7 +4029,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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: {
@@ -4052,7 +4075,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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 ) {
@@ -4065,13 +4088,28 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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:
@@ -4155,7 +4193,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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];
@@ -4185,7 +4223,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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
spell_skill_id = sc->data[i]->val1;
spell_skill_lv = sc->data[i]->val2;
@@ -4217,7 +4255,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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(spell_skill_id, spell_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 == spell_skill_id){
cooldown += sd->skillcooldown[i].val;
@@ -4297,8 +4335,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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.
@@ -4310,7 +4347,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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 )
@@ -4333,8 +4370,10 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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);
+ 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 SR_DRAGONCOMBO:
@@ -4360,9 +4399,13 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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);
@@ -4381,6 +4424,39 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
}
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);
@@ -4394,10 +4470,10 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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;
@@ -4467,8 +4543,8 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
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);
}
@@ -4498,7 +4574,7 @@ int skill_castend_damage_id(struct block_list* src, struct block_list *bl, uint1
#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;
@@ -4695,6 +4771,9 @@ int skill_castend_id(int tid, int64 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
@@ -4780,7 +4859,7 @@ int skill_castend_id(int tid, int64 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;
}
}
@@ -4795,8 +4874,11 @@ int skill_castend_id(int tid, int64 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);
@@ -4840,7 +4922,7 @@ int skill_castend_id(int tid, int64 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) {
@@ -4960,6 +5042,42 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
case MH_STEINWAND: {
@@ -4984,7 +5102,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -5018,9 +5136,9 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
{
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))) )
@@ -5042,7 +5160,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -5138,19 +5256,20 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -5163,7 +5282,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -5220,7 +5339,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -5294,7 +5413,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -5319,7 +5438,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
}
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:
@@ -5335,8 +5454,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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
@@ -5355,7 +5474,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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:
@@ -5380,7 +5499,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
}
// 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)
@@ -5394,12 +5513,12 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -5414,16 +5533,16 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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:
@@ -5433,7 +5552,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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));
else if( bl->type == BL_MER )
@@ -5521,6 +5640,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case NC_SHAPESHIFT:
case WL_RECOGNIZEDSPELL:
case GC_VENOMIMPRESS:
+ case SC_INVISIBILITY:
case SC_DEADLYINFECT:
case LG_EXEEDBREAK:
case LG_PRESTIGE:
@@ -5539,7 +5659,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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:
@@ -5548,7 +5668,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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
);
}
@@ -5556,15 +5676,15 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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:
@@ -5574,25 +5694,25 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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:
{
int duration = skill->get_time(skill_id,skill_lv);
- clif->skill_nodamage(bl,bl,skill_id,skill_lv,sc_start(bl,type,100,skill_lv,duration)); // Master
- clif->skill_nodamage(src,src,skill_id,skill_lv,sc_start(src,type,100,skill_lv,duration)); // Homunc
+ 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,
@@ -5604,7 +5724,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
#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));
break;
@@ -5612,7 +5732,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -5632,12 +5752,12 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
}
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;
@@ -5669,7 +5789,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -5687,7 +5807,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
//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,
- (failure = 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))));
+ (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);
@@ -5760,7 +5880,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -5840,7 +5960,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -5942,18 +6062,18 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -5963,7 +6083,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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),
@@ -5992,7 +6112,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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:
@@ -6007,13 +6127,13 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
|| 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:
@@ -6022,7 +6142,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
if( tsce )
failure = status_change_end(bl, type, INVALID_TIMER);
else
- failure = sc_start(bl,type,100,skill_lv,60000);
+ failure = sc_start(src,bl,type,100,skill_lv,60000);
clif->skill_nodamage(src,bl,skill_id,skill_lv,failure);
}
break;
@@ -6039,7 +6159,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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) {
@@ -6047,7 +6167,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -6055,7 +6175,6 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case GC_CLOAKINGEXCEED:
case LG_FORCEOFVANGUARD:
case SC_REPRODUCE:
- case SC_INVISIBILITY:
if (tsce) {
int failure = status_change_end(bl, type, INVALID_TIMER);
if( failure )
@@ -6069,7 +6188,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
case RA_CAMOUFLAGE:
{
- int failure = sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ 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 )
@@ -6099,18 +6218,18 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -6158,7 +6277,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -6210,7 +6329,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
//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);
}
@@ -6576,7 +6695,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
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:
@@ -6628,6 +6747,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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)
@@ -6714,7 +6834,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
}
@@ -6769,7 +6889,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -6804,7 +6924,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -6835,7 +6955,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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:
@@ -6843,7 +6963,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
//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;
@@ -6858,7 +6978,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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 =
@@ -6870,18 +6990,18 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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:
@@ -6913,7 +7033,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -6968,7 +7088,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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],
@@ -6977,21 +7097,21 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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:
@@ -7021,12 +7141,12 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
}
@@ -7035,7 +7155,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -7065,7 +7186,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -7148,7 +7269,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
#endif
@@ -7170,7 +7291,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
//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();
@@ -7264,7 +7385,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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 ){
@@ -7286,7 +7407,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
&& (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;
@@ -7318,7 +7439,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -7334,7 +7455,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
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);
@@ -7350,38 +7471,38 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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,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));
+ 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,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;
@@ -7419,8 +7540,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
//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)) {
@@ -7428,15 +7549,15 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
}
@@ -7444,19 +7565,19 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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,
@@ -7470,7 +7591,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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,
@@ -7556,7 +7677,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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, rate,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;
@@ -7636,7 +7757,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -7646,7 +7767,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
const enum sc_type sc[] = { SC_STUN, SC_SILENCE, SC_CONFUSION, SC_BLOODING };
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;
@@ -7674,13 +7795,13 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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
@@ -7714,7 +7835,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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:
@@ -7730,11 +7851,11 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -7760,9 +7881,9 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
}
@@ -7771,36 +7892,43 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
{
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:
- {
- 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(src,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 ) {
- int members = 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 * members; // 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:
@@ -7840,7 +7968,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
if( type > SC_NONE )
clif->skill_nodamage(bl, bl, skill_id, skill_lv,
- sc_start4(bl, type, 100, skill_lv, value, 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 ){
@@ -7876,7 +8004,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -7885,7 +8013,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -7920,15 +8048,20 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -7937,7 +8070,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
/**
@@ -7957,7 +8090,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
if( sd )
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, level + (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( !level )
clif->skill_fail(sd,skill_id,USESKILL_FAIL,0);
@@ -7968,33 +8101,48 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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) ) {
- int heal = skill->calc_heal(src, bl, AL_HEAL, pc->checkskill(sd, AL_HEAL), true);
-
- if( (dstsd && pc_ismadogear(dstsd)) || status->isimmune(bl))
- heal = 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, heal, 1);
if( tsc && tsc->data[SC_AKAITSUKI] && heal )
heal = ~heal + 1;
- status->heal(bl, heal, 0, 0);
+ 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);
@@ -8016,7 +8164,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -8024,16 +8172,17 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -8093,7 +8242,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
**/
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);
@@ -8109,8 +8258,11 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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]) ){
- int failure = 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));
+ 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);
@@ -8121,18 +8273,22 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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:
@@ -8142,7 +8298,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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 ){
@@ -8163,7 +8319,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
}
}
@@ -8183,7 +8339,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
}
@@ -8193,7 +8349,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
**/
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:
@@ -8226,7 +8382,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -8262,14 +8418,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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:
{
int failure;
- if( (failure = sc_start2(bl,type,100,skill_lv,src->id,skill->get_time(skill_id,skill_lv))) )
+ 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);
@@ -8280,19 +8436,21 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -8310,7 +8468,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
}
@@ -8321,7 +8479,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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 )
@@ -8331,16 +8489,14 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -8351,34 +8507,44 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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:
@@ -8390,114 +8556,96 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -8508,7 +8656,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -8518,7 +8666,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
case LG_KINGS_GRACE:
if( flag&1 ){
int i;
- 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));
for(i=0; i<SC_MAX; i++)
{
if (!tsc->data[i])
@@ -8530,9 +8678,9 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
}
}
@@ -8552,12 +8700,12 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -8572,7 +8720,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -8580,10 +8728,10 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
if( sd ) {
short max = 5 + skill_lv;
int i;
- sc_start(bl, SC_EXPLOSIONSPIRITS, 100, skill_lv, skill->get_time(skill_id, skill_lv));
+ 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;
@@ -8646,41 +8794,32 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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:
@@ -8689,99 +8828,107 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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,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,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: {
@@ -8870,23 +9017,10 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -8903,7 +9037,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
// 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);
@@ -8971,16 +9105,6 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
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 ) {
@@ -8999,7 +9123,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -9013,8 +9137,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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 ) {
@@ -9099,9 +9223,9 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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));
}
}
}
@@ -9129,8 +9253,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
} 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));
}
}
}
@@ -9179,7 +9303,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
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);
}
@@ -9190,10 +9314,10 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
&& 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;
@@ -9209,13 +9333,13 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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));
}
}
}
@@ -9233,7 +9357,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -9242,8 +9366,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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);
@@ -9254,7 +9378,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
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;
@@ -9276,18 +9400,18 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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));
@@ -9303,9 +9427,9 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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;
@@ -9315,9 +9439,9 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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(src, 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));
+ 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));
}
@@ -9331,7 +9455,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
//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;
@@ -9354,7 +9478,7 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
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(&summon_md->bl, SC_MODECHANGE, 100, 1, 0, MD_CANATTACK|MD_AGGRESSIVE, 0, 60000);
+ sc_start4(src,&summon_md->bl, SC_MODECHANGE, 100, 1, 0, MD_CANATTACK|MD_AGGRESSIVE, 0, 60000);
}
}
if (hd)
@@ -9387,7 +9511,8 @@ int skill_castend_nodamage_id(struct block_list *src, struct block_list *bl, uin
}
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();
@@ -9551,6 +9676,14 @@ int skill_castend_pos(int tid, int64 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*);
@@ -9790,6 +9923,13 @@ 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:
@@ -9870,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:
@@ -9898,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.
@@ -9920,14 +10059,14 @@ 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;
@@ -10089,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;
@@ -10123,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;
@@ -10137,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]
@@ -10158,14 +10297,29 @@ 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:
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:
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),
@@ -10226,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;
@@ -10255,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:
@@ -10284,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);
@@ -10301,25 +10456,37 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case WM_DOMINION_IMPULSE:
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);
+ 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;
- int i;
+ int area = skill->get_splash(skill_id, skill_lv);
+ short tmpx = 0, tmpy = 0, x1 = 0, y1 = 0;
- 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);
+ 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);
+
+ 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: {
@@ -10362,7 +10529,7 @@ 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:
@@ -10548,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;
@@ -10600,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;
@@ -10828,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) )
@@ -10840,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;
@@ -10890,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!
)
@@ -10956,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)
@@ -10970,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 )
@@ -11034,13 +11200,14 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
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.
@@ -11052,7 +11219,7 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
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_TICK32(td->tick, tick);
@@ -11067,19 +11234,21 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
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: {
@@ -11115,19 +11284,19 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
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;
@@ -11146,7 +11315,7 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
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:
@@ -11161,7 +11330,7 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
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;
@@ -11173,7 +11342,7 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
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);
}
@@ -11181,7 +11350,7 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
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]
@@ -11207,9 +11376,16 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
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:
@@ -11217,7 +11393,7 @@ int skill_unit_onplace(struct skill_unit *src, struct block_list *bl, int64 tick
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;
@@ -11231,7 +11407,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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;
@@ -11247,10 +11423,15 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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;
@@ -11360,6 +11541,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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 )
@@ -11373,8 +11555,9 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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;
/**
@@ -11392,12 +11575,6 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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);
}
@@ -11421,7 +11598,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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_TICK32(td->tick, tick);
@@ -11451,7 +11628,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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);
@@ -11464,7 +11641,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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;
@@ -11567,46 +11744,46 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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;
}
@@ -11621,28 +11798,28 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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;
}
}
@@ -11658,7 +11835,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
}
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;
@@ -11688,8 +11865,12 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
* 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:
@@ -11704,13 +11885,14 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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]
@@ -11722,7 +11904,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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:
@@ -11735,20 +11917,18 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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_TICK32(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_TICK32(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;
@@ -11756,7 +11936,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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_TICK32(td->tick, tick);
@@ -11777,7 +11957,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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);
@@ -11792,11 +11972,11 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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:
@@ -11808,22 +11988,24 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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;
@@ -11832,7 +12014,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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
@@ -11852,31 +12034,11 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
break;
case UNT_VACUUM_EXTREME:
- {// TODO: official behavior in gvg area. [malufett]
- int sec = sg->limit - DIFF_TICK32(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;
@@ -11892,25 +12054,25 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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:
@@ -11921,7 +12083,7 @@ int skill_unit_onplace_timer(struct skill_unit *src, struct block_list *bl, int6
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;
}
@@ -11947,7 +12109,7 @@ int skill_unit_onout(struct skill_unit *src, struct block_list *bl, int64 tick)
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;
@@ -11957,6 +12119,7 @@ int skill_unit_onout(struct skill_unit *src, struct block_list *bl, int64 tick)
case UNT_EPICLESIS://Arch Bishop
case UNT_NEUTRALBARRIER:
case UNT_STEALTHFIELD:
+ case UNT_WARMER:
if (sce)
status_change_end(bl, type, INVALID_TIMER);
break;
@@ -11970,6 +12133,7 @@ int skill_unit_onout(struct skill_unit *src, struct block_list *bl, int64 tick)
status_change_end(bl, type, INVALID_TIMER);
break;
+ case UNT_THORNS_TRAP:
case UNT_SPIDERWEB:
{
struct block_list *target = map->id2bl(sg->val2);
@@ -12041,6 +12205,7 @@ int skill_unit_onleft(uint16 skill_id, struct block_list *bl, int64 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);
@@ -12150,10 +12315,12 @@ int skill_unit_ondamaged(struct skill_unit *src, struct block_list *bl, int64 da
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;
@@ -12275,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;
@@ -12986,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;
@@ -12997,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;
@@ -13011,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;
@@ -13031,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;
}
@@ -13617,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)
@@ -13735,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) {
@@ -13811,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;
}
@@ -13996,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] )
@@ -14276,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;
}
}
@@ -14491,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;
}
@@ -14699,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];
@@ -14731,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];
}
@@ -14839,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;
@@ -14892,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))) {
@@ -14973,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))
@@ -14999,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:
@@ -15044,33 +15217,6 @@ 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;
-}
-
/*==========================================
*
*------------------------------------------*/
@@ -15194,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++;
@@ -15228,9 +15371,6 @@ 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);
@@ -15289,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));
@@ -15720,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_TICK32(tick,group->tick)+1000;
- su->limit = DIFF_TICK32(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;
}
@@ -15779,13 +15916,8 @@ int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) {
}
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_TICK32(tick,group->tick)+1000;
- su->limit = DIFF_TICK32(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 ) {
@@ -16331,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:
@@ -16776,8 +16908,9 @@ int skill_poisoningweapon( struct map_session_data *sd, int nameid) {
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;
@@ -16865,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;
}
@@ -16881,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;
@@ -16912,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) {
@@ -17604,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:
@@ -18413,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;
@@ -18470,7 +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;
}
diff --git a/src/map/skill.h b/src/map/skill.h
index 78829f17e..13d34d267 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -2006,7 +2006,6 @@ struct skill_interface {
int (*changematerial) (struct map_session_data *sd, int n, unsigned short *item_list);
int (*get_elemental_type) (uint16 skill_id, uint16 skill_lv);
void (*cooldown_save) (struct map_session_data * sd);
- int (*maelstrom_suction) (struct block_list *bl, va_list ap);
int (*get_new_group_id) (void);
bool (*check_shadowform) (struct block_list *bl, int64 damage, int hit);
};
diff --git a/src/map/status.c b/src/map/status.c
index df79cee74..f4991cff2 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -593,21 +593,19 @@ void initChangeTables(void) {
set_sc( NC_INFRAREDSCAN , SC_INFRAREDSCAN , SI_INFRAREDSCAN , SCB_FLEE );
set_sc( NC_ANALYZE , SC_ANALYZE , SI_ANALYZE , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2 );
set_sc( NC_MAGNETICFIELD , SC_MAGNETICFIELD , SI_MAGNETICFIELD , SCB_NONE );
- set_sc( NC_NEUTRALBARRIER , SC_NEUTRALBARRIER , SI_NEUTRALBARRIER , SCB_NONE );
+ set_sc( NC_NEUTRALBARRIER , SC_NEUTRALBARRIER , SI_NEUTRALBARRIER , SCB_DEF|SCB_MDEF );
set_sc( NC_STEALTHFIELD , SC_STEALTHFIELD , SI_STEALTHFIELD , SCB_NONE );
/**
* Royal Guard
**/
set_sc( LG_REFLECTDAMAGE , SC_LG_REFLECTDAMAGE , SI_LG_REFLECTDAMAGE, SCB_NONE );
- set_sc( LG_FORCEOFVANGUARD , SC_FORCEOFVANGUARD , SI_FORCEOFVANGUARD , SCB_MAXHP|SCB_DEF );
+ set_sc( LG_FORCEOFVANGUARD , SC_FORCEOFVANGUARD , SI_FORCEOFVANGUARD , SCB_MAXHP );
set_sc( LG_EXEEDBREAK , SC_EXEEDBREAK , SI_EXEEDBREAK , SCB_NONE );
set_sc( LG_PRESTIGE , SC_PRESTIGE , SI_PRESTIGE , SCB_DEF );
set_sc( LG_BANDING , SC_BANDING , SI_BANDING , SCB_DEF2|SCB_WATK );// Renewal: atk2 & def2
set_sc( LG_PIETY , SC_BENEDICTIO , SI_BENEDICTIO , SCB_DEF_ELE );
set_sc( LG_EARTHDRIVE , SC_EARTHDRIVE , SI_EARTHDRIVE , SCB_DEF|SCB_ASPD );
set_sc( LG_INSPIRATION , SC_INSPIRATION , SI_INSPIRATION , SCB_MAXHP|SCB_WATK|SCB_HIT|SCB_VIT|SCB_AGI|SCB_STR|SCB_DEX|SCB_INT|SCB_LUK);
- set_sc( LG_SHIELDSPELL , SC_SHIELDSPELL_DEF , SI_SHIELDSPELL_DEF , SCB_WATK );
- set_sc( LG_SHIELDSPELL , SC_SHIELDSPELL_REF , SI_SHIELDSPELL_REF , SCB_DEF );
set_sc( LG_KINGS_GRACE , SC_KINGS_GRACE , SI_KINGS_GRACE , SCB_NONE );
/**
* Shadow Chaser
@@ -626,8 +624,10 @@ void initChangeTables(void) {
set_sc( SC_WEAKNESS , SC__WEAKNESS , SI_WEAKNESS , SCB_FLEE2|SCB_MAXHP );
set_sc( SC_STRIPACCESSARY , SC__STRIPACCESSARY , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK );
set_sc_with_vfx( SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE );
- add_sc( SC_CHAOSPANIC , SC_CONFUSION );
- add_sc( SC_BLOODYLUST , SC_BERSERK );
+ add_sc( SC_CHAOSPANIC , SC__CHAOS );
+ add_sc( SC_MAELSTROM , SC__MAELSTROM );
+ add_sc( SC_BLOODYLUST , SC_BERSERK );
+
/**
* Sura
**/
@@ -646,10 +646,10 @@ void initChangeTables(void) {
set_sc( WA_SWING_DANCE , SC_SWING , SI_SWINGDANCE , SCB_SPEED|SCB_ASPD );
set_sc( WA_SYMPHONY_OF_LOVER , SC_SYMPHONY_LOVE , SI_SYMPHONYOFLOVERS , SCB_MDEF );
set_sc( WA_MOONLIT_SERENADE , SC_MOONLIT_SERENADE , SI_MOONLITSERENADE , SCB_MATK );
- set_sc( MI_RUSH_WINDMILL , SC_RUSH_WINDMILL , SI_RUSHWINDMILL , SCB_BATK );
+ set_sc( MI_RUSH_WINDMILL , SC_RUSH_WINDMILL , SI_RUSHWINDMILL , SCB_WATK );
set_sc( MI_ECHOSONG , SC_ECHOSONG , SI_ECHOSONG , SCB_DEF2 );
set_sc( MI_HARMONIZE , SC_HARMONIZE , SI_HARMONIZE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
- set_sc_with_vfx( WM_POEMOFNETHERWORLD , SC_NETHERWORLD , SI_NETHERWORLD , SCB_NONE );
+ set_sc( WM_POEMOFNETHERWORLD , SC_STOP , SI_NETHERWORLD , SCB_NONE );
set_sc_with_vfx( WM_VOICEOFSIREN , SC_SIREN , SI_SIREN , SCB_NONE );
set_sc_with_vfx( WM_LULLABY_DEEPSLEEP , SC_DEEP_SLEEP , SI_DEEPSLEEP , SCB_NONE );
set_sc( WM_SIRCLEOFNATURE , SC_SIRCLEOFNATURE , SI_SIRCLEOFNATURE , SCB_NONE );
@@ -658,8 +658,8 @@ void initChangeTables(void) {
set_sc( WM_DANCE_WITH_WUG , SC_DANCE_WITH_WUG , SI_DANCEWITHWUG , SCB_ASPD );
set_sc( WM_SATURDAY_NIGHT_FEVER , SC_SATURDAY_NIGHT_FEVER , SI_SATURDAYNIGHTFEVER , SCB_BATK|SCB_DEF|SCB_FLEE|SCB_REGEN );
set_sc( WM_LERADS_DEW , SC_LERADS_DEW , SI_LERADSDEW , SCB_MAXHP );
- set_sc( WM_MELODYOFSINK , SC_MELODYOFSINK , SI_MELODYOFSINK , SCB_BATK|SCB_MATK );
- set_sc( WM_BEYOND_OF_WARCRY , SC_BEYOND_OF_WARCRY , SI_WARCRYOFBEYOND , SCB_BATK|SCB_MATK );
+ set_sc( WM_MELODYOFSINK , SC_MELODYOFSINK , SI_MELODYOFSINK , SCB_INT );
+ set_sc( WM_BEYOND_OF_WARCRY , SC_BEYOND_OF_WARCRY , SI_WARCRYOFBEYOND , SCB_STR|SCB_CRI|SCB_MAXHP );
set_sc( WM_UNLIMITED_HUMMING_VOICE, SC_UNLIMITED_HUMMING_VOICE, SI_UNLIMITEDHUMMINGVOICE, SCB_NONE );
set_sc( WM_FRIGG_SONG , SC_FRIGG_SONG , SI_FRIGG_SONG , SCB_MAXHP );
@@ -670,7 +670,7 @@ void initChangeTables(void) {
set_sc( SO_ELECTRICWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE );
set_sc( SO_SPELLFIST , SC_SPELLFIST , SI_SPELLFIST , SCB_NONE );
set_sc_with_vfx( SO_DIAMONDDUST , SC_COLD , SI_COLD , SCB_NONE ); // it does show the snow icon on mobs but doesn't affect it.
- add_sc( SO_CLOUD_KILL , SC_POISON );
+ set_sc( SO_CLOUD_KILL , SC_POISON , SI_CLOUDKILL , SCB_NONE );
set_sc( SO_STRIKING , SC_STRIKING , SI_STRIKING , SCB_WATK|SCB_CRI );
set_sc( SO_WARMER , SC_WARMER , SI_WARMER , SCB_NONE );
set_sc( SO_VACUUM_EXTREME , SC_VACUUM_EXTREME , SI_VACUUM_EXTREME , SCB_NONE );
@@ -679,6 +679,7 @@ void initChangeTables(void) {
set_sc( SO_WATER_INSIGNIA , SC_WATER_INSIGNIA , SI_WATER_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
set_sc( SO_WIND_INSIGNIA , SC_WIND_INSIGNIA , SI_WIND_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
set_sc( SO_EARTH_INSIGNIA , SC_EARTH_INSIGNIA , SI_EARTH_INSIGNIA , SCB_MDEF|SCB_DEF|SCB_MAXHP|SCB_MAXSP|SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
+ add_sc( SO_ELEMENTAL_SHIELD , SC_SAFETYWALL );
/**
* Genetic
**/
@@ -712,8 +713,8 @@ void initChangeTables(void) {
set_sc( EL_BLAST , SC_BLAST_OPTION , SI_BLAST_OPTION , SCB_ASPD );
set_sc( EL_WILD_STORM , SC_WILD_STORM_OPTION , SI_WILD_STORM_OPTION , SCB_ASPD );
set_sc( EL_PETROLOGY , SC_PETROLOGY_OPTION , SI_PETROLOGY_OPTION , SCB_MAXHP );
- set_sc( EL_CURSED_SOIL , SC_CURSED_SOIL_OPTION , SI_CURSED_SOIL_OPTION , SCB_NONE );
- set_sc( EL_UPHEAVAL , SC_UPHEAVAL_OPTION , SI_UPHEAVAL_OPTION , SCB_NONE );
+ set_sc( EL_CURSED_SOIL , SC_CURSED_SOIL_OPTION , SI_CURSED_SOIL_OPTION , SCB_MAXHP );
+ set_sc( EL_UPHEAVAL , SC_UPHEAVAL_OPTION , SI_UPHEAVAL_OPTION , SCB_MAXHP );
set_sc( EL_TIDAL_WEAPON , SC_TIDAL_WEAPON_OPTION , SI_TIDAL_WEAPON_OPTION , SCB_ALL );
set_sc( EL_ROCK_CRUSHER , SC_ROCK_CRUSHER , SI_ROCK_CRUSHER , SCB_DEF );
set_sc( EL_ROCK_CRUSHER_ATK, SC_ROCK_CRUSHER_ATK , SI_ROCK_CRUSHER_ATK , SCB_SPEED );
@@ -854,8 +855,6 @@ void initChangeTables(void) {
status->IconChangeTable[SC_SHIELDSPELL_REF] = SI_SHIELDSPELL_REF;
status->IconChangeTable[SC_BANDING_DEFENCE] = SI_BANDING_DEFENCE;
- status->IconChangeTable[SC_GLOOMYDAY_SK] = SI_GLOOMYDAY;
-
status->IconChangeTable[SC_CURSEDCIRCLE_ATKER] = SI_CURSEDCIRCLE_ATKER;
status->IconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE;
@@ -971,10 +970,17 @@ void initChangeTables(void) {
status->ChangeFlagTable[SC_MER_SP] |= SCB_MAXSP;
status->ChangeFlagTable[SC_MER_HIT] |= SCB_HIT;
// Guillotine Cross Poison Effects
- status->ChangeFlagTable[SC_PARALYSE] |= SCB_ASPD|SCB_FLEE|SCB_SPEED;
- status->ChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN;
+ status->ChangeFlagTable[SC_PARALYSE] |= SCB_FLEE|SCB_SPEED|SCB_ASPD;
status->ChangeFlagTable[SC_VENOMBLEED] |= SCB_MAXHP;
+ status->ChangeFlagTable[SC_MAGICMUSHROOM] |= SCB_REGEN;
+ status->ChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN;
+ status->ChangeFlagTable[SC_PYREXIA] |= SCB_HIT|SCB_FLEE;
status->ChangeFlagTable[SC_OBLIVIONCURSE] |= SCB_REGEN;
+ // RG status
+ status->ChangeFlagTable[SC_SHIELDSPELL_DEF] |= SCB_WATK;
+ status->ChangeFlagTable[SC_SHIELDSPELL_REF] |= SCB_DEF;
+ // Meca status
+ status->ChangeFlagTable[SC_STEALTHFIELD_MASTER] |= SCB_SPEED;
status->ChangeFlagTable[SC_SAVAGE_STEAK] |= SCB_STR;
status->ChangeFlagTable[SC_COCKTAIL_WARG_BLOOD] |= SCB_INT;
@@ -1026,7 +1032,6 @@ void initChangeTables(void) {
status->DisplayType[SC_CURSEDCIRCLE_TARGET]= true;
status->DisplayType[SC_BLOOD_SUCKER] = true;
status->DisplayType[SC__SHADOWFORM] = true;
- status->DisplayType[SC__MANHOLE] = true;
status->DisplayType[SC_MONSTER_TRANSFORM] = true;
status->DisplayType[SC_MOONSTAR] = true;
status->DisplayType[SC_SUPER_STAR] = true;
@@ -1200,8 +1205,6 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp,
status_change_end(target, SC_CLOAKING, INVALID_TIMER);
status_change_end(target, SC_CHASEWALK, INVALID_TIMER);
status_change_end(target, SC_CAMOUFLAGE, INVALID_TIMER);
- status_change_end(target, SC__INVISIBILITY, INVALID_TIMER);
- status_change_end(target, SC_DEEP_SLEEP, INVALID_TIMER);
if ((sce=sc->data[SC_ENDURE]) && !sce->val4 && !sc->data[SC_LKCONCENTRATION]) {
//Endure count is only reduced by non-players on non-gvg maps.
//val4 signals infinite endure. [Skotlex]
@@ -1233,7 +1236,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp,
if (sc->data[SC_AUTOBERSERK] &&
(!sc->data[SC_PROVOKE] || !sc->data[SC_PROVOKE]->val2) &&
st->hp < st->max_hp>>2)
- sc_start4(target,SC_PROVOKE,100,10,1,0,0,0);
+ sc_start4(src,target,SC_PROVOKE,100,10,1,0,0,0);
if (sc->data[SC_BERSERK] && st->hp <= 100)
status_change_end(target, SC_BERSERK, INVALID_TIMER);
if( sc->data[SC_RAISINGDRAGON] && st->hp <= 1000 )
@@ -1309,7 +1312,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp,
status->revive(target, sc->data[SC_KAIZEL]->val2, 0);
status->change_clear(target,0);
clif->skill_nodamage(target,target,ALL_RESURRECTION,1,1);
- sc_start(target,status->skill2sc(PR_KYRIE),100,10,time);
+ sc_start(target,target,status->skill2sc(PR_KYRIE),100,10,time);
if( target->type == BL_MOB )
((TBL_MOB*)target)->state.rebirth = 1;
@@ -1522,6 +1525,41 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per
return 1;
}
+int status_fixed_revive(struct block_list *bl, unsigned int per_hp, unsigned int per_sp) {
+ struct status_data *st;
+ unsigned int hp, sp;
+ if (!status->isdead(bl)) return 0;
+
+ st = status->get_status_data(bl);
+ if (st == &status->dummy)
+ return 0; //Invalid target.
+
+ hp = per_hp;
+ sp = per_sp;
+
+ if(hp > st->max_hp - st->hp)
+ hp = st->max_hp - st->hp;
+ else if (per_hp && !hp)
+ hp = 1;
+
+ if(sp > st->max_sp - st->sp)
+ sp = st->max_sp - st->sp;
+ else if (per_sp && !sp)
+ sp = 1;
+
+ st->hp += hp;
+ st->sp += sp;
+
+ if (bl->prev) //Animation only if character is already on a map.
+ clif->resurrection(bl, 1);
+ switch (bl->type) {
+ case BL_PC: pc->revive((TBL_PC*)bl, hp, sp); break;
+ case BL_MOB: mob->revive((TBL_MOB*)bl, hp); break;
+ case BL_HOM: homun->revive((TBL_HOM*)bl, hp, sp); break;
+ }
+ return 1;
+}
+
/*==========================================
* Checks whether the src can use the skill on the target,
* taking into account status/option of both source/target. [Skotlex]
@@ -1694,7 +1732,6 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
switch(skill_id) {//##TODO## make this a flag in skill_db?
// Skills that can be used even under Man Hole effects.
case SC_SHADOWFORM:
- case SC_STRIPACCESSARY:
break;
default:
return 0;
@@ -1721,8 +1758,13 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
return 0;
}
}
- if (sc->option&OPTION_CHASEWALK && skill_id != ST_CHASEWALK)
- return 0;
+ if ( sc->option&OPTION_CHASEWALK ) {
+ if ( sc->data[SC__INVISIBILITY] ) {
+ if ( skill_id != 0 && skill_id != SC_INVISIBILITY )
+ return 0;
+ } else if ( skill_id != ST_CHASEWALK )
+ return 0;
+ }
if( sc->data[SC_ALL_RIDING] )
return 0;//New mounts can't attack nor use skills in the client; this check makes it cheat-safe [Ind]
}
@@ -1743,6 +1785,8 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
return 0;
if(skill_id == PR_LEXAETERNA && (tsc->data[SC_FREEZE] || (tsc->data[SC_STONE] && tsc->opt1 == OPT1_STONE)))
return 0;
+ if( ( tsc->data[SC_STEALTHFIELD] || tsc->data[SC_CAMOUFLAGE] ) && !(st->mode&(MD_BOSS|MD_DETECTOR)) && flag == 4 )
+ return 0;
}
//If targetting, cloak+hide protect you, otherwise only hiding does.
hide_flag = flag?OPTION_HIDE:(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK);
@@ -1770,7 +1814,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
((sd->special_state.perfect_hiding || !is_detect) ||
(tsc->data[SC_CLOAKINGEXCEED] && is_detect)))
return 0;
- if( tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detect) && !skill_id )
+ if( tsc->data[SC_CAMOUFLAGE] && !(is_boss || is_detect) && (!skill_id || (flag == 0 && src && src->type != BL_PC)) )
return 0;
if( tsc->data[SC_STEALTHFIELD] && !is_boss )
return 0;
@@ -1825,20 +1869,17 @@ int status_check_visibility(struct block_list *src, struct block_list *target) {
if( ( tsc = status->get_sc(target) ) ) {
struct status_data *st = status->get_status_data(src);
-
- if( tsc->data[SC_STEALTHFIELD] )
- return 0;
switch (target->type) { //Check for chase-walk/hiding/cloaking opponents.
case BL_PC:
if ( tsc->data[SC_CLOAKINGEXCEED] && !(st->mode&MD_BOSS) )
return 0;
- if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&MD_BOSS) &&
+ if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC_STEALTHFIELD] || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&MD_BOSS) &&
( ((TBL_PC*)target)->special_state.perfect_hiding || !(st->mode&MD_DETECTOR) ) )
return 0;
break;
default:
- if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC__INVISIBILITY] || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&(MD_BOSS|MD_DETECTOR)) )
+ if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC_CAMOUFLAGE]) && !(st->mode&(MD_BOSS|MD_DETECTOR)) )
return 0;
}
@@ -2074,9 +2115,9 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) {
if (flag&8 && mbl) {
struct status_data *masterstatus = status->get_base_status(mbl);
if ( masterstatus ) {
- if( battle_config.slaves_inherit_speed&(masterstatus->mode&MD_CANMOVE?1:2) )
+ if (battle_config.slaves_inherit_speed&(masterstatus->mode&MD_CANMOVE ? 1 : 2))
mstatus->speed = masterstatus->speed;
- if( mstatus->speed < 2 ) /* minimum for the unit to function properly */
+ if (mstatus->speed < 2) /* minimum for the unit to function properly */
mstatus->speed = 2;
}
}
@@ -2098,6 +2139,8 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) {
mstatus->mode|= MD_CANATTACK|MD_AGGRESSIVE;
}
mstatus->hp = mstatus->max_hp;
+ if( ud->skill_id == NC_SILVERSNIPER )
+ mstatus->rhw.atk = mstatus->rhw.atk2 = 200 * ud->skill_lv;
}
}
@@ -2937,6 +2980,10 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
bstatus->rhw.range += skill_lv;
}
}
+ if( (sd->status.weapon == W_1HAXE || sd->status.weapon == W_2HAXE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0 )
+ bstatus->hit += 3*skill_lv;
+ if((sd->status.weapon == W_MACE || sd->status.weapon == W_2HMACE) && ((skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0))
+ bstatus->hit += 2*skill_lv;
// ----- FLEE CALCULATION -----
@@ -2955,6 +3002,9 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
bstatus->def = cap_value(i, DEFTYPE_MIN, DEFTYPE_MAX);
}
+ if( pc_ismadogear(sd) && (skill_lv = pc->checkskill(sd,NC_MAINFRAME)) > 0 )
+ bstatus->def += 20 + 20 * skill_lv;
+
#ifndef RENEWAL
if (!battle_config.weapon_defense_type && bstatus->def > battle_config.max_def) {
bstatus->def2 += battle_config.over_def_bonus*(bstatus->def -battle_config.max_def);
@@ -3088,6 +3138,17 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) {
sd->subrace[RC_DRAGON]+=skill_lv;
}
+ if( (skill_lv = pc->checkskill(sd, AB_EUCHARISTICA)) > 0 ) {
+ sd->right_weapon.addrace[RC_DEMON] += skill_lv;
+ sd->right_weapon.addele[ELE_DARK] += skill_lv;
+ sd->left_weapon.addrace[RC_DEMON] += skill_lv;
+ sd->left_weapon.addele[ELE_DARK] += skill_lv;
+ sd->magic_addrace[RC_DEMON] += skill_lv;
+ sd->magic_addele[ELE_DARK] += skill_lv;
+ sd->subrace[RC_DEMON] += skill_lv;
+ sd->subele[ELE_DARK] += skill_lv;
+ }
+
if(sc->count) {
if(sc->data[SC_CONCENTRATION]) { //Update the card-bonus data
sc->data[SC_CONCENTRATION]->val3 = sd->param_bonus[1]; //Agi
@@ -3394,7 +3455,7 @@ void status_calc_regen(struct block_list *bl, struct status_data *st, struct reg
if( (skill_lv=pc->checkskill(sd,NJ_NINPOU)) > 0 )
val += skill_lv*3 + skill_lv*st->max_sp/500;
if( (skill_lv=pc->checkskill(sd,WM_LESSON)) > 0 )
- val += 3 + 3 * skill_lv;
+ val += skill_lv*3 + skill_lv*st->max_sp/500;
sregen->sp = cap_value(val, 0, SHRT_MAX);
@@ -3520,7 +3581,12 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
|| (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1)
|| (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1))
regen->rate.hp *= 2;
-
+ if( sc->data[SC_VITALITYACTIVATION] )
+ regen->flag &=~RGN_SP;
+ if(sc->data[SC_EXTRACT_WHITE_POTION_Z])
+ regen->rate.hp += regen->rate.hp * sc->data[SC_EXTRACT_WHITE_POTION_Z]->val1/100;
+ if(sc->data[SC_VITATA_500])
+ regen->rate.sp += regen->rate.sp * sc->data[SC_VITATA_500]->val1/100;
}
/// Recalculates parts of an object's battle status according to the specified flags.
/// @param flag bitfield of values from enum scb_flag
@@ -4085,6 +4151,8 @@ unsigned short status_calc_str(struct block_list *bl, struct status_change *sc,
str -= sc->data[SC_HARMONIZE]->val2;
return (unsigned short)cap_value(str,0,USHRT_MAX);
}
+ if(sc->data[SC_BEYOND_OF_WARCRY])
+ str += sc->data[SC_BEYOND_OF_WARCRY]->val3;
if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && str < 50)
return 50;
if(sc->data[SC_INCALLSTATUS])
@@ -4248,6 +4316,8 @@ unsigned short status_calc_int(struct block_list *bl, struct status_change *sc,
int_ -= sc->data[SC_HARMONIZE]->val2;
return (unsigned short)cap_value(int_,0,USHRT_MAX);
}
+ if(sc->data[SC_MELODYOFSINK])
+ int_ -= sc->data[SC_MELODYOFSINK]->val3;
if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && int_ < 50)
return 50;
if(sc->data[SC_INCALLSTATUS])
@@ -4287,10 +4357,12 @@ unsigned short status_calc_int(struct block_list *bl, struct status_change *sc,
if(sc->data[SC_KYOUGAKU])
int_ -= sc->data[SC_KYOUGAKU]->val2;
- if(sc->data[SC_NOEQUIPHELM])
- int_ -= int_ * sc->data[SC_NOEQUIPHELM]->val2/100;
- if(sc->data[SC__STRIPACCESSARY])
- int_ -= int_ * sc->data[SC__STRIPACCESSARY]->val2 / 100;
+ if(bl->type != BL_PC){
+ if(sc->data[SC_NOEQUIPHELM])
+ int_ -= int_ * sc->data[SC_NOEQUIPHELM]->val2/100;
+ if(sc->data[SC__STRIPACCESSARY])
+ int_ -= int_ * sc->data[SC__STRIPACCESSARY]->val2 / 100;
+ }
if(sc->data[SC_FULL_THROTTLE])
int_ += int_ * 20 / 100;
@@ -4349,7 +4421,7 @@ unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc,
if(sc->data[SC_MARSHOFABYSS])
dex -= dex * sc->data[SC_MARSHOFABYSS]->val2 / 100;
- if(sc->data[SC__STRIPACCESSARY])
+ if(sc->data[SC__STRIPACCESSARY] && bl->type != BL_PC)
dex -= dex * sc->data[SC__STRIPACCESSARY]->val2 / 100;
if(sc->data[SC_FULL_THROTTLE])
dex += dex * 20 / 100;
@@ -4397,7 +4469,7 @@ unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc,
if(sc->data[SC_LAUDARAMUS])
luk += 4 + sc->data[SC_LAUDARAMUS]->val1;
- if(sc->data[SC__STRIPACCESSARY])
+ if(sc->data[SC__STRIPACCESSARY] && bl->type != BL_PC)
luk -= luk * sc->data[SC__STRIPACCESSARY]->val2 / 100;
if(sc->data[SC_BANANA_BOMB])
luk -= luk * sc->data[SC_BANANA_BOMB]->val1 / 100;
@@ -4439,7 +4511,7 @@ unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc,
if(sc->data[SC_FULL_SWING_K])
batk += sc->data[SC_FULL_SWING_K]->val1;
if(sc->data[SC_ODINS_POWER])
- batk += 70;
+ batk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1;
if(sc->data[SC_VOLCANIC_ASH] && (bl->type==BL_MOB)){
if(status_get_element(bl) == ELE_WATER) //water type
batk /= 2;
@@ -4474,14 +4546,8 @@ unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc,
batk += batk * sc->data[SC_HLIF_FLEET]->val3/100;
if(sc->data[SC__ENERVATION])
batk -= batk * sc->data[SC__ENERVATION]->val2 / 100;
- if(sc->data[SC_RUSH_WINDMILL])
- batk += batk * sc->data[SC_RUSH_WINDMILL]->val2/100;
if(sc->data[SC_SATURDAY_NIGHT_FEVER])
batk += 100 * sc->data[SC_SATURDAY_NIGHT_FEVER]->val1;
- if(sc->data[SC_MELODYOFSINK])
- batk -= batk * sc->data[SC_MELODYOFSINK]->val3/100;
- if(sc->data[SC_BEYOND_OF_WARCRY])
- batk += batk * sc->data[SC_BEYOND_OF_WARCRY]->val3/100;
return (unsigned short)cap_value(batk,0,USHRT_MAX);
}
@@ -4552,16 +4618,16 @@ unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc,
watk += watk * sc->data[SC_PROVOKE]->val3/100;
if(sc->data[SC_SKE])
watk += watk * 3;
- if(sc->data[SC__ENERVATION])
- watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
if(sc->data[SC_HLIF_FLEET])
watk += watk * sc->data[SC_HLIF_FLEET]->val3/100;
if(sc->data[SC_CURSE])
watk -= watk * 25/100;
- if(sc->data[SC_NOEQUIPWEAPON])
+ if(sc->data[SC_NOEQUIPWEAPON] && bl->type != BL_PC)
watk -= watk * sc->data[SC_NOEQUIPWEAPON]->val2/100;
if(sc->data[SC__ENERVATION])
watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
+ if(sc->data[SC_RUSH_WINDMILL])
+ watk += sc->data[SC_RUSH_WINDMILL]->val2;
if((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
|| (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2)
|| (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2)
@@ -4590,6 +4656,8 @@ unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc
matk += sc->data[SC_AQUAPLAY_OPTION]->val2;
if(sc->data[SC_CHILLY_AIR_OPTION])
matk += sc->data[SC_CHILLY_AIR_OPTION]->val2;
+ if(sc->data[SC_COOLER_OPTION])
+ matk += sc->data[SC_COOLER_OPTION]->val2;
if(sc->data[SC_WATER_BARRIER])
matk -= sc->data[SC_WATER_BARRIER]->val3;
if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3)
@@ -4625,6 +4693,8 @@ unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc,
matk += sc->data[SC_AQUAPLAY_OPTION]->val2;
if (sc->data[SC_CHILLY_AIR_OPTION])
matk += sc->data[SC_CHILLY_AIR_OPTION]->val2;
+ if(sc->data[SC_COOLER_OPTION])
+ matk += sc->data[SC_COOLER_OPTION]->val2;
if (sc->data[SC_WATER_BARRIER])
matk -= sc->data[SC_WATER_BARRIER]->val3;
if (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3)
@@ -4644,14 +4714,9 @@ unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc,
matk += matk * sc->data[SC_INCMATKRATE]->val1/100;
if (sc->data[SC_MOONLIT_SERENADE])
matk += matk * sc->data[SC_MOONLIT_SERENADE]->val2/100;
- if (sc->data[SC_MELODYOFSINK])
- matk += matk * sc->data[SC_MELODYOFSINK]->val3/100;
if (sc->data[SC_MTF_MATK])
matk += matk * 25 / 100;
- if (sc->data[SC_BEYOND_OF_WARCRY])
- matk -= matk * sc->data[SC_BEYOND_OF_WARCRY]->val3/100;
-
return (unsigned short)cap_value(matk,0,USHRT_MAX);
}
@@ -4683,9 +4748,11 @@ signed short status_calc_critical(struct block_list *bl, struct status_change *s
#endif
if(sc->data[SC__INVISIBILITY])
- critical += critical * sc->data[SC__INVISIBILITY]->val3 / 100;
+ critical += sc->data[SC__INVISIBILITY]->val3;
if(sc->data[SC__UNLUCKY])
critical -= critical * sc->data[SC__UNLUCKY]->val2 / 100;
+ if(sc->data[SC_BEYOND_OF_WARCRY])
+ critical += 10 * sc->data[SC_BEYOND_OF_WARCRY]->val3;
return (short)cap_value(critical,10,SHRT_MAX);
}
@@ -4714,7 +4781,7 @@ signed short status_calc_hit(struct block_list *bl, struct status_change *sc, in
if(sc->data[SC_LKCONCENTRATION])
hit += sc->data[SC_LKCONCENTRATION]->val3;
if(sc->data[SC_INSPIRATION])
- hit += 5 * sc->data[SC_INSPIRATION]->val1;
+ hit += 5 * sc->data[SC_INSPIRATION]->val1 + 25;
if(sc->data[SC_GS_ADJUSTMENT])
hit -= 30;
if(sc->data[SC_GS_ACCURACY])
@@ -4802,19 +4869,19 @@ signed short status_calc_flee(struct block_list *bl, struct status_change *sc, i
if(sc->data[SC_FEAR])
flee -= flee * 20 / 100;
if(sc->data[SC_PARALYSE])
- flee -= flee * 10 / 100; // 10% Flee reduction
+ flee -= flee / 10; // 10% Flee reduction
if(sc->data[SC_INFRAREDSCAN])
flee -= flee * 30 / 100;
if( sc->data[SC__LAZINESS] )
flee -= flee * sc->data[SC__LAZINESS]->val3 / 100;
if( sc->data[SC_GLOOMYDAY] )
- flee -= flee * sc->data[SC_GLOOMYDAY]->val2 / 100;
+ flee -= flee * ( 20 + 5 * sc->data[SC_GLOOMYDAY]->val1 ) / 100;
if( sc->data[SC_SATURDAY_NIGHT_FEVER] )
flee -= flee * (40 + 10 * sc->data[SC_SATURDAY_NIGHT_FEVER]->val1) / 100;
if( sc->data[SC_WIND_STEP_OPTION] )
flee += flee * sc->data[SC_WIND_STEP_OPTION]->val2 / 100;
if( sc->data[SC_ZEPHYR] )
- flee += flee * sc->data[SC_ZEPHYR]->val2 / 100;
+ flee += sc->data[SC_ZEPHYR]->val2;
if(sc->data[SC_VOLCANIC_ASH] && (bl->type==BL_MOB)){ //mob
if(status_get_element(bl) == ELE_WATER) //water type
flee /= 2;
@@ -4899,7 +4966,7 @@ defType status_calc_def(struct block_list *bl, struct status_change *sc, int def
def >>=1;
if(sc->data[SC_PROVOKE] && bl->type != BL_PC) // Provoke doesn't alter player defense->
def -= def * sc->data[SC_PROVOKE]->val4/100;
- if(sc->data[SC_NOEQUIPSHIELD])
+ if(sc->data[SC_NOEQUIPSHIELD] && bl->type != BL_PC)
def -= def * sc->data[SC_NOEQUIPSHIELD]->val2/100;
if (sc->data[SC_FLING])
def -= def * (sc->data[SC_FLING]->val2)/100;
@@ -4909,12 +4976,18 @@ defType status_calc_def(struct block_list *bl, struct status_change *sc, int def
def -= def * (10 + 10 * sc->data[SC_SATURDAY_NIGHT_FEVER]->val1) / 100;
if(sc->data[SC_EARTHDRIVE])
def -= def * 25 / 100;
+ if(sc->data[SC_SOLID_SKIN_OPTION])
+ def += def * sc->data[SC_SOLID_SKIN_OPTION]->val2 / 100;
if( sc->data[SC_ROCK_CRUSHER] )
def -= def * sc->data[SC_ROCK_CRUSHER]->val2 / 100;
if( sc->data[SC_POWER_OF_GAIA] )
def += def * sc->data[SC_POWER_OF_GAIA]->val2 / 100;
+ if( sc->data[SC_NEUTRALBARRIER] )
+ def += def * (5 * sc->data[SC_NEUTRALBARRIER]->val1 + 10) / 100;
+ if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 2 )
+ def += sc->data[SC_SHIELDSPELL_REF]->val2;
if( sc->data[SC_PRESTIGE] )
- def += def * sc->data[SC_PRESTIGE]->val1 / 100;
+ def += sc->data[SC_PRESTIGE]->val1;
if( sc->data[SC_FROSTMISTY] )
def -= def * 10 / 100;
if(sc->data[SC_VOLCANIC_ASH] && (bl->type==BL_MOB)){
@@ -4955,11 +5028,8 @@ signed short status_calc_def2(struct block_list *bl, struct status_change *sc, i
return 0;
if(sc->data[SC_SUN_COMFORT])
def2 += sc->data[SC_SUN_COMFORT]->val2;
- if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 )
- def2 += sc->data[SC_SHIELDSPELL_REF]->val2;
if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
def2 += (5 + sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
-
if(sc->data[SC_ANGELUS])
#ifdef RENEWAL //in renewal only the VIT stat bonus is boosted by angelus
def2 += status_get_vit(bl) / 2 * sc->data[SC_ANGELUS]->val2/100;
@@ -4984,7 +5054,7 @@ signed short status_calc_def2(struct block_list *bl, struct status_change *sc, i
if(sc->data[SC_ANALYZE])
def2 -= def2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
if( sc->data[SC_ECHOSONG] )
- def2 += def2 * sc->data[SC_ECHOSONG]->val2/100;
+ def2 += def2 * sc->data[SC_ECHOSONG]->val3/100;
if(sc->data[SC_VOLCANIC_ASH] && (bl->type==BL_MOB)){
if(status_get_race(bl)==RC_PLANT)
def2 /= 2;
@@ -5040,8 +5110,10 @@ defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int md
mdef += mdef * sc->data[SC_SYMPHONY_LOVE]->val2 / 100;
if(sc->data[SC_GENTLETOUCH_CHANGE] && sc->data[SC_GENTLETOUCH_CHANGE]->val4)
mdef -= mdef * sc->data[SC_GENTLETOUCH_CHANGE]->val4 / 100;
+ if(sc->data[SC_NEUTRALBARRIER] )
+ mdef += mdef * (5 * sc->data[SC_NEUTRALBARRIER]->val1 + 10) / 100;
if (sc->data[SC_ODINS_POWER])
- mdef -= 20 * sc->data[SC_ODINS_POWER]->val1;
+ mdef -= 20;
if(sc->data[SC_BURNING])
mdef -= mdef *25 / 100;
@@ -5095,7 +5167,7 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
if( sd && sd->ud.skilltimer != INVALID_TIMER && (pc->checkskill(sd,SA_FREECAST) > 0 || sd->ud.skill_id == LG_EXEEDBREAK) )
{
if( sd->ud.skill_id == LG_EXEEDBREAK )
- speed_rate = 100 + 60 - (sd->ud.skill_lv * 10);
+ speed_rate = 160 - 10 * sd->ud.skill_lv;
else
speed_rate = 175 - 5 * pc->checkskill(sd,SA_FREECAST);
}
@@ -5144,7 +5216,7 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
if( sc->data[SC_DEC_AGI] )
val = max( val, 25 );
- if( sc->data[SC_QUAGMIRE] || sc->data[SC_HALLUCINATIONWALK_POSTDELAY] || (sc->data[SC_GLOOMYDAY] && sc->data[SC_GLOOMYDAY]->val4) )
+ if( sc->data[SC_QUAGMIRE] || sc->data[SC_HALLUCINATIONWALK_POSTDELAY] )
val = max( val, 50 );
if( sc->data[SC_DONTFORGETME] )
val = max( val, sc->data[SC_DONTFORGETME]->val3 );
@@ -5174,6 +5246,8 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
val = max( val, sc->data[SC_CAMOUFLAGE]->val1 < 3 ? 0 : 25 * (5 - sc->data[SC_CAMOUFLAGE]->val1) );
if( sc->data[SC__GROOMY] )
val = max( val, sc->data[SC__GROOMY]->val2);
+ if( sc->data[SC_GLOOMYDAY] )
+ val = max( val, sc->data[SC_GLOOMYDAY]->val3 ); // Should be 50 (-50% speed)
if( sc->data[SC_STEALTHFIELD_MASTER] )
val = max( val, 30 );
if( sc->data[SC_BANDING_DEFENCE] )
@@ -5226,7 +5300,7 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
if( sc->data[SC_GN_CARTBOOST] )
val = max( val, sc->data[SC_GN_CARTBOOST]->val2 );
if( sc->data[SC_SWING] )
- val = max( val, sc->data[SC_SWING]->val2 );
+ val = max( val, sc->data[SC_SWING]->val3 );
if( sc->data[SC_WIND_STEP_OPTION] )
val = max( val, sc->data[SC_WIND_STEP_OPTION]->val2 );
if( sc->data[SC_FULL_THROTTLE] )
@@ -5335,20 +5409,20 @@ short status_calc_aspd(struct block_list *bl, struct status_change *sc, short fl
if( sc->data[SC_PARALYSE] )
skills2 -= 10;
if( sc->data[SC__BODYPAINT] )
- skills2 -= 2 + 5 * sc->data[SC__BODYPAINT]->val1;
+ skills2 -= sc->data[SC__BODYPAINT]->val1;
if( sc->data[SC__INVISIBILITY] )
skills2 -= sc->data[SC__INVISIBILITY]->val2 ;
if( sc->data[SC__GROOMY] )
skills2 -= sc->data[SC__GROOMY]->val2;
if( sc->data[SC_GLOOMYDAY] )
- skills2 -= sc->data[SC_GLOOMYDAY]->val3;
+ skills2 -= ( 15 + 5 * sc->data[SC_GLOOMYDAY]->val1 );
if( sc->data[SC_EARTHDRIVE] )
skills2 -= 25;
if( sc->data[SC_MELON_BOMB] )
skills2 -= sc->data[SC_MELON_BOMB]->val1;
if( sc->data[SC_SWING] )
- skills2 += sc->data[SC_SWING]->val2;
+ skills2 += sc->data[SC_SWING]->val3;
if( sc->data[SC_DANCE_WITH_WUG] )
skills2 += sc->data[SC_DANCE_WITH_WUG]->val3;
if( sc->data[SC_GENTLETOUCH_CHANGE] )
@@ -5514,17 +5588,17 @@ short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int
if( sc->data[SC_PARALYSE] )
aspd_rate += 100;
if( sc->data[SC__BODYPAINT] )
- aspd_rate += 200 + 50 * sc->data[SC__BODYPAINT]->val1;
+ aspd_rate += 10 * 5 * sc->data[SC__BODYPAINT]->val1;
if( sc->data[SC__INVISIBILITY] )
aspd_rate += sc->data[SC__INVISIBILITY]->val2 * 10 ;
if( sc->data[SC__GROOMY] )
aspd_rate += sc->data[SC__GROOMY]->val2 * 10;
if( sc->data[SC_SWING] )
- aspd_rate -= sc->data[SC_SWING]->val2 * 10;
+ aspd_rate -= sc->data[SC_SWING]->val3 * 10;
if( sc->data[SC_DANCE_WITH_WUG] )
aspd_rate -= sc->data[SC_DANCE_WITH_WUG]->val3 * 10;
if( sc->data[SC_GLOOMYDAY] )
- aspd_rate += sc->data[SC_GLOOMYDAY]->val3 * 10;
+ aspd_rate += ( 15 + 5 * sc->data[SC_GLOOMYDAY]->val1 );
if( sc->data[SC_EARTHDRIVE] )
aspd_rate += 250;
if( sc->data[SC_GENTLETOUCH_CHANGE] )
@@ -5595,11 +5669,13 @@ unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc,
if(sc->data[SC__WEAKNESS])
maxhp -= maxhp * sc->data[SC__WEAKNESS]->val2 / 100;
if(sc->data[SC_LERADS_DEW])
- maxhp += maxhp * sc->data[SC_LERADS_DEW]->val3 / 100;
+ maxhp += sc->data[SC_LERADS_DEW]->val3;
+ if(sc->data[SC_BEYOND_OF_WARCRY])
+ maxhp -= maxhp * sc->data[SC_BEYOND_OF_WARCRY]->val4 / 100;
if(sc->data[SC_FORCEOFVANGUARD])
maxhp += maxhp * 3 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100;
- if(sc->data[SC_INSPIRATION]) //Custom value.
- maxhp += maxhp * 3 * sc->data[SC_INSPIRATION]->val1 / 100;
+ if(sc->data[SC_INSPIRATION])
+ maxhp += maxhp * 5 * sc->data[SC_INSPIRATION]->val1 / 100 + 600 * sc->data[SC_INSPIRATION]->val1;
if(sc->data[SC_RAISINGDRAGON])
maxhp += maxhp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100;
if(sc->data[SC_GENTLETOUCH_CHANGE]) // Max HP decrease: [Skill Level x 4] %
@@ -5612,6 +5688,10 @@ unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc,
maxhp -= sc->data[SC_MYSTERIOUS_POWDER]->val1 / 100;
if(sc->data[SC_PETROLOGY_OPTION])
maxhp += maxhp * sc->data[SC_PETROLOGY_OPTION]->val2 / 100;
+ if(sc->data[SC_CURSED_SOIL_OPTION])
+ maxhp += maxhp * sc->data[SC_CURSED_SOIL_OPTION]->val2 / 100;
+ if(sc->data[SC_UPHEAVAL_OPTION])
+ maxhp += maxhp * sc->data[SC_UPHEAVAL_OPTION]->val3 / 100;
if (sc->data[SC_ANGRIFFS_MODUS])
maxhp += maxhp * 5 * sc->data[SC_ANGRIFFS_MODUS]->val1 /100;
if (sc->data[SC_GOLDENE_FERSE])
@@ -6181,18 +6261,33 @@ void status_change_init(struct block_list *bl) {
//Applies SC defense to a given status change.
//Returns the adjusted duration based on flag values.
//the flag values are the same as in status->change_start.
-int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int tick, int flag) {
+int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, int flag) {
//Percentual resistance: 10000 = 100% Resist
//Example: 50% -> sc_def=5000 -> 25%; 5000ms -> tick_def=5000 -> 2500ms
int sc_def = 0, tick_def = -1; //-1 = use sc_def
//Linear resistance substracted from rate and tick after percentual resistance was applied
//Example: 25% -> sc_def2=2000 -> 5%; 2500ms -> tick_def2=2000 -> 500ms
- int sc_def2 = 0, tick_def2 = -1; //-1 = use sc_def2
+ int sc_def2 = 0, tick_def2 = -1; //-1 = use sc_def2 (pre-re only)
+
struct status_data *st;
struct status_change *sc;
struct map_session_data *sd;
nullpo_ret(bl);
+
+ if(!src)
+ return tick ? tick : 1; // If no source, it can't be resisted (NPC given)
+
+/// Returns the 'bl's level, capped to 'cap'
+#define SCDEF_LVL_CAP(bl, cap) ( (bl) ? (status->get_lv(bl) > (cap) ? (cap) : status->get_lv(bl)) : 0 )
+/// Renewal level modifier.
+/// In renewal, returns the difference between the levels of 'bl' and 'src', both capped to 'maxlv', multiplied by 'factor'
+/// In pre-renewal, returns zero.
+#ifdef RENEWAL
+#define SCDEF_LVL_DIFF(bl, src, maxlv, factor) ( ( SCDEF_LVL_CAP((bl), (maxlv)) - SCDEF_LVL_CAP((src), (maxlv)) ) * (factor) )
+#else
+#define SCDEF_LVL_DIFF(bl, src, maxlv, factor) 0
+#endif
//Status that are blocked by Golden Thief Bug card or Wand of Hermod
if (status->isimmune(bl))
@@ -6234,53 +6329,145 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
sc = status->get_sc(bl);
if( sc && !sc->count )
sc = NULL;
+
+ if (sc && sc->data[SC_KINGS_GRACE]) {
+ // Protects against status effects
+ switch (type) {
+ case SC_POISON:
+ case SC_BLIND:
+ case SC_FREEZE:
+ case SC_STONE:
+ case SC_STUN:
+ case SC_SLEEP:
+ 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_DEEP_SLEEP:
+ case SC_FEAR:
+ case SC_MANDRAGORA:
+ case SC__CHAOS:
+ return 0;
+ }
+ }
+
switch (type) {
case SC_STUN:
+ sc_def = st->vit*100;
+ sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10);
+#ifdef RENEWAL
+ tick_def2 = st->luk*10;
+#endif
+ break;
case SC_POISON:
- if( sc && sc->data[SC__UNLUCKY] )
- return tick;
case SC_DPOISON:
+ sc_def = st->vit*100;
+ sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10);
+#ifdef RENEWAL
+ if (sd) {
+ //For players: 60000 - 450*vit - 100*luk
+ tick_def = st->vit*75;
+ tick_def2 = st->luk*100;
+ } else {
+ //For monsters: 30000 - 200*vit
+ tick>>=1;
+ tick_def = (st->vit*200)/3;
+ }
+#endif
+ break;
case SC_SILENCE:
+#ifdef RENEWAL
+ sc_def = st->int_*100;
+ sc_def2 = (st->vit + st->luk) * 5 + SCDEF_LVL_DIFF(bl, src, 99, 10);
+ tick_def2 = st->luk * 10;
+#else
+ sc_def = st->vit*100;
+ sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10);
+#endif
+ break;
case SC_BLOODING:
+#ifdef RENEWAL
+ sc_def = st->agi*100;
+ tick_def2 = st->luk*10;
+#else
sc_def = st->vit*100;
- sc_def2 = st->luk*10;
+#endif
+ sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10);
break;
case SC_SLEEP:
sc_def = st->int_*100;
- sc_def2 = st->luk*10;
+ sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10);
+#ifdef RENEWAL
+ tick_def2 = st->luk*10;
+#endif
break;
case SC_DEEP_SLEEP:
sc_def = st->int_*50;
- tick_def = st->int_*10 + status->get_lv(bl) * 65 / 10; //Seems to be -1 sec every 10 int and -5% chance every 10 int.
+ tick_def = 0; // Linear reduction instead
+ tick_def2 = st->int_ * 50 + SCDEF_LVL_CAP(bl, 150) * 50; // kRO balance update lists this formula
break;
case SC_DEC_AGI:
- case SC_ADORAMUS: //Arch Bishop
- if (sd) tick>>=1; //Half duration for players.
+ case SC_ADORAMUS:
+ if (sd) tick >>= 1; //Half duration for players.
+ sc_def = st->mdef*100;
+#ifndef RENEWAL
+ sc_def2 = st->luk*10;
+ tick_def2 = 0; //No duration reduction
+#endif
+ tick_def = 0; //No duration reduction
+ break;
case SC_STONE:
- //Impossible to reduce duration with stats
- tick_def = 0;
- tick_def2 = 0;
+ sc_def = st->mdef*100;
+ sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10);
+ tick_def = 0; //No duration reduction
+#ifndef RENEWAL
+ tick_def2 = 0; //No duration reduction
+#endif
+ break;
case SC_FREEZE:
sc_def = st->mdef*100;
- sc_def2 = st->luk*10;
+ sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10);
+ tick_def = 0; //No duration reduction
+#ifdef RENEWAL
+ tick_def2 = status_get_luk(src) * -10; //Caster can increase final duration with luk
+#else
+ tick_def2 = 0; //No duration reduction
+#endif
break;
case SC_CURSE:
- //Special property: inmunity when luk is greater than level or zero
- if (st->luk > status->get_lv(bl) || st->luk == 0)
+ // Special property: immunity when luk is zero
+ if (st->luk == 0)
+ return 0;
+#ifndef RENEWAL
+ // Special property: immunity when luk is greater than level
+ if (st->luk > status->get_lv(bl))
return 0;
+#endif
sc_def = st->luk*100;
- sc_def2 = st->luk*10;
+ sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(NULL, src, 99, 10); // Curse only has a level penalty and no resistance
tick_def = st->vit*100;
+#ifdef RENEWAL
+ tick_def2 = st->luk*10;
+#endif
break;
case SC_BLIND:
- if( sc && sc->data[SC__UNLUCKY] )
- return tick;
sc_def = (st->vit + st->int_)*50;
- sc_def2 = st->luk*10;
+ sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10);
+#ifdef RENEWAL
+ tick_def2 = st->luk*10;
+#endif
break;
case SC_CONFUSION:
sc_def = (st->str + st->int_)*50;
- sc_def2 = st->luk*10;
+ sc_def2 = st->luk*10 + SCDEF_LVL_DIFF(bl, src, 99, 10);
+#ifdef RENEWAL
+ sc_def2 = -sc_def2; // Reversed sc_def2
+ tick_def2 = st->luk*10;
+#endif
break;
case SC_ANKLESNARE:
if(st->mode&MD_BOSS) // Lasts 5 times less on bosses
@@ -6291,7 +6478,7 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
case SC_STONESKIN:
if (sd) //Duration greatly reduced for players.
tick /= 15;
- sc_def2 = status->get_lv(bl)*20 + st->vit*25 + st->agi*10; // Lineal Reduction of Rate
+ sc_def2 = st->vit*25 + st->agi*10 + SCDEF_LVL_CAP(bl, 99) * 20; // Linear Reduction of Rate
tick_def2 = 0; //No duration reduction
break;
case SC_MARSHOFABYSS:
@@ -6302,49 +6489,60 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
//5 second (fixed) + { Stasis Skill level * 5 - (Target's VIT + DEX) / 20 }
tick_def2 = (st->vit + st->dex)*50;
break;
- if( bl->type == BL_PC )
- tick -= (status->get_lv(bl) / 5 + st->vit / 4 + st->agi / 10)*100;
+ case SC_WHITEIMPRISON:
+ if( tick == 5000 ) // 100% on caster
+ break;
+ if (bl->type == BL_PC)
+ tick_def2 = st->vit*25 + st->agi*10 + SCDEF_LVL_CAP(bl, 150) * 20;
else
- tick -= (st->vit + st->luk) / 20 * 1000;
+ tick_def2 = (st->vit + st->luk)*50;
break;
case SC_BURNING:
- tick -= 75 * st->luk + 125 * st->agi;
- tick = max(tick,5000); // Minimum Duration 5s.
+ tick_def2 = 75*st->luk + 125*st->agi;
break;
case SC_FROSTMISTY:
- tick -= 1000 * ((st->vit + st->dex) / 20);
- tick = max(tick,6000); // Minimum Duration 6s.
+ tick_def2 = (st->vit + st->dex)*50;
break;
case SC_OBLIVIONCURSE: // 100% - (100 - 0.8 x INT)
- sc_def = 100 - ( 100 - st->int_* 8 / 10 );
- sc_def = max(sc_def, 5); // minimum of 5%
+ sc_def = st->int_*80;
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_DEATHHURT:
+ case SC_PYREXIA:
+ case SC_LEECHESEND:
+ tick_def2 = (st->vit + st->luk) * 500;
break;
case SC_WUGBITE: // {(Base Success chance) - (Target's AGI / 4)}
- rate -= st->agi*100/4;
- rate = max(rate,5000); // minimum of 50%
+ sc_def2 = st->agi*25;
break;
case SC_ELECTRICSHOCKER:
- if( bl->type == BL_MOB )
- tick -= 1000 * (st->agi/10);
+ tick_def2 = (st->vit + st->agi) * 70;
break;
case SC_COLD:
- tick -= (1000*(st->vit/10))+(status->get_lv(bl)/50);
+ tick_def2 = st->vit*100 + status->get_lv(bl)*20;
+ break;
+ case SC_VACUUM_EXTREME:
+ tick_def2 = st->str*50;
+ break;
+ case SC_MANDRAGORA:
+ sc_def = (st->vit + st->luk)*20;
break;
case SC_SIREN:
- tick -= 1000 * ((status->get_lv(bl) / 10) + ((sd?sd->status.job_level:0) / 5));
- tick = max(tick,10000);
+ tick_def2 = (status->get_lv(bl) * 100) + ((bl->type == BL_PC)?((TBL_PC*)bl)->status.job_level : 0);
break;
case SC_KYOUGAKU:
- tick -= 1000 * status_get_int(bl) / 20;
+ tick_def2 = st->int_ * 50;
break;
case SC_NEEDLE_OF_PARALYZE:
- tick -= 50 * (st->vit + st->luk); //(1000/20);
+ tick_def2 = (st->vit + st->luk) * 50;
break;
default:
//Effect that cannot be reduced? Likely a buff.
if (!(rnd()%10000 < rate))
return 0;
- return tick?tick:1;
+ return tick ? tick : 1;
}
if (sd) {
@@ -6384,11 +6582,16 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
sc_def += sc->data[SC_SIEGFRIED]->val3*100; //Status resistance.
}
- //When no tick def, reduction is the same for both.
- if(tick_def < 0)
+ //When tick def not set, reduction is the same for both.
+ if(tick_def == -1)
tick_def = sc_def;
- if(tick_def2 < 0)
+ if(tick_def2 == -1) {
+#ifdef RENEWAL
+ tick_def2 = 0;
+#else
tick_def2 = sc_def2;
+#endif
+ }
//Natural resistance
if (!(flag&8)) {
@@ -6397,8 +6600,11 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
//Minimum chances
switch (type) {
+ case SC_OBLIVIONCURSE:
+ rate = max(rate,500); //Minimum of 5%
+ break;
case SC_WUGBITE:
- rate = max(rate, 5000); //Minimum of 50%
+ rate = max(rate,5000); //Minimum of 50%
break;
}
@@ -6410,6 +6616,9 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
if( sd->sc.data[SC_TARGET_BLOOD] )
rate -= rate*sd->sc.data[SC_TARGET_BLOOD]->val1/100;
}
+
+ //Aegis accuracy
+ if(rate > 0 && rate%10 != 0) rate += (10 - rate%10);
}
if (!(rnd()%10000 < rate))
@@ -6428,13 +6637,14 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
//Minimum durations
switch (type) {
case SC_ANKLESNARE:
+ case SC_BURNING:
case SC_MARSHOFABYSS:
case SC_STASIS:
+ case SC_DEEP_SLEEP:
tick = max(tick, 5000); //Minimum duration 5s
break;
- case SC_BURNING:
case SC_FROSTMISTY:
- tick = max(tick, 10000); //Minimum duration 10s
+ tick = max(tick, 6000);
break;
default:
//Skills need to trigger even if the duration is reduced below 1ms
@@ -6443,6 +6653,8 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
}
return tick;
+#undef SCDEF_LVL_CAP
+#undef SCDEF_LVL_DIFF
}
/* [Ind/Hercules] fast-checkin sc-display array */
void status_display_add(struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3) {
@@ -6514,7 +6726,7 @@ void status_display_remove(struct map_session_data *sd, enum sc_type type) {
* &4: sc_data loaded, no value has to be altered.
* &8: rate should not be reduced
*------------------------------------------*/
-int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag) {
+int status_change_start(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag) {
struct map_session_data *sd = NULL;
struct status_change* sc;
struct status_change_entry* sce;
@@ -6549,12 +6761,20 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX) // Confirmed.
return 0; // Immune to status ailements
switch( type ) {
- case SC_QUAGMIRE://Tester said it protects against this and decrease agi.
- case SC_DEC_AGI:
+ case SC_DEEP_SLEEP:
+ case SC__CHAOS:
case SC_BURNING:
+ case SC_STUN:
+ case SC_SLEEP:
+ case SC_CURSE:
+ case SC_STONE:
+ case SC_POISON:
+ case SC_BLIND:
+ case SC_SILENCE:
+ case SC_BLOODING:
+ case SC_FREEZE:
case SC_FROSTMISTY:
- //case SC_WHITEIMPRISON://Need confirm. Protected against this in the past. [Rytech]
- case SC_MARSHOFABYSS:
+ case SC_COLD:
case SC_TOXIN:
case SC_PARALYSE:
case SC_VENOMBLEED:
@@ -6562,9 +6782,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_DEATHHURT:
case SC_PYREXIA:
case SC_OBLIVIONCURSE:
- case SC_LEECHESEND:
- case SC_COLD: ////08/31/2011 - Class Balance Changes
- case SC_DEEP_SLEEP:
+ case SC_MARSHOFABYSS:
case SC_MANDRAGORA:
return 0;
}
@@ -6572,22 +6790,37 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX )
return 0; // Immune to status ailements
switch( type ) {
- case SC_DEEP_SLEEP:
- case SC_SATURDAY_NIGHT_FEVER:
- case SC_PYREXIA:
- case SC_DEATHHURT:
- case SC_MAGICMUSHROOM:
- case SC_VENOMBLEED:
+ case SC_POISON:
+ case SC_BLIND:
+ case SC_STUN:
+ case SC_SILENCE:
+ case SC__CHAOS:
+ case SC_STONE:
+ case SC_SLEEP:
+ case SC_BLOODING:
+ case SC_CURSE:
+ case SC_BURNING:
+ case SC_FROSTMISTY:
+ case SC_FREEZE:
+ case SC_COLD:
+ case SC_FEAR:
case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_DEATHHURT:
+ case SC_PYREXIA:
case SC_OBLIVIONCURSE:
case SC_LEECHESEND:
+ case SC_DEEP_SLEEP:
+ case SC_SATURDAY_NIGHT_FEVER:
+ case SC__BODYPAINT:
case SC__ENERVATION:
case SC__GROOMY:
+ case SC__IGNORANCE:
case SC__LAZINESS:
case SC__UNLUCKY:
case SC__WEAKNESS:
- case SC__BODYPAINT:
- case SC__IGNORANCE:
return 0;
}
}
@@ -6596,7 +6829,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
//Adjust tick according to status resistances
if( !(flag&(1|4)) ) {
- tick = status->get_sc_def(bl, type, rate, tick, flag);
+ tick = status->get_sc_def(src, bl, type, rate, tick, flag);
if( !tick ) return 0;
}
@@ -6616,6 +6849,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
|| (type==SC_ANGRIFFS_MODUS && sc->data[SC_GOLDENE_FERSE])
)
return 0;
+ case SC_VACUUM_EXTREME:
+ if(sc->data[SC_HALLUCINATIONWALK] || sc->data[SC_HOVERING])
+ return 0;
+ break;
case SC_STONE:
if(sc->data[SC_POWER_OF_GAIA])
return 0;
@@ -6623,7 +6860,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
//Undead are immune to Freeze/Stone
if (undead_flag && !(flag&1))
return 0;
- case SC_DEEP_SLEEP:
case SC_SLEEP:
case SC_STUN:
case SC_FROSTMISTY:
@@ -6636,7 +6872,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
//There all like berserk, do not everlap each other
case SC_BERSERK:
- if( sc->data[SC__BLOODYLUST] || sc->data[SC_SATURDAY_NIGHT_FEVER] )
+ if( sc->data[SC__BLOODYLUST] )
return 0;
break;
@@ -6879,8 +7115,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if(sc->data[i]) return 0;
}
break;
- case SC_SATURDAY_NIGHT_FEVER:
- if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION])
+ case SC_MAGNETICFIELD:
+ if(sc->data[SC_HOVERING])
return 0;
break;
case SC_OFFERTORIUM:
@@ -6934,6 +7170,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC__WEAKNESS:
case SC__IGNORANCE:
+ // Other Effects
+ case SC_VACUUM_EXTREME:
+
return 0;
}
}
@@ -6958,6 +7197,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
//Also blocks the ones below...
case SC_DEC_AGI:
+ case SC_ADORAMUS:
status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
//Also blocks the ones below...
case SC_DONTFORGETME:
@@ -7022,9 +7262,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
break;
case SC_CARTBOOST:
- if(sc->data[SC_DEC_AGI])
+ if(sc->data[SC_DEC_AGI] || sc->data[SC_ADORAMUS])
{ //Cancel Decrease Agi, but take no further effect [Skotlex]
status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
+ status_change_end(bl, SC_ADORAMUS, INVALID_TIMER);
return 0;
}
break;
@@ -7093,47 +7334,43 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
break;
+ //Group A Status (doesn't overlap)
case SC_SWING:
case SC_SYMPHONY_LOVE:
case SC_MOONLIT_SERENADE:
case SC_RUSH_WINDMILL:
case SC_ECHOSONG:
- case SC_HARMONIZE: //group A doesn't overlap
+ case SC_HARMONIZE:
+ case SC_FRIGG_SONG:
if (type != SC_SWING) status_change_end(bl, SC_SWING, INVALID_TIMER);
if (type != SC_SYMPHONY_LOVE) status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER);
if (type != SC_MOONLIT_SERENADE) status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER);
if (type != SC_RUSH_WINDMILL) status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER);
if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
+ if (type != SC_FRIGG_SONG) status_change_end(bl, SC_FRIGG_SONG, INVALID_TIMER);
break;
+ //Group B Status
case SC_SIREN:
case SC_DEEP_SLEEP:
- case SC_GLOOMYDAY:
- case SC_SONG_OF_MANA:
- case SC_DANCE_WITH_WUG:
- case SC_SATURDAY_NIGHT_FEVER:
+ case SC_SIRCLEOFNATURE:
case SC_LERADS_DEW:
case SC_MELODYOFSINK:
case SC_BEYOND_OF_WARCRY:
- case SC_UNLIMITED_HUMMING_VOICE: //group B
+ case SC_UNLIMITED_HUMMING_VOICE:
+ case SC_GLOOMYDAY:
+ case SC_SONG_OF_MANA:
+ case SC_DANCE_WITH_WUG:
if (type != SC_SIREN) status_change_end(bl, SC_SIREN, INVALID_TIMER);
if (type != SC_DEEP_SLEEP) status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER);
+ if (type != SC_SIRCLEOFNATURE) status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER);
if (type != SC_LERADS_DEW) status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER);
if (type != SC_MELODYOFSINK) status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
if (type != SC_BEYOND_OF_WARCRY) status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER);
if (type != SC_UNLIMITED_HUMMING_VOICE) status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER);
- if (type != SC_GLOOMYDAY) {
- status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
- status_change_end(bl, SC_GLOOMYDAY_SK, INVALID_TIMER);
- }
+ if (type != SC_GLOOMYDAY) status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
if (type != SC_SONG_OF_MANA) status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER);
if (type != SC_DANCE_WITH_WUG) status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER);
- if (type != SC_SATURDAY_NIGHT_FEVER) {
- if (sc->data[SC_SATURDAY_NIGHT_FEVER]) {
- sc->data[SC_SATURDAY_NIGHT_FEVER]->val2 = 0; //mark to not lose hp
- status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER);
- }
- }
break;
case SC_REFLECTSHIELD:
status_change_end(bl, SC_LG_REFLECTDAMAGE, INVALID_TIMER);
@@ -7145,12 +7382,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_SHIELDSPELL_MDEF:
case SC_SHIELDSPELL_REF:
status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
- if( type != SC_SHIELDSPELL_DEF )
- status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER);
- if( type != SC_SHIELDSPELL_MDEF )
- status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER);
- if( type != SC_SHIELDSPELL_REF )
- status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
+ status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER);
+ status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER);
+ status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
break;
case SC_GENTLETOUCH_ENERGYGAIN:
case SC_GENTLETOUCH_CHANGE:
@@ -7208,6 +7442,15 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_MARIONETTE:
case SC_NOCHAT:
case SC_HLIF_CHANGE: //Otherwise your Hp/Sp would get refilled while still within effect of the last invocation.
+ case SC_ABUNDANCE:
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_DEATHHURT:
+ case SC_PYREXIA:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
case SC__INVISIBILITY:
case SC__ENERVATION:
case SC__GROOMY:
@@ -7215,6 +7458,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC__LAZINESS:
case SC__WEAKNESS:
case SC__UNLUCKY:
+ case SC__CHAOS:
return 0;
case SC_COMBOATTACK:
case SC_DANCING:
@@ -7281,6 +7525,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
calc_flag = status->ChangeFlagTable[type];
if(!(flag&4)) { //&4 - Do not parse val settings when loading SCs
switch(type) {
+ case SC_ADORAMUS:
+ sc_start(src,bl,SC_BLIND,100,val1,skill->get_time(status->sc2skill(type),val1));
+ // Fall through to SC_INC_AGI
case SC_DEC_AGI:
case SC_INC_AGI:
val2 = 2 + val1; //Agi change
@@ -7293,10 +7540,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
int i;
for( i = 0; i < 5; i++ ) {
if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) )
- status->change_start(&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
}
} else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
- status->change_start(&tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, 1);
}
//val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk)
if( val4 )
@@ -7305,7 +7552,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_AUTOBERSERK:
if (st->hp < st->max_hp>>2 &&
(!sc->data[SC_PROVOKE] || sc->data[SC_PROVOKE]->val2==0))
- sc_start4(bl,SC_PROVOKE,100,10,1,0,0,60000);
+ sc_start4(src,bl,SC_PROVOKE,100,10,1,0,0,60000);
tick = -1;
break;
case SC_CRUCIS:
@@ -7335,7 +7582,16 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_KYRIE:
val2 = APPLY_RATE(st->max_hp, (val1 * 2 + 10)); //%Max HP to absorb
- val3 = (val1 / 2 + 5); //Hits
+ // val4 holds current about of party memebers when casting AB_PRAEFATIO,
+ // as Praefatio's barrier has more health and blocks more hits than Kyrie Elesion.
+ if( val4 < 1 ) //== PR_KYRIE
+ val3 = (val1 / 2 + 5); // Hits
+ else { //== AB_PRAEFATIO
+ val2 += val4 * 2; //Increase barrier strength per party member.
+ val3 = 6 + val1;
+ }
+ if( sd )
+ val1 = min(val1,pc->checkskill(sd,PR_KYRIE)); // use skill level to determine barrier health.
break;
case SC_MAGICPOWER:
//val1: Skill lv
@@ -7381,10 +7637,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
int i;
for( i = 0; i < 5; i++ ) {
if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) )
- status->change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
}
} else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
- status->change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
}
break;
case SC_NOEQUIPWEAPON:
@@ -7520,9 +7776,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (st->hp - diff < st->max_hp>>2)
diff = st->hp - (st->max_hp>>2);
if( val2 && bl->type == BL_MOB ) {
- struct block_list* src = map->id2bl(val2);
- if( src )
- mob->log_damage((TBL_MOB*)bl,src,diff);
+ struct block_list* src2 = map->id2bl(val2);
+ if( src2 )
+ mob->log_damage((TBL_MOB*)bl,src2,diff);
}
status_zap(bl, diff, 0);
}
@@ -7637,11 +7893,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if( sd ) {
for( i = 0; i < 5; i++ ) {
if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) )
- status->change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
}
}
else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) )
- status->change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
+ status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
}
}
break;
@@ -7658,7 +7914,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
for (i = 0; i < 5; i++) {
//See if there are devoted characters, and pass the status to them. [Skotlex]
if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])))
- status->change_start(&tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,1);
+ status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,1);
}
}
}
@@ -7685,14 +7941,14 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_JOINTBEAT:
if( val2&BREAK_NECK )
- sc_start2(bl,SC_BLOODING,100,val1,val3,skill->get_time2(status->sc2skill(type),val1));
+ sc_start2(src,bl,SC_BLOODING,100,val1,val3,skill->get_time2(status->sc2skill(type),val1));
break;
case SC_BERSERK:
if( val3 == SC__BLOODYLUST )
- sc_start(bl,(sc_type)val3,100,val1,tick);
+ sc_start(src,bl,(sc_type)val3,100,val1,tick);
if( !val3 && !(!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4) )
- sc_start4(bl, SC_ENDURE, 100,10,0,0,2, tick);
+ sc_start4(src, bl, SC_ENDURE, 100,10,0,0,2, tick);
//HP healing is performing after the calc_status call.
//Val2 holds HP penalty
if (!val4) val4 = skill->get_time2(status->sc2skill(type),val1);
@@ -7785,7 +8041,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
while( i >= 0 ) {
type2 = types[i];
if( d_sc->data[type2] )
- sc_start(bl, type2, 100, d_sc->data[type2]->val1, skill->get_time(status->sc2skill(type2),d_sc->data[type2]->val1));
+ sc_start(bl, bl, type2, 100, d_sc->data[type2]->val1, skill->get_time(status->sc2skill(type2),d_sc->data[type2]->val1));
i--;
}
}
@@ -7794,25 +8050,25 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_COMA: //Coma. Sends a char to 1HP. If val2, do not zap sp
if( val3 && bl->type == BL_MOB ) {
- struct block_list* src = map->id2bl(val3);
- if( src )
- mob->log_damage((TBL_MOB*)bl,src,st->hp - 1);
+ struct block_list* src2 = map->id2bl(val3);
+ if( src2 )
+ mob->log_damage((TBL_MOB*)bl,src2,st->hp - 1);
}
status_zap(bl, st->hp-1, val2 ? 0 : st->sp);
return 1;
break;
case SC_RG_CCONFINE_S:
{
- struct block_list *src = val2 ? map->id2bl(val2) : NULL;
- struct status_change *sc2 = src ? status->get_sc(src) : NULL;
+ struct block_list *src2 = val2 ? map->id2bl(val2) : NULL;
+ struct status_change *sc2 = src ? status->get_sc(src2) : NULL;
struct status_change_entry *sce2 = sc2 ? sc2->data[SC_RG_CCONFINE_M] : NULL;
- if (src && sc2) {
+ if (src2 && sc2) {
if (!sce2) //Start lock on caster.
- sc_start4(src,SC_RG_CCONFINE_M,100,val1,1,0,0,tick+1000);
+ sc_start4(src,src2,SC_RG_CCONFINE_M,100,val1,1,0,0,tick+1000);
else { //Increase count of locked enemies and refresh time.
(sce2->val2)++;
timer->delete(sce2->timer, status->change_timer);
- sce2->timer = timer->add(timer->gettick()+tick+1000, status->change_timer, src->id, SC_RG_CCONFINE_M);
+ sce2->timer = timer->add(timer->gettick()+tick+1000, status->change_timer, src2->id, SC_RG_CCONFINE_M);
}
} else //Status failed.
return 0;
@@ -7910,7 +8166,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 5*val1; //Batk/Watk Increase
val3 = 10*val1; //Hit Increase
val4 = 5*val1; //Def reduction
- sc_start(bl, SC_ENDURE, 100, 1, tick); //Endure effect
+ sc_start(src, bl, SC_ENDURE, 100, 1, tick); //Endure effect
break;
case SC_ANGELUS:
val2 = 5*val1; //def increase
@@ -8159,8 +8415,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_WEAPONBLOCKING:
val2 = 10 + 2 * val1; // Chance
- val4 = tick / 3000;
- tick_time = 3000; // [GodLesZ] tick time
+ val4 = tick / 5000;
+ tick_time = 5000; // [GodLesZ] tick time
break;
case SC_TOXIN:
val4 = tick / 10000;
@@ -8171,7 +8427,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
tick_time = 4000; // [GodLesZ] tick time
break;
case SC_PYREXIA:
- status->change_start(bl,SC_BLIND,10000,val1,0,0,0,30000,11); // Blind status that last for 30 seconds
+ status->change_start(src, bl,SC_BLIND,10000,val1,0,0,0,30000,11); // Blind status that last for 30 seconds
val4 = tick / 3000;
tick_time = 3000; // [GodLesZ] tick time
break;
@@ -8212,7 +8468,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_READING_SB:
// val2 = sp reduction per second
- tick_time = 5000; // [GodLesZ] tick time
+ tick_time = 10000; // [GodLesZ] tick time
break;
case SC_SUMMON1:
case SC_SUMMON2:
@@ -8233,6 +8489,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case 4: val2 = ELE_WATER; break;
}
break;
+ case SC_STEALTHFIELD_MASTER:
+ val4 = tick / 1000;
+ tick_time = 2000 + (1000 * val1);
+ break;
case SC_ELECTRICSHOCKER:
case SC_COLD:
case SC_MEIKYOUSISUI:
@@ -8255,6 +8515,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
tick = -1;
break;
+ case SC__REPRODUCE:
+ val4 = tick / 1000;
+ tick_time = 1000;
+ break;
case SC__SHADOWFORM: {
struct map_session_data * s_sd = map->id2sd(val2);
if( s_sd )
@@ -8269,7 +8533,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC__INVISIBILITY:
val2 = 50 - 10 * val1; // ASPD
- val3 = 20 * val1; // CRITICAL
+ val3 = 200 * val1; // CRITICAL
val4 = tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
@@ -8301,8 +8565,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC__WEAKNESS:
val2 = 10 * val1;
// bypasses coating protection and MADO
- sc_start(bl,SC_NOEQUIPWEAPON,100,val1,tick);
- sc_start(bl,SC_NOEQUIPSHIELD,100,val1,tick);
+ sc_start(src, bl,SC_NOEQUIPWEAPON,100,val1,tick);
+ sc_start(src, bl,SC_NOEQUIPSHIELD,100,val1,tick);
break;
case SC_GN_CARTBOOST:
if( val1 < 3 )
@@ -8327,31 +8591,25 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_BLOOD_SUCKER:
{
- struct block_list *src = map->id2bl(val2);
+ struct block_list *src2 = map->id2bl(val2);
val3 = 1;
- if(src)
- val3 = 200 + 100 * val1 + status_get_int(src);
+ if(src2)
+ val3 = 200 + 100 * val1 + status_get_int(src2);
val4 = tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
}
break;
- case SC_VACUUM_EXTREME:
- tick -= (st->str / 20) * 1000;
- val4 = val3 = tick / 100;
- tick_time = 100; // [GodLesZ] tick time
- break;
case SC_SWING:
- val2 = 4 * val1; // Walk speed and aspd reduction.
+ val3 = 5 * val1 + val2;//Movement Speed And ASPD Increase
break;
case SC_SYMPHONY_LOVE:
+ val2 = 12 * val1 + val2 + sd->status.job_level / 4;//MDEF Increase In %
+ case SC_MOONLIT_SERENADE:
case SC_RUSH_WINDMILL:
- case SC_ECHOSONG:
- val2 = 6 * val1;
- val2 += val3; //Adding 1% * Lesson Bonus
- val2 += (int)(val4*2/10); //Adding 0.2% per JobLevel
+ val2 = 6 * val1 + val2 + sd->status.job_level / 5;
break;
- case SC_MOONLIT_SERENADE:
- val2 = 10 * val1;
+ case SC_ECHOSONG:
+ val3 = 6 * val1 + val2 + sd->status.job_level / 4;//DEF Increase In %
break;
case SC_HARMONIZE:
val2 = 5 + 5 * val1;
@@ -8365,34 +8623,36 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
tick_time = 2000; // [GodLesZ] tick time
break;
case SC_SIRCLEOFNATURE:
- val2 = 1 + val1; //SP consume
- val3 = 40 * val1; //HP recovery
+ val2 = 40 * val1;//HP recovery
+ val3 = 4 * val1;//SP drain
val4 = tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_SONG_OF_MANA:
- val3 = 10 + (2 * val2);
- val4 = tick/3000;
- tick_time = 3000; // [GodLesZ] tick time
+ val3 = 10 + 5 * val2;
+ val4 = tick/5000;
+ tick_time = 5000; // [GodLesZ] tick time
break;
case SC_SATURDAY_NIGHT_FEVER:
- if (!val4) val4 = skill->get_time2(status->sc2skill(type),val1);
- if (!val4) val4 = 3000;
- val3 = tick/val4;
- tick_time = val4; // [GodLesZ] tick time
+ /*val2 = 12000 - 2000 * val1;//HP/SP Drain Timer
+ if ( val2 < 1000 )
+ val2 = 1000;//Added to prevent val3 from dividing by 0 when using level 6 or higher through commands. [Rytech]
+ val3 = tick/val2;*/
+ val3 = tick / 3000;
+ tick_time = 3000;// [GodLesZ] tick time
break;
case SC_GLOOMYDAY:
- val2 = 20 + 5 * val1; // Flee reduction.
- val3 = 15 + 5 * val1; // ASPD reduction.
- if( sd && rand()%100 < val1 ){ // (Skill Lv) %
- val4 = 1; // reduce walk speed by half.
- if( pc_isriding(sd) ) pc->setriding(sd, 0);
- if( pc_isridingdragon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_DRAGON);
+ if ( !val2 ) {
+ val2 = (val4 > 0 ? max(15, rnd()%(val4*5)) : 0) + val1 * 10;
+ }
+ if ( rnd()%10000 < val1*100 ) { // 1% per SkillLv chance
+ if ( !val3 )
+ val3 = 50;
+ if( sd ) {
+ if( pc_isriding(sd) ) pc->setriding(sd, 0);
+ if( pc_isridingdragon(sd) ) pc->setoption(sd, sd->sc.option&~OPTION_DRAGON);
+ }
}
- break;
- case SC_GLOOMYDAY_SK:
- // Random number between [15 ~ (Voice Lesson Skill Level x 5) + (Skill Level x 10)] %.
- val2 = 15 + rand()%( (sd?pc->checkskill(sd, WM_LESSON)*5:0) + val1*10 );
break;
case SC_SITDOWN_FORCE:
case SC_BANANA_BOMB_SITDOWN_POSTDELAY:
@@ -8404,28 +8664,32 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
break;
case SC_DANCE_WITH_WUG:
- val3 = (5 * val1) + (1 * val2); //Still need official value.
+ val3 = 5 + 5 * val2;//ASPD Increase
+ val4 = 20 + 10 * val2;//Fixed Cast Time Reduction
break;
case SC_LERADS_DEW:
- val3 = (5 * val1) + (1 * val2);
+ val3 = 200 * val1 + 300 * val2;//MaxHP Increase
break;
case SC_MELODYOFSINK:
- val3 = (5 * val1) + (1 * val2);
+ val3 = val1 * (2 + val2);//INT Reduction. Formula Includes Caster And 2nd Performer.
+ val4 = tick/1000;
+ tick_time = 1000;
break;
case SC_BEYOND_OF_WARCRY:
- val3 = (5 * val1) + (1 * val2);
+ val3 = val1 * (2 + val2);//STR And Crit Reduction. Formula Includes Caster And 2nd Performer.
+ val4 = 4 * val1 + 4 * val2;//MaxHP Reduction
break;
case SC_UNLIMITED_HUMMING_VOICE:
{
struct unit_data *ud = unit->bl2ud(bl);
if( ud == NULL ) return 0;
ud->state.skillcastcancel = 0;
- val3 = 15 - (2 * val2);
+ val3 = 15 - (3 * val2);//Increased SP Cost.
}
break;
case SC_LG_REFLECTDAMAGE:
val2 = 15 + 5 * val1;
- val3 = (val1==5)?20:(val1+4)*2; // SP consumption
+ val3 = 25 + 5 * val1; //Number of Reflects
val4 = tick/10000;
tick_time = 10000; // [GodLesZ] tick time
break;
@@ -8442,11 +8706,14 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val1 += (sd->inventory_data[index]->weight / 10 * sd->inventory_data[index]->wlv) * status->get_lv(bl) / 100;
}
break;
- case SC_PRESTIGE: // Based on suggested formula in iRO Wiki and some test, still need more test. [pakpil]
- val2 = ((st->int_ + st->luk) / 6) + 5; // Chance to evade magic damage.
+ case SC_PRESTIGE:
+ val2 = (st->int_ + st->luk) * val1 / 20;// Chance to evade magic damage.
+ val2 = val2 * status->get_lv(bl) / 200;
+ val2 += val1;
val1 *= 15; // Defence added
if( sd )
val1 += 10 * pc->checkskill(sd,CR_DEFENDER);
+ val1 *= status->get_lv(bl) / 100;
break;
case SC_BANDING:
tick_time = 5000; // [GodLesZ] tick time
@@ -8457,16 +8724,13 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_INSPIRATION:
if( sd ) {
- val2 = (40 * val1) + (3 * sd->status.job_level); // ATK bonus
- val3 = (sd->status.job_level / 10) * 2 + 12; // All stat bonus
+ val2 = 40 * val1 + 3 * sd->status.job_level;// ATK bonus
+ val3 = sd->status.base_level / 10 + sd->status.job_level / 5;// All stat bonus
}
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
+ val4 = tick / 5000;
+ tick_time = 5000; // [GodLesZ] tick time
status->change_clear_buffs(bl,3); //Remove buffs/debuffs
break;
- case SC_CRESCENTELBOW:
- val2 = 94 + val1;
- break;
case SC_LIGHTNINGWALK: // [(Job Level / 2) + (40 + 5 * Skill Level)] %
val1 = (sd?sd->status.job_level:2)/2 + 40 + 5 * val1;
break;
@@ -8476,25 +8740,28 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_GENTLETOUCH_CHANGE:
{// take note there is no def increase as skill desc says. [malufett]
- struct block_list * src;
+ struct block_list * src2;
val3 = st->agi * val1 / 60; // ASPD increase: [(Target AGI x Skill Level) / 60] %
- if( (src = map->id2bl(val2)) ){
- val4 = ( 200/status_get_int(src) ) * val1;// MDEF decrease: MDEF [(200 / Caster INT) x Skill Level]
- val2 = ( status_get_dex(src)/4 + status_get_str(src)/2 ) * val1 / 5; // ATK increase: ATK [{(Caster DEX / 4) + (Caster STR / 2)} x Skill Level / 5]
+ if( (src2 = map->id2bl(val2)) ){
+ val4 = ( 200/status_get_int(src2) ) * val1;// MDEF decrease: MDEF [(200 / Caster INT) x Skill Level]
+ val2 = ( status_get_dex(src2)/4 + status_get_str(src2)/2 ) * val1 / 5; // ATK increase: ATK [{(Caster DEX / 4) + (Caster STR / 2)} x Skill Level / 5]
}
}
break;
case SC_GENTLETOUCH_REVITALIZE:
{// take note there is no vit,aspd,speed increase as skill desc says. [malufett]
- struct block_list * src;
+ struct block_list * src2;
val3 = val1 * 30 + 150; // Natural HP recovery increase: [(Skill Level x 30) + 50] %
- if( (src = map->id2bl(val2)) ) // the stat def is not shown in the status window and it is process differently
- val4 = ( status_get_vit(src)/4 ) * val1; // STAT DEF increase: [(Caster VIT / 4) x Skill Level]
+ if( (src2 = map->id2bl(val2)) ) // the stat def is not shown in the status window and it is process differently
+ val4 = ( status_get_vit(src2)/4 ) * val1; // STAT DEF increase: [(Caster VIT / 4) x Skill Level]
}
break;
+ case SC_PYROTECHNIC_OPTION:
+ val2 = 60;
+ break;
case SC_HEATER_OPTION:
val2 = 120; // Watk. TODO: Renewal (Atk2)
- val3 = 33; // % Increase effects.
+ val3 = (sd ? sd->status.job_level : 0); // % Increase damage.
val4 = 3; // Change into fire element.
break;
case SC_TROPIC_OPTION:
@@ -8505,8 +8772,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 40;
break;
case SC_COOLER_OPTION:
- val2 = 80; // % Freezing chance
- val3 = 33; // % increased damage
+ val2 = 80; // Bonus Matk
+ val3 = (sd ? sd->status.job_level : 0); // % Freezing chance
val4 = 1; // Change into water elemet
break;
case SC_CHILLY_AIR_OPTION:
@@ -8517,7 +8784,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 50; // % Increase speed and flee.
break;
case SC_BLAST_OPTION:
- val2 = 20;
+ val2 = (sd ? sd->status.job_level : 0); // % Increase damage
val3 = ELE_WIND;
break;
case SC_WILD_STORM_OPTION:
@@ -8527,13 +8794,17 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 5;
val3 = 50;
break;
+ case SC_SOLID_SKIN_OPTION:
+ val2 = 33; // % Increase DEF
+ break;
case SC_CURSED_SOIL_OPTION:
val2 = 10;
- val3 = 33;
+ val3 = (sd ? sd->status.job_level : 0); // % Increase Damage
val4 = 2;
break;
case SC_UPHEAVAL_OPTION:
val2 = WZ_EARTHSPIKE;
+ val3 = 15; // Bonus MaxHP
break;
case SC_CIRCLE_OF_FIRE_OPTION:
val2 = 300;
@@ -8542,7 +8813,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_WATER_DROP_OPTION:
case SC_WIND_CURTAIN_OPTION:
case SC_STONE_SHIELD_OPTION:
- val2 = 20; // Elemental modifier. Not confirmed.
+ val2 = 100; // Elemental modifier.
break;
case SC_CIRCLE_OF_FIRE:
case SC_FIRE_CLOAK:
@@ -8557,10 +8828,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_WATER_BARRIER:
val2 = 40; // Increasement. Mdef1 ???
- val3 = 20; // Reductions. Atk2, Flee1, Matk1 ????
+ val3 = 30; // Reductions. Atk2, Flee1, Matk1 ????
break;
case SC_ZEPHYR:
- val2 = 22; // Flee.
+ val2 = 25; // Flee.
break;
case SC_TIDAL_WEAPON:
val2 = 20; // Increase Elemental's attack.
@@ -8657,7 +8928,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 2*val1; //aspd reduction %
val3 = 2*val1; //dmg reduction %
if(sc->data[SC_NEEDLE_OF_PARALYZE])
- sc_start(bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
+ sc_start(src, bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
break;
case SC_STYLE_CHANGE: //[Lighta] need real info
tick = -1;
@@ -8684,10 +8955,13 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_FRIGG_SONG:
val2 = 5 * val1;
- val3 = 1000 + 100 * val1;
- tick_time = 10000;
+ val3 = (20 * val1) + 80;
+ tick_time = 1000;
val4 = tick / tick_time;
break;
+ case SC_DARKCROW:
+ val2 = 30 * val1;
+ break;
case SC_MONSTER_TRANSFORM:
if( !mob->db_checkid(val1) )
val1 = 1002; // default poring
@@ -8862,6 +9136,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
//Those that make you stop attacking/walking....
switch (type) {
+ case SC_VACUUM_EXTREME:
+ if(!map_flag_gvg(bl->m))
+ unit->stop_walking(bl,1);
+ break;
case SC_FREEZE:
case SC_STUN:
case SC_SLEEP:
@@ -8885,11 +9163,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_WUGBITE:
case SC_THORNS_TRAP:
case SC__MANHOLE:
+ case SC__CHAOS:
case SC_COLD:
case SC_CURSEDCIRCLE_ATKER:
case SC_CURSEDCIRCLE_TARGET:
case SC_FEAR:
- case SC_NETHERWORLD:
case SC_MEIKYOUSISUI:
case SC_KYOUGAKU:
case SC_NEEDLE_OF_PARALYZE:
@@ -8943,7 +9221,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_STONE: sc->opt1 = OPT1_STONEWAIT; break;
case SC_FREEZE: sc->opt1 = OPT1_FREEZE; break;
case SC_STUN: sc->opt1 = OPT1_STUN; break;
- case SC_DEEP_SLEEP: opt_flag = 0;
case SC_SLEEP: sc->opt1 = OPT1_SLEEP; break;
case SC_BURNING: sc->opt1 = OPT1_BURNING; break; // Burning need this to be showed correctly. [pakpil]
case SC_WHITEIMPRISON: sc->opt1 = OPT1_IMPRISON; break;
@@ -8954,6 +9231,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_SILENCE: sc->opt2 |= OPT2_SILENCE; break;
case SC_CRUCIS:
+ case SC__CHAOS:
sc->opt2 |= OPT2_SIGNUMCRUCIS;
break;
@@ -9057,10 +9335,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_CLOAKING:
case SC_CLOAKINGEXCEED:
- case SC__INVISIBILITY:
sc->option |= OPTION_CLOAK;
opt_flag = 2;
break;
+ case SC__INVISIBILITY:
case SC_CHASEWALK:
sc->option |= OPTION_CHASEWALK|OPTION_CLOAK;
opt_flag = 2;
@@ -9366,10 +9644,10 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
#ifdef ANTI_MAYAP_CHEAT
- if( sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE) )
+ if (sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE))
invisible = true;
#endif
-
+
vd = status->get_viewdata(bl);
calc_flag = status->ChangeFlagTable[type];
switch(type) {
@@ -9404,7 +9682,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
&& DIFF_TICK(timer->gettick(), starttick) <= 1000
&& (!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0))
)
- sc_start(bl,SC_STRUP,100,sce->val1,skill->get_time2(status->sc2skill(type), sce->val1));
+ sc_start(bl, bl,SC_STRUP,100,sce->val1,skill->get_time2(status->sc2skill(type), sce->val1));
}
break;
case SC_AUTOBERSERK:
@@ -9599,7 +9877,6 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
break;
case SC_BERSERK:
- case SC_SATURDAY_NIGHT_FEVER:
if(st->hp > 200 && sc && sc->data[SC__BLOODYLUST]) {
status_percent_heal(bl, 100, 0);
status_change_end(bl, SC__BLOODYLUST, INVALID_TIMER);
@@ -9609,9 +9886,9 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
sc->data[SC_ENDURE]->val4 = 0;
status_change_end(bl, SC_ENDURE, INVALID_TIMER);
}
- sc_start4(bl, SC_GDSKILL_REGENERATION, 100, 10,0,0,(RGN_HP|RGN_SP), skill->get_time(LK_BERSERK, sce->val1));
+ sc_start4(bl, bl, SC_GDSKILL_REGENERATION, 100, 10,0,0,(RGN_HP|RGN_SP), skill->get_time(LK_BERSERK, sce->val1));
if( type == SC_SATURDAY_NIGHT_FEVER ) //Sit down force of Saturday Night Fever has the duration of only 3 seconds.
- sc_start(bl,SC_SITDOWN_FORCE,100,sce->val1,skill->get_time2(WM_SATURDAY_NIGHT_FEVER,sce->val1));
+ sc_start(bl,bl,SC_SITDOWN_FORCE,100,sce->val1,skill->get_time2(WM_SATURDAY_NIGHT_FEVER,sce->val1));
break;
case SC_GOSPEL:
if (sce->val3) { //Clear the group.
@@ -9670,9 +9947,10 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
break;
case SC_STOP:
if( sce->val2 ) {
- struct block_list* tbl = map->id2bl(sce->val2);
+ struct block_list *tbl = map->id2bl(sce->val2);
+ struct status_change *tsc = NULL;
sce->val2 = 0;
- if( tbl && (sc = status->get_sc(tbl)) && sc->data[SC_STOP] && sc->data[SC_STOP]->val2 == bl->id )
+ if( tbl && (tsc = status->get_sc(tbl)) && tsc->data[SC_STOP] && tsc->data[SC_STOP]->val2 == bl->id )
status_change_end(tbl, SC_STOP, INVALID_TIMER);
}
break;
@@ -9686,7 +9964,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
clif->millenniumshield(bl,0);
break;
case SC_HALLUCINATIONWALK:
- sc_start(bl,SC_HALLUCINATIONWALK_POSTDELAY,100,sce->val1,skill->get_time2(GC_HALLUCINATIONWALK,sce->val1));
+ sc_start(bl,bl,SC_HALLUCINATIONWALK_POSTDELAY,100,sce->val1,skill->get_time2(GC_HALLUCINATIONWALK,sce->val1));
break;
case SC_WHITEIMPRISON:
{
@@ -9782,7 +10060,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
calc_flag = SCB_ALL;/* required for overlapping */
break;
case SC_FULL_THROTTLE:
- sc_start(bl,SC_REBOUND,100,sce->val1,skill->get_time2(ALL_FULL_THROTTLE,sce->val1));
+ sc_start(bl,bl,SC_REBOUND,100,sce->val1,skill->get_time2(ALL_FULL_THROTTLE,sce->val1));
break;
case SC_MONSTER_TRANSFORM:
if( sce->val2 )
@@ -9811,12 +10089,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
opt_flag = 1;
- switch(type){
+ switch(type) {
case SC_STONE:
case SC_FREEZE:
case SC_STUN:
case SC_SLEEP:
- case SC_DEEP_SLEEP:
case SC_BURNING:
case SC_WHITEIMPRISON:
case SC_COLD:
@@ -9833,6 +10110,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
sc->opt2 &= ~OPT2_DPOISON;
break;
case SC_CRUCIS:
+ case SC__CHAOS:
sc->opt2 &= ~OPT2_SIGNUMCRUCIS;
break;
@@ -9842,11 +10120,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
break;
case SC_CLOAKING:
case SC_CLOAKINGEXCEED:
- case SC__INVISIBILITY:
sc->option &= ~OPTION_CLOAK;
case SC_CAMOUFLAGE:
opt_flag|= 2;
break;
+ case SC__INVISIBILITY:
case SC_CHASEWALK:
sc->option &= ~(OPTION_CHASEWALK|OPTION_CLOAK);
opt_flag|= 2;
@@ -9980,11 +10258,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
#ifdef ANTI_MAYAP_CHEAT
- if( invisible && !(sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE)) ) {
+ if (invisible && !(sc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_INVISIBLE))) {
clif->fixpos(bl);
}
#endif
-
+
if (calc_flag&SCB_DYE) { //Restore DYE color
if (vd && !vd->cloth_color && sce->val4)
clif->changelook(bl,LOOK_CLOTHES_COLOR,sce->val4);
@@ -10109,7 +10387,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
break; //Not enough SP to continue.
if (!sc->data[SC_CHASEWALK2]) {
- sc_start(bl, SC_CHASEWALK2,100,1<<(sce->val1-1),
+ sc_start(bl,bl, SC_CHASEWALK2,100,1<<(sce->val1-1),
(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_ROGUE?10:1) //SL bonus -> x10 duration
* skill->get_time2(status->sc2skill(type),sce->val1));
}
@@ -10495,7 +10773,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
if( --(sce->val4) > 0 ) {
if( !status->charge(bl,0,3) )
break;
- sc_timer_next(3000+tick,status->change_timer,bl->id,data);
+ sc_timer_next(5000+tick,status->change_timer,bl->id,data);
return 0;
}
break;
@@ -10563,7 +10841,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
status_change_end(bl, (sc_type)i, INVALID_TIMER);
break;
}
- sc_timer_next(5000 + tick, status->change_timer, bl->id, data);
+ sc_timer_next(10000 + tick, status->change_timer, bl->id, data);
return 0;
case SC_ELECTRICSHOCKER:
@@ -10583,10 +10861,13 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
break;
case SC__REPRODUCE:
- if(!status->charge(bl, 0, 1))
- break;
- sc_timer_next(1000+tick, status->change_timer, bl->id, data);
- return 0;
+ if( --(sce->val4) >= 0 ) {
+ if( !status_charge(bl, 0, 9 - (1 + sce->val1) / 2) )
+ break;
+ sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
+ return 0;
+ }
+ break;
case SC__SHADOWFORM:
if( --(sce->val4) > 0 ) {
@@ -10598,8 +10879,8 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
break;
case SC__INVISIBILITY:
- if( --(sce->val4) > 0 ) {
- if( !status->charge(bl, 0, (st->sp * 6 - sce->val1) / 100) )// 6% - skill_lv.
+ if( --(sce->val4) >= 0 ) {
+ if( !status->charge(bl, 0, status_get_max_sp(bl) * (12 - sce->val1*2) / 100) )
break;
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
return 0;
@@ -10614,12 +10895,6 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
return 0;
}
break;
- case SC_VACUUM_EXTREME:
- if( --(sce->val4) > 0 ) {
- sc_timer_next(100 + tick, status->change_timer, bl->id, data);
- return 0;
- }
- break;
case SC_BLOOD_SUCKER:
if( --(sce->val4) > 0 ) {
struct block_list *src = map->id2bl(sce->val2);
@@ -10648,41 +10923,46 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
break;
case SC_DEEP_SLEEP:
- if( --(sce->val4) > 0 ) {
- // Recovers 1% HP/SP every 2 seconds.
- status->heal(bl, st->max_hp / 100, st->max_sp / 100, 2);
+ if( --(sce->val4) >= 0 )
+ {// Recovers 3% of the player's MaxHP/MaxSP every 2 seconds.
+ status->heal(bl, st->max_hp * 3 / 100, st->max_sp * 3 / 100, 2);
sc_timer_next(2000 + tick, status->change_timer, bl->id, data);
return 0;
}
break;
case SC_SIRCLEOFNATURE:
- if( --(sce->val4) > 0 ) {
- if( !status->charge(bl,0,sce->val2) )
+ if( --(sce->val4) >= 0 ) {
+ if( !status_charge(bl,0,sce->val3) )
break;
- status->heal(bl, sce->val3, 0, 1);
- sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
+ status->heal(bl, sce->val2, 0, 1);
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
return 0;
}
break;
case SC_SONG_OF_MANA:
- if( --(sce->val4) > 0 ) {
+ if( --(sce->val4) >= 0 ) {
status->heal(bl,0,sce->val3,3);
- sc_timer_next(3000 + tick, status->change_timer, bl->id, data);
+ sc_timer_next(5000 + tick, status->change_timer, bl->id, data);
return 0;
}
break;
case SC_SATURDAY_NIGHT_FEVER:
- // 1% HP/SP drain every val4 seconds [Jobbie]
- if( --(sce->val3) > 0 ) {
- int hp = st->hp / 100;
- int sp = st->sp / 100;
- if( !status->charge(bl, hp, sp) )
- break;
- sc_timer_next(sce->val4+tick, status->change_timer, bl->id, data);
+ if( --(sce->val3) >= 0 ) {
+ if( !status_charge(bl, st->max_hp * 1 / 100, st->max_sp * 1 / 100) )
+ break;
+ sc_timer_next(3000+tick, status->change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_MELODYOFSINK:
+ if( --(sce->val4) >= 0 ) {
+ status_charge(bl, 0, st->max_sp * ( 2 * sce->val1 + 2 * sce->val2 ) / 100);
+ sc_timer_next(1000+tick, status->change_timer, bl->id, data);
return 0;
}
break;
@@ -10696,7 +10976,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
return 0;
}
break;
-
+
case SC_FORCEOFVANGUARD:
if( !status->charge(bl, 0, (24 - 4 * sce->val1)) )
break;
@@ -10712,10 +10992,10 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
break;
case SC_LG_REFLECTDAMAGE:
- if( --(sce->val4) > 0 ) {
- if( !status->charge(bl,0,sce->val3) )
+ if( --(sce->val4) >= 0 ) {
+ if( !status->charge(bl,0,10) )
break;
- sc_timer_next(10000 + tick, status->change_timer, bl->id, data);
+ sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
return 0;
}
break;
@@ -10744,7 +11024,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
if( --(sce->val3) <= 0 )
break; // Time out
if( sce->val2 == bl->id ) {
- if( !status->charge(bl,0,14 + (3 * sce->val1)) )
+ if( !status->charge(bl,0,50) )
break; // No more SP status should end, and in the next second will end for the other affected players
} else {
struct block_list *src = map->id2bl(sce->val2);
@@ -10756,14 +11036,33 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
}
break;
+ case SC_STEALTHFIELD_MASTER:
+ if(--(sce->val4) >= 0) {
+ // 1% SP Upkeep Cost
+ int sp = st->max_sp / 100;
+
+ if( st->sp <= sp )
+ status_change_end(bl,SC_STEALTHFIELD_MASTER,INVALID_TIMER);
+
+ if( !status_charge(bl,0,sp) )
+ break;
+
+ if( !sc->data[SC_STEALTHFIELD_MASTER] )
+ break;
+
+ sc_timer_next((2000 + 1000 * sce->val1)+tick,status->change_timer,bl->id, data);
+ return 0;
+ }
+ break;
+
case SC_INSPIRATION:
- if(--(sce->val4) > 0) {
- int hp = st->max_hp * (7-sce->val1) / 100;
- int sp = st->max_sp * (9-sce->val1) / 100;
+ if(--(sce->val4) >= 0) {
+ int hp = st->max_hp * (35 - 5 * sce->val1) / 1000;
+ int sp = st->max_sp * (45 - 5 * sce->val1) / 1000;
if( !status->charge(bl,hp,sp) ) break;
- sc_timer_next(1000+tick,status->change_timer,bl->id, data);
+ sc_timer_next(5000+tick,status->change_timer,bl->id, data);
return 0;
}
break;
@@ -10854,7 +11153,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) {
case SC_FRIGG_SONG:
if( --(sce->val4) > 0 ) {
status->heal(bl, sce->val3, 0, 0);
- sc_timer_next(10000 + tick, status->change_timer, bl->id, data);
+ sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
return 0;
}
break;
@@ -10891,17 +11190,14 @@ int status_change_timer_sub(struct block_list* bl, va_list ap) {
status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
- status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER);
break;
case SC_RUWACH: /* Reveal hidden target and deal little dammages if ennemy */
if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] ||
- tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_CLOAKINGEXCEED] ||
- tsc->data[SC__INVISIBILITY])) {
+ tsc->data[SC_CAMOUFLAGE] || 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_CAMOUFLAGE, INVALID_TIMER);
status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
- status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER);
if(battle->check_target( src, bl, BCT_ENEMY ) > 0)
skill->attack(BF_MAGIC,src,src,bl,AL_RUWACH,1,tick,0);
}
@@ -11110,7 +11406,6 @@ int status_change_clear_buffs (struct block_list* bl, int type) {
continue;
break;
case SC_BERSERK:
- case SC_SATURDAY_NIGHT_FEVER:
if(type&4)
continue;
sc->data[i]->val2 = 0;
@@ -11205,7 +11500,7 @@ int status_change_spread( struct block_list *src, struct block_list *bl ) {
data.val2 = sc->data[i]->val2;
data.val3 = sc->data[i]->val3;
data.val4 = sc->data[i]->val4;
- status->change_start(bl,(sc_type)i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,1|2|8);
+ status->change_start(src,bl,(sc_type)i,10000,data.val1,data.val2,data.val3,data.val4,data.tick,1|2|8);
flag = 1;
}
}
@@ -11378,7 +11673,7 @@ int status_natural_heal(struct block_list* bl, va_list args) {
val*=2;
sd->state.doridori = 0;
if ((rate = pc->checkskill(sd,TK_SPTIME)))
- sc_start(bl,status->skill2sc(TK_SPTIME),
+ sc_start(bl,bl,status->skill2sc(TK_SPTIME),
100,rate,skill->get_time(TK_SPTIME, rate));
if ((sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR
&&rnd()%10000 < battle_config.sg_angel_skill_ratio
@@ -11673,7 +11968,7 @@ void status_defaults(void) {
status->set_sp = status_set_sp;
status->heal = status_heal;
status->revive = status_revive;
-
+ status->fixed_revive = status_fixed_revive;
status->get_regen_data = status_get_regen_data;
status->get_status_data = status_get_status_data;
status->get_base_status = status_get_base_status;
diff --git a/src/map/status.h b/src/map/status.h
index d3148b4e0..06bea3908 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -373,7 +373,7 @@ typedef enum sc_type {
/**
* 3rd
**/
- SC_FEAR,
+ SC_FEAR, // 310
SC_FROSTMISTY,
/**
* Rune Knight
@@ -386,20 +386,20 @@ typedef enum sc_type {
SC_REUSE_REFRESH,
SC_GIANTGROWTH,
SC_STONEHARDSKIN,
- SC_VITALITYACTIVATION,
+ SC_VITALITYACTIVATION, // 320
SC_STORMBLAST,
SC_FIGHTINGSPIRIT,
SC_ABUNDANCE,
/**
* Arch Bishop
- **/
+ **/
SC_ADORAMUS,
SC_EPICLESIS,
SC_ORATIO,
SC_LAUDAAGNUS,
SC_LAUDARAMUS,
SC_RENOVATIO,
- SC_EXPIATIO,
+ SC_EXPIATIO, // 330
SC_DUPLELIGHT,
SC_SECRAMENT,
/**
@@ -412,7 +412,7 @@ typedef enum sc_type {
SC_SUMMON1,
SC_SUMMON2,
SC_SUMMON3,
- SC_SUMMON4,
+ SC_SUMMON4, // 340
SC_SUMMON5,
SC_READING_SB,
SC_FREEZINGSP,
@@ -428,7 +428,7 @@ typedef enum sc_type {
* Mechanic
**/
SC_ACCELERATION,
- SC_HOVERING,
+ SC_HOVERING, // 350
SC_SHAPESHIFT,
SC_INFRAREDSCAN,
SC_ANALYZE,
@@ -438,7 +438,7 @@ typedef enum sc_type {
SC_STEALTHFIELD,
SC_STEALTHFIELD_MASTER,
SC_OVERHEAT,
- SC_OVERHEAT_LIMITPOINT,
+ SC_OVERHEAT_LIMITPOINT, // 360
/**
* Guillotine Cross
**/
@@ -451,7 +451,7 @@ typedef enum sc_type {
SC_ROLLINGCUTTER,
SC_TOXIN,
SC_PARALYSE,
- SC_VENOMBLEED,
+ SC_VENOMBLEED, // 370
SC_MAGICMUSHROOM,
SC_DEATHHURT,
SC_PYREXIA,
@@ -464,7 +464,7 @@ typedef enum sc_type {
SC_FORCEOFVANGUARD,
SC_SHIELDSPELL_DEF,
SC_SHIELDSPELL_MDEF,
- SC_SHIELDSPELL_REF,
+ SC_SHIELDSPELL_REF, // 380
SC_EXEEDBREAK,
SC_PRESTIGE,
SC_BANDING,
@@ -477,7 +477,7 @@ typedef enum sc_type {
SC_SPELLFIST,
SC_COLD,
SC_STRIKING,
- SC_WARMER,
+ SC_WARMER, // 390
SC_VACUUM_EXTREME,
SC_PROPERTYWALK,
/**
@@ -490,30 +490,30 @@ typedef enum sc_type {
SC_ECHOSONG,
SC_HARMONIZE,
SC_SIREN,
- SC_DEEP_SLEEP,
+ SC_DEEP_SLEEP, // 400
SC_SIRCLEOFNATURE,
SC_GLOOMYDAY,
- SC_GLOOMYDAY_SK,
- SC_SONG_OF_MANA,
+ //SC_GLOOMYDAY_SK,
+ SC_SONG_OF_MANA = 404,
SC_DANCE_WITH_WUG,
SC_SATURDAY_NIGHT_FEVER,
SC_LERADS_DEW,
SC_MELODYOFSINK,
SC_BEYOND_OF_WARCRY,
- SC_UNLIMITED_HUMMING_VOICE,
+ SC_UNLIMITED_HUMMING_VOICE, // 410
SC_SITDOWN_FORCE,
- SC_NETHERWORLD,
+ //SC_NETHERWORLD,
/**
* Sura
**/
- SC_CRESCENTELBOW,
+ SC_CRESCENTELBOW = 413,
SC_CURSEDCIRCLE_ATKER,
SC_CURSEDCIRCLE_TARGET,
SC_LIGHTNINGWALK,
SC_RAISINGDRAGON,
SC_GENTLETOUCH_ENERGYGAIN,
SC_GENTLETOUCH_CHANGE,
- SC_GENTLETOUCH_REVITALIZE,
+ SC_GENTLETOUCH_REVITALIZE, // 420
/**
* Genetic
**/
@@ -526,7 +526,7 @@ typedef enum sc_type {
SC_STOMACHACHE,
SC_MYSTERIOUS_POWDER,
SC_MELON_BOMB,
- SC_BANANA_BOMB,
+ SC_BANANA_BOMB, // 430
SC_BANANA_BOMB_SITDOWN_POSTDELAY,
SC_SAVAGE_STEAK,
SC_COCKTAIL_WARG_BLOOD,
@@ -536,7 +536,7 @@ typedef enum sc_type {
SC_PUTTI_TAILS_NOODLES,
SC_BOOST500,
SC_FULL_SWING_K,
- SC_MANA_PLUS,
+ SC_MANA_PLUS, // 440
SC_MUSTLE_M,
SC_LIFE_FORCE_F,
SC_EXTRACT_WHITE_POTION_Z,
@@ -549,7 +549,7 @@ typedef enum sc_type {
SC__AUTOSHADOWSPELL,
SC__SHADOWFORM,
SC__BODYPAINT,
- SC__INVISIBILITY,
+ SC__INVISIBILITY, // 450
SC__DEADLYINFECT,
SC__ENERVATION,
SC__GROOMY,
@@ -559,7 +559,7 @@ typedef enum sc_type {
SC__WEAKNESS,
SC__STRIPACCESSARY,
SC__MANHOLE,
- SC__BLOODYLUST,
+ SC__BLOODYLUST, // 460
/**
* Elemental Spirits
**/
@@ -572,7 +572,7 @@ typedef enum sc_type {
SC_WATER_DROP,
SC_WATER_DROP_OPTION,
SC_WATER_BARRIER,
- SC_WIND_STEP,
+ SC_WIND_STEP, // 470
SC_WIND_STEP_OPTION,
SC_WIND_CURTAIN,
SC_WIND_CURTAIN_OPTION,
@@ -582,7 +582,7 @@ typedef enum sc_type {
SC_STONE_SHIELD,
SC_STONE_SHIELD_OPTION,
SC_POWER_OF_GAIA,
- SC_PYROTECHNIC,
+ SC_PYROTECHNIC, // 480
SC_PYROTECHNIC_OPTION,
SC_HEATER,
SC_HEATER_OPTION,
@@ -592,7 +592,7 @@ typedef enum sc_type {
SC_AQUAPLAY_OPTION,
SC_COOLER,
SC_COOLER_OPTION,
- SC_CHILLY_AIR,
+ SC_CHILLY_AIR, // 490
SC_CHILLY_AIR_OPTION,
SC_GUST,
SC_GUST_OPTION,
@@ -602,7 +602,7 @@ typedef enum sc_type {
SC_WILD_STORM_OPTION,
SC_PETROLOGY,
SC_PETROLOGY_OPTION,
- SC_CURSED_SOIL,
+ SC_CURSED_SOIL, // 500
SC_CURSED_SOIL_OPTION,
SC_UPHEAVAL,
SC_UPHEAVAL_OPTION,
@@ -613,21 +613,21 @@ typedef enum sc_type {
/* Guild Aura */
SC_LEADERSHIP,
SC_GLORYWOUNDS,
- SC_SOULCOLD,
+ SC_SOULCOLD, // 510
SC_HAWKEYES,
/* ... */
SC_ODINS_POWER,
/* Sorcerer .extra */
SC_FIRE_INSIGNIA,
SC_WATER_INSIGNIA,
- SC_WIND_INSIGNIA,
+ SC_WIND_INSIGNIA,
SC_EARTH_INSIGNIA,
/* new pushcart */
SC_PUSH_CART,
/* Warlock Spell books */
SC_SPELLBOOK1,
SC_SPELLBOOK2,
- SC_SPELLBOOK3,
+ SC_SPELLBOOK3, // 520
SC_SPELLBOOK4,
SC_SPELLBOOK5,
SC_SPELLBOOK6,
@@ -639,13 +639,13 @@ typedef enum sc_type {
/* Max HP & SP */
SC_INCMHP,
SC_INCMSP,
- SC_PARTYFLEE,
+ SC_PARTYFLEE,
/**
* Kagerou & Oboro [malufett]
**/
SC_MEIKYOUSISUI,
SC_KO_JYUMONJIKIRI,
- SC_KYOUGAKU,
+ SC_KYOUGAKU, // 530
SC_IZAYOI,
SC_ZENKAI,
SC_KG_KAGEHUMI,
@@ -656,19 +656,19 @@ typedef enum sc_type {
SC_AKAITSUKI,
//homon S
- SC_STYLE_CHANGE,
- SC_GOLDENE_FERSE,
- SC_ANGRIFFS_MODUS,
- SC_ERASER_CUTTER,
- SC_OVERED_BOOST,
- SC_LIGHT_OF_REGENE,
- SC_VOLCANIC_ASH,
- SC_GRANITIC_ARMOR,
- SC_MAGMA_FLOW,
- SC_PYROCLASTIC,
- SC_NEEDLE_OF_PARALYZE,
- SC_PAIN_KILLER,
-#ifdef RENEWAL
+ SC_STYLE_CHANGE,
+ SC_GOLDENE_FERSE, // 540
+ SC_ANGRIFFS_MODUS,
+ SC_ERASER_CUTTER,
+ SC_OVERED_BOOST,
+ SC_LIGHT_OF_REGENE,
+ SC_VOLCANIC_ASH,
+ SC_GRANITIC_ARMOR,
+ SC_MAGMA_FLOW,
+ SC_PYROCLASTIC,
+ SC_NEEDLE_OF_PARALYZE,
+ SC_PAIN_KILLER, // 550
+#ifdef RENEWAL
SC_EXTREMITYFIST2,
SC_RAID,
#endif
@@ -679,7 +679,7 @@ typedef enum sc_type {
SC_KINGS_GRACE,
SC_TELEKINESIS_INTENSE,
SC_OFFERTORIUM,
- SC_FRIGG_SONG,
+ SC_FRIGG_SONG, // 560
SC_ALL_RIDING,
SC_HANBOK,
@@ -691,7 +691,7 @@ typedef enum sc_type {
SC_MTF_RANGEATK,
SC_MTF_MATK,
SC_MTF_MLEATKED,
- SC_MTF_CRIDAMAGE,
+ SC_MTF_CRIDAMAGE, // 570
SC_MOONSTAR,
SC_SUPER_STAR,
@@ -700,6 +700,8 @@ typedef enum sc_type {
SC_STRANGELIGHTS,
SC_DECORATION_OF_MUSIC,
+ SC__MAELSTROM,
+ SC__CHAOS,
SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
} sc_type;
// Official status change ids, used to display status icons on the client.
@@ -1434,6 +1436,7 @@ enum si_type {
//SI_ = 735,
SI_CHILL = 736,
SI_BURNT = 737,
+ SI_FLASHCOMBO = 740,
SI_B_TRAP = 752,
SI_E_CHAIN = 753,
SI_E_QD_SHOT_READY = 754,
@@ -1833,9 +1836,9 @@ struct status_change {
#define status_get_mode(bl) (status->get_status_data(bl)->mode)
//Short version, receives rate in 1->100 range, and does not uses a flag setting.
-#define sc_start(bl, type, rate, val1, tick) (status->change_start((bl),(type),100*(rate),(val1),0,0,0,(tick),0))
-#define sc_start2(bl, type, rate, val1, val2, tick) (status->change_start((bl),(type),100*(rate),(val1),(val2),0,0,(tick),0))
-#define sc_start4(bl, type, rate, val1, val2, val3, val4, tick) (status->change_start((bl),(type),100*(rate),(val1),(val2),(val3),(val4),(tick),0))
+#define sc_start(src, bl, type, rate, val1, tick) (status->change_start((src),(bl),(type),100*(rate),(val1),0,0,0,(tick),0))
+#define sc_start2(src, bl, type, rate, val1, val2, tick) (status->change_start((src),(bl),(type),100*(rate),(val1),(val2),0,0,(tick),0))
+#define sc_start4(src, bl, type, rate, val1, val2, val3, val4, tick) (status->change_start((src),(bl),(type),100*(rate),(val1),(val2),(val3),(val4),(tick),0))
#define status_change_end(bl,type,tid) (status->change_end_((bl),(type),(tid),__FILE__,__LINE__))
@@ -1912,6 +1915,7 @@ struct status_interface {
int (*set_sp) (struct block_list *bl, unsigned int sp, int flag);
int (*heal) (struct block_list *bl,int64 hp,int64 sp, int flag);
int (*revive) (struct block_list *bl, unsigned char per_hp, unsigned char per_sp);
+ int (*fixed_revive) (struct block_list *bl, unsigned int per_hp, unsigned int per_sp);
struct regen_data * (*get_regen_data) (struct block_list *bl);
struct status_data * (*get_status_data) (struct block_list *bl);
struct status_data * (*get_base_status) (struct block_list *bl);
@@ -1932,8 +1936,8 @@ struct status_interface {
struct status_change * (*get_sc) (struct block_list *bl);
int (*isdead) (struct block_list *bl);
int (*isimmune) (struct block_list *bl);
- int (*get_sc_def) (struct block_list *bl, enum sc_type type, int rate, int tick, int flag);
- int (*change_start) (struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag);
+ int (*get_sc_def) (struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, int flag);
+ int (*change_start) (struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag);
int (*change_end_) (struct block_list* bl, enum sc_type type, int tid, const char* file, int line);
int (*kaahi_heal_timer) (int tid, int64 tick, int id, intptr_t data);
int (*change_timer) (int tid, int64 tick, int id, intptr_t data);
diff --git a/src/map/unit.c b/src/map/unit.c
index 320649a6c..2926661ad 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -377,7 +377,7 @@ int unit_walktoxy( struct block_list *bl, short x, short y, int flag)
unit->set_target(ud, 0);
sc = status->get_sc(bl);
- if (sc && sc->data[SC_CONFUSION]) //Randomize the target position
+ if (sc && (sc->data[SC_CONFUSION] || sc->data[SC__CHAOS])) //Randomize the target position
map->random_dir(bl, &ud->to_x, &ud->to_y);
if(ud->walktimer != INVALID_TIMER) {
@@ -449,7 +449,7 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, int
unit->set_target(ud, 0);
sc = status->get_sc(bl);
- if (sc && sc->data[SC_CONFUSION]) //Randomize the target position
+ if (sc && (sc->data[SC_CONFUSION] || sc->data[SC__CHAOS])) //Randomize the target position
map->random_dir(bl, &ud->to_x, &ud->to_y);
if(ud->walktimer != INVALID_TIMER) {
@@ -968,7 +968,7 @@ int unit_can_move(struct block_list *bl) {
|| sc->data[SC_CURSEDCIRCLE_ATKER]
|| sc->data[SC_CURSEDCIRCLE_TARGET]
|| (sc->data[SC_COLD] && bl->type != BL_MOB)
- || sc->data[SC_NETHERWORLD]
+ || sc->data[SC_DEEP_SLEEP]
|| (sc->data[SC_CAMOUFLAGE] && sc->data[SC_CAMOUFLAGE]->val1 < 3 && !(sc->data[SC_CAMOUFLAGE]->val3&1))
|| sc->data[SC_MEIKYOUSISUI]
|| sc->data[SC_KG_KAGEHUMI]
@@ -1012,10 +1012,10 @@ int unit_resume_running(int tid, int64 tick, int id, intptr_t data) {
if(sd && pc_isridingwug(sd))
clif->skill_nodamage(ud->bl,ud->bl,RA_WUGDASH,ud->skill_lv,
- sc_start4(ud->bl,status->skill2sc(RA_WUGDASH),100,ud->skill_lv,unit->getdir(ud->bl),0,0,1));
+ sc_start4(ud->bl,ud->bl,status->skill2sc(RA_WUGDASH),100,ud->skill_lv,unit->getdir(ud->bl),0,0,1));
else
clif->skill_nodamage(ud->bl,ud->bl,TK_RUN,ud->skill_lv,
- sc_start4(ud->bl,status->skill2sc(TK_RUN),100,ud->skill_lv,unit->getdir(ud->bl),0,0,0));
+ sc_start4(ud->bl,ud->bl,status->skill2sc(TK_RUN),100,ud->skill_lv,unit->getdir(ud->bl),0,0,0));
if (sd) clif->walkok(sd);
@@ -1470,10 +1470,6 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
- if( (skill_id >= SC_MANHOLE && skill_id <= SC_FEINTBOMB) && map->getcell(src->m, skill_x, skill_y, CELL_CHKMAELSTROM) ) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- return 0;
- }
}
if (!status->check_skilluse(src, NULL, skill_id, 0))
@@ -1956,7 +1952,7 @@ int unit_skillcastcancel(struct block_list *bl,int type)
return 0;
if (sd && (sd->special_state.no_castcancel2 ||
- ((sd->sc.data[SC_UNLIMITED_HUMMING_VOICE] || sd->special_state.no_castcancel) && !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground))) //fixed flags being read the wrong way around [blackhole89]
+ ( sd->special_state.no_castcancel && !map_flag_gvg(bl->m) && !map->list[bl->m].flag.battleground))) //fixed flags being read the wrong way around [blackhole89]
return 0;
}
@@ -2106,6 +2102,11 @@ int unit_remove_map(struct block_list *bl, clr_type clrtype, const char* file, i
status_change_end(bl, SC_STOP, INVALID_TIMER);
status_change_end(bl, SC_WUGDASH, INVALID_TIMER);
status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
+ status_change_end(bl, SC_MAGNETICFIELD, INVALID_TIMER);
+ status_change_end(bl, SC_NEUTRALBARRIER_MASTER, INVALID_TIMER);
+ status_change_end(bl, SC_NEUTRALBARRIER, INVALID_TIMER);
+ status_change_end(bl, SC_STEALTHFIELD_MASTER, INVALID_TIMER);
+ status_change_end(bl, SC_STEALTHFIELD, INVALID_TIMER);
status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
status_change_end(bl, SC__MANHOLE, INVALID_TIMER);
status_change_end(bl, SC_VACUUM_EXTREME, INVALID_TIMER);