summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authormalufett <malufett.eat.my.binaries@gmail.com>2013-06-13 01:56:21 +0800
committermalufett <malufett.eat.my.binaries@gmail.com>2013-06-13 01:56:21 +0800
commit0395610469ffcd3b71c93ef90861f73e0ab8d16f (patch)
tree5755aa69c3fef1355bc164a3870a1b25ecce9cf6 /src/map
parent8821ff87533b037d5d4914db6dbdeacfa5fca4ce (diff)
downloadhercules-0395610469ffcd3b71c93ef90861f73e0ab8d16f.tar.gz
hercules-0395610469ffcd3b71c93ef90861f73e0ab8d16f.tar.bz2
hercules-0395610469ffcd3b71c93ef90861f73e0ab8d16f.tar.xz
hercules-0395610469ffcd3b71c93ef90861f73e0ab8d16f.zip
Hercules Renewal Phase : Renewal
Rename SC names to eagis standard. Implement SC Configuration.(see db/sc_config.txt) Skill updates and fixes. Some code optimization. Signed-off-by: malufett <malufett.eat.my.binaries@gmail.com>
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.c8
-rw-r--r--src/map/battle.c5229
-rw-r--r--src/map/battle.h22
-rw-r--r--src/map/clif.c181
-rw-r--r--src/map/clif.h12
-rw-r--r--src/map/itemdb.h3
-rw-r--r--src/map/map.c58
-rw-r--r--src/map/mercenary.c2
-rw-r--r--src/map/mob.c10
-rw-r--r--src/map/packets.h1
-rw-r--r--src/map/party.c2
-rw-r--r--src/map/pc.c258
-rw-r--r--src/map/pc.h18
-rw-r--r--src/map/script.c4
-rw-r--r--src/map/skill.c2437
-rw-r--r--src/map/skill.h25
-rw-r--r--src/map/status.c2787
-rw-r--r--src/map/status.h770
-rw-r--r--src/map/unit.c63
-rw-r--r--src/map/vending.c2
20 files changed, 6308 insertions, 5584 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index f96c7920a..d9810e77c 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -6148,7 +6148,7 @@ ACMD(npctalk)
unsigned long color=0;
if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEPSLEEP] || sd->sc.data[SC__BLOODYLUST] ||
+ (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || sd->sc.data[SC__BLOODYLUST] ||
(sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
return false;
@@ -6199,7 +6199,7 @@ ACMD(pettalk)
}
if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEPSLEEP] || sd->sc.data[SC__BLOODYLUST] ||
+ (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || sd->sc.data[SC__BLOODYLUST] ||
(sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
return false;
@@ -6965,7 +6965,7 @@ ACMD(homtalk)
}
if (sd->sc.count && //no "chatting" while muted.
- (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEPSLEEP] || sd->sc.data[SC__BLOODYLUST] ||
+ (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || sd->sc.data[SC__BLOODYLUST] ||
(sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
return false;
@@ -7348,7 +7348,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_DEEPSLEEP] || sd->sc.data[SC__BLOODYLUST] ||
+ (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEP_SLEEP] || sd->sc.data[SC__BLOODYLUST] ||
(sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT)))
return false;
diff --git a/src/map/battle.c b/src/map/battle.c
index a2cc7692c..a4908982c 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -363,14 +363,14 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
if( tsc->data[SC_SPIDERWEB]->val2 == 0 )
status_change_end(target, SC_SPIDERWEB, INVALID_TIMER);
}
- if( tsc->data[SC_THORNSTRAP])
- status_change_end(target, SC_THORNSTRAP, INVALID_TIMER);
+ 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_CRYSTALIZE] && target->type != BL_MOB)
status_change_end(target, SC_CRYSTALIZE, INVALID_TIMER);
if( tsc->data[SC_EARTH_INSIGNIA]) damage += damage/2;
- if( tsc->data[SC_ASH]) damage += damage/2; //150%
+ if( tsc->data[SC_VOLCANIC_ASH]) damage += damage/2; //150%
break;
case ELE_HOLY:
if( tsc->data[SC_ORATIO]) ratio += tsc->data[SC_ORATIO]->val1 * 2;
@@ -394,23 +394,454 @@ int battle_attr_fix(struct block_list *src, struct block_list *target, int damag
struct map_session_data *sd = BL_CAST(BL_PC, src);
int s;
- ARR_FIND(1, 6, s, sd->talisman[s] > 0);
+ ARR_FIND(1, 6, s, sd->charm[s] > 0);
if( s < 5 && atk_elem == s )
- ratio += sd->talisman[s] * 2; // +2% custom value
+ ratio += sd->charm[s] * 2; // +2% custom value
}
if( target && target->type == BL_PC ) {
struct map_session_data *tsd = BL_CAST(BL_PC, target);
int t;
- ARR_FIND(1, 6, t, tsd->talisman[t] > 0);
+ ARR_FIND(1, 6, t, tsd->charm[t] > 0);
if( t < 5 && atk_elem == t )
- damage -= damage * ( tsd->talisman[t] * 3 ) / 100;// -3% custom value
+ damage -= damage * ( tsd->charm[t] * 3 ) / 100;// -3% custom value
}
return damage*ratio/100;
}
+int battle_calc_weapon_damage(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, struct weapon_atk *watk, int nk, bool n_ele, short s_ele, short s_ele_, int size, int type, int flag, int flag2){ // [malufett]
+ int damage, eatk = 0;
+ struct status_change *sc;
+ struct map_session_data *sd;
+
+ if( !src || !bl )
+ return 0;
+
+ sc = status_get_sc(src);
+ sd = BL_CAST(BL_PC, src);
+
+ damage = status_get_weapon_atk(src, watk, flag);
+
+ if( sd ){
+ if( type == EQI_HAND_R )
+ damage = battle->calc_sizefix(sd, damage, EQI_HAND_R, size, flag&8);
+ else
+ damage = battle->calc_sizefix(sd, damage, EQI_HAND_L, size, flag&8);
+
+ if( sd->bonus.eatk > 0 )
+ eatk = sd->bonus.eatk;
+ if( flag&2 && sd->bonus.arrow_atk )
+ eatk += sd->bonus.arrow_atk;
+ }
+
+ if( sc && sc->count ){
+ if( sc->data[SC_ZENKAI] && watk->ele == sc->data[SC_ZENKAI]->val2 )
+ eatk += 200;
+ #ifdef RENEWAL_EDP
+ if( sc->data[SC_EDP] && skill_id != AS_GRIMTOOTH && skill_id != AS_VENOMKNIFE ){
+ eatk = eatk * sc->data[SC_EDP]->val3 / 100; // 400%
+ damage = damage * sc->data[SC_EDP]->val4 / 100; // 500%
+ damage--; // temporary until we find the correct formula [malufett]
+ }
+ #endif
+ }
+
+ /* [malufett]
+ some unknown factors that needs to be discovered. PS: it's something related with ranged attacks
+ if( eatk ){
+ eatk += unknown value;
+ eatk = eatk * (unknown value) / 100;
+ }
+ */
+
+ if( sc && sc->data[SC_WATK_ELEMENT] )
+ damage = damage + eatk;
+ else
+ damage = battle->calc_elefix(src, bl, skill_id, skill_lv, damage + eatk, nk, n_ele, s_ele, s_ele_, false, flag);
+
+ /**
+ * In RE Shield Bommerang takes weapon element only for damage calculation,
+ * - resist calculation is always against neutral
+ **/
+ if ( skill_id == CR_SHIELDBOOMERANG )
+ s_ele = s_ele_ = ELE_NEUTRAL;
+
+ if( type == EQI_HAND_R )
+ damage = battle->calc_cardfix(BF_WEAPON, src, bl, nk, s_ele, s_ele_, damage, 2, flag2);
+ else
+ damage = battle->calc_cardfix(BF_WEAPON, src, bl, nk, s_ele, s_ele_, damage, 3, flag2);
+
+ return damage;
+}
+/*==========================================
+ * Calculates the standard damage of a normal attack assuming it hits,
+ * it calculates nothing extra fancy, is needed for magnum break's WATK_ELEMENT bonus. [Skotlex]
+ *------------------------------------------
+ * Pass damage2 as NULL to not calc it.
+ * Flag values:
+ * &1: Critical hit
+ * &2: Arrow attack
+ * &4: Skill is Magic Crasher
+ * &8: Skip target size adjustment (Extremity Fist?)
+ *&16: Arrow attack but BOW, REVOLVER, RIFLE, SHOTGUN, GATLING or GRENADE type weapon not equipped (i.e. shuriken, kunai and venom knives not affected by DEX)
+ */
+
+#ifdef RENEWAL
+int battle_calc_base_damage(struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int nk, bool n_ele, short s_ele, short s_ele_, int type, int flag, int flag2)
+{
+ int damage, batk;
+ struct status_change *sc = status_get_sc(src);
+ struct status_data *status = status_get_status_data(src);
+
+ if( sc && sc->data[SC_TK_SEVENWIND] && !sc->data[SC_WATK_ELEMENT] )
+ batk = battle->calc_elefix(src, bl, skill_id, skill_lv, status->batk, nk, n_ele, s_ele, s_ele_, false, flag);
+ else
+ batk = status->batk;
+
+ if( type == EQI_HAND_L )
+ damage = batk + 3 * battle->calc_weapon_damage(src, bl, skill_id, skill_lv, &status->lhw, nk, n_ele, s_ele, s_ele_, status_get_size(bl), type, flag, flag2) / 4;
+ else
+ damage = (batk << 1) + battle->calc_weapon_damage(src, bl, skill_id, skill_lv, &status->rhw, nk, n_ele, s_ele, s_ele_, status_get_size(bl), type, flag, flag2);
+#else
+static int battle_calc_base_damage(struct status_data *status, struct weapon_atk *wa, struct status_change *sc, unsigned short t_size, struct map_session_data *sd, int flag)
+{
+ unsigned int atkmin=0, atkmax=0;
+ short type = 0;
+ int damage = 0;
+
+ if (!sd) { //Mobs/Pets
+ if(flag&4) {
+ atkmin = status->matk_min;
+ atkmax = status->matk_max;
+ } else {
+ atkmin = wa->atk;
+ atkmax = wa->atk2;
+ }
+ if (atkmin > atkmax)
+ atkmin = atkmax;
+ } else { //PCs
+ atkmax = wa->atk;
+ type = (wa == &status->lhw)?EQI_HAND_L:EQI_HAND_R;
+
+ if (!(flag&1) || (flag&2)) { //Normal attacks
+ atkmin = status->dex;
+
+ if (sd->equip_index[type] >= 0 && sd->inventory_data[sd->equip_index[type]])
+ atkmin = atkmin*(80 + sd->inventory_data[sd->equip_index[type]]->wlv*20)/100;
+
+ if (atkmin > atkmax)
+ atkmin = atkmax;
+
+ if(flag&2 && !(flag&16)) { //Bows
+ atkmin = atkmin*atkmax/100;
+ if (atkmin > atkmax)
+ atkmax = atkmin;
+ }
+ }
+ }
+
+ if (sc && sc->data[SC_MAXIMIZEPOWER])
+ atkmin = atkmax;
+
+ //Weapon Damage calculation
+ if (!(flag&1))
+ damage = (atkmax>atkmin? rnd()%(atkmax-atkmin):0)+atkmin;
+ else
+ damage = atkmax;
+
+ if (sd) {
+ //rodatazone says the range is 0~arrow_atk-1 for non crit
+ if (flag&2 && sd->bonus.arrow_atk)
+ damage += ( (flag&1) ? sd->bonus.arrow_atk : rnd()%sd->bonus.arrow_atk );
+
+ //SizeFix only for players
+ if (!(sd->special_state.no_sizefix || (flag&8)))
+ DAMAGE_RATE(type==EQI_HAND_L?
+ sd->left_weapon.atkmods[t_size]:
+ sd->right_weapon.atkmods[t_size])
+ }
+
+ //Finally, add baseatk
+ if(flag&4)
+ damage += status->matk_min;
+ else
+ damage += status->batk;
+
+ //rodatazone says that Overrefine bonuses are part of baseatk
+ //Here we also apply the weapon_atk_rate bonus so it is correctly applied on left/right hands.
+ if(sd) {
+ if (type == EQI_HAND_L) {
+ if(sd->left_weapon.overrefine)
+ damage += rnd()%sd->left_weapon.overrefine+1;
+ if (sd->weapon_atk_rate[sd->weapontype2])
+ DAMAGE_ADDRATE(sd->weapon_atk_rate[sd->weapontype2])
+ } else { //Right hand
+ if(sd->right_weapon.overrefine)
+ damage += rnd()%sd->right_weapon.overrefine+1;
+ if (sd->weapon_atk_rate[sd->weapontype1])
+ DAMAGE_ADDRATE(sd->weapon_atk_rate[sd->weapontype1])
+ }
+ }
+#endif
+ return damage;
+}
+
+int battle_calc_sizefix(struct map_session_data *sd, int damage, int type, int size, bool ignore){
+ //SizeFix only for players
+ if (!(sd->special_state.no_sizefix || (ignore)))
+ damage = damage * ( type == EQI_HAND_L ? sd->left_weapon.atkmods[size] : sd->right_weapon.atkmods[size] ) / 100;
+ return damage;
+}
+
+/*==========================================
+ * Passive skill damages increases
+ *------------------------------------------*/
+int battle_addmastery(struct map_session_data *sd,struct block_list *target,int dmg,int type)
+{
+ int damage,skill;
+ struct status_data *status = status_get_status_data(target);
+ int weapon;
+ damage = dmg;
+
+ nullpo_ret(sd);
+
+ if((skill = pc->checkskill(sd,AL_DEMONBANE)) > 0 &&
+ target->type == BL_MOB && //This bonus doesnt work against players.
+ (battle->check_undead(status->race,status->def_ele) || status->race==RC_DEMON) )
+ damage += (int)(skill*(3+sd->status.base_level/20.0));
+ //damage += (skill * 3);
+ if( (skill = pc->checkskill(sd, RA_RANGERMAIN)) > 0 && (status->race == RC_BRUTE || status->race == RC_PLANT || status->race == RC_FISH) )
+ damage += (skill * 5);
+ if( (skill = pc->checkskill(sd,NC_RESEARCHFE)) > 0 && (status->def_ele == ELE_FIRE || status->def_ele == ELE_EARTH) )
+ damage += (skill * 10);
+ if( pc_ismadogear(sd) )
+ damage += 20 + 20 * pc->checkskill(sd, NC_MADOLICENCE);
+#ifdef RENEWAL
+ if( (skill = pc->checkskill(sd,BS_WEAPONRESEARCH)) > 0 )
+ damage += (skill * 2);
+#endif
+ if((skill = pc->checkskill(sd,HT_BEASTBANE)) > 0 && (status->race==RC_BRUTE || status->race==RC_INSECT) ) {
+ damage += (skill * 4);
+ if (sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_HUNTER)
+ damage += sd->status.str;
+ }
+
+ if(type == 0)
+ weapon = sd->weapontype1;
+ else
+ weapon = sd->weapontype2;
+ switch(weapon)
+ {
+ case W_1HSWORD:
+ #ifdef RENEWAL
+ if((skill = pc->checkskill(sd,AM_AXEMASTERY)) > 0)
+ damage += (skill * 3);
+ #endif
+ case W_DAGGER:
+ if((skill = pc->checkskill(sd,SM_SWORD)) > 0)
+ damage += (skill * 4);
+ if((skill = pc->checkskill(sd,GN_TRAINING_SWORD)) > 0)
+ damage += skill * 10;
+ break;
+ case W_2HSWORD:
+ #ifdef RENEWAL
+ if((skill = pc->checkskill(sd,AM_AXEMASTERY)) > 0)
+ damage += (skill * 3);
+ #endif
+ if((skill = pc->checkskill(sd,SM_TWOHAND)) > 0)
+ damage += (skill * 4);
+ break;
+ case W_1HSPEAR:
+ case W_2HSPEAR:
+ if((skill = pc->checkskill(sd,KN_SPEARMASTERY)) > 0) {
+
+ if(!pc_isriding(sd))
+ damage += (skill * 4);
+ else if(pc_isridingdragon(sd))
+ damage += (skill * 10);
+ else
+ damage += (skill * 5);
+ }
+ break;
+ case W_1HAXE:
+ case W_2HAXE:
+ if((skill = pc->checkskill(sd,AM_AXEMASTERY)) > 0)
+ damage += (skill * 3);
+ if((skill = pc->checkskill(sd,NC_TRAININGAXE)) > 0)
+ damage += (skill * 5);
+ break;
+ case W_MACE:
+ case W_2HMACE:
+ if((skill = pc->checkskill(sd,PR_MACEMASTERY)) > 0)
+ damage += (skill * 3);
+ if((skill = pc->checkskill(sd,NC_TRAININGAXE)) > 0)
+ damage += (skill * 5);
+ break;
+ case W_FIST:
+ if((skill = pc->checkskill(sd,TK_RUN)) > 0)
+ damage += (skill * 10);
+ // No break, fallthrough to Knuckles
+ case W_KNUCKLE:
+ if((skill = pc->checkskill(sd,MO_IRONHAND)) > 0)
+ damage += (skill * 3);
+ break;
+ case W_MUSICAL:
+ if((skill = pc->checkskill(sd,BA_MUSICALLESSON)) > 0)
+ damage += (skill * 3);
+ break;
+ case W_WHIP:
+ if((skill = pc->checkskill(sd,DC_DANCINGLESSON)) > 0)
+ damage += (skill * 3);
+ break;
+ case W_BOOK:
+ if((skill = pc->checkskill(sd,SA_ADVANCEDBOOK)) > 0)
+ damage += (skill * 3);
+ break;
+ case W_KATAR:
+ if((skill = pc->checkskill(sd,AS_KATAR)) > 0)
+ damage += (skill * 3);
+ break;
+ }
+
+ return damage;
+}
+
+/*==========================================
+ * Calculates ATK masteries.
+ *------------------------------------------*/
+int battle_calc_masteryfix(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int damage, int div, bool left, bool weapon){
+ int skill, i;
+ struct map_session_data *sd;
+ struct status_change *sc;
+
+ nullpo_ret(src);
+ nullpo_ret(target);
+
+ sd = BL_CAST(BL_PC, src);
+ sc = status_get_sc(src);
+
+ if ( !sd )
+ return damage;
+
+ switch( skill_id ){ // specific skill masteries
+ case MO_INVESTIGATE:
+ case MO_EXTREMITYFIST:
+ case CR_GRANDCROSS:
+ case NJ_ISSEN:
+ case CR_ACIDDEMONSTRATION:
+ return damage;
+ case NJ_SYURIKEN:
+ if( (skill = pc->checkskill(sd,NJ_TOBIDOUGU)) > 0 && weapon )
+ damage += 3 * skill;
+ break;
+ case NJ_KUNAI:
+ if( weapon )
+ damage += 60;
+ break;
+ case RA_WUGDASH:
+ case RA_WUGSTRIKE:
+ case RA_WUGBITE:
+ damage += 30*pc->checkskill(sd, RA_TOOTHOFWUG);
+ break;
+ }
+
+ if ( sc && sc->data[SC_MIRACLE] ) i = 2; //Star anger
+ else
+ ARR_FIND(0, MAX_PC_FEELHATE, i, status_get_class(target) == sd->hate_mob[i]);
+ if ( i < MAX_PC_FEELHATE && (skill=pc->checkskill(sd,sg_info[i].anger_id)) && weapon ){
+ int ratio = sd->status.base_level + status_get_dex(src) + status_get_luk(src);
+ if ( i == 2 ) ratio += status_get_str(src); //Star Anger
+ if (skill < 4 )
+ ratio /= 12 - 3 * skill;
+ damage += damage * ratio;
+ }
+
+ if( sc ){
+ if(sc->data[SC_GN_CARTBOOST])
+ damage += 10 * sc->data[SC_GN_CARTBOOST]->val1;
+ if(sc->data[SC_CAMOUFLAGE])
+ damage += 30 * ( 10 - sc->data[SC_CAMOUFLAGE]->val4 );
+ }
+
+ // general skill masteries
+#ifdef RENEWAL
+ if( skill_id == MO_FINGEROFFENSIVE )//The finger offensive spheres on moment of attack do count. [Skotlex]
+ damage += div * sd->spiritball_old * 3;
+ else
+ damage += div * sd->spiritball * 3;
+ if( skill_id != CR_SHIELDBOOMERANG ) // Only Shield boomerang doesn't takes the Star Crumbs bonus.
+ damage += div * (left ? sd->left_weapon.star : sd->right_weapon.star);
+#else
+ if( skill_id != ASC_BREAKER && weapon ) // Adv Katar Mastery is does not applies to ASC_BREAKER, but other masteries DO apply >_>
+ if( sd->status.weapon == W_KATAR && (skill=pc->checkskill(sd,ASC_KATAR)) > 0 )
+ damage += damage * (10 + 2 * skill) / 100;
+#endif
+
+
+ damage = battle->add_mastery(sd, target, damage, left);
+
+ if((skill = pc->checkskill(sd,AB_EUCHARISTICA)) > 0 &&
+ (status_get_status_data(target)->race == RC_DEMON || status_get_status_data(target)->def_ele == ELE_DARK) )
+ damage += damage * skill / 100;
+
+ return damage;
+}
+/*==========================================
+ * Elemental attribute fix.
+ *------------------------------------------*/
+int battle_calc_elefix(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int damage, int nk, int n_ele, int s_ele, int s_ele_, bool left, int flag){
+ struct status_data *sstatus, *tstatus;
+ struct status_change *sc;
+
+ nullpo_ret(src);
+ nullpo_ret(target);
+
+ sstatus = status_get_status_data(src);
+ tstatus = status_get_status_data(target);
+ sc = status_get_sc(src);
+
+ if( (nk&NK_NO_ELEFIX) && n_ele )
+ return damage;
+
+ if( damage > 0 )
+ {
+ if( left )
+ damage = battle->attr_fix(src, target, damage, s_ele_, tstatus->def_ele, tstatus->ele_lv);
+ else{
+ 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 == GS_GROUNDDRIFT ) //Additional 50*lv Neutral damage.
+ damage += battle_attr_fix(src,target,50*skill_lv,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
+ }
+ }
+ if( sc && sc->data[SC_WATK_ELEMENT] )
+ { // Descriptions indicate this means adding a percent of a normal attack in another element. [Skotlex]
+ damage =
+#ifndef RENEWAL
+ battle->calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, ((TBL_PC*)src), (flag?2:0))
+#else
+ battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, (flag?2:0)|(sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), 0)
+#endif
+ * sc->data[SC_WATK_ELEMENT]->val2 / 100;
+
+ damage += battle->attr_fix(src, target, damage, sc->data[SC_WATK_ELEMENT]->val1, tstatus->def_ele, tstatus->ele_lv);
+ if( left ){
+ damage =
+#ifndef RENEWAL
+ battle->calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, ((TBL_PC*)src), (flag?2:0))
+#else
+ battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_L, (flag?2:0)|(sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), 0)
+#endif
+ * sc->data[SC_WATK_ELEMENT]->val2 / 100;
+ damage += battle->attr_fix(src, target, damage, sc->data[SC_WATK_ELEMENT]->val1, tstatus->def_ele, tstatus->ele_lv);
+ }
+ }
+
+ return damage;
+}
/*==========================================
* Calculates card bonuses damage adjustments.
*------------------------------------------*/
@@ -422,6 +853,9 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
if( !damage )
return 0;
+
+ nullpo_ret(src);
+ nullpo_ret(target);
sd = BL_CAST(BL_PC, src);
tsd = BL_CAST(BL_PC, target);
@@ -487,8 +921,8 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
cardfix = cardfix * ( 100 - tsd->bonus.magic_def_rate ) / 100;
- if( tsd->sc.data[SC_MDEF_RATE] )
- cardfix = cardfix * ( 100 - tsd->sc.data[SC_MDEF_RATE]->val1 ) / 100;
+ if( tsd->sc.data[SC_PROTECT_MDEF] )
+ cardfix = cardfix * ( 100 - tsd->sc.data[SC_PROTECT_MDEF]->val1 ) / 100;
if (cardfix != 1000)
damage = damage * cardfix / 1000;
@@ -618,12 +1052,6 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
if( flag&BF_LONG )
cardfix = cardfix * ( 100 + sd->bonus.long_attack_atk_rate ) / 100;
-#ifdef RENEWAL_EDP
- if( sd->sc.data[SC_EDP] ){
- cardfix = cardfix * (100 + sd->sc.data[SC_EDP]->val1 * 60 ) / 100;
- cardfix_ = cardfix_ * (100 + sd->sc.data[SC_EDP]->val1 * 60 ) / 100;
- }
-#endif
if( (left&1) && cardfix_ != 1000 )
damage = damage * cardfix_ / 1000;
else if( cardfix != 1000 )
@@ -677,8 +1105,8 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
else // BF_LONG (there's no other choice)
cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
- if( tsd->sc.data[SC_DEF_RATE] )
- cardfix = cardfix * ( 100 - tsd->sc.data[SC_DEF_RATE]->val1 ) / 100;
+ if( tsd->sc.data[SC_PROTECT_DEF] )
+ cardfix = cardfix * ( 100 - tsd->sc.data[SC_PROTECT_DEF]->val1 ) / 100;
if( cardfix != 1000 )
damage = damage * cardfix / 1000;
@@ -714,7 +1142,7 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
else // BF_LONG (there's no other choice)
cardfix = cardfix * ( 100 - tsd->bonus.long_attack_def_rate ) / 100;
- if (cardfix != 10000)
+ if (cardfix != 1000)
damage = damage * cardfix / 1000;
}
break;
@@ -724,6 +1152,1315 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li
}
/*==========================================
+ * Calculates defense reduction. [malufett]
+ * flag:
+ * &1 - idef/imdef(Ignore defense)
+ * &2 - pdef(Pierce defense)
+ * &4 - tdef(Total defense reduction)
+ *------------------------------------------*/
+int battle_calc_defense(int attack_type, struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int damage, int flag, int pdef){
+ struct status_data *sstatus, *tstatus;
+ struct map_session_data *sd, *tsd;
+ struct status_change *sc, *tsc;
+ int i;
+
+ if( !damage )
+ return 0;
+
+ nullpo_ret(src);
+ nullpo_ret(target);
+
+ sd = BL_CAST(BL_PC, src);
+ tsd = BL_CAST(BL_PC, target);
+ sstatus = status_get_status_data(src);
+ tstatus = status_get_status_data(target);
+ sc = status_get_sc(src);
+ tsc = status_get_sc(target);
+
+ switch(attack_type){
+ case BF_WEAPON:
+ {
+ /** Take note in RE
+ * def1 = equip def
+ * def2 = status def
+ **/
+ defType def1 = status_get_def(target); //Don't use tstatus->def1 due to skill timer reductions.
+ short def2 = tstatus->def2, vit_def;
+
+ def1 = status_calc_def2(target, tsc, def1, false); // equip def(RE)
+ def2 = status_calc_def(target, tsc, def2, false); // status def(RE)
+
+ if( sd ){
+ i = sd->ignore_def[is_boss(target)?RC_BOSS:RC_NONBOSS];
+ i += sd->ignore_def[tstatus->race];
+ if( i ){
+ if( i > 100 ) i = 100;
+ def1 -= def1 * i / 100;
+ def2 -= def2 * i / 100;
+ }
+ }
+
+ if( sc && sc->data[SC_EXPIATIO] ){
+ i = 5 * sc->data[SC_EXPIATIO]->val1; // 5% per level
+ def1 -= def1 * i / 100;
+ def2 -= def2 * i / 100;
+ }
+
+ if( battle_config.vit_penalty_type && battle_config.vit_penalty_target&target->type ) {
+ unsigned char target_count; //256 max targets should be a sane max
+ target_count = unit_counttargeted(target);
+ if(target_count >= battle_config.vit_penalty_count) {
+ if(battle_config.vit_penalty_type == 1) {
+ if( !tsc || !tsc->data[SC_STEELBODY] )
+ def1 = (def1 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
+ def2 = (def2 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
+ } else { //Assume type 2
+ if( !tsc || !tsc->data[SC_STEELBODY] )
+ def1 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
+ def2 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
+ }
+ }
+ if(skill_id == AM_ACIDTERROR) def1 = 0; //Acid Terror ignores only armor defense. [Skotlex]
+ if(def2 < 1) def2 = 1;
+ }
+ //Vitality reduction from rodatazone: http://rodatazone.simgaming.net/mechanics/substats.php#def
+ if (tsd) //Sd vit-eq
+ {
+#ifndef RENEWAL
+ //[VIT*0.5] + rnd([VIT*0.3], max([VIT*0.3],[VIT^2/150]-1))
+ vit_def = def2*(def2-15)/150;
+ vit_def = def2/2 + (vit_def>0?rnd()%vit_def:0);
+#else
+ vit_def = def2;
+#endif
+ if((battle->check_undead(sstatus->race,sstatus->def_ele) || sstatus->race==RC_DEMON) && //This bonus already doesnt work vs players
+ src->type == BL_MOB && (i=pc->checkskill(tsd,AL_DP)) > 0)
+ vit_def += i*(int)(3 +(tsd->status.base_level+1)*0.04); // submitted by orn
+ if( src->type == BL_MOB && (i=pc->checkskill(tsd,RA_RANGERMAIN))>0 &&
+ (sstatus->race == RC_BRUTE || sstatus->race == RC_FISH || sstatus->race == RC_PLANT) )
+ vit_def += i*5;
+ }
+ else { //Mob-Pet vit-eq
+#ifndef RENEWAL
+ //VIT + rnd(0,[VIT/20]^2-1)
+ vit_def = (def2/20)*(def2/20);
+ vit_def = def2 + (vit_def>0?rnd()%vit_def:0);
+#else
+ vit_def = def2;
+#endif
+ }
+
+ if (battle_config.weapon_defense_type) {
+ vit_def += def1*battle_config.weapon_defense_type;
+ def1 = 0;
+ }
+ #ifdef RENEWAL
+ /**
+ * RE DEF Reduction
+ * Damage = Attack * (4000+eDEF)/(4000+eDEF*10) - sDEF
+ * Pierce defence gains 1 atk per def/2
+ **/
+
+ if( def1 == -400 ) /* being hit by a gazillion units, you hit the jackpot and got -400 which creates a division by 0 and subsequently crashes */
+ def1 = -399;
+
+ if( flag&2 )
+ damage += def1 >> 1;
+
+ if( !(flag&1) && !(flag&2) )
+ if( flag&4 )
+ damage -= (def1 + vit_def);
+ else
+ damage = damage * (4000+def1) / (4000+10*def1) - vit_def;
+
+ #else
+ if( def1 > 100 ) def1 = 100;
+ if( !(flag&1) ){
+ if( flag&2 )
+ damage = damage * pdef * (def1+vit_def) / 100;
+ else
+ damage = damage * (100-def1) / 100;
+ }
+ if( !(flag&1 || flag&2) )
+ damage -= vit_def;
+ #endif
+ }
+ break;
+
+ case BF_MAGIC:
+ {
+ defType mdef = tstatus->mdef;
+ short mdef2= tstatus->mdef2;
+
+ mdef2 = status_calc_mdef(target, tsc, mdef2, false); // status mdef(RE)
+ mdef = status_calc_mdef2(target, tsc, mdef, false); // equip mde(RE)
+
+ if( flag&1 )
+ mdef = 0;
+
+ if(sd) {
+ i = sd->ignore_mdef[is_boss(target)?RC_BOSS:RC_NONBOSS];
+ i += sd->ignore_mdef[tstatus->race];
+ if (i)
+ {
+ if (i > 100) i = 100;
+ mdef -= mdef * i/100;
+ //mdef2-= mdef2* i/100;
+ }
+ }
+ #ifdef RENEWAL
+ /**
+ * RE MDEF Reduction
+ * Damage = Magic Attack * (1000+eMDEF)/(1000+eMDEF) - sMDEF
+ **/
+ damage = damage * (1000 + mdef) / (1000 + mdef * 10) - mdef2;
+ #else
+ if(battle_config.magic_defense_type)
+ damage = damage - mdef*battle_config.magic_defense_type - mdef2;
+ else
+ damage = damage * (100-mdef)/100 - mdef2;
+ #endif
+ }
+ break;
+ }
+ return damage;
+}
+
+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, addedratio;
+ struct status_change *sc, *tsc;
+ struct map_session_data *sd, *tsd;
+ struct status_data *status, *tstatus;
+
+ nullpo_ret(src);
+ nullpo_ret(target);
+
+ sd = BL_CAST(BL_PC, src);
+ tsd = BL_CAST(BL_PC, target);
+ sc = status_get_sc(src);
+ tsc = status_get_sc(target);
+ status = status_get_status_data(src);
+ tstatus = status_get_status_data(target);
+
+ addedratio = skillratio - 100;
+
+ switch(attack_type){
+ case BF_MAGIC:
+ switch(skill_id){
+ case MG_NAPALMBEAT:
+ skillratio += skill_lv * 10 - 30;
+ break;
+ case MG_FIREBALL:
+ #ifdef RENEWAL
+ skillratio += 20 * skill_lv;
+ #else
+ skillratio += skill_lv * 10 - 30;
+ #endif
+ break;
+ case MG_SOULSTRIKE:
+ if (battle->check_undead(tstatus->race,tstatus->def_ele))
+ skillratio += 5*skill_lv;
+ break;
+ case MG_FIREWALL:
+ skillratio -= 50;
+ break;
+ case MG_THUNDERSTORM:
+ /**
+ * in Renewal Thunder Storm boost is 100% (in pre-re, 80%)
+ **/
+ #ifndef RENEWAL
+ skillratio -= 20;
+ #endif
+ break;
+ case MG_FROSTDIVER:
+ skillratio += 10 * skill_lv;
+ break;
+ case AL_HOLYLIGHT:
+ skillratio += 25;
+ if (sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_PRIEST)
+ skillratio *= 5; //Does 5x damage include bonuses from other skills?
+ break;
+ case AL_RUWACH:
+ skillratio += 45;
+ break;
+ case WZ_FROSTNOVA:
+ skillratio += (100+skill_lv*10) * 2 / 3 - 100;
+ break;
+ case WZ_FIREPILLAR:
+ if (skill_lv > 10)
+ skillratio += 100;
+ else
+ skillratio -= 80;
+ break;
+ case WZ_SIGHTRASHER:
+ skillratio += 20 * skill_lv;
+ break;
+ case WZ_WATERBALL:
+ skillratio += 30 * skill_lv;
+ break;
+ case WZ_STORMGUST:
+ skillratio += 40 * skill_lv;
+ break;
+ case HW_NAPALMVULCAN:
+ skillratio += 10 * skill_lv - 30;
+ break;
+ case SL_STIN:
+ skillratio += (tstatus->size!=SZ_SMALL?-99:10*skill_lv); //target size must be small (0) for full damage.
+ break;
+ case SL_STUN:
+ skillratio += (tstatus->size!=SZ_BIG?5*skill_lv:-99); //Full damage is dealt on small/medium targets
+ break;
+ case SL_SMA:
+ skillratio += -60 + status_get_lv(src); //Base damage is 40% + lv%
+ break;
+ case NJ_KOUENKA:
+ skillratio -= 10;
+ break;
+ case NJ_KAENSIN:
+ skillratio -= 50;
+ break;
+ case NJ_BAKUENRYU:
+ skillratio += 50 * (skill_lv-1);
+ break;
+ case NJ_HYOUSYOURAKU:
+ skillratio += 50 * skill_lv;
+ break;
+ case NJ_RAIGEKISAI:
+ skillratio += 60 + 40 * skill_lv;
+ break;
+ case NJ_KAMAITACHI:
+ case NPC_ENERGYDRAIN:
+ skillratio += 100 * skill_lv;
+ break;
+ case NPC_EARTHQUAKE:
+ skillratio += 100 + 100 * skill_lv + 100 * (skill_lv/2);
+ break;
+ #ifdef RENEWAL
+ case WZ_HEAVENDRIVE:
+ case WZ_METEOR:
+ skillratio += 25;
+ break;
+ case WZ_VERMILION:
+ {
+ int interval = 0, per = interval, ratio = per;
+ while( (per++) < skill_lv ){
+ ratio += interval;
+ if(per%3==0) interval += 20;
+ }
+ if( skill_lv > 9 )
+ ratio -= 10;
+ skillratio += ratio;
+ }
+ break;
+ case NJ_HUUJIN:
+ skillratio += 50;
+ break;
+ #else
+ case WZ_VERMILION:
+ skillratio += 20*skill_lv-20;
+ break;
+ #endif
+ /**
+ * Arch Bishop
+ **/
+ case AB_JUDEX:
+ skillratio += 180 + 20 * skill_lv;
+ if (skill_lv > 4) skillratio += 20;
+ RE_LVL_DMOD(100);
+ break;
+ case AB_ADORAMUS:
+ skillratio += 400 + 100 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case AB_DUPLELIGHT_MAGIC:
+ skillratio += 100 + 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);
+ RE_LVL_DMOD(100);
+ break;
+ 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;
+ case WL_JACKFROST:
+ if( tsc && tsc->data[SC_FROSTMISTY] ){
+ skillratio += 900 + 300 * skill_lv;
+ RE_LVL_DMOD(100);
+ }else{
+ skillratio += 400 + 100 * skill_lv;
+ RE_LVL_DMOD(150);
+ }
+ break;
+ case WL_DRAINLIFE:
+ skillratio = 200 * skill_lv + status_get_int(src);
+ RE_LVL_DMOD(100);
+ break;
+ case WL_CRIMSONROCK:
+ skillratio = 300 * skill_lv;
+ RE_LVL_DMOD(100);
+ skillratio += 1300;
+ break;
+ case WL_HELLINFERNO:
+ skillratio = 300 * skill_lv;
+ RE_LVL_DMOD(100);
+ // Shadow: MATK [{( Skill Level x 300 ) x ( Caster Base Level / 100 ) x 4/5 }] %
+ // Fire : MATK [{( Skill Level x 300 ) x ( Caster Base Level / 100 ) /5 }] %
+ if( flag&ELE_DARK )
+ skillratio *= 4;
+ skillratio /= 5;
+ break;
+ case WL_COMET:
+ i = ( sc ? distance_xy(target->x, target->y, sc->comet_x, sc->comet_y) : 8 );
+ if( i <= 3 ) skillratio += 2400 + 500 * skill_lv; // 7 x 7 cell
+ else
+ if( i <= 5 ) skillratio += 1900 + 500 * skill_lv; // 11 x 11 cell
+ else
+ if( i <= 7 ) skillratio += 1400 + 500 * skill_lv; // 15 x 15 cell
+ else
+ skillratio += 900 + 500 * skill_lv; // 19 x 19 cell
+
+ if( sd && sd->status.party_id ){
+ struct map_session_data* psd;
+ int static p_sd[5] = {0, 0, 0, 0, 0}, c; // just limit it to 5
+
+ 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 );
+
+ if( (psd = iMap->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 ] %
+ RE_LVL_DMOD(120);
+ skillratio += 2500;
+ status_zap(&psd->bl, 0, skill->get_sp(skill_id, skill_lv) / 2);
+ }
+ }
+ break;
+ case WL_CHAINLIGHTNING_ATK:
+ skillratio += 400 + 100 * skill_lv;
+ RE_LVL_DMOD(100);
+ if(flag > 0)
+ skillratio += 100 * flag;
+ break;
+ case WL_EARTHSTRAIN:
+ skillratio += 1900 + 100 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case WL_TETRAVORTEX_FIRE:
+ case WL_TETRAVORTEX_WATER:
+ case WL_TETRAVORTEX_WIND:
+ case WL_TETRAVORTEX_GROUND:
+ skillratio += 400 + 500 * skill_lv;
+ break;
+ case WL_SUMMON_ATK_FIRE:
+ 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]
+ RE_LVL_DMOD(100);
+ break;
+ case LG_RAYOFGENESIS:
+ {
+ int16 lv = skill_lv;
+ int bandingBonus = 0;
+ if( sc && sc->data[SC_BANDING] )
+ 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;
+ break;
+ /*case WM_SEVERE_RAINSTORM:
+ skillratio += 50 * skill_lv;
+ 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);
+ RE_LVL_DMOD(100);
+ break;
+ case SO_FIREWALK:
+ skillratio = 300;
+ RE_LVL_DMOD(100);
+ if( sc && sc->data[SC_HEATER_OPTION] )
+ skillratio += sc->data[SC_HEATER_OPTION]->val3;
+ break;
+ case SO_ELECTRICWALK:
+ skillratio = 300;
+ RE_LVL_DMOD(100);
+ if( sc && sc->data[SC_BLAST_OPTION] )
+ skillratio += sd ? sd->status.job_level / 2 : 0;
+ break;
+ case SO_EARTHGRAVE:
+ skillratio = ( 200 * ( sd ? pc->checkskill(sd, SA_SEISMICWEAPON) : 10 ) + status_get_int(src) * skill_lv );
+ RE_LVL_DMOD(100);
+ if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
+ skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
+ break;
+ case SO_DIAMONDDUST:
+ skillratio = ( 200 * ( sd ? pc->checkskill(sd, SA_FROSTWEAPON) : 10 ) + status_get_int(src) * skill_lv );
+ RE_LVL_DMOD(100);
+ if( sc && sc->data[SC_COOLER_OPTION] )
+ skillratio += sc->data[SC_COOLER_OPTION]->val3;
+ break;
+ case SO_POISON_BUSTER:
+ skillratio += 1100 + 300 * skill_lv;
+ if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
+ skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
+ break;
+ case SO_PSYCHIC_WAVE:
+ skillratio += -100 + skill_lv * 70 + (status_get_int(src) * 3);
+ 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;
+ }
+ break;
+ case SO_VARETYR_SPEAR: //MATK [{( Endow Tornado skill level x 50 ) + ( Caster INT x Varetyr Spear Skill level )} x Caster Base Level / 100 ] %
+ 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;
+ break;
+ case SO_CLOUD_KILL:
+ skillratio += -100 + skill_lv * 40;
+ RE_LVL_DMOD(100);
+ if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
+ skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
+ break;
+ case GN_DEMONIC_FIRE:
+ if( skill_lv > 20)
+ { // Fire expansion Lv.2
+ skillratio += 110 + 20 * (skill_lv - 20) + status_get_int(src) * 3; // Need official INT bonus. [LimitLine]
+ }
+ else if( skill_lv > 10 )
+ { // Fire expansion Lv.1
+ skillratio += 110 + 20 * (skill_lv - 10) / 2;
+ }
+ else
+ skillratio += 110 + 20 * skill_lv;
+ break;
+ // Magical Elemental Spirits Attack Skills
+ case EL_FIRE_MANTLE:
+ case EL_WATER_SCREW:
+ skillratio += 900;
+ break;
+ case EL_FIRE_ARROW:
+ case EL_ROCK_CRUSHER_ATK:
+ skillratio += 200;
+ break;
+ case EL_FIRE_BOMB:
+ case EL_ICE_NEEDLE:
+ case EL_HURRICANE_ATK:
+ skillratio += 400;
+ break;
+ case EL_FIRE_WAVE:
+ case EL_TYPOON_MIS_ATK:
+ skillratio += 1100;
+ break;
+ case MH_ERASER_CUTTER:
+ if(skill_lv%2) skillratio += 400; //600:800:1000
+ else skillratio += 700; //1000:1200
+ skillratio += 100 * skill_lv;
+ break;
+ case MH_XENO_SLASHER:
+ if(skill_lv%2) skillratio += 350 + 50 * skill_lv; //500:600:700
+ else skillratio += 400 + 100 * skill_lv; //700:900
+ break;
+ case MH_HEILIGE_STANGE:
+ skillratio += 400 + 250 * skill_lv;
+ break;
+ case MH_POISON_MIST:
+ skillratio += 100 * skill_lv;
+ break;
+ case KO_KAIHOU:
+ if( sd ){
+ ARR_FIND(1, 6, i, sd->charm[i] > 0);
+ if( i < 5 ){
+ skillratio += -100 + 200 * sd->charm[i];
+ RE_LVL_DMOD(100);
+ pc->del_charm(sd, sd->charm[i], i);
+ }
+ }
+ break;
+ }
+ break;
+ case BF_WEAPON:
+ switch( skill_id )
+ {
+ case SM_BASH:
+ case MS_BASH:
+ skillratio += 30 * skill_lv;
+ break;
+ case SM_MAGNUM:
+ case MS_MAGNUM:
+ skillratio += 20 * skill_lv;
+ break;
+ case MC_MAMMONITE:
+ skillratio += 50 * skill_lv;
+ break;
+ case HT_POWER:
+ skillratio += -50 + 8 * status_get_str(src);
+ break;
+ case AC_DOUBLE:
+ case MA_DOUBLE:
+ skillratio += 10 * (skill_lv-1);
+ break;
+ case AC_SHOWER:
+ case MA_SHOWER:
+ #ifdef RENEWAL
+ skillratio += 50 + 10 * skill_lv;
+ #else
+ skillratio += -25 + 5 * skill_lv;
+ #endif
+ break;
+ case AC_CHARGEARROW:
+ case MA_CHARGEARROW:
+ skillratio += 50;
+ break;
+ #ifndef RENEWAL
+ case HT_FREEZINGTRAP:
+ case MA_FREEZINGTRAP:
+ skillratio += -50 + 10 * skill_lv;
+ break;
+ #endif
+ case KN_PIERCE:
+ case ML_PIERCE:
+ skillratio += 10 * skill_lv;
+ break;
+ case MER_CRASH:
+ skillratio += 10 * skill_lv;
+ break;
+ case KN_SPEARSTAB:
+ skillratio += 15 * skill_lv;
+ break;
+ case KN_SPEARBOOMERANG:
+ skillratio += 50*skill_lv;
+ break;
+ case KN_BRANDISHSPEAR:
+ case ML_BRANDISH:
+ {
+ int ratio = 100 + 20 * skill_lv;
+ skillratio += ratio - 100;
+ if(skill_lv>3 && flag==1) skillratio += ratio / 2;
+ if(skill_lv>6 && flag==1) skillratio += ratio / 4;
+ if(skill_lv>9 && flag==1) skillratio += ratio / 8;
+ if(skill_lv>6 && flag==2) skillratio += ratio / 2;
+ if(skill_lv>9 && flag==2) skillratio += ratio / 4;
+ if(skill_lv>9 && flag==3) skillratio += ratio / 2;
+ break;
+ }
+ case KN_BOWLINGBASH:
+ case MS_BOWLINGBASH:
+ skillratio+= 40 * skill_lv;
+ break;
+ case AS_GRIMTOOTH:
+ skillratio += 20 * skill_lv;
+ break;
+ case AS_POISONREACT:
+ skillratio += 30 * skill_lv;
+ break;
+ case AS_SONICBLOW:
+ skillratio += -50 + 5 * skill_lv;
+ break;
+ case TF_SPRINKLESAND:
+ skillratio += 30;
+ break;
+ case MC_CARTREVOLUTION:
+ skillratio += 50;
+ if( sd && sd->cart_weight )
+ skillratio += 100 * sd->cart_weight / sd->cart_weight_max; // +1% every 1% weight
+ else if (!sd)
+ skillratio += 100; //Max damage for non players.
+ break;
+ case NPC_RANDOMATTACK:
+ skillratio += 100 * skill_lv;
+ break;
+ case NPC_WATERATTACK:
+ case NPC_GROUNDATTACK:
+ case NPC_FIREATTACK:
+ case NPC_WINDATTACK:
+ case NPC_POISONATTACK:
+ case NPC_HOLYATTACK:
+ case NPC_DARKNESSATTACK:
+ case NPC_UNDEADATTACK:
+ case NPC_TELEKINESISATTACK:
+ case NPC_BLOODDRAIN:
+ case NPC_ACIDBREATH:
+ case NPC_DARKNESSBREATH:
+ case NPC_FIREBREATH:
+ case NPC_ICEBREATH:
+ case NPC_THUNDERBREATH:
+ case NPC_HELLJUDGEMENT:
+ case NPC_PULSESTRIKE:
+ skillratio += 100 * (skill_lv-1);
+ break;
+ case RG_BACKSTAP:
+ if( sd && sd->status.weapon == W_BOW && battle_config.backstab_bow_penalty )
+ skillratio += (200 + 40 * skill_lv) / 2;
+ else
+ skillratio += 200 + 40 * skill_lv;
+ break;
+ case RG_RAID:
+ skillratio += 40 * skill_lv;
+ break;
+ case RG_INTIMIDATE:
+ skillratio += 30 * skill_lv;
+ break;
+ case CR_SHIELDCHARGE:
+ skillratio += 20 * skill_lv;
+ break;
+ case CR_SHIELDBOOMERANG:
+ skillratio += 30 * skill_lv;
+ break;
+ case NPC_DARKCROSS:
+ case CR_HOLYCROSS:
+ {
+ int ratio = 35 * skill_lv;
+ #ifdef RENEWAL
+ if(sd && sd->status.weapon == W_2HSPEAR)
+ ratio *= 2;
+ #endif
+ skillratio += ratio;
+ break;
+ }
+ case AM_DEMONSTRATION:
+ skillratio += 20 * skill_lv;
+ break;
+ case AM_ACIDTERROR:
+ skillratio += 40 * skill_lv;
+ break;
+ case MO_FINGEROFFENSIVE:
+ skillratio+= 50 * skill_lv;
+ break;
+ case MO_INVESTIGATE:
+ skillratio += 75 * skill_lv;
+ break;
+ #ifndef RENEWAL
+ case MO_EXTREMITYFIST:
+ { //Overflow check. [Skotlex]
+ unsigned int ratio = skillratio + 100*(8 + sstatus->sp/10);
+ //You'd need something like 6K SP to reach this max, so should be fine for most purposes.
+ if (ratio > 60000) ratio = 60000; //We leave some room here in case skillratio gets further increased.
+ skillratio = (unsigned short)ratio;
+ }
+ break;
+ #endif
+ case MO_TRIPLEATTACK:
+ skillratio += 20 * skill_lv;
+ break;
+ case MO_CHAINCOMBO:
+ skillratio += 50 + 50 * skill_lv;
+ break;
+ case MO_COMBOFINISH:
+ skillratio += 140 + 60 * skill_lv;
+ break;
+ case BA_MUSICALSTRIKE:
+ case DC_THROWARROW:
+ skillratio += 25 + 25 * skill_lv;
+ break;
+ case CH_TIGERFIST:
+ skillratio += 100 * skill_lv - 60;
+ break;
+ case CH_CHAINCRUSH:
+ skillratio += 300 + 100 * skill_lv;
+ break;
+ case CH_PALMSTRIKE:
+ skillratio += 100 + 100 * skill_lv;
+ break;
+ case LK_HEADCRUSH:
+ skillratio += 40 * skill_lv;
+ break;
+ case LK_JOINTBEAT:
+ i = 10 * skill_lv - 50;
+ // Although not clear, it's being assumed that the 2x damage is only for the break neck ailment.
+ if (flag&BREAK_NECK) i*=2;
+ skillratio += i;
+ break;
+ case ASC_METEORASSAULT:
+ skillratio += 40 * skill_lv - 60;
+ break;
+ case SN_SHARPSHOOTING:
+ case MA_SHARPSHOOTING:
+ skillratio += 100 + 50 * skill_lv;
+ break;
+ case CG_ARROWVULCAN:
+ skillratio += 100 + 100 * skill_lv;
+ break;
+ case AS_SPLASHER:
+ skillratio += 400 + 50 * skill_lv;
+ if(sd)
+ skillratio += 20 * pc->checkskill(sd,AS_POISONREACT);
+ break;
+ #ifndef RENEWAL
+ case ASC_BREAKER:
+ skillratio += 100*skill_lv-100;
+ break;
+ #endif
+ case PA_SACRIFICE:
+ skillratio += 10 * skill_lv - 10;
+ break;
+ case PA_SHIELDCHAIN:
+ skillratio += 30 * skill_lv;
+ break;
+ case WS_CARTTERMINATION:
+ i = 10 * (16 - skill_lv);
+ if (i < 1) i = 1;
+ //Preserve damage ratio when max cart weight is changed.
+ if(sd && sd->cart_weight)
+ skillratio += sd->cart_weight/i * 80000/battle_config.max_cart_weight - 100;
+ else if (!sd)
+ skillratio += 80000 / i - 100;
+ break;
+ case TK_DOWNKICK:
+ skillratio += 60 + 20 * skill_lv;
+ break;
+ case TK_STORMKICK:
+ skillratio += 60 + 20 * skill_lv;
+ break;
+ case TK_TURNKICK:
+ skillratio += 90 + 30 * skill_lv;
+ break;
+ case TK_COUNTER:
+ skillratio += 90 + 30 * skill_lv;
+ break;
+ case TK_JUMPKICK:
+ skillratio += -70 + 10*skill_lv;
+ if (sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == skill_id)
+ skillratio += 10 * status_get_lv(src) / 3; //Tumble bonus
+ if (flag)
+ {
+ skillratio += 10 * status_get_lv(src) / 3; //Running bonus (TODO: What is the real bonus?)
+ if( sc && sc->data[SC_STRUP] ) // Spurt bonus
+ skillratio *= 2;
+ }
+ break;
+ case GS_TRIPLEACTION:
+ skillratio += 50 * skill_lv;
+ break;
+ case GS_BULLSEYE:
+ //Only works well against brute/demihumans non bosses.
+ if((tstatus->race == RC_BRUTE || tstatus->race == RC_DEMIHUMAN)
+ && !(tstatus->mode&MD_BOSS))
+ skillratio += 400;
+ break;
+ case GS_TRACKING:
+ skillratio += 100 * (skill_lv+1);
+ break;
+ case GS_PIERCINGSHOT:
+ skillratio += 20 * skill_lv;
+ break;
+ case GS_RAPIDSHOWER:
+ skillratio += 10 * skill_lv;
+ break;
+ case GS_DESPERADO:
+ skillratio += 50 * (skill_lv-1);
+ break;
+ case GS_DUST:
+ skillratio += 50 * skill_lv;
+ break;
+ case GS_FULLBUSTER:
+ skillratio += 100 * (skill_lv+2);
+ break;
+ case GS_SPREADATTACK:
+ #ifdef RENEWAL
+ skillratio += 20 * (skill_lv);
+ #else
+ skillratio += 20 * (skill_lv-1);
+ #endif
+ break;
+ case NJ_HUUMA:
+ skillratio += 50 + 150 * skill_lv;
+ break;
+ case NJ_TATAMIGAESHI:
+ skillratio += 10 * skill_lv;
+ break;
+ case NJ_KASUMIKIRI:
+ skillratio += 10 * skill_lv;
+ break;
+ case NJ_KIRIKAGE:
+ skillratio += 100 * (skill_lv-1);
+ break;
+ case KN_CHARGEATK:
+ {
+ int k = (flag-1)/3; //+100% every 3 cells of distance
+ if( k > 2 ) k = 2; // ...but hard-limited to 300%.
+ skillratio += 100 * k;
+ }
+ break;
+ case HT_PHANTASMIC:
+ skillratio += 50;
+ break;
+ case MO_BALKYOUNG:
+ skillratio += 200;
+ break;
+ case HFLI_MOON: //[orn]
+ skillratio += 10 + 110 * skill_lv;
+ break;
+ case HFLI_SBR44: //[orn]
+ skillratio += 100 * (skill_lv-1);
+ break;
+ case NPC_VAMPIRE_GIFT:
+ skillratio += ((skill_lv-1)%5+1) * 100;
+ break;
+ case RK_SONICWAVE:
+ skillratio += -100 + 100 * (skill_lv + 5);
+ skillratio = skillratio * (100 + (status_get_lv(src)-100) / 2) / 100;
+ break;
+ case RK_HUNDREDSPEAR:
+ skillratio += 500 + (80 * 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 += (10000 - min(10000, sd->inventory_data[index]->weight)) / 10;
+ skillratio = skillratio * (100 + (status_get_lv(src)-100) / 2) / 100 + 50 * pc->checkskill(sd,LK_SPIRALPIERCE);
+ }
+ break;
+ case RK_WINDCUTTER:
+ skillratio += -100 + 50 * (skill_lv + 2);
+ 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( status->rhw.ele == ELE_FIRE )
+ skillratio += 100 * skill_lv;
+ break;
+ case RK_CRUSHSTRIKE:
+ if( sd )
+ {//ATK [{Weapon Level * (Weapon Upgrade Level + 6) * 100} + (Weapon ATK) + (Weapon Weight)]%
+ short index = sd->equip_index[EQI_HAND_R];
+ if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON )
+ skillratio += -100 + sd->inventory_data[index]->weight/10 + status->rhw.atk +
+ 100 * sd->inventory_data[index]->wlv * (sd->status.inventory[index].refine + 6);
+ }
+ break;
+ case RK_STORMBLAST:
+ skillratio += -100 + 100 * (sd ? pc->checkskill(sd,RK_RUNEMASTERY) : 1) + 100 * (status_get_int(src) / 4);
+ break;
+ case RK_PHANTOMTHRUST:
+ skillratio += -100 + 50 * skill_lv + 10 * ( sd ? pc->checkskill(sd,KN_SPEARMASTERY) : 10);
+ RE_LVL_DMOD(150);
+ break;
+ /**
+ * GC Guilotine Cross
+ **/
+ case GC_CROSSIMPACT:
+ skillratio += 900 + 100 * skill_lv;
+ RE_LVL_DMOD(120);
+ break;
+ case GC_PHANTOMMENACE:
+ skillratio += 200;
+ break;
+ case GC_COUNTERSLASH:
+ //ATK [{(Skill Level x 100) + 300} x Caster's Base Level / 120]% + ATK [(AGI x 2) + (Caster's Job Level x 4)]%
+ skillratio += 200 + (100 * skill_lv);
+ RE_LVL_DMOD(120);
+ skillratio += status_get_agi(src) * 2 + (sd?sd->status.job_level:0) * 4;
+ break;
+ case GC_ROLLINGCUTTER:
+ skillratio += -50 + 50 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case GC_CROSSRIPPERSLASHER:
+ skillratio += 300 + 80 * skill_lv;
+ RE_LVL_DMOD(100);
+ if( sc && sc->data[SC_ROLLINGCUTTER] )
+ skillratio += sc->data[SC_ROLLINGCUTTER]->val1 * status_get_agi(src);
+ break;
+ case GC_DARKCROW:
+ skillratio += 100 * (skill_lv - 1);
+ break;
+ /**
+ * Arch Bishop
+ **/
+ case AB_DUPLELIGHT_MELEE:
+ skillratio += 10 * skill_lv;
+ break;
+ /**
+ * Ranger
+ **/
+ case RA_ARROWSTORM:
+ skillratio += 900 + 80 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case RA_AIMEDBOLT:
+ skillratio += 400 + 50 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case RA_CLUSTERBOMB:
+ skillratio += 100 + 100 * skill_lv;
+ break;
+ case RA_WUGDASH:// ATK 300%
+ skillratio += 200;
+ break;
+ case RA_WUGSTRIKE:
+ skillratio += -100 + 200 * skill_lv;
+ break;
+ case RA_WUGBITE:
+ skillratio += 300 + 200 * skill_lv;
+ if ( skill_lv == 5 ) skillratio += 100;
+ break;
+ case RA_SENSITIVEKEEN:
+ skillratio += 50 * skill_lv;
+ break;
+ /**
+ * Mechanic
+ **/
+ case NC_BOOSTKNUCKLE:
+ skillratio += 100 + 100 * skill_lv + status_get_dex(src);
+ RE_LVL_DMOD(100);
+ break;
+ case NC_PILEBUNKER:
+ skillratio += 200 + 100 * skill_lv + status_get_str(src);
+ RE_LVL_DMOD(100);
+ break;
+ case NC_VULCANARM:
+ skillratio += -100 + 70 * skill_lv + status_get_dex(src);
+ RE_LVL_DMOD(100);
+ break;
+ case NC_FLAMELAUNCHER:
+ case NC_COLDSLOWER:
+ skillratio += 200 + 300 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case NC_ARMSCANNON:
+ switch( tstatus->size ) {
+ case SZ_SMALL: skillratio += 100 + 500 * skill_lv; break;// Small
+ case SZ_MEDIUM: skillratio += 100 + 400 * skill_lv; break;// Medium
+ case SZ_BIG: skillratio += 100 + 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]
+ break;
+ case NC_AXEBOOMERANG:
+ skillratio += 60 + 40 * 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]
+ }
+ 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);
+ break;
+ case NC_AXETORNADO:
+ skillratio += 100 + 100 * skill_lv + status_get_vit(src);
+ RE_LVL_DMOD(100);
+ break;
+ case SC_FATALMENACE:
+ skillratio += 100 * skill_lv;
+ break;
+ case SC_TRIANGLESHOT:
+ skillratio += 270 + 30 * skill_lv;
+ break;
+ case SC_FEINTBOMB:
+ skillratio += 100 + 100 * skill_lv;
+ break;
+ case LG_CANNONSPEAR:// Stimated formula. Still need confirm it.
+ skillratio += -100 + (50 + status_get_str(src)) * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case LG_BANISHINGPOINT:
+ skillratio += -100 + ((50 * skill_lv) + (30 * ((sd)?pc->checkskill(sd,SM_BASH):1)));
+ RE_LVL_DMOD(100);
+ break;
+ case LG_SHIELDPRESS:
+ skillratio += 60 + 43 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case LG_PINPOINTATTACK:
+ skillratio += -100 + ((100 * skill_lv) + (10 * status_get_agi(src)) );
+ RE_LVL_DMOD(100);
+ break;
+ case LG_RAGEBURST:
+ if( sd && sd->spiritball_old )
+ skillratio += -100 + (sd->spiritball_old * 200);
+ else
+ skillratio += -100 + 15 * 200;
+ RE_LVL_DMOD(100);
+ break;
+ case LG_SHIELDSPELL:// [(Casters Base Level x 4) + (Shield DEF x 10) + (Casters VIT x 2)] %
+ if( sd ) {
+ 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%
+ break;
+ case LG_MOONSLASHER:
+ skillratio += -100 + (120 * skill_lv + ((sd) ? pc->checkskill(sd,LG_OVERBRAND) : 5) * 80);
+ RE_LVL_DMOD(100);
+ break;
+ case LG_OVERBRAND:
+ skillratio += -100 + 400 * skill_lv + (pc->checkskill(sd,CR_SPEARQUICKEN) * 30);
+ RE_LVL_DMOD(100);
+ break;
+ case LG_OVERBRAND_BRANDISH:
+ skillratio += -100 + 300 * skill_lv + (2 * (status_get_str(src) + status_get_dex(src)) / 3);
+ RE_LVL_DMOD(100);
+ break;
+ case LG_OVERBRAND_PLUSATK:
+ skillratio += -100 + 150 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case LG_RAYOFGENESIS:
+ skillratio += 200 + 300 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case LG_EARTHDRIVE:
+ skillratio = (skillratio + 100) * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case LG_HESPERUSLIT:
+ skillratio += 120 * skill_lv - 100;
+ break;
+ case SR_DRAGONCOMBO:
+ skillratio += 40 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case SR_SKYNETBLOW:
+ if( sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == SR_DRAGONCOMBO )//ATK [{(Skill Level x 100) + (Caster AGI) + 150} x Caster Base Level / 100] %
+ skillratio += 100 * skill_lv + status_get_agi(src) + 50;
+ else //ATK [{(Skill Level x 80) + (Caster AGI)} x Caster Base Level / 100] %
+ skillratio += -100 + 80 * skill_lv + status_get_agi(src);
+ RE_LVL_DMOD(100);
+ break;
+ case SR_EARTHSHAKER:
+ if( tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || // [(Skill Level x 150) x (Caster Base Level / 100) + (Caster INT x 3)] %
+ tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKINGEXCEED] || tsc->data[SC__INVISIBILITY]) ){
+ skillratio += -100 + 150 * skill_lv;
+ RE_LVL_DMOD(100);
+ skillratio += status_get_int(src) * 3;
+ }else{ //[(Skill Level x 50) x (Caster Base Level / 100) + (Caster INT x 2)] %
+ skillratio += 50 * (skill_lv-2);
+ RE_LVL_DMOD(100);
+ skillratio += status_get_int(src) * 2;
+ }
+ break;
+ case SR_FALLENEMPIRE:// ATK [(Skill Level x 150 + 100) x Caster Base Level / 150] %
+ skillratio += 150 *skill_lv;
+ RE_LVL_DMOD(150);
+ break;
+ case SR_TIGERCANNON:// ATK [((Caster consumed HP + SP) / 4) x Caster Base Level / 100] %
+ {
+ int hp = status_get_max_hp(src) * (10 + 2 * skill_lv) / 100,
+ sp = status_get_max_sp(src) * (6 + skill_lv) / 100;
+ if( sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE ) // ATK [((Caster consumed HP + SP) / 2) x Caster Base Level / 100] %
+ skillratio += -100 + hp+sp / 2;
+ else
+ skillratio += -100 + (hp+sp) / 4;
+ RE_LVL_DMOD(100);
+ }
+ break;
+ case SR_RAMPAGEBLASTER:
+ skillratio += 20 * skill_lv * (sd?sd->spiritball_old:5) - 100;
+ if( sc && sc->data[SC_EXPLOSIONSPIRITS] ){
+ skillratio += sc->data[SC_EXPLOSIONSPIRITS]->val1 * 20;
+ RE_LVL_DMOD(120);
+ }else
+ RE_LVL_DMOD(150);
+ break;
+ case SR_KNUCKLEARROW:
+ if( 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( tsd && tsd->weight )
+ skillratio += 100 * (tsd->weight / tsd->max_weight);
+ }else // ATK [(Skill Level x 100 + 500) x Caster Base Level / 100] %
+ skillratio += 400 + (100 * skill_lv);
+ 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);
+ RE_LVL_DMOD(100);
+ break;
+ case SR_GATEOFHELL:
+ if( sc && sc->data[SC_COMBOATTACK]
+ && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE )
+ skillratio += 800 * skill_lv -100;
+ else
+ skillratio += 500 * skill_lv -100;
+ RE_LVL_DMOD(100);
+ break;
+ case SR_GENTLETOUCH_QUIET:
+ skillratio += 100 * skill_lv - 100 + status_get_dex(src);
+ RE_LVL_DMOD(100);
+ break;
+ case SR_HOWLINGOFLION:
+ skillratio += 300 * skill_lv - 100;
+ RE_LVL_DMOD(150);
+ break;
+ case SR_RIDEINLIGHTNING: // ATK [{(Skill Level x 200) + Additional Damage} x Caster Base Level / 100] %
+ if( (status->rhw.ele) == ELE_WIND || (status->lhw.ele) == ELE_WIND )
+ skillratio += skill_lv * 50;
+ skillratio += -100 + 200 * skill_lv;
+ 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);
+ 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);
+ RE_LVL_DMOD(100);
+ skillratio /= 10;
+ break;
+ case WM_GREAT_ECHO:
+ skillratio += 800 + 100 * skill_lv;
+ if( sd ) { // Still need official value [pakpil]
+ short lv = (short)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;
+ 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;
+ 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);
+ break;
+ case GN_SPORE_EXPLOSION:
+ skillratio += 200 + 100 * skill_lv;
+ break;
+ case GN_CRAZYWEED_ATK:
+ skillratio += 400 + 100 * skill_lv;
+ break;
+ case GN_SLINGITEM_RANGEMELEEATK:
+ if( sd ) {
+ switch( sd->itemid ) {
+ case 13260: // Apple Bomob
+ case 13261: // Coconut Bomb
+ case 13262: // Melon Bomb
+ case 13263: // Pinapple Bomb
+ skillratio += 400; // Unconfirded
+ break;
+ case 13264: // Banana Bomb 2000%
+ skillratio += 1900;
+ break;
+ case 13265: skillratio -= 75; break; // Black Lump 25%
+ case 13266: skillratio -= 25; break; // Hard Black Lump 75%
+ case 13267: skillratio += 100; break; // Extremely Hard Black Lump 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;
+ break;
+ // Physical Elemantal Spirits Attack Skills
+ case EL_CIRCLE_OF_FIRE:
+ case EL_FIRE_BOMB_ATK:
+ case EL_STONE_RAIN:
+ skillratio += 200;
+ break;
+ case EL_FIRE_WAVE_ATK:
+ skillratio += 500;
+ break;
+ case EL_TIDAL_WEAPON:
+ skillratio += 1400;
+ break;
+ case EL_WIND_SLASH:
+ skillratio += 100;
+ break;
+ case EL_HURRICANE:
+ skillratio += 600;
+ break;
+ case EL_TYPOON_MIS:
+ case EL_WATER_SCREW_ATK:
+ skillratio += 900;
+ break;
+ case EL_STONE_HAMMER:
+ skillratio += 400;
+ break;
+ case EL_ROCK_CRUSHER:
+ skillratio += 700;
+ break;
+ case KO_JYUMONJIKIRI:
+ skillratio += -100 + 150 * skill_lv;
+ RE_LVL_DMOD(120);
+ if( tsc && tsc->data[SC_KO_JYUMONJIKIRI] )
+ skillratio += status_get_lv(src) * skill_lv;
+ case KO_HUUMARANKA:
+ skillratio += -100 + 150 * skill_lv + status_get_agi(src) + status_get_dex(src) + 100 * (sd ? pc->checkskill(sd, NJ_HUUMA) : 0);
+ break;
+ case KO_SETSUDAN:
+ skillratio += -100 + 100 * skill_lv;
+ RE_LVL_DMOD(100);
+ break;
+ case KO_BAKURETSU:
+ skillratio += -100 + (50 + status_get_dex(src) / 4) * skill_lv * (sd?pc->checkskill(sd,NJ_TOBIDOUGU):10) * 4 / 100;
+ RE_LVL_DMOD(120);
+ skillratio += 10 * (sd ? sd->status.job_level : 0);
+ break;
+ case MH_NEEDLE_OF_PARALYZE:
+ skillratio += 600 + 100 * skill_lv;
+ break;
+ case MH_STAHL_HORN:
+ skillratio += 400 + 100 * skill_lv;
+ break;
+ case MH_LAVA_SLIDE:
+ skillratio += -100 + 70 * skill_lv;
+ break;
+ case MH_TINDER_BREAKER:
+ case MH_MAGMA_FLOW:
+ skillratio += -100 + 100 * skill_lv;
+ break;
+ }
+ if( sc && sc->data[SC_EDP] ){
+ skillratio -= addedratio;
+ if( skill_id == AS_SONICBLOW ||
+ skill_id == GC_COUNTERSLASH ||
+ skill_id == GC_CROSSIMPACT )
+ skillratio >>= 1;
+ skillratio += addedratio;
+ }
+ }
+ if( skillratio < 1 )
+ return 0;
+ return skillratio;
+}
+/*==========================================
* Check dammage trough status.
* ATK may be MISS, BLOCKED FAIL, reduc, increase, end status...
* After this we apply bg/gvg reduction
@@ -834,7 +2571,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
{
clif->skill_nodamage(bl,src,GC_WEAPONBLOCKING,1,1);
d->dmg_lv = ATK_BLOCK;
- sc_start2(bl,SC_COMBO,100,GC_WEAPONBLOCKING,src->id,2000);
+ sc_start2(bl,SC_COMBOATTACK,100,GC_WEAPONBLOCKING,src->id,2000);
return 0;
}
if( (sce=sc->data[SC_AUTOGUARD]) && flag&BF_WEAPON && !(skill->get_nk(skill_id)&NK_NO_CARDFIX_ATK) && rnd()%100 < sce->val2 )
@@ -850,7 +2587,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
delay = 100;
unit_set_walkdelay(bl, iTimer->gettick(), delay, 1);
- if(sc->data[SC_SHRINK] && rnd()%100<5*sce->val1)
+ if(sc->data[SC_CR_SHRINK] && rnd()%100<5*sce->val1)
skill->blown(bl,src,skill->get_blewcount(CR_SHRINK,1),-1,0);
return 0;
}
@@ -879,20 +2616,20 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
return 0;
}
- if(sc->data[SC_DODGE] && ( !sc->opt1 || sc->opt1 == OPT1_BURNING ) &&
- (flag&BF_LONG || sc->data[SC_SPURT])
+ if(sc->data[SC_DODGE_READY] && ( !sc->opt1 || sc->opt1 == OPT1_BURNING ) &&
+ (flag&BF_LONG || sc->data[SC_STRUP])
&& rnd()%100 < 20) {
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_COMBO])
- sc_start4(bl, SC_COMBO, 100, TK_JUMPKICK, src->id, 1, 0, 2000);
+ if (!sc->data[SC_COMBOATTACK])
+ sc_start4(bl, SC_COMBOATTACK, 100, TK_JUMPKICK, src->id, 1, 0, 2000);
return 0;
}
if(sc->data[SC_HERMODE] && flag&BF_MAGIC)
return 0;
- if(sc->data[SC_TATAMIGAESHI] && (flag&(BF_MAGIC|BF_LONG)) == BF_LONG)
+ 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) ) {
@@ -915,7 +2652,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
return 0;
}
- if (((sce=sc->data[SC_UTSUSEMI]) || sc->data[SC_BUNSINJYUTSU])
+ if (((sce=sc->data[SC_NJ_UTSUSEMI]) || sc->data[SC_NJ_BUNSINJYUTSU])
&& flag&BF_WEAPON && !(skill->get_nk(skill_id)&NK_NO_CARDFIX_ATK)) {
skill->additional_effect (src, bl, skill_id, skill_lv, flag, ATK_BLOCK, iTimer->gettick() );
@@ -927,21 +2664,21 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
}
//Both need to be consumed if they are active.
if (sce && --(sce->val2) <= 0)
- status_change_end(bl, SC_UTSUSEMI, INVALID_TIMER);
- if ((sce=sc->data[SC_BUNSINJYUTSU]) && --(sce->val2) <= 0)
- status_change_end(bl, SC_BUNSINJYUTSU, INVALID_TIMER);
+ status_change_end(bl, SC_NJ_UTSUSEMI, INVALID_TIMER);
+ if ((sce=sc->data[SC_NJ_BUNSINJYUTSU]) && --(sce->val2) <= 0)
+ status_change_end(bl, SC_NJ_BUNSINJYUTSU, INVALID_TIMER);
return 0;
}
//Now damage increasing effects
- if( sc->data[SC_AETERNA] && skill_id != PF_SOULBURN )
+ if( sc->data[SC_LEXAETERNA] && skill_id != PF_SOULBURN )
{
if( src->type != BL_MER || skill_id == 0 )
damage <<= 1; // Lex Aeterna only doubles damage of regular attacks from mercenaries
if( skill_id != ASC_BREAKER || !(flag&BF_WEAPON) )
- status_change_end(bl, SC_AETERNA, INVALID_TIMER); //Shouldn't end until Breaker's non-weapon part connects.
+ status_change_end(bl, SC_LEXAETERNA, INVALID_TIMER); //Shouldn't end until Breaker's non-weapon part connects.
}
#ifdef RENEWAL
@@ -955,9 +2692,9 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
if( damage ) {
struct map_session_data *tsd = BL_CAST(BL_PC, src);
- if( sc->data[SC_DEEPSLEEP] ) {
+ if( sc->data[SC_DEEP_SLEEP] ) {
damage += damage / 2; // 1.5 times more damage while in Deep Sleep.
- status_change_end(bl,SC_DEEPSLEEP,INVALID_TIMER);
+ status_change_end(bl,SC_DEEP_SLEEP,INVALID_TIMER);
}
if( tsd && sd && sc->data[SC_CRYSTALIZE] && flag&BF_WEAPON ){
switch(tsd->status.weapon){
@@ -984,8 +2721,8 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
break;
}
}
- if( sc->data[SC_VOICEOFSIREN] )
- status_change_end(bl,SC_VOICEOFSIREN,INVALID_TIMER);
+ if( sc->data[SC_SIREN] )
+ status_change_end(bl,SC_SIREN,INVALID_TIMER);
}
//Finally damage reductions....
@@ -1003,11 +2740,11 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
(flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
damage = damage * ( 100 - sc->data[SC_DEFENDER]->val2 ) / 100;
- if(sc->data[SC_ADJUSTMENT] &&
+ if(sc->data[SC_GS_ADJUSTMENT] &&
(flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
damage -= damage * 20 / 100;
- if(sc->data[SC_FOGWALL] && skill_id != RK_DRAGONBREATH) {
+ if(sc->data[SC_FOGWALL] && skill_id != RK_DRAGONBREATH && skill_id != RK_DRAGONBREATH_WATER) {
if(flag&BF_SKILL) //25% reduction
damage -= damage * 25 / 100;
else if ((flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
@@ -1060,7 +2797,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
skill->castend_damage_id(bl,src,MH_MAGMA_FLOW,sce->val1,iTimer->gettick(),0);
}
- if( (sce = sc->data[SC_STONEHARDSKIN]) && flag&BF_WEAPON && damage > 0 ) {
+ if( (sce = sc->data[SC_STONEHARDSKIN]) && flag&(BF_SHORT|BF_WEAPON) && damage > 0 ) {
sce->val2 -= damage;
if( src->type == BL_PC ) {
TBL_PC *ssd = BL_CAST(BL_PC, src);
@@ -1070,7 +2807,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
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_STRIPWEAPON, 30, 0, skill->get_time2(RK_STONEHARDSKIN, sce->val1));
+ sc_start(src, SC_NOEQUIPWEAPON, 30, 0, skill->get_time2(RK_STONEHARDSKIN, sce->val1));
if( sce->val2 <= 0 )
status_change_end(bl, SC_STONEHARDSKIN, INVALID_TIMER);
}
@@ -1085,10 +2822,10 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
#endif
//Finally added to remove the status of immobile when aimedbolt is used. [Jobbie]
- if( skill_id == RA_AIMEDBOLT && (sc->data[SC_BITE] || sc->data[SC_ANKLE] || sc->data[SC_ELECTRICSHOCKER]) )
+ if( skill_id == RA_AIMEDBOLT && (sc->data[SC_WUGBITE] || sc->data[SC_ANKLESNARE] || sc->data[SC_ELECTRICSHOCKER]) )
{
- status_change_end(bl, SC_BITE, INVALID_TIMER);
- status_change_end(bl, SC_ANKLE, INVALID_TIMER);
+ status_change_end(bl, SC_WUGBITE, INVALID_TIMER);
+ status_change_end(bl, SC_ANKLESNARE, INVALID_TIMER);
status_change_end(bl, SC_ELECTRICSHOCKER, INVALID_TIMER);
}
@@ -1126,7 +2863,7 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damag
//Probably not the most correct place, but it'll do here
//(since battle_drain is strictly for players currently)
- if ((sce=sc->data[SC_BLOODLUST]) && flag&BF_WEAPON && damage > 0 &&
+ if ((sce=sc->data[SC_HAMI_BLOODLUST]) && flag&BF_WEAPON && damage > 0 &&
rnd()%100 < sce->val3)
status_heal(src, damage*sce->val4/100, 0, 3);
@@ -1353,207 +3090,6 @@ int battle_calc_drain(int damage, int rate, int per) {
}
/*==========================================
- * Passif skill dammages increases
- *------------------------------------------*/
-int battle_addmastery(struct map_session_data *sd,struct block_list *target,int dmg,int type) {
- int damage,skill;
- struct status_data *status = status_get_status_data(target);
- int weapon;
- damage = dmg;
-
- nullpo_ret(sd);
-
- if((skill = pc->checkskill(sd,AL_DEMONBANE)) > 0 &&
- target->type == BL_MOB && //This bonus doesnt work against players.
- (battle->check_undead(status->race,status->def_ele) || status->race==RC_DEMON) )
- damage += (skill*(int)(3+(sd->status.base_level+1)*0.05)); // submitted by orn
- //damage += (skill * 3);
- if( (skill = pc->checkskill(sd, RA_RANGERMAIN)) > 0 && (status->race == RC_BRUTE || status->race == RC_PLANT || status->race == RC_FISH) )
- damage += (skill * 5);
- if( (skill = pc->checkskill(sd,NC_RESEARCHFE)) > 0 && (status->def_ele == ELE_FIRE || status->def_ele == ELE_EARTH) )
- damage += (skill * 10);
- if( pc_ismadogear(sd) )
- damage += 20 + 20 * pc->checkskill(sd, NC_MADOLICENCE);
-
- if((skill = pc->checkskill(sd,HT_BEASTBANE)) > 0 && (status->race==RC_BRUTE || status->race==RC_INSECT) ) {
- damage += (skill * 4);
- if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_HUNTER)
- damage += sd->status.str;
- }
-
- if(type == 0)
- weapon = sd->weapontype1;
- else
- weapon = sd->weapontype2;
- switch(weapon)
- {
- case W_1HSWORD:
- #ifdef RENEWAL
- if((skill = pc->checkskill(sd,AM_AXEMASTERY)) > 0)
- damage += (skill * 3);
- #endif
- case W_DAGGER:
- if((skill = pc->checkskill(sd,SM_SWORD)) > 0)
- damage += (skill * 4);
- if((skill = pc->checkskill(sd,GN_TRAINING_SWORD)) > 0)
- damage += skill * 10;
- break;
- case W_2HSWORD:
- #ifdef RENEWAL
- if((skill = pc->checkskill(sd,AM_AXEMASTERY)) > 0)
- damage += (skill * 3);
- #endif
- if((skill = pc->checkskill(sd,SM_TWOHAND)) > 0)
- damage += (skill * 4);
- break;
- case W_1HSPEAR:
- case W_2HSPEAR:
- if((skill = pc->checkskill(sd,KN_SPEARMASTERY)) > 0) {
- if(!pc_isriding(sd))
- damage += (skill * 4);
- else
- damage += (skill * 5);
- }
- break;
- case W_1HAXE:
- case W_2HAXE:
- if((skill = pc->checkskill(sd,AM_AXEMASTERY)) > 0)
- damage += (skill * 3);
- if((skill = pc->checkskill(sd,NC_TRAININGAXE)) > 0)
- damage += (skill * 5);
- break;
- case W_MACE:
- case W_2HMACE:
- if((skill = pc->checkskill(sd,PR_MACEMASTERY)) > 0)
- damage += (skill * 3);
- if((skill = pc->checkskill(sd,NC_TRAININGAXE)) > 0)
- damage += (skill * 5);
- break;
- case W_FIST:
- if((skill = pc->checkskill(sd,TK_RUN)) > 0)
- damage += (skill * 10);
- // No break, fallthrough to Knuckles
- case W_KNUCKLE:
- if((skill = pc->checkskill(sd,MO_IRONHAND)) > 0)
- damage += (skill * 3);
- break;
- case W_MUSICAL:
- if((skill = pc->checkskill(sd,BA_MUSICALLESSON)) > 0)
- damage += (skill * 3);
- break;
- case W_WHIP:
- if((skill = pc->checkskill(sd,DC_DANCINGLESSON)) > 0)
- damage += (skill * 3);
- break;
- case W_BOOK:
- if((skill = pc->checkskill(sd,SA_ADVANCEDBOOK)) > 0)
- damage += (skill * 3);
- break;
- case W_KATAR:
- if((skill = pc->checkskill(sd,AS_KATAR)) > 0)
- damage += (skill * 3);
- break;
- }
-
- return damage;
-}
-/*==========================================
- * Calculates the standard damage of a normal attack assuming it hits,
- * it calculates nothing extra fancy, is needed for magnum break's WATK_ELEMENT bonus. [Skotlex]
- *------------------------------------------
- * Pass damage2 as NULL to not calc it.
- * Flag values:
- * &1: Critical hit
- * &2: Arrow attack
- * &4: Skill is Magic Crasher
- * &8: Skip target size adjustment (Extremity Fist?)
- *&16: Arrow attack but BOW, REVOLVER, RIFLE, SHOTGUN, GATLING or GRENADE type weapon not equipped (i.e. shuriken, kunai and venom knives not affected by DEX)
- */
-int battle_calc_base_damage(struct status_data *status, struct weapon_atk *wa, struct status_change *sc, unsigned short t_size, struct map_session_data *sd, int flag) {
- unsigned int atkmin=0, atkmax=0;
- short type = 0;
- int damage = 0;
-
- if (!sd)
- { //Mobs/Pets
- if(flag&4)
- {
- atkmin = status->matk_min;
- atkmax = status->matk_max;
- } else {
- atkmin = wa->atk;
- atkmax = wa->atk2;
- }
- if (atkmin > atkmax)
- atkmin = atkmax;
- } else { //PCs
- atkmax = wa->atk;
- type = (wa == &status->lhw)?EQI_HAND_L:EQI_HAND_R;
-
- if (!(flag&1) || (flag&2))
- { //Normal attacks
- atkmin = status->dex;
-
- if (sd->equip_index[type] >= 0 && sd->inventory_data[sd->equip_index[type]])
- atkmin = atkmin*(80 + sd->inventory_data[sd->equip_index[type]]->wlv*20)/100;
-
- if (atkmin > atkmax)
- atkmin = atkmax;
-
- if(flag&2 && !(flag&16))
- { //Bows
- atkmin = atkmin*atkmax/100;
- if (atkmin > atkmax)
- atkmax = atkmin;
- }
- }
- }
-
- if (sc && sc->data[SC_MAXIMIZEPOWER])
- atkmin = atkmax;
-
- //Weapon Damage calculation
- if (!(flag&1))
- damage = (atkmax>atkmin? rnd()%(atkmax-atkmin):0)+atkmin;
- else
- damage = atkmax;
-
- if (sd)
- {
- //rodatazone says the range is 0~arrow_atk-1 for non crit
- if (flag&2 && sd->bonus.arrow_atk)
- damage += ( (flag&1) ? sd->bonus.arrow_atk : rnd()%sd->bonus.arrow_atk );
-
- //SizeFix only for players
- if (!(sd->special_state.no_sizefix || (flag&8)))
- damage = damage * ( type == EQI_HAND_L ? sd->left_weapon.atkmods[t_size] : sd->right_weapon.atkmods[t_size] ) / 100;
- }
-
- //Finally, add baseatk
- if(flag&4)
- damage += status->matk_min;
- else
- damage += status->batk;
-
- //rodatazone says that Overrefine bonuses are part of baseatk
- //Here we also apply the weapon_atk_rate bonus so it is correctly applied on left/right hands.
- if(sd) {
- if (type == EQI_HAND_L) {
- if(sd->left_weapon.overrefine)
- damage += rnd()%sd->left_weapon.overrefine+1;
- if (sd->weapon_atk_rate[sd->weapontype2])
- damage += damage * sd->weapon_atk_rate[sd->weapontype2] / 100;
- } else { //Right hand
- if(sd->right_weapon.overrefine)
- damage += rnd()%sd->right_weapon.overrefine+1;
- if (sd->weapon_atk_rate[sd->weapontype1])
- damage += damage * sd->weapon_atk_rate[sd->weapontype1] / 100;
- }
- }
- return damage;
-}
-
-/*==========================================
* Consumes ammo for the given skill.
*------------------------------------------*/
void battle_consume_ammo(TBL_PC*sd, int skill_id, int lv) {
@@ -1610,10 +3146,721 @@ int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id) {
}
return 0;
}
-
//For quick div adjustment.
#define damage_div_fix(dmg, div) { if (div > 1) (dmg)*=div; else if (div < 0) (div)*=-1; }
/*==========================================
+ * battle_calc_magic_attack [DracoRPG]
+ *------------------------------------------*/
+struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag) {
+ int i, nk;
+ short s_ele = 0;
+ unsigned int skillratio = 100; //Skill dmg modifiers.
+
+ TBL_PC *sd;
+// TBL_PC *tsd;
+ struct status_change *sc, *tsc;
+ struct Damage ad;
+ struct status_data *sstatus = status_get_status_data(src);
+ struct status_data *tstatus = status_get_status_data(target);
+ struct {
+ unsigned imdef : 1;
+ unsigned infdef : 1;
+ } flag;
+
+ memset(&ad,0,sizeof(ad));
+ memset(&flag,0,sizeof(flag));
+
+ if(src==NULL || target==NULL)
+ {
+ nullpo_info(NLP_MARK);
+ return ad;
+ }
+ //Initial Values
+ ad.damage = 1;
+ ad.div_=skill->get_num(skill_id,skill_lv);
+ ad.amotion=skill->get_inf(skill_id)&INF_GROUND_SKILL?0:sstatus->amotion; //Amotion should be 0 for ground skills.
+ ad.dmotion=tstatus->dmotion;
+ ad.blewcount = skill->get_blewcount(skill_id,skill_lv);
+ ad.flag=BF_MAGIC|BF_SKILL;
+ ad.dmg_lv=ATK_DEF;
+ nk = skill->get_nk(skill_id);
+ flag.imdef = nk&NK_IGNORE_DEF?1:0;
+
+ sd = BL_CAST(BL_PC, src);
+// tsd = BL_CAST(BL_PC, target);
+ sc = status_get_sc(src);
+ tsc = status_get_sc(target);
+
+ //Initialize variables that will be used afterwards
+ s_ele = skill->get_ele(skill_id, skill_lv);
+
+ if (s_ele == -1){ // pl=-1 : the skill takes the weapon's element
+ s_ele = sstatus->rhw.ele;
+ if( sd ){ //Summoning 10 charm will endow your weapon
+ ARR_FIND(1, 6, i, sd->charm[i] >= 10);
+ if( i < 5 ) s_ele = i;
+ }
+ }else if (s_ele == -2) //Use status element
+ s_ele = status_get_attack_sc_element(src,status_get_sc(src));
+ else if( s_ele == -3 ) //Use random element
+ s_ele = rnd()%ELE_MAX;
+
+ if( skill_id == SO_PSYCHIC_WAVE ) {
+ if( sc && sc->count ) {
+ if( sc->data[SC_HEATER_OPTION] ) s_ele = sc->data[SC_HEATER_OPTION]->val4;
+ else if( sc->data[SC_COOLER_OPTION] ) s_ele = sc->data[SC_COOLER_OPTION]->val4;
+ else if( sc->data[SC_BLAST_OPTION] ) s_ele = sc->data[SC_BLAST_OPTION]->val3;
+ else if( sc->data[SC_CURSED_SOIL_OPTION] ) s_ele = sc->data[SC_CURSED_SOIL_OPTION]->val4;
+ }
+ }
+
+ //Set miscellaneous data that needs be filled
+ if(sd) {
+ sd->state.arrow_atk = 0;
+ ad.blewcount += battle->blewcount_bonus(sd, skill_id);
+ }
+
+ //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;
+ }
+
+ switch(skill_id) {
+ case MG_FIREWALL:
+ case NJ_KAENSIN:
+ ad.dmotion = 0; //No flinch animation.
+ if ( tstatus->def_ele == ELE_FIRE || battle->check_undead(tstatus->race, tstatus->def_ele) )
+ ad.blewcount = 0; //No knockback
+ break;
+ case PR_SANCTUARY:
+ ad.dmotion = 0; //No flinch animation.
+ break;
+ case WL_HELLINFERNO:
+ if( mflag&ELE_DARK )
+ s_ele = ELE_DARK;
+ break;
+ case KO_KAIHOU:
+ if( sd ){
+ ARR_FIND(1, 6, i, sd->charm[i] > 0);
+ if( i < 5 )
+ s_ele = i;
+ }
+ break;
+#ifdef RENEWAL
+ case CR_ACIDDEMONSTRATION:
+ case ASC_BREAKER:
+ case HW_MAGICCRASHER:
+ flag.imdef = 1;
+ break;
+#endif
+ }
+
+ if (!flag.infdef) //No need to do the math for plants
+ {
+#ifdef RENEWAL
+ ad.damage = 0; //reinitialize..
+#endif
+//MATK_RATE scales the damage. 100 = no change. 50 is halved, 200 is doubled, etc
+#define MATK_RATE( a ) { ad.damage= ad.damage*(a)/100; }
+//Adds dmg%. 100 = +100% (double) damage. 10 = +10% damage
+#define MATK_ADDRATE( a ) { ad.damage+= ad.damage*(a)/100; }
+//Adds an absolute value to damage. 100 = +100 damage
+#define MATK_ADD( a ) { ad.damage+= a; }
+
+ switch (skill_id)
+ { //Calc base damage according to skill
+ case AL_HEAL:
+ case PR_BENEDICTIO:
+ case PR_SANCTUARY:
+ /**
+ * Arch Bishop
+ **/
+ case AB_HIGHNESSHEAL:
+ ad.damage = skill->calc_heal(src, target, skill_id, skill_lv, false);
+ break;
+ case PR_ASPERSIO:
+ ad.damage = 40;
+ break;
+ case ALL_RESURRECTION:
+ case PR_TURNUNDEAD:
+ //Undead check is on skill_castend_damageid code.
+ i = 20*skill_lv + sstatus->luk + sstatus->int_ + status_get_lv(src)
+ + 200 - 200*tstatus->hp/tstatus->max_hp; // there is no changed in success chance in renewal. [malufett]
+ if(i > 700) i = 700;
+ if(rnd()%1000 < i && !(tstatus->mode&MD_BOSS))
+ ad.damage = tstatus->hp;
+ else {
+ #ifdef RENEWAL
+ MATK_ADD(status_get_matk(src, 2));
+ #else
+ ad.damage = status_get_lv(src) + sstatus->int_ + skill_lv * 10;
+ #endif
+ }
+ break;
+ case PF_SOULBURN:
+ ad.damage = tstatus->sp * 2;
+ break;
+ /**
+ * Arch Bishop
+ **/
+ case AB_RENOVATIO:
+ //Damage calculation from iRO wiki. [Jobbie]
+ ad.damage = (int)((15 * status_get_lv(src)) + (1.5 * sstatus->int_));
+ break;
+ default: {
+ MATK_ADD( status_get_matk(src, 2) );
+
+ if (nk&NK_SPLASHSPLIT) { // Divide MATK in case of multiple targets skill
+ if(mflag>0)
+ ad.damage/= mflag;
+ else
+ ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_id, skill->get_name(skill_id));
+ }
+
+ if (sc){
+ if( sc->data[SC_TELEKINESIS_INTENSE] && s_ele == ELE_GHOST )
+ skillratio += 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]
+ ad.div_ = 1;// ad mods, to make it work similar to regular hits [Xazax]
+ ad.flag = BF_WEAPON|BF_SHORT;
+ ad.type = 0;
+ }
+ break;
+ default:
+ MATK_RATE(battle->calc_skillratio(BF_MAGIC, src, target, skill_id, skill_lv, skillratio, mflag));
+ }
+ //Constant/misc additions from skills
+ if (skill_id == WZ_FIREPILLAR)
+ MATK_ADD(50);
+ if( sd && (i=pc->checkskill(sd,AB_EUCHARISTICA)) > 0 &&
+ (tstatus->race == RC_DEMON || tstatus->def_ele == ELE_DARK) )
+ MATK_ADDRATE(i);
+ }
+ }
+#ifndef HMAP_ZONE_DAMAGE_CAP_TYPE
+ if( target && skill_id ) {
+ for(i = 0; i < map[target->m].zone->capped_skills_count; i++) {
+ if( skill_id == map[target->m].zone->capped_skills[i]->nameid && (map[target->m].zone->capped_skills[i]->type & target->type) ) {
+ if( target->type == BL_MOB && map[target->m].zone->capped_skills[i]->subtype != MZS_NONE ) {
+ if( (((TBL_MOB*)target)->status.mode&MD_BOSS) && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_BOSS) )
+ continue;
+ if( ((TBL_MOB*)target)->special_state.clone && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_CLONE) )
+ continue;
+ }
+ if( ad.damage > map[target->m].zone->capped_skills[i]->cap )
+ ad.damage = map[target->m].zone->capped_skills[i]->cap;
+ if( ad.damage2 > map[target->m].zone->capped_skills[i]->cap )
+ ad.damage2 = map[target->m].zone->capped_skills[i]->cap;
+ break;
+ }
+ }
+ }
+#endif
+#ifdef RENEWAL
+ ad.damage = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
+#endif
+ if(sd) {
+ //Damage bonuses
+ if ((i = pc->skillatk_bonus(sd, skill_id)))
+ ad.damage += ad.damage*i/100;
+
+ if( (i = battle->adjust_skill_damage(src->m,skill_id)) )
+ MATK_RATE(i);
+
+ //Ignore Defense?
+ if (!flag.imdef && (
+ sd->bonus.ignore_mdef_ele & ( 1 << tstatus->def_ele ) ||
+ sd->bonus.ignore_mdef_race & ( 1 << tstatus->race ) ||
+ sd->bonus.ignore_mdef_race & ( is_boss(target) ? 1 << RC_BOSS : 1 << RC_NONBOSS )
+ ))
+ flag.imdef = 1;
+ }
+
+ ad.damage = battle->calc_defense(BF_MAGIC, src, target, skill_id, skill_lv, ad.damage, (flag.imdef?1:0), 0);
+
+ if (skill_id == NPC_EARTHQUAKE)
+ { //Adds atk2 to the damage, should be influenced by number of hits and skill-ratio, but not mdef reductions. [Skotlex]
+ //Also divide the extra bonuses from atk2 based on the number in range [Kevin]
+ if(mflag>0)
+ ad.damage+= (sstatus->rhw.atk2*skillratio/100)/mflag;
+ else
+ ShowError("Zero range by %d:%s, divide per 0 avoided!\n", skill_id, skill->get_name(skill_id));
+ }
+
+ if(ad.damage<1)
+ ad.damage=1;
+ else if(sc){//only applies when hit
+ // TODO: there is another factor that contribute with the damage and need to be formulated. [malufett]
+ switch(skill_id){
+ case MG_LIGHTNINGBOLT:
+ case MG_THUNDERSTORM:
+ case MG_FIREBOLT:
+ case MG_FIREWALL:
+ case MG_COLDBOLT:
+ case MG_FROSTDIVER:
+ case WZ_EARTHSPIKE:
+ case WZ_HEAVENDRIVE:
+ if(sc->data[SC_GUST_OPTION] || sc->data[SC_PETROLOGY_OPTION]
+ || sc->data[SC_PYROTECHNIC_OPTION] || sc->data[SC_AQUAPLAY_OPTION])
+ ad.damage += (6 + sstatus->int_/4) + max(sstatus->dex-10,0)/30;
+ break;
+ }
+ }
+
+ if (!(nk&NK_NO_ELEFIX))
+ ad.damage=battle->attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
+
+ if( skill_id == CR_GRANDCROSS || skill_id == NPC_GRANDDARKNESS )
+ { //Apply the physical part of the skill's damage. [Skotlex]
+ struct Damage wd = battle->calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
+ ad.damage = battle->attr_fix(src, target, wd.damage + ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv) * (100 + 40*skill_lv)/100;
+ if( src == target )
+ {
+ if( src->type == BL_PC )
+ ad.damage = ad.damage/2;
+ else
+ ad.damage = 0;
+ }
+ }
+
+#ifndef RENEWAL
+ ad.damage = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
+#endif
+ }
+
+ damage_div_fix(ad.damage, ad.div_);
+
+ if (flag.infdef && ad.damage)
+ ad.damage = ad.damage>0?1:-1;
+
+ ad.damage=battle->calc_damage(src,target,&ad,ad.damage,skill_id,skill_lv);
+ if( map_flag_gvg2(target->m) )
+ ad.damage=battle->calc_gvg_damage(src,target,ad.damage,ad.div_,skill_id,skill_lv,ad.flag);
+ else if( map[target->m].flag.battleground )
+ ad.damage=battle->calc_bg_damage(src,target,ad.damage,ad.div_,skill_id,skill_lv,ad.flag);
+
+ switch( skill_id ) { /* post-calc modifiers */
+ case SO_VARETYR_SPEAR: { // Physical damage.
+ struct Damage wd = battle->calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
+ if(!flag.infdef && ad.damage > 1)
+ ad.damage += wd.damage;
+ break;
+ }
+ //case HM_ERASER_CUTTER:
+ }
+
+ return ad;
+}
+
+/*==========================================
+ * Calculate Misc dammage for skill_id
+ *------------------------------------------*/
+struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag) {
+ int temp;
+ short i, nk;
+ short s_ele;
+
+ struct map_session_data *sd, *tsd;
+ struct Damage md; //DO NOT CONFUSE with md of mob_data!
+ struct status_data *sstatus = status_get_status_data(src);
+ struct status_data *tstatus = status_get_status_data(target);
+ struct status_change *tsc = status_get_sc(target);
+ struct status_change *sc = status_get_sc(src);
+
+ memset(&md,0,sizeof(md));
+
+ if( src == NULL || target == NULL ){
+ nullpo_info(NLP_MARK);
+ return md;
+ }
+
+ //Some initial values
+ md.amotion=skill->get_inf(skill_id)&INF_GROUND_SKILL?0:sstatus->amotion;
+ md.dmotion=tstatus->dmotion;
+ md.div_=skill->get_num( skill_id,skill_lv );
+ md.blewcount=skill->get_blewcount(skill_id,skill_lv);
+ md.dmg_lv=ATK_DEF;
+ md.flag=BF_MISC|BF_SKILL;
+
+ nk = skill->get_nk(skill_id);
+
+ sd = BL_CAST(BL_PC, src);
+ tsd = BL_CAST(BL_PC, target);
+
+ if(sd) {
+ sd->state.arrow_atk = 0;
+ md.blewcount += battle->blewcount_bonus(sd, skill_id);
+ }
+
+ s_ele = skill->get_ele(skill_id, skill_lv);
+ if (s_ele < 0 && s_ele != -3) //Attack that takes weapon's element for misc attacks? Make it neutral [Skotlex]
+ s_ele = ELE_NEUTRAL;
+ else if (s_ele == -3) //Use random element
+ s_ele = rnd()%ELE_MAX;
+
+ //Skill Range Criteria
+ md.flag |= battle->range_type(src, target, skill_id, skill_lv);
+
+ switch( skill_id )
+ {
+#ifdef RENEWAL
+ case HT_LANDMINE:
+ case MA_LANDMINE:
+ case HT_BLASTMINE:
+ case HT_CLAYMORETRAP:
+ md.damage = skill_lv * sstatus->dex * (3+status_get_lv(src)/100) * (1+sstatus->int_/35);
+ md.damage += md.damage * (rnd()%20-10) / 100;
+ md.damage += 40 * (sd?pc->checkskill(sd,RA_RESEARCHTRAP):0);
+ break;
+#else
+ case HT_LANDMINE:
+ case MA_LANDMINE:
+ md.damage=skill_lv*(sstatus->dex+75)*(100+sstatus->int_)/100;
+ break;
+ case HT_BLASTMINE:
+ md.damage=skill_lv*(sstatus->dex/2+50)*(100+sstatus->int_)/100;
+ break;
+ case HT_CLAYMORETRAP:
+ md.damage=skill_lv*(sstatus->dex/2+75)*(100+sstatus->int_)/100;
+ break;
+#endif
+ case HT_BLITZBEAT:
+ case SN_FALCONASSAULT:
+ //Blitz-beat Damage.
+ if(!sd || (temp = pc->checkskill(sd,HT_STEELCROW)) <= 0)
+ temp=0;
+ md.damage=(sstatus->dex/10+sstatus->int_/2+temp*3+40)*2;
+ if(mflag > 1) //Autocasted Blitz.
+ nk|=NK_SPLASHSPLIT;
+
+ if (skill_id == SN_FALCONASSAULT) {
+ //Div fix of Blitzbeat
+ temp = skill->get_num(HT_BLITZBEAT, 5);
+ damage_div_fix(md.damage, temp);
+
+ //Falcon Assault Modifier
+ md.damage=md.damage*(150+70*skill_lv)/100;
+ }
+ break;
+ case TF_THROWSTONE:
+ md.damage=50;
+ break;
+ case BA_DISSONANCE:
+ md.damage=30+skill_lv*10;
+ if (sd)
+ md.damage+= 3*pc->checkskill(sd,BA_MUSICALLESSON);
+ break;
+ case NPC_SELFDESTRUCTION:
+ md.damage = sstatus->hp;
+ break;
+ case NPC_SMOKING:
+ md.damage=3;
+ break;
+ case NPC_DARKBREATH:
+ md.damage = 500 + (skill_lv-1)*1000 + rnd()%1000;
+ if(md.damage > 9999) md.damage = 9999;
+ break;
+ case PA_PRESSURE:
+ md.damage=500+300*skill_lv;
+ break;
+ case PA_GOSPEL:
+ md.damage = 1+rnd()%9999;
+ break;
+ case CR_ACIDDEMONSTRATION:
+#ifdef RENEWAL
+ {// [malufett]
+ int matk=0, atk;
+ short tdef = status_get_total_def(target);
+ short tmdef = status_get_total_mdef(target);
+ int targetVit = min(120, status_get_vit(target));
+ short totaldef = (tmdef + tdef - ((unsigned _int64)(tmdef + tdef) >> 32)) >> 1;
+
+ matk = battle->calc_magic_attack(src, target, skill_id, skill_lv, mflag).damage;
+ atk = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, false, s_ele, ELE_NEUTRAL, EQI_HAND_R, (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), md.flag);
+ md.damage = matk + atk;
+ if( src->type == BL_MOB ){
+ totaldef = (tdef + tmdef) >> 1;
+ md.damage = 7 * targetVit * skill_lv * (atk + matk) / 100;
+ /*
+ // Pending [malufett]
+ if( unknown condition )
+ md.damage >>= 1;
+ if( unknown condition ){
+ md.damage = 7 * md.damage % 20;
+ md.damage = 7 * md.damage / 20;
+ }*/
+ }else{
+ float vitfactor = 0.0f, temp;
+
+ if( (vitfactor=(status_get_vit(target)-120.0f)) > 0)
+ vitfactor = (vitfactor * (matk + atk) / 10) / status_get_vit(target);
+ temp = max(0, vitfactor) + (targetVit * (matk + atk)) / 10;
+ md.damage = (int)(temp * 70 * skill_lv / 100);
+ }
+ md.damage -= totaldef;
+ }
+#else
+ // updated the formula based on a Japanese formula found to be exact [Reddozen]
+ if(tstatus->vit+sstatus->int_) //crash fix
+ md.damage = (int)(7*tstatus->vit*sstatus->int_*sstatus->int_ / (10*(tstatus->vit+sstatus->int_)));
+ else
+ md.damage = 0;
+ if (tsd) md.damage>>=1;
+#endif
+ if (md.damage < 0 || md.damage > INT_MAX>>1)
+ //Overflow prevention, will anyone whine if I cap it to a few billion?
+ //Not capped to INT_MAX to give some room for further damage increase.
+ md.damage = INT_MAX>>1;
+ break;
+
+ case KO_MUCHANAGE:
+ md.damage = skill->get_zeny(skill_id ,skill_lv);
+ md.damage = md.damage * (50 + rand()%50) / 100;
+ if ( is_boss(target) || (sd && !pc->checkskill(sd,NJ_TOBIDOUGU)) )
+ md.damage >>= 1;
+ break;
+ case NJ_ZENYNAGE:
+ md.damage = skill->get_zeny(skill_id ,skill_lv);
+ if (!md.damage) md.damage = 2;
+ md.damage = rand()%md.damage + md.damage;
+ if (is_boss(target))
+ md.damage=md.damage / 3;
+ else if (tsd)
+ md.damage=md.damage / 2;
+ break;
+ case GS_FLING:
+ md.damage = sd?sd->status.job_level:status_get_lv(src);
+ break;
+ case HVAN_EXPLOSION: //[orn]
+ md.damage = sstatus->max_hp * (50 + 50 * skill_lv) / 100;
+ break ;
+ case ASC_BREAKER:
+ {
+#ifndef RENEWAL
+ md.damage = 500+rnd()%500 + 5*skill_lv * sstatus->int_;
+ nk|=NK_IGNORE_FLEE|NK_NO_ELEFIX; //These two are not properties of the weapon based part.
+#else
+ int ratio = 300 + 50 * skill_lv;
+ int matk = battle->calc_magic_attack(src, target, skill_id, skill_lv, mflag).damage;
+ short totaldef = status_get_total_def(target) + status_get_total_mdef(target);
+ int atk = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, false, s_ele, ELE_NEUTRAL, EQI_HAND_R, (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), md.flag);
+
+ if( sc && sc->data[SC_EDP] )
+ ratio >>= 1;
+ md.damage = (matk + atk) * ratio / 100;
+ md.damage -= totaldef;
+#endif
+ }
+ break;
+ case HW_GRAVITATION:
+ md.damage = 200+200*skill_lv;
+ md.dmotion = 0; //No flinch animation.
+ break;
+ case NPC_EVILLAND:
+ md.damage = skill->calc_heal(src,target,skill_id,skill_lv,false);
+ break;
+ case RK_DRAGONBREATH:
+ 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;
+ md.flag |= BF_LONG|BF_WEAPON;
+ break;
+ /**
+ * Ranger
+ **/
+ case RA_CLUSTERBOMB:
+ case RA_FIRINGTRAP:
+ case RA_ICEBOUNDTRAP:
+ md.damage = skill_lv * sstatus->dex + sstatus->int_ * 5 ;
+ RE_LVL_TMDMOD();
+ if(sd)
+ {
+ int researchskill_lv = pc->checkskill(sd,RA_RESEARCHTRAP);
+ if(researchskill_lv)
+ md.damage = md.damage * 20 * researchskill_lv / (skill_id == RA_CLUSTERBOMB?50:100);
+ else
+ md.damage = 0;
+ }else
+ md.damage = md.damage * 200 / (skill_id == RA_CLUSTERBOMB?50:100);
+
+ break;
+ /**
+ * Mechanic
+ **/
+ case NC_SELFDESTRUCTION:
+ {
+ short totaldef = status_get_total_def(target);
+ md.damage = ( (sd?pc->checkskill(sd,NC_MAINFRAME):10) + 8 ) * ( skill_lv + 1 ) * ( status_get_sp(src) + sstatus->vit );
+ RE_LVL_MDMOD(100);
+ md.damage += status_get_hp(src) - totaldef;
+ }
+ break;
+ case NC_MAGMA_ERUPTION:
+ md.damage = 1200 + 400 * skill_lv;
+ break;
+ case GN_THORNS_TRAP:
+ 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)) );
+ break;
+ case KO_HAPPOKUNAI:
+ {
+ struct Damage wd = battle->calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
+ short totaldef = status_get_total_def(target);
+ md.damage = 3 * wd.damage * (5 + skill_lv) / 5;
+ md.damage -= totaldef;
+ }
+ break;
+ }
+
+ if (nk&NK_SPLASHSPLIT){ // Divide ATK among targets
+ if(mflag>0)
+ md.damage/= mflag;
+ else
+ ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_id, skill->get_name(skill_id));
+ }
+
+ damage_div_fix(md.damage, md.div_);
+
+ if (!(nk&NK_IGNORE_FLEE))
+ {
+ i = 0; //Temp for "hit or no hit"
+ if(tsc && tsc->opt1 && tsc->opt1 != OPT1_STONEWAIT && tsc->opt1 != OPT1_BURNING)
+ i = 1;
+ else {
+ short
+ flee = tstatus->flee,
+#ifdef RENEWAL
+ hitrate = 0; //Default hitrate
+#else
+ hitrate = 80; //Default hitrate
+#endif
+
+ if(battle_config.agi_penalty_type && battle_config.agi_penalty_target&target->type) {
+ unsigned char attacker_count; //256 max targets should be a sane max
+ attacker_count = unit_counttargeted(target);
+ if(attacker_count >= battle_config.agi_penalty_count)
+ {
+ if (battle_config.agi_penalty_type == 1)
+ flee = (flee * (100 - (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100;
+ else //asume type 2: absolute reduction
+ flee -= (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num;
+ if(flee < 1) flee = 1;
+ }
+ }
+
+ hitrate+= sstatus->hit - flee;
+#ifdef RENEWAL
+ if( sd ) //in Renewal hit bonus from Vultures Eye is not anymore shown in status window
+ hitrate += pc->checkskill(sd,AC_VULTURE);
+#endif
+ if( skill_id == KO_MUCHANAGE )
+ hitrate = (int)((10 - ((float)1 / (status_get_dex(src) + status_get_luk(src))) * 500) * ((float)skill_lv / 2 + 5));
+
+ hitrate = cap_value(hitrate, battle_config.min_hitrate, battle_config.max_hitrate);
+
+ if(rnd()%100 < hitrate)
+ i = 1;
+ }
+ if (!i) {
+ md.damage = 0;
+ md.dmg_lv=ATK_FLEE;
+ }
+ }
+#ifndef HMAP_ZONE_DAMAGE_CAP_TYPE
+ if( target && skill_id ) {
+ for(i = 0; i < map[target->m].zone->capped_skills_count; i++) {
+ if( skill_id == map[target->m].zone->capped_skills[i]->nameid && (map[target->m].zone->capped_skills[i]->type & target->type) ) {
+ if( target->type == BL_MOB && map[target->m].zone->capped_skills[i]->subtype != MZS_NONE ) {
+ if( (((TBL_MOB*)target)->status.mode&MD_BOSS) && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_BOSS) )
+ continue;
+ if( ((TBL_MOB*)target)->special_state.clone && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_CLONE) )
+ continue;
+ }
+ if( md.damage > map[target->m].zone->capped_skills[i]->cap )
+ md.damage = map[target->m].zone->capped_skills[i]->cap;
+ if( md.damage2 > map[target->m].zone->capped_skills[i]->cap )
+ md.damage2 = map[target->m].zone->capped_skills[i]->cap;
+ break;
+ }
+ }
+ }
+#endif
+ md.damage = battle->calc_cardfix(BF_MISC, src, target, nk, s_ele, 0, md.damage, 0, md.flag);
+
+ if (sd && (i = pc->skillatk_bonus(sd, skill_id)))
+ md.damage += md.damage*i/100;
+
+ if( (i = battle->adjust_skill_damage(src->m,skill_id)) )
+ md.damage = md.damage * i / 100;
+
+ if(md.damage < 0)
+ md.damage = 0;
+ else if(md.damage && tstatus->mode&MD_PLANT){
+ switch(skill_id){
+ case HT_LANDMINE:
+ case MA_LANDMINE:
+ case HT_BLASTMINE:
+ case HT_CLAYMORETRAP:
+ case RA_CLUSTERBOMB:
+#ifdef RENEWAL
+ break;
+#endif
+ 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))
+ md.damage=battle->attr_fix(src, target, md.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
+
+ md.damage=battle->calc_damage(src,target,&md,md.damage,skill_id,skill_lv);
+ if( map_flag_gvg2(target->m) )
+ md.damage=battle->calc_gvg_damage(src,target,md.damage,md.div_,skill_id,skill_lv,md.flag);
+ else if( map[target->m].flag.battleground )
+ md.damage=battle->calc_bg_damage(src,target,md.damage,md.div_,skill_id,skill_lv,md.flag);
+
+ switch( skill_id ) {
+ case RA_FIRINGTRAP:
+ case RA_ICEBOUNDTRAP:
+ if( md.damage == 1 ) break;
+ case RA_CLUSTERBOMB:
+ {
+ struct Damage wd;
+ wd = battle->calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
+ md.damage += wd.damage;
+ }
+ break;
+ case NJ_ZENYNAGE:
+ if( sd ) {
+ if ( md.damage > sd->status.zeny )
+ md.damage = sd->status.zeny;
+ pc->payzeny(sd, md.damage,LOG_TYPE_STEAL,NULL);
+ }
+ break;
+ }
+
+ return md;
+}
+
+/*==========================================
* battle_calc_weapon_attack (by Skotlex)
*------------------------------------------*/
struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int wflag)
@@ -1642,6 +3889,9 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
unsigned rh : 1; //Attack considers right hand (wd.damage)
unsigned lh : 1; //Attack considers left hand (wd.damage2)
unsigned weapon : 1; //It's a weapon attack (consider VVS, and all that)
+#ifdef RENEWAL
+ unsigned tdef : 1; //Total defence reduction
+#endif
} flag;
memset(&wd,0,sizeof(wd));
@@ -1682,6 +3932,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
nk |= NK_NO_CARDFIX_ATK|NK_IGNORE_FLEE;
flag.hit = nk&NK_IGNORE_FLEE?1:0;
flag.idef = flag.idef2 = nk&NK_IGNORE_DEF?1:0;
+ flag.tdef = 0;
if (sc && !sc->count)
sc = NULL; //Skip checking as there are no status changes active.
@@ -1756,10 +4007,23 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
case LK_SPIRALPIERCE:
if (!sd) wd.flag=(wd.flag&~(BF_RANGEMASK|BF_WEAPONMASK))|BF_LONG|BF_MISC;
break;
+
+ case MO_INVESTIGATE:
+ flag.pdef = flag.pdef2 = 2;
+ break;
+
+ case RA_AIMEDBOLT:
+ if( tsc && (tsc->data[SC_WUGBITE] || tsc->data[SC_ANKLESNARE] || tsc->data[SC_ELECTRICSHOCKER]) )
+ wd.div_ = tstatus->size + 2 + ( (rnd()%100 < 50-tstatus->size*10) ? 1 : 0 );
+ break;
+#ifdef RENEWAL
+ case HW_MAGICCRASHER:
+ flag.tdef = 1;
+ break;
+#endif
}
} else //Range for normal attacks.
wd.flag |= flag.arrow?BF_LONG:BF_SHORT;
-
if ( (!skill_id || skill_id == PA_SACRIFICE) && tstatus->flee2 && rnd()%1000 < tstatus->flee2 )
{ //Check for Lucky Dodge
wd.type=0x0b;
@@ -1774,8 +4038,8 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
{ //Take weapon's element
s_ele = sstatus->rhw.ele;
s_ele_ = sstatus->lhw.ele;
- if( sd ){ //Summoning 10 talisman will endow your weapon.
- ARR_FIND(1, 6, i, sd->talisman[i] >= 10);
+ if( sd ){ //Summoning 10 charm will endow your weapon.
+ ARR_FIND(1, 6, i, sd->charm[i] >= 10);
if( i < 5 ) s_ele = s_ele_ = i;
}
if( flag.arrow && sd && sd->bonus.arrow_ele )
@@ -1880,9 +4144,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
if( sc && sc->data[SC_CAMOUFLAGE] )
cri += 10 * (10-sc->data[SC_CAMOUFLAGE]->val4);
+#ifndef RENEWAL
//The official equation is *2, but that only applies when sd's do critical.
//Therefore, we use the old value 3 on cases when an sd gets attacked by a mob
cri -= tstatus->luk*(!sd&&tsd?3:2);
+#else
+ cri -= status_get_lv(target) / 15 + 2 * status_get_luk(target);
+#endif
if( tsc && tsc->data[SC_SLEEP] ) {
cri <<= 1;
@@ -1910,11 +4178,10 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
if (flag.cri) {
wd.type = 0x0a;
-#ifdef RENEWAL
- flag.hit = 1;
-#else
- flag.idef = flag.idef2 = flag.hit = 1;
+#ifndef RENEWAL
+ flag.idef = flag.idef2 =
#endif
+ flag.hit = 1;
} else { //Check for Perfect Hit
if(sd && sd->bonus.perfect_hit > 0 && rnd()%100 < sd->bonus.perfect_hit)
flag.hit = 1;
@@ -1930,7 +4197,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
flag.hit = 1;
break;
case CR_SHIELDBOOMERANG:
- if( sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_CRUSADER )
+ if( sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_CRUSADER )
flag.hit = 1;
break;
}
@@ -2028,7 +4295,10 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
hitrate = cap_value(hitrate, battle_config.min_hitrate, battle_config.max_hitrate);
-
+#ifdef RENEWAL
+ if( !sd )
+ hitrate = cap_value(hitrate, 5, 95);
+#endif
if(rnd()%100 >= hitrate)
wd.dmg_lv = ATK_FLEE;
else
@@ -2057,11 +4327,35 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
wd.damage = sstatus->max_hp* 9/100;
wd.damage2 = 0;
break;
-#ifndef RENEWAL
- case NJ_ISSEN:
+
+#ifdef RENEWAL
+ case MO_EXTREMITYFIST: // [malufett]
+ wd.damage = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|8, wd.flag);
+ // first value is still not confirm.
+ wd.damage = status_get_sp(src) + 10 * status_get_sp(src) * wd.damage / 100 + 8 * wd.damage;
+ flag.tdef = 1;
+ break;
+ case NJ_ISSEN: // [malufett]
+ {
+ short totaldef = status_get_total_def(target);
+ i = 0;
+ wd.damage = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, (sc && sc->data[SC_MAXIMIZEPOWER]?1:0)|(sc && sc->data[SC_WEAPONPERFECT]?8:0), wd.flag);
+ if( sc && sc->data[SC_NJ_BUNSINJYUTSU] && (i=sc->data[SC_NJ_BUNSINJYUTSU]->val2) > 0 )
+ wd.div_ = ~( i++ + 2 ) + 1;
+ wd.damage *= sstatus->hp * skill_lv;
+ wd.damage = wd.damage / sstatus->max_hp + sstatus->hp + i * (wd.damage / sstatus->max_hp + sstatus->hp) / 5;
+ ATK_ADD(-totaldef);
+ if( is_boss(target) )
+ ATK_RATE(50);
+ flag.idef = 1;
+ }
+#else
+
wd.damage = 40*sstatus->str +skill_lv*(sstatus->hp/10 + 35);
wd.damage2 = 0;
- break;
+#endif
+ break;
+#ifndef RENEWAL
case LK_SPIRALPIERCE:
case ML_SPIRALPIERCE:
if (sd) {
@@ -2111,12 +4405,18 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
default:
{
- i = (flag.cri?1:0)|
+ i = (flag.cri
+#ifdef RENEWAL
+ || (sc && sc->data[SC_MAXIMIZEPOWER])
+#endif
+ ?1:0)|
(flag.arrow?2:0)|
+#ifndef RENEWAL
(skill_id == HW_MAGICCRASHER?4:0)|
- (!skill_id && sc && sc->data[SC_CHANGE]?4:0)|
(skill_id == MO_EXTREMITYFIST?8:0)|
- (sc && sc->data[SC_WEAPONPERFECTION]?8:0);
+#endif
+ (!skill_id && sc && sc->data[SC_HLIF_CHANGE]?4:0)|
+ (sc && sc->data[SC_WEAPONPERFECT]?8:0);
if (flag.arrow && sd)
switch(sd->status.weapon) {
case W_BOW:
@@ -2128,10 +4428,18 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
default:
i |= 16; // for ex. shuriken must not be influenced by DEX
}
+#ifdef RENEWAL
+ wd.damage = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_R, i, wd.flag);
+ wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon);
+ if (flag.lh){
+ wd.damage2 = battle->calc_base_damage(src, target, skill_id, skill_lv, nk, n_ele, s_ele, s_ele_, EQI_HAND_L, i, wd.flag);
+ wd.damage2 = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage2, wd.div_, 1, flag.weapon);
+ }
+#else
wd.damage = battle->calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, sd, i);
if (flag.lh)
wd.damage2 = battle->calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, sd, i);
-
+#endif
if (nk&NK_SPLASHSPLIT){ // Divide ATK among targets
if(wflag>0)
wd.damage/= wflag;
@@ -2157,214 +4465,38 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
} //End switch(skill_id)
//Skill damage modifiers that stack linearly
+ if( sd && sd->status.weapon == W_KATAR && (i=pc->checkskill(sd,ASC_KATAR)) > 0 )
+ skillratio += skillratio * (13 + 2 * i) / 100;
if(sc && skill_id != PA_SACRIFICE)
{
if(sc->data[SC_OVERTHRUST])
skillratio += sc->data[SC_OVERTHRUST]->val3;
- if(sc->data[SC_MAXOVERTHRUST])
- skillratio += sc->data[SC_MAXOVERTHRUST]->val2;
- if (sc->data[SC_BERSERK] || sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC__BLOODYLUST])
+ if(sc->data[SC_OVERTHRUSTMAX])
+ skillratio += sc->data[SC_OVERTHRUSTMAX]->val2;
+ if (sc->data[SC_BERSERK] || sc->data[SC_SATURDAY_NIGHT_FEVER] || sc->data[SC__BLOODYLUST])
skillratio += 100;
- if(sc->data[SC_ZENKAI] && sstatus->rhw.ele == sc->data[SC_ZENKAI]->val2 )
- skillratio += sc->data[SC_ZENKAI]->val1 * 2;
+#ifdef RENEWAL
+ if( sc->data[SC_TRUESIGHT] )
+ skillratio += 2*sc->data[SC_TRUESIGHT]->val1;
+ if( sc->data[SC_LKCONCENTRATION] )
+ skillratio += sc->data[SC_LKCONCENTRATION]->val2;
+#endif
+ 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( !skill_id )
{
ATK_RATE(skillratio);
}
else
{
- switch( skill_id )
- {
- case SM_BASH:
- case MS_BASH:
- skillratio += 30*skill_lv;
- break;
- case SM_MAGNUM:
- case MS_MAGNUM:
- skillratio += 20*skill_lv;
- break;
- case MC_MAMMONITE:
- skillratio += 50*skill_lv;
- break;
- case HT_POWER:
- skillratio += -50+8*sstatus->str;
- break;
- case AC_DOUBLE:
- case MA_DOUBLE:
- skillratio += 10*(skill_lv-1);
- break;
- case AC_SHOWER:
- case MA_SHOWER:
- #ifdef RENEWAL
- skillratio += 50+10*skill_lv;
- #else
- skillratio += -25+5*skill_lv;
- #endif
- break;
- case AC_CHARGEARROW:
- case MA_CHARGEARROW:
- skillratio += 50;
- break;
-#ifndef RENEWAL
- case HT_FREEZINGTRAP:
- case MA_FREEZINGTRAP:
- skillratio += -50+10*skill_lv;
- break;
-#endif
- case KN_PIERCE:
- case ML_PIERCE:
- skillratio += 10*skill_lv;
- break;
- case MER_CRASH:
- skillratio += 10*skill_lv;
- break;
- case KN_SPEARSTAB:
- skillratio += 15*skill_lv;
- break;
- case KN_SPEARBOOMERANG:
- skillratio += 50*skill_lv;
- break;
- case KN_BRANDISHSPEAR:
- case ML_BRANDISH:
- {
- int ratio = 100+20*skill_lv;
- skillratio += ratio-100;
- if(skill_lv>3 && wflag==1) skillratio += ratio/2;
- if(skill_lv>6 && wflag==1) skillratio += ratio/4;
- if(skill_lv>9 && wflag==1) skillratio += ratio/8;
- if(skill_lv>6 && wflag==2) skillratio += ratio/2;
- if(skill_lv>9 && wflag==2) skillratio += ratio/4;
- if(skill_lv>9 && wflag==3) skillratio += ratio/2;
- break;
- }
- case KN_BOWLINGBASH:
- case MS_BOWLINGBASH:
- skillratio+= 40*skill_lv;
- break;
- case AS_GRIMTOOTH:
- skillratio += 20*skill_lv;
- break;
- case AS_POISONREACT:
- skillratio += 30*skill_lv;
- break;
- case AS_SONICBLOW:
- skillratio += -50+5*skill_lv;
- break;
- case TF_SPRINKLESAND:
- skillratio += 30;
- break;
- case MC_CARTREVOLUTION:
- skillratio += 50;
- if(sd && sd->cart_weight)
- skillratio += 100*sd->cart_weight/sd->cart_weight_max; // +1% every 1% weight
- else if (!sd)
- skillratio += 100; //Max damage for non players.
- break;
- case NPC_RANDOMATTACK:
- skillratio += 100*skill_lv;
- break;
- case NPC_WATERATTACK:
- case NPC_GROUNDATTACK:
- case NPC_FIREATTACK:
- case NPC_WINDATTACK:
- case NPC_POISONATTACK:
- case NPC_HOLYATTACK:
- case NPC_DARKNESSATTACK:
- case NPC_UNDEADATTACK:
- case NPC_TELEKINESISATTACK:
- case NPC_BLOODDRAIN:
- case NPC_ACIDBREATH:
- case NPC_DARKNESSBREATH:
- case NPC_FIREBREATH:
- case NPC_ICEBREATH:
- case NPC_THUNDERBREATH:
- case NPC_HELLJUDGEMENT:
- case NPC_PULSESTRIKE:
- skillratio += 100*(skill_lv-1);
- break;
- case RG_BACKSTAP:
- if(sd && sd->status.weapon == W_BOW && battle_config.backstab_bow_penalty)
- skillratio += (200+40*skill_lv)/2;
- else
- skillratio += 200+40*skill_lv;
- break;
- case RG_RAID:
- skillratio += 40*skill_lv;
- break;
- case RG_INTIMIDATE:
- skillratio += 30*skill_lv;
- break;
- case CR_SHIELDCHARGE:
- skillratio += 20*skill_lv;
- break;
- case CR_SHIELDBOOMERANG:
- skillratio += 30*skill_lv;
- break;
- case NPC_DARKCROSS:
- case CR_HOLYCROSS:
- {
- int ratio = 35*skill_lv;
- #ifdef RENEWAL
- if(sd && sd->status.weapon == W_2HSPEAR)
- ratio *= 2;
- #endif
- skillratio += ratio;
- break;
- }
- case AM_DEMONSTRATION:
- skillratio += 20*skill_lv;
- break;
- case AM_ACIDTERROR:
- skillratio += 40*skill_lv;
- break;
- case MO_FINGEROFFENSIVE:
- skillratio+= 50 * skill_lv;
- break;
- case MO_INVESTIGATE:
- skillratio += 75*skill_lv;
- flag.pdef = flag.pdef2 = 2;
- break;
- case MO_EXTREMITYFIST:
- { //Overflow check. [Skotlex]
- unsigned int ratio = skillratio + 100*(8 + sstatus->sp/10);
- //You'd need something like 6K SP to reach this max, so should be fine for most purposes.
- if (ratio > 60000) ratio = 60000; //We leave some room here in case skillratio gets further increased.
- skillratio = (unsigned short)ratio;
- }
- break;
- case MO_TRIPLEATTACK:
- skillratio += 20*skill_lv;
- break;
- case MO_CHAINCOMBO:
- skillratio += 50+50*skill_lv;
- break;
- case MO_COMBOFINISH:
- skillratio += 140+60*skill_lv;
- break;
- case BA_MUSICALSTRIKE:
- case DC_THROWARROW:
- skillratio += 25+25*skill_lv;
- break;
- case CH_TIGERFIST:
- skillratio += 100*skill_lv-60;
- break;
- case CH_CHAINCRUSH:
- skillratio += 300+100*skill_lv;
- break;
- case CH_PALMSTRIKE:
- skillratio += 100+100*skill_lv;
- break;
- case LK_HEADCRUSH:
- skillratio += 40*skill_lv;
- break;
- case LK_JOINTBEAT:
- i = 10*skill_lv-50;
- // Although not clear, it's being assumed that the 2x damage is only for the break neck ailment.
- if (wflag&BREAK_NECK) i*=2;
- skillratio += i;
- break;
-#ifdef RENEWAL
+ switch(skill_id){
+ #ifdef RENEWAL
case LK_SPIRALPIERCE:
case ML_SPIRALPIERCE:
{// Formula: Floor[Floor(Weapon Weight/2)*skill level + ATK ]*(100%+50%*s.lvl) * 5 multi-hits
@@ -2375,575 +4507,26 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
sd->inventory_data[index] &&
sd->inventory_data[index]->type == IT_WEAPON)
weight = sd->inventory_data[index]->weight/20;
- ATK_ADD(weight * skill_lv)
- skillratio += 50*skill_lv;
+ ATK_ADD(weight * skill_lv);
}
- break;
-#endif
- case ASC_METEORASSAULT:
- skillratio += 40*skill_lv-60;
- break;
- case SN_SHARPSHOOTING:
- case MA_SHARPSHOOTING:
- skillratio += 100+50*skill_lv;
- break;
- case CG_ARROWVULCAN:
- skillratio += 100+100*skill_lv;
- break;
- case AS_SPLASHER:
- skillratio += 400+50*skill_lv;
- if(sd)
- skillratio += 20 * pc->checkskill(sd,AS_POISONREACT);
- break;
- case ASC_BREAKER:
- skillratio += 100*skill_lv-100;
- break;
- case PA_SACRIFICE:
- skillratio += 10*skill_lv-10;
- break;
- case PA_SHIELDCHAIN:
- skillratio += 30*skill_lv;
- break;
- case WS_CARTTERMINATION:
- i = 10 * (16 - skill_lv);
- if (i < 1) i = 1;
- //Preserve damage ratio when max cart weight is changed.
- if(sd && sd->cart_weight)
- skillratio += sd->cart_weight/i * 80000/battle_config.max_cart_weight - 100;
- else if (!sd)
- skillratio += 80000 / i - 100;
- break;
- case TK_DOWNKICK:
- skillratio += 60 + 20*skill_lv;
- break;
- case TK_STORMKICK:
- skillratio += 60 + 20*skill_lv;
- break;
- case TK_TURNKICK:
- skillratio += 90 + 30*skill_lv;
- break;
- case TK_COUNTER:
- skillratio += 90 + 30*skill_lv;
- break;
- case TK_JUMPKICK:
- skillratio += -70 + 10*skill_lv;
- if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill_id)
- skillratio += 10*status_get_lv(src)/3; //Tumble bonus
- if (wflag)
- {
- skillratio += 10*status_get_lv(src)/3; //Running bonus (TODO: What is the real bonus?)
- if( sc && sc->data[SC_SPURT] ) // Spurt bonus
- skillratio *= 2;
- }
- break;
- case GS_TRIPLEACTION:
- skillratio += 50*skill_lv;
- break;
- case GS_BULLSEYE:
- //Only works well against brute/demihumans non bosses.
- if((tstatus->race == RC_BRUTE || tstatus->race == RC_DEMIHUMAN)
- && !(tstatus->mode&MD_BOSS))
- skillratio += 400;
- break;
- case GS_TRACKING:
- skillratio += 100 *(skill_lv+1);
- break;
- case GS_PIERCINGSHOT:
- skillratio += 20*skill_lv;
- break;
- case GS_RAPIDSHOWER:
- skillratio += 10*skill_lv;
- break;
- case GS_DESPERADO:
- skillratio += 50*(skill_lv-1);
- break;
- case GS_DUST:
- skillratio += 50*skill_lv;
- break;
- case GS_FULLBUSTER:
- skillratio += 100*(skill_lv+2);
- break;
- case GS_SPREADATTACK:
- #ifdef RENEWAL
- skillratio += 20*(skill_lv);
- #else
- skillratio += 20*(skill_lv-1);
- #endif
- break;
-#ifdef RENEWAL
- case NJ_ISSEN:
- skillratio += 100 * (skill_lv-1);
- break;
-#endif
- case NJ_HUUMA:
- skillratio += 50 + 150*skill_lv;
- break;
case NJ_TATAMIGAESHI:
-#ifdef RENEWAL
- ATK_RATE(200);
-#endif
- skillratio += 10*skill_lv;
- break;
- case NJ_KASUMIKIRI:
- skillratio += 10*skill_lv;
- break;
- case NJ_KIRIKAGE:
- skillratio += 100*(skill_lv-1);
- break;
- case KN_CHARGEATK:
- {
- int k = (wflag-1)/3; //+100% every 3 cells of distance
- if( k > 2 ) k = 2; // ...but hard-limited to 300%.
- skillratio += 100 * k;
- }
- break;
- case HT_PHANTASMIC:
- skillratio += 50;
- break;
- case MO_BALKYOUNG:
- skillratio += 200;
- break;
- case HFLI_MOON: //[orn]
- skillratio += 10+110*skill_lv;
- break;
- case HFLI_SBR44: //[orn]
- skillratio += 100 *(skill_lv-1);
- break;
- case NPC_VAMPIRE_GIFT:
- skillratio += ((skill_lv-1)%5+1)*100;
- break;
- case RK_SONICWAVE:
- skillratio += 400 + 100 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case RK_HUNDREDSPEAR:
- skillratio += 500 + (80 * 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 += max(10000 - sd->inventory_data[index]->weight, 0) / 10;
- skillratio += 50 * pc->checkskill(sd,LK_SPIRALPIERCE);
- } // (1 + [(Casters Base Level - 100) / 200])
- skillratio = skillratio * (100 + (status_get_lv(src)-100) / 2) / 100;
- break;
- case RK_WINDCUTTER:
- skillratio += 50 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case RK_IGNITIONBREAK:
- i = distance_bl(src,target);
- if( i < 2 )
- skillratio = 200 + 200 * skill_lv;
- else if( i < 4 )
- skillratio = 100 + 200 * skill_lv;
- else
- skillratio = 100 + 100 * skill_lv;
- RE_LVL_DMOD(100);
- if( sstatus->rhw.ele == ELE_FIRE )
- skillratio += skillratio / 2;
- break;
- case RK_CRUSHSTRIKE:
- if( sd )
- {//ATK [{Weapon Level * (Weapon Upgrade Level + 6) * 100} + (Weapon ATK) + (Weapon Weight)]%
- 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 + sstatus->rhw.atk +
- 100 * sd->inventory_data[index]->wlv * (sd->status.inventory[index].refine + 6);
- }
- break;
- case RK_STORMBLAST:
- skillratio = 100 * (sd ? pc->checkskill(sd,RK_RUNEMASTERY) : 1) + 100 * (sstatus->int_ / 4);
- break;
- case RK_PHANTOMTHRUST:
- skillratio = 50 * skill_lv + 10 * ( sd ? pc->checkskill(sd,KN_SPEARMASTERY) : 10);
- //if( s_level > 100 ) skillratio += skillratio * s_level / 150; // Base level bonus. This is official, but is disabled until I can confirm something with was changed or not. [Rytech]
- //if( s_level > 100 ) skillratio += skillratio * (s_level - 100) / 200; // Base level bonus.
- break;
- /**
- * GC Guilotine Cross
- **/
- case GC_CROSSIMPACT:
- skillratio += 900 + 100 * skill_lv;
- RE_LVL_DMOD(120);
- break;
- case GC_PHANTOMMENACE:
- skillratio += 200;
- break;
- case GC_COUNTERSLASH:
- //ATK [{(Skill Level x 100) + 300} x Caster's Base Level / 120]% + ATK [(AGI x 2) + (Caster's Job Level x 4)]%
- skillratio += 200 + (100 * skill_lv);
- RE_LVL_DMOD(120);
- skillratio += sstatus->agi + (sd?sd->status.job_level:0) * 4;
- break;
- case GC_ROLLINGCUTTER:
- skillratio += -50 + 50 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case GC_CROSSRIPPERSLASHER:
- skillratio += 300 + 80 * skill_lv;
- RE_LVL_DMOD(100);
- if( sc && sc->data[SC_ROLLINGCUTTER] )
- skillratio += sc->data[SC_ROLLINGCUTTER]->val1 * sstatus->agi;
- break;
- /**
- * Arch Bishop
- **/
- case AB_DUPLELIGHT_MELEE:
- skillratio += 10 * skill_lv;
- break;
- /**
- * Ranger
- **/
- case RA_ARROWSTORM:
- skillratio += 900 + 80 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case RA_AIMEDBOLT:
- skillratio += 400 + 50 * skill_lv;
- RE_LVL_DMOD(100);
- if( tsc && (tsc->data[SC_BITE] || tsc->data[SC_ANKLE] || tsc->data[SC_ELECTRICSHOCKER]) )
- wd.div_ = tstatus->size + 2 + ( (rnd()%100 < 50-tstatus->size*10) ? 1 : 0 );
- break;
- case RA_CLUSTERBOMB:
- skillratio += 100 + 100 * skill_lv;
- break;
- case RA_WUGDASH:// ATK 300%
- skillratio += 200;
- break;
- case RA_WUGSTRIKE:
- skillratio = 200 * skill_lv;
- break;
- case RA_WUGBITE:
- skillratio += 300 + 200 * skill_lv;
- if ( skill_lv == 5 ) skillratio += 100;
- break;
- case RA_SENSITIVEKEEN:
- skillratio += 50 * skill_lv;
- break;
- /**
- * Mechanic
- **/
- case NC_BOOSTKNUCKLE:
- skillratio += 100 + 100 * skill_lv + sstatus->dex;
- RE_LVL_DMOD(100);
- break;
- case NC_PILEBUNKER:
- skillratio += 200 + 100 * skill_lv + sstatus->str;
- RE_LVL_DMOD(100);
- break;
- case NC_VULCANARM:
- skillratio = 70 * skill_lv + sstatus->dex;
- RE_LVL_DMOD(100);
- break;
- case NC_FLAMELAUNCHER:
- case NC_COLDSLOWER:
- skillratio += 200 + 300 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case NC_ARMSCANNON:
- switch( tstatus->size ) {
- case SZ_SMALL: skillratio += 100 + 500 * skill_lv; break;// Small
- case SZ_MEDIUM: skillratio += 100 + 400 * skill_lv; break;// Medium
- case SZ_BIG: skillratio += 100 + 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]
- break;
- case NC_AXEBOOMERANG:
- skillratio += 60 + 40 * 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]
- }
- RE_LVL_DMOD(100);
- break;
- case NC_POWERSWING:
- skillratio += 80 + 20 * skill_lv + sstatus->str + sstatus->dex;
- RE_LVL_DMOD(100);
- break;
- case NC_AXETORNADO:
- skillratio += 100 + 100 * skill_lv + sstatus->vit;
- RE_LVL_DMOD(100);
- break;
- case SC_FATALMENACE:
- skillratio += 100 * skill_lv;
- break;
- case SC_TRIANGLESHOT:
- skillratio += 270 + 30 * skill_lv;
- break;
- case SC_FEINTBOMB:
- skillratio += 100 + 100 * skill_lv;
- break;
- case LG_CANNONSPEAR:// Stimated formula. Still need confirm it.
- skillratio += -100 + (50 + sstatus->str) * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case LG_BANISHINGPOINT:
- skillratio += -100 + ((50 * skill_lv) + (30 * ((sd)?pc->checkskill(sd,SM_BASH):1)));
- RE_LVL_DMOD(100);
- break;
- case LG_SHIELDPRESS:
- skillratio += 60 + 43 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case LG_PINPOINTATTACK:
- skillratio = ((100 * skill_lv) + (10 * status_get_agi(src)) );
- RE_LVL_DMOD(100);
- break;
- case LG_RAGEBURST:
- if( sd && sd->spiritball_old )
- skillratio += -100 + (sd->spiritball_old * 200);
- else
- skillratio += -100 + 15 * 200;
- RE_LVL_DMOD(100);
- break;
- case LG_SHIELDSPELL:// [(Casters Base Level x 4) + (Shield DEF x 10) + (Casters VIT x 2)] %
- if( sd ) {
- struct item_data *shield_data = sd->inventory_data[sd->equip_index[EQI_HAND_L]];
- skillratio = status_get_lv(src) * 4 + status_get_vit(src) * 2;
- if( shield_data )
- skillratio += shield_data->def * 10;
- } else
- skillratio += 2400; //2500%
- break;
- case LG_MOONSLASHER:
- skillratio += -100 + (120 * skill_lv + ((sd) ? pc->checkskill(sd,LG_OVERBRAND) : 5) * 80);
- RE_LVL_DMOD(100);
- break;
- case LG_OVERBRAND:
- skillratio = 400 * skill_lv + (pc->checkskill(sd,CR_SPEARQUICKEN) * 30);
- RE_LVL_DMOD(100);
- break;
- case LG_OVERBRAND_BRANDISH:
- skillratio = 300 * skill_lv + (2 * (sstatus->str + sstatus->dex) / 3);
- RE_LVL_DMOD(100);
- break;
- case LG_OVERBRAND_PLUSATK:
- skillratio = 150 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case LG_RAYOFGENESIS:
- skillratio = 300 + 300 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case LG_EARTHDRIVE:
- skillratio = (skillratio + 100) * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case LG_HESPERUSLIT:
- skillratio += 120 * skill_lv - 100;
- break;
- case SR_DRAGONCOMBO:
- skillratio += 40 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case SR_SKYNETBLOW:
- //ATK [{(Skill Level x 80) + (Caster AGI)} x Caster Base Level / 100] %
- skillratio = 80 * skill_lv + sstatus->agi;
- if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_DRAGONCOMBO )//ATK [{(Skill Level x 100) + (Caster AGI) + 150} x Caster Base Level / 100] %
- skillratio = 100 * skill_lv + sstatus->agi + 150;
- RE_LVL_DMOD(100);
- break;
- case SR_EARTHSHAKER:
- if( tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || // [(Skill Level x 150) x (Caster Base Level / 100) + (Caster INT x 3)] %
- tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKINGEXCEED] || tsc->data[SC__INVISIBILITY]) ){
- skillratio = 150 * skill_lv;
- RE_LVL_DMOD(100);
- skillratio += sstatus->int_ * 3;
- }else{ //[(Skill Level x 50) x (Caster Base Level / 100) + (Caster INT x 2)] %
- skillratio += 50 * (skill_lv-2);
- RE_LVL_DMOD(100);
- skillratio += sstatus->int_ * 2;
- }
- break;
- case SR_FALLENEMPIRE:// ATK [(Skill Level x 150 + 100) x Caster Base Level / 150] %
- skillratio += 150 *skill_lv;
- RE_LVL_DMOD(150);
- break;
- case SR_TIGERCANNON:// ATK [((Caster consumed HP + SP) / 4) x Caster Base Level / 100] %
- {
- int hp = sstatus->max_hp * (10 + 2 * skill_lv) / 100,
- sp = sstatus->max_sp * (6 + skill_lv) / 100;
- skillratio = (hp+sp) / 4;
- if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE ) // ATK [((Caster consumed HP + SP) / 2) x Caster Base Level / 100] %
- skillratio = hp+sp / 2;
- RE_LVL_DMOD(100);
- }
- break;
- case SR_RAMPAGEBLASTER:
- skillratio += 20 * skill_lv * (sd?sd->spiritball_old:5) - 100;
- if( sc && sc->data[SC_EXPLOSIONSPIRITS] ){
- skillratio += sc->data[SC_EXPLOSIONSPIRITS]->val1 * 20;
- RE_LVL_DMOD(120);
- }else
- RE_LVL_DMOD(150);
- break;
- case SR_KNUCKLEARROW:
- if( wflag&4 ){ // 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] %
- skillratio += 400 + (100 * skill_lv);
- RE_LVL_DMOD(100);
- break;
- case SR_WINDMILL: // ATK [(Caster Base Level + Caster DEX) x Caster Base Level / 100] %
- skillratio = status_get_lv(src) + sstatus->dex;
- RE_LVL_DMOD(100);
- break;
- case SR_GATEOFHELL:
- if( sc && sc->data[SC_COMBO]
- && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE )
- skillratio += 800 * skill_lv -100;
- else
- skillratio += 500 * skill_lv -100;
- RE_LVL_DMOD(100);
- break;
- case SR_GENTLETOUCH_QUIET:
- skillratio += 100 * skill_lv - 100 + sstatus->dex;
- RE_LVL_DMOD(100);
- break;
- case SR_HOWLINGOFLION:
- skillratio += 300 * skill_lv - 100;
- RE_LVL_DMOD(150);
- break;
- case SR_RIDEINLIGHTNING: // ATK [{(Skill Level x 200) + Additional Damage} x Caster Base Level / 100] %
- if( (sstatus->rhw.ele) == ELE_WIND || (sstatus->lhw.ele) == ELE_WIND )
- skillratio += skill_lv * 50;
- skillratio += -100 + 200 * skill_lv;
- 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);
- RE_LVL_DMOD(100);
- break;
- case WM_SEVERE_RAINSTORM_MELEE:
- //ATK [{(Caster DEX + AGI) x (Skill Level / 5)} x Caster Base Level / 100] %
- skillratio = (sstatus->dex + sstatus->agi) * (skill_lv * 2);
- RE_LVL_DMOD(100);
- skillratio /= 10;
- break;
- case WM_GREAT_ECHO:
- skillratio += 800 + 100 * skill_lv;
- if( sd ) { // Still need official value [pakpil]
- short lv = (short)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;
- break;
- case GN_CART_TORNADO:
- // ATK [( Skill Level x 50 ) + ( Cart Weight / ( 150 - Caster Base STR ))] + ( Cart Remodeling Skill Level x 50 )] %
- skillratio = 50 * skill_lv;
- if( sd && sd->cart_weight)
- skillratio += sd->cart_weight/10 / max(150-sstatus->str,1) + pc->checkskill(sd, GN_REMODELING_CART) * 50;
- break;
- case GN_CARTCANNON:
- // ATK [{( Cart Remodeling Skill Level x 50 ) x ( INT / 40 )} + ( Cart Cannon Skill Level x 60 )] %
- skillratio = 60 * skill_lv;
- if( sd ) skillratio += pc->checkskill(sd, GN_REMODELING_CART) * 50 * (sstatus->int_ / 40);
- break;
- case GN_SPORE_EXPLOSION:
- skillratio += 200 + 100 * skill_lv;
- break;
- case GN_CRAZYWEED_ATK:
- skillratio += 400 + 100 * skill_lv;
- break;
- case GN_SLINGITEM_RANGEMELEEATK:
- if( sd ) {
- switch( sd->itemid ) {
- case 13260: // Apple Bomob
- case 13261: // Coconut Bomb
- case 13262: // Melon Bomb
- case 13263: // Pinapple Bomb
- skillratio += 400; // Unconfirded
- break;
- case 13264: // Banana Bomb 2000%
- skillratio += 1900;
- break;
- case 13265: skillratio -= 75; break; // Black Lump 25%
- case 13266: skillratio -= 25; break; // Hard Black Lump 75%
- case 13267: skillratio += 100; break; // Extremely Hard Black Lump 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 = 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;
- break;
- // Physical Elemantal Spirits Attack Skills
- case EL_CIRCLE_OF_FIRE:
- case EL_FIRE_BOMB_ATK:
- case EL_STONE_RAIN:
- skillratio += 200;
- break;
- case EL_FIRE_WAVE_ATK:
- skillratio += 500;
- break;
- case EL_TIDAL_WEAPON:
- skillratio += 1400;
- break;
- case EL_WIND_SLASH:
- skillratio += 100;
- break;
- case EL_HURRICANE:
- skillratio += 600;
- break;
- case EL_TYPOON_MIS:
- case EL_WATER_SCREW_ATK:
- skillratio += 900;
- break;
- case EL_STONE_HAMMER:
- skillratio += 400;
- break;
- case EL_ROCK_CRUSHER:
- skillratio += 700;
- break;
- case KO_JYUMONJIKIRI:
- if( tsc && tsc->data[SC_JYUMONJIKIRI] )
- wd.div_ = wd.div_ * -1;// needs more info
- skillratio += -100 + 150 * skill_lv;
- case KO_HUUMARANKA:
- skillratio += -100 + 150 * skill_lv + sstatus->dex/2 + sstatus->agi/2; // needs more info
- break;
- case KO_SETSUDAN:
- skillratio += 100 * (skill_lv-1);
- break;
- case KO_BAKURETSU:
- skillratio = 50 * skill_lv * (sd?pc->checkskill(sd,NJ_TOBIDOUGU):10);
- break;
- case MH_NEEDLE_OF_PARALYZE:
- skillratio += 600 + 100 * skill_lv;
- break;
- case MH_STAHL_HORN:
- skillratio += 400 + 100 * skill_lv;
- break;
- case MH_LAVA_SLIDE:
- skillratio = 70 * skill_lv;
- break;
- case MH_TINDER_BREAKER:
- case MH_MAGMA_FLOW:
- skillratio += -100 + 100 * skill_lv;
- break;
+ if( skill_id != LK_SPIRALPIERCE && skill_id != ML_SPIRALPIERCE )
+ ATK_RATE(200);
+ #endif
+ default:
+ ATK_RATE(battle->calc_skillratio(BF_WEAPON, src, target, skill_id, skill_lv, skillratio, wflag));
}
-#ifdef RENEWAL
- if( sc && sc->data[SC_TRUESIGHT] )
- skillratio += 2*sc->data[SC_TRUESIGHT]->val1;
-#endif
- ATK_RATE(skillratio);
//Constant/misc additions from skills
switch (skill_id) {
case MO_EXTREMITYFIST:
ATK_ADD(250 + 150*skill_lv);
break;
+#ifdef RENEWAL
+ case HW_MAGICCRASHER:
+ ATK_ADD(battle->calc_magic_attack(src, target, skill_id, skill_lv, wflag).damage / 5);
+ break;
+#endif
case TK_DOWNKICK:
case TK_STORMKICK:
case TK_TURNKICK:
@@ -2954,26 +4537,15 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
ATK_ADD(10*pc->checkskill(sd, TK_RUN));
break;
case GS_MAGICALBULLET:
- if(sstatus->matk_max>sstatus->matk_min) {
- ATK_ADD(sstatus->matk_min+rnd()%(sstatus->matk_max-sstatus->matk_min));
- } else {
- ATK_ADD(sstatus->matk_min);
- }
- break;
+#ifndef RENEWAL
+ ATK_ADD( status_get_matk(src, 2) );
+#else
+ ATK_ADD( battle->calc_magic_attack(src, target, skill_id, skill_lv, wflag).damage );
+ flag.tdef = 1;
+#endif
case NJ_SYURIKEN:
ATK_ADD(4*skill_lv);
break;
-#ifdef RENEWAL
- case NJ_ISSEN:
- // Damage = (current HP + atk * skill_lv) - (sdef+edef)
- ATK_ADD(sstatus->hp);
- wd.damage2 = 0;// needs more info if this really 0 for dual weilding KG/OB. [malufett]
- if( sc && sc->data[SC_BUNSINJYUTSU] && (i=sc->data[SC_BUNSINJYUTSU]->val2) > 0){
- wd.div_ = -( i + 2 ); // mirror image number of hits + 2
- ATK_ADDRATE(20 + i*20); // (20 + 20 * mirror image) %
- }
- break;
-#endif
case HT_FREEZINGTRAP:
if(sd)
ATK_ADD( 40 * pc->checkskill(sd, RA_RESEARCHTRAP) );
@@ -2981,23 +4553,11 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
case RA_WUGDASH ://(Caster Current Weight x 10 / 8)
if( sd && sd->weight )
ATK_ADD( sd->weight / 8 );
- case RA_WUGSTRIKE:
- case RA_WUGBITE:
- if(sd)
- ATK_ADD(30*pc->checkskill(sd, RA_TOOTHOFWUG));
- break;
- case SR_GATEOFHELL:
- ATK_ADD (sstatus->max_hp - status_get_hp(src));
- if(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->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_TIGERCANNON: // (Tiger Cannon skill level x 240) + (Target Base Level x 40)
ATK_ADD( skill_lv * 240 + status_get_lv(target) * 40 );
- if( sc && sc->data[SC_COMBO]
- && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE ) // (Tiger Cannon skill level x 500) + (Target Base Level x 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)
ATK_ADD( skill_lv * 500 + status_get_lv(target) * 40 );
break;
case SR_FALLENEMPIRE:// [(Target Size value + Skill Level - 1) x Caster STR] + [(Target current weight x Caster DEX / 120)]
@@ -3009,26 +4569,20 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
break;
case KO_SETSUDAN:
- if( tsc && tsc->data[SC_SPIRIT] ){
- ATK_ADDRATE(10*tsc->data[SC_SPIRIT]->val1);// +10% custom value.
- status_change_end(target,SC_SPIRIT,INVALID_TIMER);
+ if( tsc && tsc->data[SC_SOULLINK] ){
+ ATK_ADDRATE(200*tsc->data[SC_SOULLINK]->val1);
+ status_change_end(target,SC_SOULLINK,INVALID_TIMER);
}
break;
- case KO_KAIHOU:
- if( sd ){
- ARR_FIND(1, 6, i, sd->talisman[i] > 0);
- if( i < 5 ){
- s_ele = i;
- ATK_ADDRATE(100 * sd->talisman[i]);// +100% custom value.
- pc->del_talisman(sd, sd->talisman[i], i);
- }
- }
+ case KO_MAKIBISHI:
+ wd.damage = 20 * skill_lv;
break;
}
}
+#ifndef RENEWAL
//Div fix.
damage_div_fix(wd.damage, wd.div_);
-
+#endif
//The following are applied on top of current damage and are stackable.
if ( sc ) {
#ifndef RENEWAL
@@ -3038,46 +4592,39 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
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 == LG_SHIELDPRESS || skill_id == RK_HUNDREDSPEAR ||
+ skill_id == CR_SHIELDCHARGE ) )
ATK_ADDRATE(sc->data[SC_GLOOMYDAY_SK]->val2);
if( sc->data[SC_EDP] ){
switch(skill_id){
- case AS_SPLASHER: case AS_VENOMKNIFE:
#ifndef RENEWAL_EDP
+ case AS_SPLASHER: case AS_VENOMKNIFE:
case AS_GRIMTOOTH:
-#endif
break;
-#ifndef RENEWAL_EDP
- case ASC_BREAKER: case ASC_METEORASSAULT: break;
-#else
- case AS_SONICBLOW:
- case ASC_BREAKER:
- case GC_COUNTERSLASH:
- case GC_CROSSIMPACT:
- ATK_RATE(50); // only modifier is halved but still benefit with the damage bonus
-#endif
+ case ASC_METEORASSAULT: break;
default:
ATK_ADDRATE(sc->data[SC_EDP]->val3);
+#endif
}
}
if(sc->data[SC_STYLE_CHANGE]){
- TBL_HOM *hd = BL_CAST(BL_HOM,src);
- if (hd) ATK_ADD(hd->homunculus.spiritball * 3);
- }
+ TBL_HOM *hd = BL_CAST(BL_HOM,src);
+ if (hd) ATK_ADD(hd->homunculus.spiritball * 3);
+ }
}
switch (skill_id) {
case AS_SONICBLOW:
- if (sc && sc->data[SC_SPIRIT] &&
- sc->data[SC_SPIRIT]->val2 == SL_ASSASIN)
+ if (sc && sc->data[SC_SOULLINK] &&
+ sc->data[SC_SOULLINK]->val2 == SL_ASSASIN)
ATK_ADDRATE(map_flag_gvg(src->m)?25:100); //+25% dmg on woe/+100% dmg on nonwoe
if(sd && pc->checkskill(sd,AS_SONICACCEL)>0)
ATK_ADDRATE(10);
break;
case CR_SHIELDBOOMERANG:
- if(sc && sc->data[SC_SPIRIT] &&
- sc->data[SC_SPIRIT]->val2 == SL_CRUSADER)
+ if(sc && sc->data[SC_SOULLINK] &&
+ sc->data[SC_SOULLINK]->val2 == SL_CRUSADER)
ATK_ADDRATE(100);
break;
case NC_AXETORNADO:
@@ -3092,7 +4639,9 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if( sd ) {
if (skill_id && (i = pc->skillatk_bonus(sd, skill_id)))
ATK_ADDRATE(i);
-
+ if( (i=pc->checkskill(sd,AB_EUCHARISTICA)) > 0 &&
+ (tstatus->race == RC_DEMON || tstatus->def_ele == ELE_DARK) )
+ ATK_ADDRATE(-i);
if( skill_id != PA_SACRIFICE && skill_id != MO_INVESTIGATE && skill_id != CR_GRANDCROSS && skill_id != NPC_GRANDDARKNESS && skill_id != PA_SHIELDCHAIN && !flag.cri )
{ //Elemental/Racial adjustments
if( sd->right_weapon.def_ratio_atk_ele & (1<<tstatus->def_ele) ||
@@ -3135,129 +4684,16 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
}
- if (!flag.idef || !flag.idef2)
- { //Defense reduction
- short vit_def;
- defType def1 = status_get_def(target); //Don't use tstatus->def1 due to skill timer reductions.
- short def2 = tstatus->def2;
-#ifdef RENEWAL
- if( tsc && tsc->data[SC_ASSUMPTIO] )
- def1 <<= 1; // only eDEF is doubled
-#endif
- if( sd )
- {
- i = sd->ignore_def[is_boss(target)?RC_BOSS:RC_NONBOSS];
- i += sd->ignore_def[tstatus->race];
- if( i )
- {
- if( i > 100 ) i = 100;
- def1 -= def1 * i / 100;
- def2 -= def2 * i / 100;
- }
- }
-
- if( sc && sc->data[SC_EXPIATIO] ){
- i = 5 * sc->data[SC_EXPIATIO]->val1; // 5% per level
- def1 -= def1 * i / 100;
- def2 -= def2 * i / 100;
- }
-
- if( tsc && tsc->data[SC_GT_REVITALIZE] && tsc->data[SC_GT_REVITALIZE]->val4 )
- def2 += 2 * tsc->data[SC_GT_REVITALIZE]->val4;
-
- if( tsc && tsc->data[SC_CAMOUFLAGE] ){
- i = 5 * (10-tsc->data[SC_CAMOUFLAGE]->val4);
- def1 -= def1 * i / 100;
- def2 -= def2 * i / 100;
- }
+ if(!flag.idef || !flag.idef2) { //Defense reduction
+ wd.damage = battle->calc_defense(BF_WEAPON, src, target, skill_id, skill_lv, wd.damage, (flag.idef?1:0)|(flag.pdef?2:0)|(flag.tdef?4:0), flag.pdef);
+ if( wd.damage2 )
+ wd.damage2 = battle->calc_defense(BF_WEAPON, src, target, skill_id, skill_lv, wd.damage2, (flag.idef2?1:0)|(flag.pdef2?2:0)|(flag.tdef?4:0), flag.pdef2);
+ }
- if( battle_config.vit_penalty_type && battle_config.vit_penalty_target&target->type ) {
- unsigned char target_count; //256 max targets should be a sane max
- target_count = unit_counttargeted(target);
- if(target_count >= battle_config.vit_penalty_count) {
- if(battle_config.vit_penalty_type == 1) {
- if( !tsc || !tsc->data[SC_STEELBODY] )
- def1 = (def1 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
- def2 = (def2 * (100 - (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num))/100;
- } else { //Assume type 2
- if( !tsc || !tsc->data[SC_STEELBODY] )
- def1 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
- def2 -= (target_count - (battle_config.vit_penalty_count - 1))*battle_config.vit_penalty_num;
- }
- }
- if(skill_id == AM_ACIDTERROR) def1 = 0; //Acid Terror ignores only armor defense. [Skotlex]
- if(def2 < 1) def2 = 1;
- }
- //Vitality reduction from rodatazone: http://rodatazone.simgaming.net/mechanics/substats.php#def
- if (tsd) //Sd vit-eq
- {
-#ifndef RENEWAL
- //[VIT*0.5] + rnd([VIT*0.3], max([VIT*0.3],[VIT^2/150]-1))
- vit_def = def2*(def2-15)/150;
- vit_def = def2/2 + (vit_def>0?rnd()%vit_def:0);
-#else
- vit_def = def2;
-#endif
- if((battle->check_undead(sstatus->race,sstatus->def_ele) || sstatus->race==RC_DEMON) && //This bonus already doesnt work vs players
- src->type == BL_MOB && (temp=pc->checkskill(tsd,AL_DP)) > 0)
- vit_def += temp*(int)(3 +(tsd->status.base_level+1)*0.04); // submitted by orn
- if( src->type == BL_MOB && (temp=pc->checkskill(tsd,RA_RANGERMAIN))>0 &&
- (sstatus->race == RC_BRUTE || sstatus->race == RC_FISH || sstatus->race == RC_PLANT) )
- vit_def += temp*5;
#ifdef RENEWAL
- if( temp == NJ_ISSEN ){//TODO: do better implementation if other skills(same func) are found [malufett]
- vit_def += def1;
- def1 = 0;
- }
-#endif
- }
- else { //Mob-Pet vit-eq
-#ifndef RENEWAL
- //VIT + rnd(0,[VIT/20]^2-1)
- vit_def = (def2/20)*(def2/20);
- vit_def = def2 + (vit_def>0?rnd()%vit_def:0);
-#else
- vit_def = def2;
+ //Div fix.
+ damage_div_fix(wd.damage, wd.div_);
#endif
- }
-
-
- if (battle_config.weapon_defense_type) {
- vit_def += def1*battle_config.weapon_defense_type;
- def1 = 0;
- }
- #ifdef RENEWAL
- /**
- * RE DEF Reduction
- * Damage = Attack * (4000+eDEF)/(4000+eDEF) - sDEF
- * Pierce defence gains 1 atk per def/2
- **/
-
- if( def1 == -400 ) /* being hit by a gazillion units, you hit the jackpot and got -400 which creates a division by 0 and subsequently crashes */
- def1 = -399;
-
- ATK_ADD2(
- flag.pdef ?(def1/2):0,
- flag.pdef2?(def1/2):0
- );
- if( !flag.idef && !flag.pdef )
- wd.damage = wd.damage * (4000+def1) / (4000+10*def1) - vit_def;
- if( flag.lh && !flag.idef2 && !flag.pdef2 )
- wd.damage2 = wd.damage2 * (4000+def1) / (4000+10*def1) - vit_def;
-
- #else
- if (def1 > 100) def1 = 100;
- ATK_RATE2(
- flag.idef ?100:(flag.pdef ? flag.pdef*(def1+vit_def) : (100-def1)),
- flag.idef2?100:(flag.pdef2? flag.pdef2*(def1+vit_def) : (100-def1))
- );
- ATK_ADD2(
- flag.idef ||flag.pdef ?0:-vit_def,
- flag.idef2||flag.pdef2?0:-vit_def
- );
- #endif
- }
-
//Post skill/vit reduction damage increases
if( sc )
{ //SC skill damages
@@ -3272,20 +4708,8 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
#endif
ATK_ADD(20*lv);
}
-
- if(sc->data[SC_GN_CARTBOOST])
- ATK_ADD(10*sc->data[SC_GN_CARTBOOST]->val1);
-
- if(sc->data[SC_GT_CHANGE] && sc->data[SC_GT_CHANGE]->val2){
- struct block_list *bl; // ATK increase: ATK [{(Caster DEX / 4) + (Caster STR / 2)} x Skill Level / 5]
- if( (bl = iMap->id2bl(sc->data[SC_GT_CHANGE]->val2)) )
- ATK_ADD( ( status_get_dex(bl)/4 + status_get_str(bl)/2 ) * sc->data[SC_GT_CHANGE]->val1 / 5 );
- }
-
- if(sc->data[SC_CAMOUFLAGE])
- ATK_ADD(30 * (10-sc->data[SC_CAMOUFLAGE]->val4) );
}
-
+#ifndef RENEWAL
//Refine bonus
if( sd && flag.weapon && skill_id != MO_INVESTIGATE && skill_id != MO_EXTREMITYFIST )
{ // Counts refine bonus multiple times
@@ -3296,83 +4720,37 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
ATK_ADD2(sstatus->rhw.atk2, sstatus->lhw.atk2);
}
}
-
//Set to min of 1
if (flag.rh && wd.damage < 1) wd.damage = 1;
if (flag.lh && wd.damage2 < 1) wd.damage2 = 1;
+#else
+ if (flag.rh && wd.damage < 1) wd.damage = 0;
+ if (flag.lh && wd.damage2 < 1) wd.damage2 = 0;
+#endif
- if (sd && flag.weapon &&
- skill_id != MO_INVESTIGATE &&
- skill_id != MO_EXTREMITYFIST &&
- skill_id != CR_GRANDCROSS)
- { //Add mastery damage
- if(skill_id != ASC_BREAKER && sd->status.weapon == W_KATAR &&
- (temp=pc->checkskill(sd,ASC_KATAR)) > 0)
- { //Adv Katar Mastery is does not applies to ASC_BREAKER,
- // but other masteries DO apply >_>
- ATK_ADDRATE(10+ 2*temp);
- }
-
- wd.damage = battle->add_mastery(sd,target,wd.damage,0);
- if (flag.lh)
- wd.damage2 = battle->add_mastery(sd,target,wd.damage2,1);
-
- if (sc && sc->data[SC_MIRACLE]) i = 2; //Star anger
- else
- ARR_FIND(0, MAX_PC_FEELHATE, i, t_class == sd->hate_mob[i]);
- if (i < MAX_PC_FEELHATE && (temp=pc->checkskill(sd,sg_info[i].anger_id))) {
- skillratio = sd->status.base_level + sstatus->dex + sstatus->luk;
- if (i == 2) skillratio += sstatus->str; //Star Anger
- if (temp<4)
- skillratio /= 12-3*temp;
- ATK_ADDRATE(skillratio);
- }
- if (skill_id == NJ_SYURIKEN && (temp = pc->checkskill(sd,NJ_TOBIDOUGU)) > 0) {
- ATK_ADD(3*temp);
- } else if (skill_id == NJ_KUNAI)
- ATK_ADD(60);
- }
+#ifndef RENEWAL
+ wd.damage = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage, wd.div_, 0, flag.weapon);
+ if( flag.lh)
+ wd.damage2 = battle->calc_masteryfix(src, target, skill_id, skill_lv, wd.damage2, wd.div_, 1, flag.weapon);
+#else
+ if( flag.cri )
+ ATK_ADDRATE(40);
+#endif
} //Here ends flag.hit section, the rest of the function applies to both hitting and missing attacks
else if(wd.div_ < 0) //Since the attack missed...
wd.div_ *= -1;
-
+#ifndef RENEWAL
if(sd && (temp=pc->checkskill(sd,BS_WEAPONRESEARCH)) > 0)
ATK_ADD(temp*2);
-
+#endif
if(skill_id==TF_POISON)
ATK_ADD(15*skill_lv);
- if( !(nk&NK_NO_ELEFIX) && !n_ele )
- { //Elemental attribute fix
- if( wd.damage > 0 )
- {
- wd.damage=battle->attr_fix(src,target,wd.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
- wd.damage = battle->attr_fix(src,target,wd.damage,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
- if( skill_id== GS_GROUNDDRIFT ) //Additional 50*lv Neutral damage.
- wd.damage += battle->attr_fix(src,target,50*skill_lv,ELE_NEUTRAL,tstatus->def_ele, tstatus->ele_lv);
- }
- if( flag.lh && wd.damage2 > 0 )
- wd.damage2 = battle->attr_fix(src,target,wd.damage2,s_ele_,tstatus->def_ele, tstatus->ele_lv);
- if( sc && sc->data[SC_WATK_ELEMENT] )
- { // Descriptions indicate this means adding a percent of a normal attack in another element. [Skotlex]
- int damage = battle->calc_base_damage(sstatus, &sstatus->rhw, sc, tstatus->size, sd, (flag.arrow?2:0)) * sc->data[SC_WATK_ELEMENT]->val2 / 100;
- wd.damage += battle->attr_fix(src, target, damage, sc->data[SC_WATK_ELEMENT]->val1, tstatus->def_ele, tstatus->ele_lv);
-
- if( flag.lh ) {
- damage = battle->calc_base_damage(sstatus, &sstatus->lhw, sc, tstatus->size, sd, (flag.arrow?2:0)) * sc->data[SC_WATK_ELEMENT]->val2 / 100;
- wd.damage2 += battle->attr_fix(src, target, damage, sc->data[SC_WATK_ELEMENT]->val1, tstatus->def_ele, tstatus->ele_lv);
- }
- }
- #ifdef RENEWAL
- /**
- * In RE Shield Bommerang takes weapon element only for damage calculation,
- * - resist calculation is always against neutral
- **/
- if ( skill_id == CR_SHIELDBOOMERANG )
- s_ele = s_ele_ = ELE_NEUTRAL;
- #endif
- }
+#ifndef RENEWAL
+ wd.damage = battle->calc_elefix(src, target, skill_id, skill_lv, wd.damage, nk, n_ele, s_ele, s_ele_, false, flag.arrow);
+ if( flag.lh )
+ wd.damage2 = battle->calc_elefix(src, target, skill_id, skill_lv, wd.damage2, nk, n_ele, s_ele, s_ele_, true, flag.arrow);
+#endif
if(skill_id == CR_GRANDCROSS || skill_id == NPC_GRANDDARKNESS)
return wd; //Enough, rest is not needed.
@@ -3395,6 +4773,7 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
}
#endif
+#ifndef RENEWAL
if (sd) {
if (skill_id != CR_SHIELDBOOMERANG) //Only Shield boomerang doesn't takes the Star Crumbs bonus.
ATK_ADD2(wd.div_*sd->right_weapon.star, wd.div_*sd->left_weapon.star);
@@ -3403,7 +4782,6 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
} else {
ATK_ADD(wd.div_*sd->spiritball*3);
}
-
//Card Fix, sd side
wd.damage = battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, 2, wd.flag);
if( flag.lh )
@@ -3419,11 +4797,13 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
ATK_ADD(10*sd->status.inventory[index].refine);
}
}
-
//Card Fix, tsd side
- if(tsd) //if player on player then it was already measured above
- wd.damage = battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, flag.lh, wd.flag);
-
+ if(tsd){ //if player on player then it was already measured above
+ wd.damage = battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage, 2, wd.flag);
+ if( flag.lh )
+ wd.damage2 = battle->calc_cardfix(BF_WEAPON, src, target, nk, s_ele, s_ele_, wd.damage2, 3, wd.flag);
+ }
+#endif
if( flag.infdef ) { //Plants receive 1 damage when hit
short class_ = status_get_class(target);
if( flag.hit || wd.damage > 0 )
@@ -3454,24 +4834,34 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
flag.lh=0;
} else if(flag.rh && flag.lh) { //Dual-wield
if (wd.damage) {
- if( (temp = pc->checkskill(sd,AS_RIGHT)) )
- ATK_RATER(50 + (temp * 10))
- else if( (temp = pc->checkskill(sd,KO_RIGHT)) )
- ATK_RATER(70 + (temp * 10))
- if(wd.damage < 1) wd.damage = 1;
+ temp = pc->checkskill(sd,AS_RIGHT) * 10;
+ if( (sd->class_&MAPID_UPPERMASK) == MAPID_KAGEROUOBORO )
+ temp = pc->checkskill(sd,KO_RIGHT) * 10 + 20;
+ ATK_RATER( 50 + temp );
}
if (wd.damage2) {
- if( (temp = pc->checkskill(sd,AS_LEFT)) )
- ATK_RATEL(30 + (temp * 10))
- else if( (temp = pc->checkskill(sd,KO_LEFT)) )
- ATK_RATEL(50 + (temp * 10))
- if(wd.damage2 < 1) wd.damage2 = 1;
+ temp = pc->checkskill(sd,AS_LEFT) * 10;
+ if( (sd->class_&MAPID_UPPERMASK) == MAPID_KAGEROUOBORO )
+ temp = pc->checkskill(sd,KO_LEFT) * 10 + 20;
+ ATK_RATEL( 30 + temp );
}
+#ifdef RENEWAL
+ if(wd.damage < 0) wd.damage = 0;
+ if(wd.damage2 < 0) wd.damage2 = 0;
+#else
+ if(wd.damage < 1) wd.damage = 1;
+ if(wd.damage2 < 1) wd.damage2 = 1;
+#endif
} else if(sd->status.weapon == W_KATAR && !skill_id) { //Katars (offhand damage only applies to normal attacks, tested on Aegis 10.2)
temp = pc->checkskill(sd,TF_DOUBLE);
wd.damage2 = wd.damage * (1 + (temp * 2))/100;
- if(wd.damage && !wd.damage2) wd.damage2 = 1;
+ if(wd.damage && !wd.damage2) wd.damage2 =
+#ifdef RENEWAL
+ 0;
+#else
+ 1;
+#endif
flag.lh = 1;
}
}
@@ -3482,8 +4872,82 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
if(!flag.lh && wd.damage2)
wd.damage2=0;
+ if( sc ) {
+ //SG_FUSION hp penalty [Komurka]
+ if (sc->data[SC_FUSION]) {
+ int hp= sstatus->max_hp;
+ if (sd && tsd) {
+ hp = 8*hp/100;
+ if ((sstatus->hp * 100) <= (sstatus->max_hp * 20))
+ hp = sstatus->hp;
+ } else
+ hp = 2*hp/100; //2% hp loss per hit
+ status_zap(src, hp, 0);
+ }
+ if( !skill_id ) {
+ if( sc->data[SC_ENCHANTBLADE] ) { // it also works with bear hands..intended in official
+ //[( ( Skill Lv x 20 ) + 100 ) x ( casterBaseLevel / 150 )] + casterInt
+ ATK_ADD(( sc->data[SC_ENCHANTBLADE]->val1 * 20 + 100 ) * status_get_lv(src) / 150 + status_get_int(src));
+ }
+ }
+ status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER);
+ }
+
+ switch(skill_id){
+ case LG_RAYOFGENESIS:
+ {
+ struct Damage md = battle->calc_magic_attack(src, target, skill_id, skill_lv, wflag);
+ 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
+ int damage = wd.damage + wd.damage2, rdamage = 0, rdelay = 0;
+
+ if( src != target &&
+ (!skill_id || skill_id ||
+ ( src->type == BL_SKILL && ( skill_id == SG_SUN_WARM || skill_id == SG_MOON_WARM || skill_id == SG_STAR_WARM ) )) ){
+
+ rdamage = battle->calc_return_damage(target, src, &damage, wd.flag, 0, &rdelay);
+
+ if( tsc && tsc->count ) {
+ if( tsc && tsc->data[SC_DEATHBOUND] ){
+ wd.damage = damage;
+ wd.damage2 = 0;
+ status_change_end(target,SC_DEATHBOUND,INVALID_TIMER);
+ }
+ }
+ if( rdamage > 0 ) {
+ if( tsc && tsc->data[SC_LG_REFLECTDAMAGE] ) {
+ if( src != target ) {// Don't reflect your own damage (Grand Cross)
+ bool change = false;
+ if( sd && !sd->state.autocast )
+ change = true;
+ if( change )
+ sd->state.autocast = 1;
+ iMap->foreachinshootrange(battle->damage_area,target,skill->get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,iTimer->gettick(),target,wd.amotion,sstatus->dmotion,rdamage,tstatus->race);
+ if( change )
+ sd->state.autocast = 0;
+ }
+ } else {
+ //Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
+ if( tsd && src != target )
+ battle->drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
+ battle->delay_damage(iTimer->gettick(), wd.amotion,target,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,rdelay,true);
+ skill->additional_effect(target, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,iTimer->gettick());
+ }
+ }
+ }
if(!wd.damage2)
{
wd.damage = battle->calc_damage(src,target,&wd,wd.damage,skill_id,skill_lv);
@@ -3502,1071 +4966,50 @@ struct Damage battle_calc_weapon_attack(struct block_list *src,struct block_list
}
else
{
+#ifdef RENEWAL
+ wd.damage = battle->calc_damage(src,target,&wd,wd.damage,skill_id,skill_lv);
+ wd.damage2 = battle->calc_damage(src,target,&wd,wd.damage2,skill_id,skill_lv);
+#else
int d1 = wd.damage + wd.damage2,d2 = wd.damage2;
wd.damage = battle->calc_damage(src,target,&wd,d1,skill_id,skill_lv);
+#endif
if( map_flag_gvg2(target->m) )
wd.damage = battle->calc_gvg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
else if( map[target->m].flag.battleground )
wd.damage = battle->calc_bg_damage(src,target,wd.damage,wd.div_,skill_id,skill_lv,wd.flag);
+#ifndef RENEWAL
wd.damage2 = d2*100/d1 * wd.damage/100;
if(wd.damage > 1 && wd.damage2 < 1) wd.damage2 = 1;
wd.damage-=wd.damage2;
+#endif
}
}
//Reject Sword bugreport:4493 by Daegaladh
- if(wd.damage && tsc && tsc->data[SC_REJECTSWORD] &&
+ if(wd.damage && tsc && tsc->data[SC_SWORDREJECT] &&
(src->type!=BL_PC || (
((TBL_PC *)src)->weapontype1 == W_DAGGER ||
((TBL_PC *)src)->weapontype1 == W_1HSWORD ||
((TBL_PC *)src)->status.weapon == W_2HSWORD
)) &&
- rnd()%100 < tsc->data[SC_REJECTSWORD]->val2
+ rnd()%100 < tsc->data[SC_SWORDREJECT]->val2
) {
ATK_RATER(50)
status_fix_damage(target,src,wd.damage,clif->damage(target,src,iTimer->gettick(),0,0,wd.damage,0,0,0));
- clif->skill_nodamage(target,target,ST_REJECTSWORD,tsc->data[SC_REJECTSWORD]->val1,1);
- if( --(tsc->data[SC_REJECTSWORD]->val3) <= 0 )
- status_change_end(target, SC_REJECTSWORD, INVALID_TIMER);
+ clif->skill_nodamage(target,target,ST_REJECTSWORD,tsc->data[SC_SWORDREJECT]->val1,1);
+ if( --(tsc->data[SC_SWORDREJECT]->val3) <= 0 )
+ status_change_end(target, SC_SWORDREJECT, INVALID_TIMER);
}
+#ifndef RENEWAL
if(skill_id == ASC_BREAKER) { //Breaker's int-based damage (a misc attack?)
struct Damage md = battle->calc_misc_attack(src, target, skill_id, skill_lv, wflag);
wd.damage += md.damage;
}
- if( sc ) {
- //SG_FUSION hp penalty [Komurka]
- if (sc->data[SC_FUSION]) {
- int hp= sstatus->max_hp;
- if (sd && tsd) {
- hp = 8*hp/100;
- if ((sstatus->hp * 100) <= (sstatus->max_hp * 20))
- hp = sstatus->hp;
- } else
- hp = 2*hp/100; //2% hp loss per hit
- status_zap(src, hp, 0);
- }
- /**
- * affecting non-skills
- **/
- if( !skill_id ) {
- /**
- * RK Enchant Blade
- **/
- if( sc->data[SC_ENCHANTBLADE] && sd && ( (flag.rh && sd->weapontype1) || (flag.lh && sd->weapontype2) ) ) {
- //[( ( Skill Lv x 20 ) + 100 ) x ( casterBaseLevel / 150 )] + casterInt
- ATK_ADD( ( sc->data[SC_ENCHANTBLADE]->val1*20+100 ) * status_get_lv(src) / 150 + status_get_int(src) );
- }
- }
- status_change_end(src,SC_CAMOUFLAGE, INVALID_TIMER);
- }
- if( skill_id == LG_RAYOFGENESIS ) {
- struct Damage md = battle->calc_magic_attack(src, target, skill_id, skill_lv, wflag);
- wd.damage += md.damage;
- }
-
- return wd;
-}
-
-/*==========================================
- * battle_calc_magic_attack [DracoRPG]
- *------------------------------------------*/
-struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag) {
- int i, nk;
- short s_ele = 0;
- unsigned int skillratio = 100; //Skill dmg modifiers.
-
- TBL_PC *sd;
-// TBL_PC *tsd;
- struct status_change *sc, *tsc;
- struct Damage ad;
- struct status_data *sstatus = status_get_status_data(src);
- struct status_data *tstatus = status_get_status_data(target);
- struct {
- unsigned imdef : 1;
- unsigned infdef : 1;
- } flag;
-
- memset(&ad,0,sizeof(ad));
- memset(&flag,0,sizeof(flag));
-
- if(src==NULL || target==NULL)
- {
- nullpo_info(NLP_MARK);
- return ad;
- }
- //Initial Values
- ad.damage = 1;
- ad.div_=skill->get_num(skill_id,skill_lv);
- ad.amotion=skill->get_inf(skill_id)&INF_GROUND_SKILL?0:sstatus->amotion; //Amotion should be 0 for ground skills.
- ad.dmotion=tstatus->dmotion;
- ad.blewcount = skill->get_blewcount(skill_id,skill_lv);
- ad.flag=BF_MAGIC|BF_SKILL;
- ad.dmg_lv=ATK_DEF;
- nk = skill->get_nk(skill_id);
- flag.imdef = nk&NK_IGNORE_DEF?1:0;
-
- sd = BL_CAST(BL_PC, src);
-// tsd = BL_CAST(BL_PC, target);
- sc = status_get_sc(src);
- tsc = status_get_sc(target);
-
- //Initialize variables that will be used afterwards
- s_ele = skill->get_ele(skill_id, skill_lv);
-
- if (s_ele == -1){ // pl=-1 : the skill takes the weapon's element
- s_ele = sstatus->rhw.ele;
- if( sd ){ //Summoning 10 talisman will endow your weapon
- ARR_FIND(1, 6, i, sd->talisman[i] >= 10);
- if( i < 5 ) s_ele = i;
- }
- }else if (s_ele == -2) //Use status element
- s_ele = status_get_attack_sc_element(src,status_get_sc(src));
- else if( s_ele == -3 ) //Use random element
- s_ele = rnd()%ELE_MAX;
-
- if( skill_id == SO_PSYCHIC_WAVE ) {
- if( sc && sc->count ) {
- if( sc->data[SC_HEATER_OPTION] ) s_ele = sc->data[SC_HEATER_OPTION]->val4;
- else if( sc->data[SC_COOLER_OPTION] ) s_ele = sc->data[SC_COOLER_OPTION]->val4;
- else if( sc->data[SC_BLAST_OPTION] ) s_ele = sc->data[SC_BLAST_OPTION]->val3;
- else if( sc->data[SC_CURSED_SOIL_OPTION] ) s_ele = sc->data[SC_CURSED_SOIL_OPTION]->val4;
- }
- }
-
- //Set miscellaneous data that needs be filled
- if(sd) {
- sd->state.arrow_atk = 0;
- ad.blewcount += battle->blewcount_bonus(sd, skill_id);
- }
-
- //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;
- }
-
- switch(skill_id) {
- case MG_FIREWALL:
- case NJ_KAENSIN:
- ad.dmotion = 0; //No flinch animation.
- if ( tstatus->def_ele == ELE_FIRE || battle->check_undead(tstatus->race, tstatus->def_ele) )
- ad.blewcount = 0; //No knockback
- break;
- case PR_SANCTUARY:
- ad.dmotion = 0; //No flinch animation.
- break;
- }
-
- if (!flag.infdef) //No need to do the math for plants
- {
-#ifdef RENEWAL
- ad.damage = 0; //reinitialize..
#endif
-//MATK_RATE scales the damage. 100 = no change. 50 is halved, 200 is doubled, etc
-#define MATK_RATE( a ) { ad.damage= ad.damage*(a)/100; }
-//Adds dmg%. 100 = +100% (double) damage. 10 = +10% damage
-#define MATK_ADDRATE( a ) { ad.damage+= ad.damage*(a)/100; }
-//Adds an absolute value to damage. 100 = +100 damage
-#define MATK_ADD( a ) { ad.damage+= a; }
-
- switch (skill_id)
- { //Calc base damage according to skill
- case AL_HEAL:
- case PR_BENEDICTIO:
- case PR_SANCTUARY:
- /**
- * Arch Bishop
- **/
- case AB_HIGHNESSHEAL:
- ad.damage = skill->calc_heal(src, target, skill_id, skill_lv, false);
- break;
- case PR_ASPERSIO:
- ad.damage = 40;
- break;
- case ALL_RESURRECTION:
- case PR_TURNUNDEAD:
- //Undead check is on skill_castend_damageid code.
- #ifdef RENEWAL
- i = 10*skill_lv + sstatus->luk + sstatus->int_ + status_get_lv(src)
- + 300 - 300*tstatus->hp/tstatus->max_hp;
- #else
- i = 20*skill_lv + sstatus->luk + sstatus->int_ + status_get_lv(src)
- + 200 - 200*tstatus->hp/tstatus->max_hp;
- #endif
- if(i > 700) i = 700;
- if(rnd()%1000 < i && !(tstatus->mode&MD_BOSS))
- ad.damage = tstatus->hp;
- else {
- #ifdef RENEWAL
- if (sstatus->matk_max > sstatus->matk_min) {
- MATK_ADD(sstatus->matk_min+rnd()%(sstatus->matk_max-sstatus->matk_min));
- } else {
- MATK_ADD(sstatus->matk_min);
- }
- MATK_RATE(skill_lv);
- #else
- ad.damage = status_get_lv(src) + sstatus->int_ + skill_lv * 10;
- #endif
- }
- break;
- case PF_SOULBURN:
- ad.damage = tstatus->sp * 2;
- break;
- /**
- * Arch Bishop
- **/
- case AB_RENOVATIO:
- //Damage calculation from iRO wiki. [Jobbie]
- ad.damage = (int)((15 * status_get_lv(src)) + (1.5 * sstatus->int_));
- break;
- default: {
- if (sstatus->matk_max > sstatus->matk_min) {
- MATK_ADD(sstatus->matk_min+rnd()%(sstatus->matk_max-sstatus->matk_min));
- } else {
- MATK_ADD(sstatus->matk_min);
- }
-
- if (nk&NK_SPLASHSPLIT) { // Divide MATK in case of multiple targets skill
- if(mflag>0)
- ad.damage/= mflag;
- else
- ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_id, skill->get_name(skill_id));
- }
-
- switch(skill_id){
- case MG_NAPALMBEAT:
- skillratio += skill_lv*10-30;
- break;
- case MG_FIREBALL:
- #ifdef RENEWAL
- skillratio += 20*skill_lv;
- #else
- skillratio += skill_lv*10-30;
- #endif
- break;
- case MG_SOULSTRIKE:
- if (battle->check_undead(tstatus->race,tstatus->def_ele))
- skillratio += 5*skill_lv;
- break;
- case MG_FIREWALL:
- skillratio -= 50;
- break;
- 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]
- ad.div_ = 1;// ad mods, to make it work similar to regular hits [Xazax]
- ad.flag = BF_WEAPON|BF_SHORT;
- ad.type = 0;
- }
- break;
- case MG_THUNDERSTORM:
- /**
- * in Renewal Thunder Storm boost is 100% (in pre-re, 80%)
- **/
- #ifndef RENEWAL
- skillratio -= 20;
- #endif
- break;
- case MG_FROSTDIVER:
- skillratio += 10*skill_lv;
- break;
- case AL_HOLYLIGHT:
- skillratio += 25;
- if (sd && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_PRIEST)
- skillratio *= 5; //Does 5x damage include bonuses from other skills?
- break;
- case AL_RUWACH:
- skillratio += 45;
- break;
- case WZ_FROSTNOVA:
- skillratio += (100+skill_lv*10)*2/3-100;
- break;
- case WZ_FIREPILLAR:
- if (skill_lv > 10)
- skillratio += 100;
- else
- skillratio -= 80;
- break;
- case WZ_SIGHTRASHER:
- skillratio += 20*skill_lv;
- break;
- case WZ_WATERBALL:
- skillratio += 30*skill_lv;
- break;
- case WZ_STORMGUST:
- skillratio += 40*skill_lv;
- break;
- case HW_NAPALMVULCAN:
- skillratio += 10*skill_lv-30;
- break;
- case SL_STIN:
- skillratio += (tstatus->size!=SZ_SMALL?-99:10*skill_lv); //target size must be small (0) for full damage.
- break;
- case SL_STUN:
- skillratio += (tstatus->size!=SZ_BIG?5*skill_lv:-99); //Full damage is dealt on small/medium targets
- break;
- case SL_SMA:
- skillratio += -60 + status_get_lv(src); //Base damage is 40% + lv%
- break;
- case NJ_KOUENKA:
- skillratio -= 10;
- break;
- case NJ_KAENSIN:
- skillratio -= 50;
- break;
- case NJ_BAKUENRYU:
- skillratio += 50*(skill_lv-1);
- break;
- case NJ_HYOUSYOURAKU:
- skillratio += 50*skill_lv;
- break;
- case NJ_RAIGEKISAI:
- skillratio += 60 + 40*skill_lv;
- break;
- case NJ_KAMAITACHI:
- case NPC_ENERGYDRAIN:
- skillratio += 100*skill_lv;
- break;
- case NPC_EARTHQUAKE:
- skillratio += 100 +100*skill_lv +100*(skill_lv/2);
- break;
- #ifdef RENEWAL
- case WZ_HEAVENDRIVE:
- case WZ_METEOR:
- skillratio += 25;
- break;
- case WZ_VERMILION:
- {
- int interval = 0, per = interval, ratio = per;
- while( (per++) < skill_lv ){
- ratio += interval;
- if(per%3==0) interval += 20;
- }
- if( skill_lv > 9 )
- ratio -= 10;
- skillratio += ratio;
- }
- break;
- case NJ_HUUJIN:
- skillratio += 50;
- break;
- #else
- case WZ_VERMILION:
- skillratio += 20*skill_lv-20;
- break;
- #endif
- /**
- * Arch Bishop
- **/
- case AB_JUDEX:
- skillratio += 180 + 20 * skill_lv;
- if (skill_lv > 4) skillratio += 20;
- RE_LVL_DMOD(100);
- break;
- case AB_ADORAMUS:
- skillratio += 400 + 100 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case AB_DUPLELIGHT_MAGIC:
- skillratio += 100 + 20 * skill_lv;
- break;
- /**
- * Warlock
- **/
- case WL_SOULEXPANSION:
- skillratio += 300 + 100 * skill_lv + sstatus->int_;
- RE_LVL_DMOD(100);
- break;
- case WL_FROSTMISTY:
- skillratio += 100 + 100 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case WL_JACKFROST:
- if( tsc && tsc->data[SC_FREEZING] ){
- skillratio += 900 + 300 * skill_lv;
- RE_LVL_DMOD(100);
- }else{
- skillratio += 400 + 100 * skill_lv;
- RE_LVL_DMOD(150);
- }
- break;
- case WL_DRAINLIFE:
- skillratio = 200 * skill_lv + sstatus->int_;
- RE_LVL_DMOD(100);
- break;
- case WL_CRIMSONROCK:
- skillratio += 1200 + 300 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case WL_HELLINFERNO:
- skillratio = 300 * skill_lv;
- RE_LVL_DMOD(100);
- // Shadow: MATK [{( Skill Level x 300 ) x ( Caster Base Level / 100 ) x 4/5 }] %
- // Fire : MATK [{( Skill Level x 300 ) x ( Caster Base Level / 100 ) /5 }] %
- if( mflag&ELE_DARK ){ skillratio *= 4; s_ele = ELE_DARK; }
- skillratio /= 5;
- break;
- case WL_COMET: {
- struct status_change * sc = status_get_sc(src);
- if( sc )
- i = distance_xy(target->x, target->y, sc->comet_x, sc->comet_y);
- else
- i = 8;
- if( i < 2 ) skillratio = 2500 + 500 * skill_lv;
- else
- if( i < 4 ) skillratio = 1600 + 400 * skill_lv;
- else
- if( i < 6 ) skillratio = 1200 + 300 * skill_lv;
- else
- skillratio = 800 + 200 * skill_lv;
- }
- break;
- case WL_CHAINLIGHTNING_ATK:
- skillratio += 100 + 300 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case WL_EARTHSTRAIN:
- skillratio += 1900 + 100 * skill_lv;
- RE_LVL_DMOD(100);
- break;
- case WL_TETRAVORTEX_FIRE:
- case WL_TETRAVORTEX_WATER:
- case WL_TETRAVORTEX_WIND:
- case WL_TETRAVORTEX_GROUND:
- skillratio += 400 + 500 * skill_lv;
- break;
- case WL_SUMMON_ATK_FIRE:
- 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]
- RE_LVL_DMOD(100);
- break;
- case LG_RAYOFGENESIS:
- {
- int16 lv = skill_lv;
- int bandingBonus = 0;
- if( sc && sc->data[SC_BANDING] )
- 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;
- break;
- /*case WM_SEVERE_RAINSTORM:
- skillratio += 50 * skill_lv;
- 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);
- RE_LVL_DMOD(100);
- break;
- case SO_FIREWALK:
- skillratio = 300;
- RE_LVL_DMOD(100);
- if( sc && sc->data[SC_HEATER_OPTION] )
- skillratio += sc->data[SC_HEATER_OPTION]->val3;
- break;
- case SO_ELECTRICWALK:
- skillratio = 300;
- RE_LVL_DMOD(100);
- if( sc && sc->data[SC_BLAST_OPTION] )
- skillratio += sd ? sd->status.job_level / 2 : 0;
- break;
- case SO_EARTHGRAVE:
- skillratio = ( 200 * ( sd ? pc->checkskill(sd, SA_SEISMICWEAPON) : 10 ) + sstatus->int_ * skill_lv );
- RE_LVL_DMOD(100);
- if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
- skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
- break;
- case SO_DIAMONDDUST:
- skillratio = ( 200 * ( sd ? pc->checkskill(sd, SA_FROSTWEAPON) : 10 ) + sstatus->int_ * skill_lv );
- RE_LVL_DMOD(100);
- if( sc && sc->data[SC_COOLER_OPTION] )
- skillratio += sc->data[SC_COOLER_OPTION]->val3;
- break;
- case SO_POISON_BUSTER:
- skillratio += 1100 + 300 * skill_lv;
- if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
- skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
- break;
- case SO_PSYCHIC_WAVE:
- skillratio += -100 + skill_lv * 70 + (sstatus->int_ * 3);
- 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;
- }
- break;
- case SO_VARETYR_SPEAR: //MATK [{( Endow Tornado skill level x 50 ) + ( Caster INT x Varetyr Spear Skill level )} x Caster Base Level / 100 ] %
- 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;
- break;
- case SO_CLOUD_KILL:
- skillratio += -100 + skill_lv * 40;
- RE_LVL_DMOD(100);
- if( sc && sc->data[SC_CURSED_SOIL_OPTION] )
- skillratio += sc->data[SC_CURSED_SOIL_OPTION]->val2;
- break;
- case GN_DEMONIC_FIRE:
- if( skill_lv > 20)
- { // Fire expansion Lv.2
- skillratio += 110 + 20 * (skill_lv - 20) + status_get_int(src) * 3; // Need official INT bonus. [LimitLine]
- }
- else if( skill_lv > 10 )
- { // Fire expansion Lv.1
- skillratio += 110 + 20 * (skill_lv - 10) / 2;
- }
- else
- skillratio += 110 + 20 * skill_lv;
- break;
- // Magical Elemental Spirits Attack Skills
- case EL_FIRE_MANTLE:
- case EL_WATER_SCREW:
- skillratio += 900;
- break;
- case EL_FIRE_ARROW:
- case EL_ROCK_CRUSHER_ATK:
- skillratio += 200;
- break;
- case EL_FIRE_BOMB:
- case EL_ICE_NEEDLE:
- case EL_HURRICANE_ATK:
- skillratio += 400;
- break;
- case EL_FIRE_WAVE:
- case EL_TYPOON_MIS_ATK:
- skillratio += 1100;
- break;
- case MH_ERASER_CUTTER:
- if(skill_lv%2) skillratio += 400; //600:800:1000
- else skillratio += 700; //1000:1200
- skillratio += 100 * skill_lv;
- break;
- case MH_XENO_SLASHER:
- if(skill_lv%2) skillratio += 350 + 50 * skill_lv; //500:600:700
- else skillratio += 400 + 100 * skill_lv; //700:900
- break;
- case MH_HEILIGE_STANGE:
- skillratio += 400 + 250 * skill_lv;
- break;
- case MH_POISON_MIST:
- skillratio += 100 * skill_lv;
- break;
- }
-
- MATK_RATE(skillratio);
-
- //Constant/misc additions from skills
- if (skill_id == WZ_FIREPILLAR)
- MATK_ADD(50);
- }
- }
-#ifndef HMAP_ZONE_DAMAGE_CAP_TYPE
- if( target && skill_id ) {
- for(i = 0; i < map[target->m].zone->capped_skills_count; i++) {
- if( skill_id == map[target->m].zone->capped_skills[i]->nameid && (map[target->m].zone->capped_skills[i]->type & target->type) ) {
- if( target->type == BL_MOB && map[target->m].zone->capped_skills[i]->subtype != MZS_NONE ) {
- if( (((TBL_MOB*)target)->status.mode&MD_BOSS) && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_BOSS) )
- continue;
- if( ((TBL_MOB*)target)->special_state.clone && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_CLONE) )
- continue;
- }
- if( ad.damage > map[target->m].zone->capped_skills[i]->cap )
- ad.damage = map[target->m].zone->capped_skills[i]->cap;
- if( ad.damage2 > map[target->m].zone->capped_skills[i]->cap )
- ad.damage2 = map[target->m].zone->capped_skills[i]->cap;
- break;
- }
- }
- }
-#endif
-#ifdef RENEWAL
- ad.damage = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
-#endif
- if(sd) {
- //Damage bonuses
- if ((i = pc->skillatk_bonus(sd, skill_id)))
- ad.damage += ad.damage*i/100;
-
- if( (i = battle->adjust_skill_damage(src->m,skill_id)) )
- MATK_RATE(i);
-
- //Ignore Defense?
- if (!flag.imdef && (
- sd->bonus.ignore_mdef_ele & ( 1 << tstatus->def_ele ) ||
- sd->bonus.ignore_mdef_race & ( 1 << tstatus->race ) ||
- sd->bonus.ignore_mdef_race & ( is_boss(target) ? 1 << RC_BOSS : 1 << RC_NONBOSS )
- ))
- flag.imdef = 1;
- }
-
- if(!flag.imdef){
- defType mdef = tstatus->mdef;
- int mdef2= tstatus->mdef2;
-#ifdef RENEWAL
- if(tsc && tsc->data[SC_ASSUMPTIO])
- mdef <<= 1; // only eMDEF is doubled
-#endif
- if(sd) {
- i = sd->ignore_mdef[is_boss(target)?RC_BOSS:RC_NONBOSS];
- i+= sd->ignore_mdef[tstatus->race];
- if (i)
- {
- if (i > 100) i = 100;
- mdef -= mdef * i/100;
- //mdef2-= mdef2* i/100;
- }
- }
- #ifdef RENEWAL
- /**
- * RE MDEF Reduction
- * Damage = Magic Attack * (1000+eMDEF)/(1000+eMDEF) - sMDEF
- **/
- ad.damage = ad.damage * (1000 + mdef) / (1000 + mdef * 10) - mdef2;
- #else
- if(battle_config.magic_defense_type)
- ad.damage = ad.damage - mdef*battle_config.magic_defense_type - mdef2;
- else
- ad.damage = ad.damage * (100-mdef)/100 - mdef2;
- #endif
- }
-
- if (skill_id == NPC_EARTHQUAKE)
- { //Adds atk2 to the damage, should be influenced by number of hits and skill-ratio, but not mdef reductions. [Skotlex]
- //Also divide the extra bonuses from atk2 based on the number in range [Kevin]
- if(mflag>0)
- ad.damage+= (sstatus->rhw.atk2*skillratio/100)/mflag;
- else
- ShowError("Zero range by %d:%s, divide per 0 avoided!\n", skill_id, skill->get_name(skill_id));
- }
-
- if(ad.damage<1)
- ad.damage=1;
- else if(sc){//only applies when hit
- // TODO: there is another factor that contribute with the damage and need to be formulated. [malufett]
- switch(skill_id){
- case MG_LIGHTNINGBOLT:
- case MG_THUNDERSTORM:
- case MG_FIREBOLT:
- case MG_FIREWALL:
- case MG_COLDBOLT:
- case MG_FROSTDIVER:
- case WZ_EARTHSPIKE:
- case WZ_HEAVENDRIVE:
- if(sc->data[SC_GUST_OPTION] || sc->data[SC_PETROLOGY_OPTION]
- || sc->data[SC_PYROTECHNIC_OPTION] || sc->data[SC_AQUAPLAY_OPTION])
- ad.damage += (6 + sstatus->int_/4) + max(sstatus->dex-10,0)/30;
- break;
- }
- }
-
- if (!(nk&NK_NO_ELEFIX))
- ad.damage=battle->attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
-
- if( skill_id == CR_GRANDCROSS || skill_id == NPC_GRANDDARKNESS )
- { //Apply the physical part of the skill's damage. [Skotlex]
- struct Damage wd = battle->calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
- ad.damage = battle->attr_fix(src, target, wd.damage + ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv) * (100 + 40*skill_lv)/100;
- if( src == target )
- {
- if( src->type == BL_PC )
- ad.damage = ad.damage/2;
- else
- ad.damage = 0;
- }
- }
-
-#ifndef RENEWAL
- ad.damage = battle->calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
-#endif
- }
-
- damage_div_fix(ad.damage, ad.div_);
-
- if (flag.infdef && ad.damage)
- ad.damage = ad.damage>0?1:-1;
-
- ad.damage=battle->calc_damage(src,target,&ad,ad.damage,skill_id,skill_lv);
- if( map_flag_gvg2(target->m) )
- ad.damage=battle->calc_gvg_damage(src,target,ad.damage,ad.div_,skill_id,skill_lv,ad.flag);
- else if( map[target->m].flag.battleground )
- ad.damage=battle->calc_bg_damage(src,target,ad.damage,ad.div_,skill_id,skill_lv,ad.flag);
-
- switch( skill_id ) { /* post-calc modifiers */
- case SO_VARETYR_SPEAR: { // Physical damage.
- struct Damage wd = battle->calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
- if(!flag.infdef && ad.damage > 1)
- ad.damage += wd.damage;
- break;
- }
- //case HM_ERASER_CUTTER:
- }
-
- return ad;
+ return wd;
}
/*==========================================
- * Calculate Misc dammage for skill_id
- *------------------------------------------*/
-struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag) {
- int temp;
- short i, nk;
- short s_ele;
-
- struct map_session_data *sd, *tsd;
- struct Damage md; //DO NOT CONFUSE with md of mob_data!
- struct status_data *sstatus = status_get_status_data(src);
- struct status_data *tstatus = status_get_status_data(target);
-
- memset(&md,0,sizeof(md));
-
- if( src == NULL || target == NULL ){
- nullpo_info(NLP_MARK);
- return md;
- }
-
- //Some initial values
- md.amotion=skill->get_inf(skill_id)&INF_GROUND_SKILL?0:sstatus->amotion;
- md.dmotion=tstatus->dmotion;
- md.div_=skill->get_num( skill_id,skill_lv );
- md.blewcount=skill->get_blewcount(skill_id,skill_lv);
- md.dmg_lv=ATK_DEF;
- md.flag=BF_MISC|BF_SKILL;
-
- nk = skill->get_nk(skill_id);
-
- sd = BL_CAST(BL_PC, src);
- tsd = BL_CAST(BL_PC, target);
-
- if(sd) {
- sd->state.arrow_atk = 0;
- md.blewcount += battle->blewcount_bonus(sd, skill_id);
- }
-
- s_ele = skill->get_ele(skill_id, skill_lv);
- if (s_ele < 0 && s_ele != -3) //Attack that takes weapon's element for misc attacks? Make it neutral [Skotlex]
- s_ele = ELE_NEUTRAL;
- else if (s_ele == -3) //Use random element
- s_ele = rnd()%ELE_MAX;
-
- //Skill Range Criteria
- md.flag |= battle->range_type(src, target, skill_id, skill_lv);
-
- switch( skill_id )
- {
-#ifdef RENEWAL
- case HT_LANDMINE:
- case MA_LANDMINE:
- case HT_BLASTMINE:
- case HT_CLAYMORETRAP:
- md.damage = skill_lv * sstatus->dex * (3+status_get_lv(src)/100) * (1+sstatus->int_/35);
- md.damage += md.damage * (rnd()%20-10) / 100;
- md.damage += 40 * (sd?pc->checkskill(sd,RA_RESEARCHTRAP):0);
- break;
-#else
- case HT_LANDMINE:
- case MA_LANDMINE:
- md.damage=skill_lv*(sstatus->dex+75)*(100+sstatus->int_)/100;
- break;
- case HT_BLASTMINE:
- md.damage=skill_lv*(sstatus->dex/2+50)*(100+sstatus->int_)/100;
- break;
- case HT_CLAYMORETRAP:
- md.damage=skill_lv*(sstatus->dex/2+75)*(100+sstatus->int_)/100;
- break;
-#endif
- case HT_BLITZBEAT:
- case SN_FALCONASSAULT:
- //Blitz-beat Damage.
- if(!sd || (temp = pc->checkskill(sd,HT_STEELCROW)) <= 0)
- temp=0;
- md.damage=(sstatus->dex/10+sstatus->int_/2+temp*3+40)*2;
- if(mflag > 1) //Autocasted Blitz.
- nk|=NK_SPLASHSPLIT;
-
- if (skill_id == SN_FALCONASSAULT) {
- //Div fix of Blitzbeat
- temp = skill->get_num(HT_BLITZBEAT, 5);
- damage_div_fix(md.damage, temp);
-
- //Falcon Assault Modifier
- md.damage=md.damage*(150+70*skill_lv)/100;
- }
- break;
- case TF_THROWSTONE:
- md.damage=50;
- break;
- case BA_DISSONANCE:
- md.damage=30+skill_lv*10;
- if (sd)
- md.damage+= 3*pc->checkskill(sd,BA_MUSICALLESSON);
- break;
- case NPC_SELFDESTRUCTION:
- md.damage = sstatus->hp;
- break;
- case NPC_SMOKING:
- md.damage=3;
- break;
- case NPC_DARKBREATH:
- md.damage = 500 + (skill_lv-1)*1000 + rnd()%1000;
- if(md.damage > 9999) md.damage = 9999;
- break;
- case PA_PRESSURE:
- md.damage=500+300*skill_lv;
- break;
- case PA_GOSPEL:
- md.damage = 1+rnd()%9999;
- break;
- case CR_ACIDDEMONSTRATION: // updated the formula based on a Japanese formula found to be exact [Reddozen]
- if(tstatus->vit+sstatus->int_) //crash fix
- md.damage = (int)(7*tstatus->vit*sstatus->int_*sstatus->int_ / (10*(tstatus->vit+sstatus->int_)));
- else
- md.damage = 0;
- if (tsd) md.damage>>=1;
- if (md.damage < 0 || md.damage > INT_MAX>>1)
- //Overflow prevention, will anyone whine if I cap it to a few billion?
- //Not capped to INT_MAX to give some room for further damage increase.
- md.damage = INT_MAX>>1;
- break;
- case NJ_ZENYNAGE:
- case KO_MUCHANAGE:
- md.damage = skill->get_zeny(skill_id ,skill_lv);
- if (!md.damage) md.damage = 2;
- md.damage = rand()%md.damage + md.damage / (skill_id==NJ_ZENYNAGE?1:2) ;
- if (is_boss(target))
- md.damage=md.damage / (skill_id==NJ_ZENYNAGE?3:2);
- else if (tsd) // need confirmation for KO_MUCHANAGE
- md.damage=md.damage/2;
- break;
- case GS_FLING:
- md.damage = sd?sd->status.job_level:status_get_lv(src);
- break;
- case HVAN_EXPLOSION: //[orn]
- md.damage = sstatus->max_hp * (50 + 50 * skill_lv) / 100;
- break ;
- case ASC_BREAKER:
- md.damage = 500+rnd()%500 + 5*skill_lv * sstatus->int_;
- nk|=NK_IGNORE_FLEE|NK_NO_ELEFIX; //These two are not properties of the weapon based part.
- break;
- case HW_GRAVITATION:
- md.damage = 200+200*skill_lv;
- md.dmotion = 0; //No flinch animation.
- break;
- case NPC_EVILLAND:
- md.damage = skill->calc_heal(src,target,skill_id,skill_lv,false);
- break;
- case RK_DRAGONBREATH:
- 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;
- md.flag |= BF_LONG|BF_WEAPON;
- break;
- /**
- * Ranger
- **/
- case RA_CLUSTERBOMB:
- case RA_FIRINGTRAP:
- case RA_ICEBOUNDTRAP:
- md.damage = skill_lv * sstatus->dex + sstatus->int_ * 5 ;
- RE_LVL_TMDMOD();
- if(sd)
- {
- int researchskill_lv = pc->checkskill(sd,RA_RESEARCHTRAP);
- if(researchskill_lv)
- md.damage = md.damage * 20 * researchskill_lv / (skill_id == RA_CLUSTERBOMB?50:100);
- else
- md.damage = 0;
- }else
- md.damage = md.damage * 200 / (skill_id == RA_CLUSTERBOMB?50:100);
-
- break;
- /**
- * Mechanic
- **/
- case NC_SELFDESTRUCTION:
- {
- short totaldef = tstatus->def2 + (short)status_get_def(target);
- md.damage = ( (sd?pc->checkskill(sd,NC_MAINFRAME):10) + 8 ) * ( skill_lv + 1 ) * ( status_get_sp(src) + sstatus->vit );
- RE_LVL_MDMOD(100);
- md.damage += status_get_hp(src) - totaldef;
- }
- break;
- case GN_THORNS_TRAP:
- 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)) );
- break;
- case KO_HAPPOKUNAI:
- {
- struct Damage wd = battle->calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
- short totaldef = tstatus->def2 + (short)status_get_def(target);
- md.damage = wd.damage * 60 * (5 + skill_lv) / 100;
- md.damage -= totaldef;
- }
- break;
- case KO_MAKIBISHI:
- md.damage = 20 * skill_lv;
- break;
- }
-
- if (nk&NK_SPLASHSPLIT){ // Divide ATK among targets
- if(mflag>0)
- md.damage/= mflag;
- else
- ShowError("0 enemies targeted by %d:%s, divide per 0 avoided!\n", skill_id, skill->get_name(skill_id));
- }
-
- damage_div_fix(md.damage, md.div_);
-
- if (!(nk&NK_IGNORE_FLEE))
- {
- struct status_change *sc = status_get_sc(target);
- i = 0; //Temp for "hit or no hit"
- if(sc && sc->opt1 && sc->opt1 != OPT1_STONEWAIT && sc->opt1 != OPT1_BURNING)
- i = 1;
- else {
- short
- flee = tstatus->flee,
-#ifdef RENEWAL
- hitrate = 0; //Default hitrate
-#else
- hitrate = 80; //Default hitrate
-#endif
-
- if(battle_config.agi_penalty_type && battle_config.agi_penalty_target&target->type) {
- unsigned char attacker_count; //256 max targets should be a sane max
- attacker_count = unit_counttargeted(target);
- if(attacker_count >= battle_config.agi_penalty_count)
- {
- if (battle_config.agi_penalty_type == 1)
- flee = (flee * (100 - (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num))/100;
- else //asume type 2: absolute reduction
- flee -= (attacker_count - (battle_config.agi_penalty_count - 1))*battle_config.agi_penalty_num;
- if(flee < 1) flee = 1;
- }
- }
-
- hitrate+= sstatus->hit - flee;
-#ifdef RENEWAL
- if( sd ) //in Renewal hit bonus from Vultures Eye is not anymore shown in status window
- hitrate += pc->checkskill(sd,AC_VULTURE);
-#endif
- hitrate = cap_value(hitrate, battle_config.min_hitrate, battle_config.max_hitrate);
-
- if(rnd()%100 < hitrate)
- i = 1;
- }
- if (!i) {
- md.damage = 0;
- md.dmg_lv=ATK_FLEE;
- }
- }
-#ifndef HMAP_ZONE_DAMAGE_CAP_TYPE
- if( target && skill_id ) {
- for(i = 0; i < map[target->m].zone->capped_skills_count; i++) {
- if( skill_id == map[target->m].zone->capped_skills[i]->nameid && (map[target->m].zone->capped_skills[i]->type & target->type) ) {
- if( target->type == BL_MOB && map[target->m].zone->capped_skills[i]->subtype != MZS_NONE ) {
- if( (((TBL_MOB*)target)->status.mode&MD_BOSS) && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_BOSS) )
- continue;
- if( ((TBL_MOB*)target)->special_state.clone && !(map[target->m].zone->disabled_skills[i]->subtype&MZS_CLONE) )
- continue;
- }
- if( md.damage > map[target->m].zone->capped_skills[i]->cap )
- md.damage = map[target->m].zone->capped_skills[i]->cap;
- if( md.damage2 > map[target->m].zone->capped_skills[i]->cap )
- md.damage2 = map[target->m].zone->capped_skills[i]->cap;
- break;
- }
- }
- }
-#endif
- md.damage = battle->calc_cardfix(BF_MISC, src, target, nk, s_ele, 0, md.damage, 0, md.flag);
-
- if (sd && (i = pc->skillatk_bonus(sd, skill_id)))
- md.damage += md.damage*i/100;
-
- if( (i = battle->adjust_skill_damage(src->m,skill_id)) )
- md.damage = md.damage * i / 100;
-
- if(md.damage < 0)
- md.damage = 0;
- else if(md.damage && tstatus->mode&MD_PLANT){
- switch(skill_id){
- case HT_LANDMINE:
- case MA_LANDMINE:
- case HT_BLASTMINE:
- case HT_CLAYMORETRAP:
- case RA_CLUSTERBOMB:
-#ifdef RENEWAL
- break;
-#endif
- 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))
- md.damage=battle->attr_fix(src, target, md.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
-
- md.damage=battle->calc_damage(src,target,&md,md.damage,skill_id,skill_lv);
- if( map_flag_gvg2(target->m) )
- md.damage=battle->calc_gvg_damage(src,target,md.damage,md.div_,skill_id,skill_lv,md.flag);
- else if( map[target->m].flag.battleground )
- md.damage=battle->calc_bg_damage(src,target,md.damage,md.div_,skill_id,skill_lv,md.flag);
-
- switch( skill_id ) {
- case RA_FIRINGTRAP:
- case RA_ICEBOUNDTRAP:
- if( md.damage == 1 ) break;
- case RA_CLUSTERBOMB:
- {
- struct Damage wd;
- wd = battle->calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
- md.damage += wd.damage;
- }
- break;
- case NJ_ZENYNAGE:
- if( sd ) {
- if ( md.damage > sd->status.zeny )
- md.damage = sd->status.zeny;
- pc->payzeny(sd, md.damage,LOG_TYPE_STEAL,NULL);
- }
- break;
- }
-
- return md;
-}
-/*==========================================
* Battle main entry, from skill->attack
*------------------------------------------*/
struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,uint16 skill_id,uint16 skill_lv,int count)
@@ -4614,19 +5057,19 @@ struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct bl
}
//Calculates BF_WEAPON returned damage.
-int battle_calc_return_damage(struct block_list* bl, struct block_list *src, int *dmg, int flag, uint16 skill_id){
+int battle_calc_return_damage(struct block_list* bl, struct block_list *src, int *dmg, int flag, uint16 skill_id, int *delay){
+ int rdamage = 0, damage = *dmg, rdelay = *delay, trdamage = 0;
struct map_session_data* sd;
- int rdamage = 0, damage = *dmg;
struct status_change* sc;
+ int max_reflect_damage;
sd = BL_CAST(BL_PC, bl);
sc = status_get_sc(bl);
+ max_reflect_damage = max(status_get_max_hp(bl), status_get_max_hp(bl) * status_get_lv(bl) / 100);
- if( sc && sc->data[SC_REFLECTDAMAGE] ) {
- int max_damage = status_get_max_hp(bl) * status_get_lv(bl) / 100;
- rdamage = (*dmg) * sc->data[SC_REFLECTDAMAGE]->val2 / 100;
- if( rdamage > max_damage ) rdamage = max_damage;
- }else if( sc && sc->data[SC_CRESCENTELBOW] && !is_boss(src) && rnd()%100 < sc->data[SC_CRESCENTELBOW]->val2 ){
+#define NORMALIZE_RDAMAGE(d){ trdamage += rdamage = max(1, min(max_reflect_damage, d)); }
+
+ if( sc && 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(bl) / 125;
if (ratio > 5000) ratio = 5000; // Maximum of 5000% ATK
@@ -4638,42 +5081,56 @@ int battle_calc_return_damage(struct block_list* bl, struct block_list *src, int
status_damage(src, bl, status_damage(bl, src, rdamage, 0, 0, 1)/10, 0, 0, 1);
status_change_end(bl, SC_CRESCENTELBOW, INVALID_TIMER);
return 0; // Just put here to minimize redundancy
- }else if (flag & BF_SHORT) {//Bounces back part of the damage.
- if ( sd && sd->bonus.short_weapon_damage_return ) {
- rdamage += damage * sd->bonus.short_weapon_damage_return / 100;
- if(rdamage < 1) rdamage = 1;
+ }
+ if( flag & BF_SHORT) {//Bounces back part of the damage.
+ if ( sd && sd->bonus.short_weapon_damage_return ){
+ NORMALIZE_RDAMAGE(damage * sd->bonus.short_weapon_damage_return / 100);
+ rdelay = clif->damage(src, src, iTimer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0);
}
if( sc && sc->count ) {
- if ( sc->data[SC_REFLECTSHIELD] && skill_id != WS_CARTTERMINATION ) {
- rdamage += damage * sc->data[SC_REFLECTSHIELD]->val2 / 100;
- if (rdamage < 1) rdamage = 1;
+ if( sc->data[SC_REFLECTSHIELD] && skill_id != WS_CARTTERMINATION ){
+ NORMALIZE_RDAMAGE(damage * sc->data[SC_REFLECTSHIELD]->val2 / 100);
+ rdelay = clif->skill_damage(src, src, iTimer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, CR_REFLECTSHIELD, 1, 4);
+ }
+ if( sc->data[SC_LG_REFLECTDAMAGE] && rand()%100 < (30 + 10*sc->data[SC_LG_REFLECTDAMAGE]->val1) ) {
+ if( skill_id != HT_LANDMINE && skill_id != HT_CLAYMORETRAP
+ && skill_id != RA_CLUSTERBOMB && (skill_id <= RA_VERDURETRAP || skill_id > RA_ICEBOUNDTRAP && skill_id != MA_LANDMINE) ){
+ NORMALIZE_RDAMAGE((*dmg) * sc->data[SC_LG_REFLECTDAMAGE]->val2 / 100);
+ rdelay = clif->damage(src, src, iTimer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0);
+ }
}
- if(sc->data[SC_DEATHBOUND] && skill_id != WS_CARTTERMINATION && !(src->type == BL_MOB && is_boss(src)) ) {
+ if( sc->data[SC_DEATHBOUND] && skill_id != WS_CARTTERMINATION && !is_boss(src) ) {
uint8 dir = iMap->calc_dir(bl,src->x,src->y),
- t_dir = unit_getdir(bl);
-
- if( distance_bl(src,bl) <= 0 || !iMap->check_dir(dir,t_dir) ) {
- int rd1 = 0;
- rd1 = min(damage,status_get_max_hp(bl)) * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage.
- *dmg = rd1 * 30 / 100; // Received damage = 30% of amplifly damage.
- clif->skill_damage(src,bl,iTimer->gettick(), status_get_amotion(src), 0, -30000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1,6);
- status_change_end(bl,SC_DEATHBOUND,INVALID_TIMER);
- rdamage += rd1;
- if (rdamage < 1) rdamage = 1;
+ t_dir = unit_getdir(bl);
+
+ if( !iMap->check_dir(dir,t_dir) ) {
+ int rd1 = damage * sc->data[SC_DEATHBOUND]->val2 / 100; // Amplify damage.
+ trdamage += rdamage = rd1 - (*dmg = rd1 * 30 / 100); // not normalized as intended.
+ clif->skill_damage(src, bl, iTimer->gettick(), status_get_amotion(src), 0, -3000, 1, RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1, 6);
+ skill->blown(bl, src, skill->get_blewcount(RK_DEATHBOUND, sc->data[SC_DEATHBOUND]->val1), unit_getdir(src), 0);
+ if( skill_id )
+ status_change_end(bl, SC_DEATHBOUND, INVALID_TIMER);
+ rdelay = clif->damage(src, src, iTimer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0);
}
}
}
+ if( sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 2 && !is_boss(src) ){
+ NORMALIZE_RDAMAGE(damage * sc->data[SC_SHIELDSPELL_DEF]->val2 / 100);
+ rdelay = clif->damage(src, src, iTimer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0);
+ }
} else {
- if (sd && sd->bonus.long_weapon_damage_return) {
- rdamage += damage * sd->bonus.long_weapon_damage_return / 100;
- if (rdamage < 1) rdamage = 1;
+ if (sd && sd->bonus.long_weapon_damage_return){
+ NORMALIZE_RDAMAGE(damage * sd->bonus.long_weapon_damage_return / 100);
+ rdelay = clif->damage(src, src, iTimer->gettick(), status_get_amotion(src), status_get_dmotion(src), rdamage, 1, 4, 0);
}
}
+
+ if( !(sc && sc->data[SC_DEATHBOUND]) ){
+ if( sc && sc->data[SC_KYOMU] ) // Nullify reflecting ability
+ return 0;
+ }
- if( sc && sc->data[SC_KYOMU] ) // Nullify reflecting ability
- rdamage = 0;
-
- return rdamage;
+ return max(0, trdamage);
}
void battle_drain(TBL_PC *sd, struct block_list *tbl, int rdamage, int ldamage, int race, int boss)
@@ -4898,17 +5355,17 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
return ATK_DEF;
return ATK_MISS;
}
- if( sc->data[SC_GT_ENERGYGAIN] ) {
- if( sd && rnd()%100 < 10 + 5 * sc->data[SC_GT_ENERGYGAIN]->val1)
+ if( sc->data[SC_GENTLETOUCH_ENERGYGAIN] ) {
+ if( sd && rnd()%100 < 10 + 5 * sc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1)
pc->addspiritball(sd,
- skill->get_time(MO_CALLSPIRITS, sc->data[SC_GT_ENERGYGAIN]->val1),
- sc->data[SC_GT_ENERGYGAIN]->val1);
+ skill->get_time(MO_CALLSPIRITS, sc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1),
+ sc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1);
}
- if( tsc && tsc->data[SC_GT_ENERGYGAIN] ) {
- if( tsd && rnd()%100 < 10 + 5 * tsc->data[SC_GT_ENERGYGAIN]->val1)
+ if( tsc && tsc->data[SC_GENTLETOUCH_ENERGYGAIN] ) {
+ if( tsd && rnd()%100 < 10 + 5 * tsc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1)
pc->addspiritball(tsd,
- skill->get_time(MO_CALLSPIRITS, tsc->data[SC_GT_ENERGYGAIN]->val1),
- tsc->data[SC_GT_ENERGYGAIN]->val1);
+ skill->get_time(MO_CALLSPIRITS, tsc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1),
+ tsc->data[SC_GENTLETOUCH_ENERGYGAIN]->val1);
}
if( sc && sc->data[SC_CRUSHSTRIKE] ){
uint16 skill_lv = sc->data[SC_CRUSHSTRIKE]->val1;
@@ -4958,19 +5415,6 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
skill_id = AB_DUPLELIGHT_MAGIC;
skill->attack(skill->get_type(skill_id), src, src, target, skill_id, sc->data[SC_DUPLELIGHT]->val1, tick, SD_LEVEL);
}
-
- rdamage = battle->calc_return_damage(target,src, &damage, wd.flag, 0);
- if( rdamage > 0 ) {
- if( tsc && tsc->data[SC_REFLECTDAMAGE] ) {
- if( src != target ) {// Don't reflect your own damage (Grand Cross)
- iMap->foreachinshootrange(battle->damage_area,target,skill->get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,wd.amotion,wd.dmotion,rdamage,tstatus->race);
- }
- } else {
- rdelay = clif->damage(src, src, tick, wd.amotion, sstatus->dmotion, rdamage, 1, 4, 0);
- //Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
- skill->additional_effect(target,src,CR_REFLECTSHIELD,1,BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
- }
- }
}
wd.dmotion = clif->damage(src, target, tick, wd.amotion, wd.dmotion, wd.damage, wd.div_ , wd.type, wd.damage2);
@@ -5023,7 +5467,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
uint16 skill_id = sc->data[SC_AUTOSPELL]->val2;
uint16 skill_lv = sc->data[SC_AUTOSPELL]->val3;
int i = rnd()%100;
- if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_SAGE)
+ if (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_SAGE)
i = 0; //Max chance, no skill_lv reduction. [Skotlex]
if (i >= 50) skill_lv -= 2;
else if (i >= 15) skill_lv--;
@@ -5099,7 +5543,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
sd->state.autocast = 0;
sd->ud.canact_tick = tick + skill->delay_fix(src, r_skill, r_lv);
- clif->status_change(src, SI_ACTIONDELAY, 1, skill->delay_fix(src, r_skill, r_lv), 0, 0, 1);
+ clif->status_change(src, SI_POSTDELAY, 1, skill->delay_fix(src, r_skill, r_lv), 0, 0, 1);
}
}
@@ -5110,11 +5554,6 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
battle->drain(sd, target, wd.damage, wd.damage2, tstatus->race, is_boss(target));
}
}
- if (rdamage > 0 && !(tsc && tsc->data[SC_REFLECTDAMAGE])) { //By sending attack type "none" skill->additional_effect won't be invoked. [Skotlex]
- if(tsd && src != target)
- battle->drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
- battle->delay_damage(tick, wd.amotion, target, src, 0, CR_REFLECTSHIELD, 0, rdamage, ATK_DEF, rdelay, true);
- }
if (tsc) {
if (tsc->data[SC_POISONREACT] &&
@@ -5243,7 +5682,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
if (((TBL_PC*)target)->invincible_timer != INVALID_TIMER || pc_isinvisible((TBL_PC*)target))
return -1; //Cannot be targeted yet.
if( sc && sc->count ) {
- if( sc->data[SC_VOICEOFSIREN] && sc->data[SC_VOICEOFSIREN]->val2 == target->id )
+ if( sc->data[SC_SIREN] && sc->data[SC_SIREN]->val2 == target->id )
return -1;
}
}
@@ -5265,6 +5704,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
if( skill->get_inf2(su->group->skill_id)&INF2_TRAP ) { //Only a few skills can target traps...
switch( battle->get_current_skill(src) ) {
case RK_DRAGONBREATH:// it can only hit traps in pvp/gvg maps
+ case RK_DRAGONBREATH_WATER:
if( !map[m].flag.pvp && !map[m].flag.gvg )
break;
case 0://you can hit them without skills
@@ -5838,7 +6278,6 @@ static const struct _battle_data {
{ "ignore_items_gender", &battle_config.ignore_items_gender, 1, 0, 1, },
{ "copyskill_restrict", &battle_config.copyskill_restrict, 2, 0, 2, },
{ "berserk_cancels_buffs", &battle_config.berserk_cancels_buffs, 0, 0, 1, },
- { "debuff_on_logout", &battle_config.debuff_on_logout, 1|2, 0, 1|2, },
{ "monster_ai", &battle_config.mob_ai, 0x000, 0x000, 0x77F, },
{ "hom_setting", &battle_config.hom_setting, 0xFFFF, 0x0000, 0xFFFF, },
{ "dynamic_mobs", &battle_config.dynamic_mobs, 1, 0, 1, },
@@ -6239,9 +6678,15 @@ void battle_defaults(void) {
battle->drain = battle_drain;
battle->calc_return_damage = battle_calc_return_damage;
battle->calc_weapon_attack = battle_calc_weapon_attack;
+ battle->calc_weapon_damage = battle_calc_weapon_damage;
+ battle->calc_defense = battle_calc_defense;
battle->attr_ratio = battle_attr_ratio;
battle->attr_fix = battle_attr_fix;
battle->calc_cardfix = battle_calc_cardfix;
+ battle->calc_elefix = battle_calc_elefix;
+ battle->calc_masteryfix = battle_calc_masteryfix;
+ battle->calc_skillratio = battle_calc_skillratio;
+ battle->calc_sizefix = battle_calc_sizefix;
battle->get_master = battle_get_master;
battle->get_targeted = battle_gettargeted;
battle->get_enemy = battle_getenemy;
diff --git a/src/map/battle.h b/src/map/battle.h
index f2d870032..bbe723f36 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -348,7 +348,6 @@ struct Battle_Config {
int copyskill_restrict; // [Aru]
int berserk_cancels_buffs; // [Aru]
- int debuff_on_logout; // Removes a few "official" negative Scs on logout. [Skotlex]
int mob_ai; //Configures various mob_ai settings to make them smarter or dumber(official). [Skotlex]
int hom_setting; //Configures various homunc settings which make them behave unlike normal characters.. [Skotlex]
int dynamic_mobs; // Dynamic Mobs [Wizputer] - battle.conf flag implemented by [random]
@@ -489,13 +488,25 @@ struct battle_interface {
/* drain damage */
void (*drain) (struct map_session_data *sd, struct block_list *tbl, int rdamage, int ldamage, int race, int boss);
/* damage return/reflect */
- int (*calc_return_damage) (struct block_list *bl, struct block_list *src, int *, int flag, uint16 skill_id);
+ int (*calc_return_damage) (struct block_list *bl, struct block_list *src, int *, int flag, uint16 skill_id, int*);
/* attribute rate */
int (*attr_ratio) (int atk_elem, int def_type, int def_lv);
/* applies attribute modifiers */
int (*attr_fix) (struct block_list *src, struct block_list *target, int damage, int atk_elem, int def_type, int def_lv);
/* applies card modifiers */
int (*calc_cardfix) (int attack_type, struct block_list *src, struct block_list *target, int nk, int s_ele, int s_ele_, int damage, int left, int flag);
+ /* applies element modifiers */
+ int (*calc_elefix) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int damage, int nk, int n_ele, int s_ele, int s_ele_, bool left, int flag);
+ /* applies mastery modifiers */
+ int (*calc_masteryfix) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int damage, int div, bool left, bool weapon);
+ /* 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 */
+ int (*calc_sizefix) (struct map_session_data *sd, int damage, int type, int size, bool ignore);
+ /* get weapon damage */
+ int (*calc_weapon_damage) (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, struct weapon_atk *watk, int nk, bool n_ele, short s_ele, short s_ele_, int size, int type, int flag, int flag2);
+ /* applies defense reductions */
+ int (*calc_defense) (int attack_type, struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, int damage, int flag, int pdef);
/* get master (who does this unit respond to?) */
struct block_list *(*get_master) (struct block_list *src);
/* returns a random unit who is targeting this unit */
@@ -521,7 +532,12 @@ struct battle_interface {
int (*blewcount_bonus) (struct map_session_data *sd, uint16 skill_id);
/* skill range criteria */
int (*range_type) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv);
- int (*calc_base_damage) (struct status_data *status, struct weapon_atk *wa, struct status_change *sc, unsigned short t_size, struct map_session_data *sd, int flag);
+ int (*calc_base_damage)
+#ifdef RENEWAL
+ (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, int nk, bool n_ele, short s_ele, short s_ele_, int type, int flag, int flag2);
+#else
+ (struct status_data *status, struct weapon_atk *wa, struct status_change *sc, unsigned short t_size, struct map_session_data *sd, int flag);
+#endif
struct Damage (*calc_misc_attack) (struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag);
struct Damage (*calc_magic_attack) (struct block_list *src,struct block_list *target,uint16 skill_id,uint16 skill_lv,int mflag);
int (*adjust_skill_damage) (int m, unsigned short skill_id);
diff --git a/src/map/clif.c b/src/map/clif.c
index 202469605..2f8ecd6a4 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1259,12 +1259,12 @@ void clif_spiritball_single(int fd, struct map_session_data *sd) {
/*==========================================
* Kagerou/Oboro amulet spirit
*------------------------------------------*/
-void clif_talisman_single(int fd, struct map_session_data *sd, short type) {
+void clif_charm_single(int fd, struct map_session_data *sd, short type) {
WFIFOHEAD(fd, packet_len(0x08cf));
WFIFOW(fd,0)=0x08cf;
WFIFOL(fd,2)=sd->bl.id;
WFIFOW(fd,6)=type;
- WFIFOW(fd,8)=sd->talisman[type];
+ WFIFOW(fd,8)=sd->charm[type];
WFIFOSET(fd, packet_len(0x08cf));
}
@@ -1358,8 +1358,8 @@ int clif_spawn(struct block_list *bl)
clif->sc_load(&sd->bl, sd->bl.id,AREA,StatusIconChangeTable[sd->sc_display[i]->type],sd->sc_display[i]->val1,sd->sc_display[i]->val2,sd->sc_display[i]->val3);
}
for(i = 1; i < 5; i++){
- if( sd->talisman[i] > 0 )
- clif->talisman(sd, i);
+ if( sd->charm[i] > 0 )
+ clif->charm(sd, i);
}
if (sd->status.robe)
clif->refreshlook(bl,bl->id,LOOK_ROBE,sd->status.robe,AREA);
@@ -3461,7 +3461,9 @@ void clif_arrowequip(struct map_session_data *sd,int val)
nullpo_retv(sd);
pc_stop_attack(sd); // [Valaris]
-
+#if PACKETVER >= 20121128
+ clif->status_change(&sd->bl, SI_CLIENT_ONLY_EQUIP_ARROW, 1, INVALID_TIMER, 0, 0, 0);
+#endif
fd=sd->fd;
WFIFOHEAD(fd, packet_len(0x013c));
WFIFOW(fd,0)=0x013c;
@@ -4309,8 +4311,8 @@ void clif_getareachar_pc(struct map_session_data* sd,struct map_session_data* ds
if(dstsd->spiritball > 0)
clif->spiritball_single(sd->fd, dstsd);
for(i = 1; i < 5; i++){
- if( dstsd->talisman[i] > 0 )
- clif->talisman_single(sd->fd, dstsd, i);
+ if( dstsd->charm[i] > 0 )
+ clif->charm_single(sd->fd, dstsd, i);
}
for( i = 0; i < dstsd->sc_display_count; i++ ) {
clif->sc_load(&sd->bl,dstsd->bl.id,SELF,StatusIconChangeTable[dstsd->sc_display[i]->type],dstsd->sc_display[i]->val1,dstsd->sc_display[i]->val2,dstsd->sc_display[i]->val3);
@@ -4471,9 +4473,9 @@ int clif_damage(struct block_list* src, struct block_list* dst, unsigned int tic
type = clif_calc_delay(type,div,damage+damage2,ddelay);
sc = status_get_sc(dst);
if(sc && sc->count) {
- if(sc->data[SC_HALLUCINATION]) {
- if(damage) damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
- if(damage2) damage2 = damage2*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
+ if(sc->data[SC_ILLUSION]) {
+ if(damage) damage = damage*(sc->data[SC_ILLUSION]->val2) + rnd()%100;
+ if(damage2) damage2 = damage2*(sc->data[SC_ILLUSION]->val2) + rnd()%100;
}
}
@@ -4643,12 +4645,21 @@ void clif_getareachar_item(struct map_session_data* sd,struct flooritem_data* fi
/// Notifies the client of a skill unit.
/// 011f <id>.L <creator id>.L <x>.W <y>.W <unit id>.B <visible>.B (ZC_SKILL_ENTRY)
/// 01c9 <id>.L <creator id>.L <x>.W <y>.W <unit id>.B <visible>.B <has msg>.B <msg>.80B (ZC_SKILL_ENTRY2)
+/// 08c7 <lenght>.W <id> L <creator id>.L <x>.W <y>.W <unit id>.B <range>.W <visible>.B (ZC_SKILL_ENTRY3)
+/// 099f <lenght>.W <id> L <creator id>.L <x>.W <y>.W <unit id>.L <range>.W <visible>.B (ZC_SKILL_ENTRY4)
void clif_getareachar_skillunit(struct map_session_data *sd, struct skill_unit *unit) {
- int fd = sd->fd;
+ int fd = sd->fd, header = 0x11f, pos=0;
if( unit->group->state.guildaura )
return;
+#if PACKETVER >= 20130320
+ if(unit->group->unit_id > UCHAR_MAX){
+ header = 0x99f;
+ pos = 2;
+ }
+#endif
+
#if PACKETVER >= 3
if(unit->group->unit_id==UNT_GRAFFITI) { // Graffiti [Valaris]
WFIFOHEAD(fd,packet_len(0x1c9));
@@ -4665,20 +4676,26 @@ void clif_getareachar_skillunit(struct map_session_data *sd, struct skill_unit *
return;
}
#endif
- WFIFOHEAD(fd,packet_len(0x11f));
- WFIFOW(fd, 0)=0x11f;
- WFIFOL(fd, 2)=unit->bl.id;
- WFIFOL(fd, 6)=unit->group->src_id;
- WFIFOW(fd,10)=unit->bl.x;
- WFIFOW(fd,12)=unit->bl.y;
+ WFIFOHEAD(fd,packet_len(header));
+ WFIFOW(fd, 0)=header;
+ if(pos > 0)
+ WFIFOL(fd, pos)=packet_len(header);
+ WFIFOL(fd, 2 + pos)=unit->bl.id;
+ WFIFOL(fd, 6 + pos)=unit->group->src_id;
+ WFIFOW(fd,10 + pos)=unit->bl.x;
+ WFIFOW(fd,12 + pos)=unit->bl.y;
if (battle_config.traps_setting&1 && skill->get_inf2(unit->group->skill_id)&INF2_TRAP)
WFIFOB(fd,14)=UNT_DUMMYSKILL; //Use invisible unit id for traps.
else if (skill->get_unit_flag(unit->group->skill_id) & UF_RANGEDSINGLEUNIT && !(unit->val2 & UF_RANGEDSINGLEUNIT))
WFIFOB(fd,14)=UNT_DUMMYSKILL; //Use invisible unit id for traps.
- else
+ else if(pos > 0){
+ WFIFOL(fd,16)=unit->group->unit_id;
+ WFIFOW(fd,20)=unit->range;
+ pos += 5;
+ }else
WFIFOB(fd,14)=unit->group->unit_id;
- WFIFOB(fd,15)=1; // ignored by client (always gets set to 1)
- WFIFOSET(fd,packet_len(0x11f));
+ WFIFOB(fd,15 + pos)=1; // ignored by client (always gets set to 1)
+ WFIFOSET(fd,packet_len(header));
if(unit->group->skill_id == WZ_ICEWALL)
clif->changemapcell(fd,unit->bl.m,unit->bl.x,unit->bl.y,5,SELF);
@@ -5134,8 +5151,8 @@ int clif_skill_damage(struct block_list *src,struct block_list *dst,unsigned int
type = clif_calc_delay(type,div,damage,ddelay);
sc = status_get_sc(dst);
if(sc && sc->count) {
- if(sc->data[SC_HALLUCINATION] && damage)
- damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
+ if(sc->data[SC_ILLUSION] && damage)
+ damage = damage*(sc->data[SC_ILLUSION]->val2) + rnd()%100;
}
#if PACKETVER < 3
@@ -5223,8 +5240,8 @@ int clif_skill_damage2(struct block_list *src,struct block_list *dst,unsigned in
sc = status_get_sc(dst);
if(sc && sc->count) {
- if(sc->data[SC_HALLUCINATION] && damage)
- damage = damage*(sc->data[SC_HALLUCINATION]->val2) + rnd()%100;
+ if(sc->data[SC_ILLUSION] && damage)
+ damage = damage*(sc->data[SC_ILLUSION]->val2) + rnd()%100;
}
WBUFW(buf,0)=0x115;
@@ -5330,12 +5347,20 @@ void clif_skill_poseffect(struct block_list *src,uint16 skill_id,int val,int x,i
void clif_skill_setunit(struct skill_unit *unit)
{
unsigned char buf[128];
+ int header = 0x11f, pos = 0;
nullpo_retv(unit);
if( unit->group->state.guildaura )
return;
+#if PACKETVER >= 20130320
+ if(unit->group->unit_id > UCHAR_MAX){
+ header = 0x99f;
+ pos = 2;
+ }
+#endif
+
#if PACKETVER >= 3
if(unit->group->unit_id==UNT_GRAFFITI) { // Graffiti [Valaris]
WBUFW(buf, 0)=0x1c9;
@@ -5351,19 +5376,25 @@ void clif_skill_setunit(struct skill_unit *unit)
return;
}
#endif
- WBUFW(buf, 0)=0x11f;
- WBUFL(buf, 2)=unit->bl.id;
- WBUFL(buf, 6)=unit->group->src_id;
- WBUFW(buf,10)=unit->bl.x;
- WBUFW(buf,12)=unit->bl.y;
+ WBUFW(buf, 0)=header;
+ if(pos > 0)
+ WBUFW(buf, pos)=packet_len(header);
+ WBUFL(buf, 2 + pos)=unit->bl.id;
+ WBUFL(buf, 6 + pos)=unit->group->src_id;
+ WBUFW(buf,10 + pos)=unit->bl.x;
+ WBUFW(buf,12 + pos)=unit->bl.y;
if (unit->group->state.song_dance&0x1 && unit->val2&UF_ENSEMBLE)
WBUFB(buf,14)=unit->val2&UF_SONG?UNT_DISSONANCE:UNT_UGLYDANCE;
else if (skill->get_unit_flag(unit->group->skill_id) & UF_RANGEDSINGLEUNIT && !(unit->val2 & UF_RANGEDSINGLEUNIT))
WBUFB(buf, 14) = UNT_DUMMYSKILL; // Only display the unit at center.
- else
+ else if(pos > 0){
+ WBUFL(buf,16)=unit->group->unit_id;
+ WBUFW(buf,20)=unit->range;
+ pos += 5;
+ }else
WBUFB(buf,14)=unit->group->unit_id;
- WBUFB(buf,15)=1; // ignored by client (always gets set to 1)
- clif->send(buf,packet_len(0x11f),&unit->bl,AREA);
+ WBUFB(buf,15 + pos)=1; // ignored by client (always gets set to 1)
+ clif->send(buf,packet_len(header),&unit->bl,AREA);
}
@@ -5388,9 +5419,10 @@ void clif_skill_warppoint(struct map_session_data* sd, uint16 skill_id, uint16 s
WFIFOSET(fd,packet_len(0x11c));
sd->menuskill_id = skill_id;
- if (skill_id == AL_WARP)
+ if (skill_id == AL_WARP){
sd->menuskill_val = (sd->ud.skillx<<16)|sd->ud.skilly; //Store warp position here.
- else
+ sd->state.workinprogress = 3;
+ }else
sd->menuskill_val = skill_lv;
}
@@ -5423,10 +5455,11 @@ void clif_skill_memomessage(struct map_session_data* sd, int type)
/// type:
/// 0 = "Unable to Teleport in this area" in color 0xFFFF00 (cyan)
/// 1 = "Saved point cannot be memorized." in color 0x0000FF (red)
+/// 2 = "This skill cannot be used within this area." in color 0xFFFF00 (cyan)
///
/// @param sd Who receives the message
/// @param type What message
-void clif_skill_teleportmessage(struct map_session_data *sd, int type)
+void clif_skill_mapinfomessage(struct map_session_data *sd, int type)
{
int fd;
@@ -5621,6 +5654,9 @@ void clif_status_change(struct block_list *bl,int type,int flag,int tick,int val
if (!(status_type2relevant_bl_types(type)&bl->type)) // only send status changes that actually matter to the client
return;
+ if ( tick < 0 )
+ tick = 9999;
+
sd = BL_CAST(BL_PC, bl);
p.PacketType = status_changeType;
@@ -6061,6 +6097,7 @@ void clif_item_identify_list(struct map_session_data *sd)
WFIFOSET(fd,WFIFOW(fd,2));
sd->menuskill_id = MC_IDENTIFY;
sd->menuskill_val = c;
+ sd->state.workinprogress = 3;
}
}
@@ -6163,25 +6200,20 @@ void clif_item_refine_list(struct map_session_data *sd)
int fd;
uint16 skill_lv;
int wlv;
- int refine_item[5];
nullpo_retv(sd);
skill_lv = pc->checkskill(sd,WS_WEAPONREFINE);
fd=sd->fd;
-
- refine_item[0] = -1;
- refine_item[1] = pc->search_inventory(sd,1010);
- refine_item[2] = pc->search_inventory(sd,1011);
- refine_item[3] = refine_item[4] = pc->search_inventory(sd,984);
-
+
WFIFOHEAD(fd, MAX_INVENTORY * 13 + 4);
WFIFOW(fd,0)=0x221;
for(i=c=0;i<MAX_INVENTORY;i++){
- if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].refine < skill_lv &&
- sd->status.inventory[i].identify && (wlv=itemdb_wlv(sd->status.inventory[i].nameid)) >=1 &&
- refine_item[wlv]!=-1 && !(sd->status.inventory[i].equip&EQP_ARMS)){
+ if(sd->status.inventory[i].nameid > 0 && sd->status.inventory[i].identify
+ && (wlv=itemdb_wlv(sd->status.inventory[i].nameid)) >=1
+ && !sd->inventory_data[i]->flag.no_refine
+ && !(sd->status.inventory[i].equip&EQP_ARMS)){
WFIFOW(fd,c*13+ 4)=i+2;
WFIFOW(fd,c*13+ 6)=sd->status.inventory[i].nameid;
WFIFOB(fd,c*13+ 8)=sd->status.inventory[i].refine;
@@ -8498,8 +8530,8 @@ void clif_refresh(struct map_session_data *sd)
if (sd->spiritball)
clif->spiritball_single(sd->fd, sd);
for(i = 1; i < 5; i++){
- if( sd->talisman[i] > 0 )
- clif->talisman_single(sd->fd, sd, i);
+ if( sd->charm[i] > 0 )
+ clif->charm_single(sd->fd, sd, i);
}
if (sd->vd.cloth_color)
clif->refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);
@@ -9499,7 +9531,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
if (iMap->night_flag && map[sd->bl.m].flag.nightenabled) {
sd->state.night = 1;
- clif->status_change(&sd->bl, SI_NIGHT, 1, 0, 0, 0, 0);
+ clif->status_change(&sd->bl, SI_SKE, 1, 0, 0, 0, 0);
}
// Notify everyone that this char logged in [Skotlex].
@@ -9537,11 +9569,11 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
if( iMap->night_flag && map[sd->bl.m].flag.nightenabled ) { //Display night.
if( !sd->state.night ) {
sd->state.night = 1;
- clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_NIGHT);
+ clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_SKE);
}
} else if( sd->state.night ) { //Clear night display.
sd->state.night = 0;
- clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_NIGHT);
+ clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_SKE);
}
if( map[sd->bl.m].flag.battleground ) {
@@ -9586,7 +9618,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
npc_script_event(sd, NPCE_LOADMAP);
if (pc->checkskill(sd, SG_DEVIL) && !pc->nextjobexp(sd)) //blindness [Komurka]
- clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_DEVIL);
+ clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_DEVIL1);
if (sd->sc.opt2) //Client loses these on warp.
clif->changeoption(&sd->bl);
@@ -9862,7 +9894,7 @@ void clif_parse_GlobalMessage(int fd, struct map_session_data* sd)
if( atcommand->parse(fd, sd, message, 1) )
return;
- if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEPSLEEP] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
+ if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
return;
if( battle_config.min_chat_delay ) { //[Skotlex]
@@ -10321,7 +10353,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd)
if ( atcommand->parse(fd, sd, message, 1) )
return;
- if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEPSLEEP] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))
+ if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT))
return;
if (battle_config.min_chat_delay) { //[Skotlex]
@@ -10602,7 +10634,7 @@ void clif_parse_EquipItem(int fd,struct map_session_data *sd)
return;
} else if ( sd->state.storage_flag || sd->sc.opt1 )
; //You can equip/unequip stuff while storage is open/under status changes
- else if ( pc_cant_act2(sd) )
+ else if ( pc_cant_act2(sd) || sd->state.prerefining )
return;
if(!sd->status.inventory[index].identify) {
@@ -10730,7 +10762,7 @@ void clif_parse_UnequipItem(int fd,struct map_session_data *sd)
return;
} else if ( sd->state.storage_flag || sd->sc.opt1 )
; //You can equip/unequip stuff while storage is open/under status changes
- else if ( pc_cant_act2(sd) )
+ else if ( pc_cant_act2(sd) || sd->state.prerefining )
return;
index = RFIFOW(fd,2)-2;
@@ -10751,7 +10783,12 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd)
clif_clearunit_area(&sd->bl,CLR_DEAD);
return;
}
-
+ if( sd->npc_id || sd->state.workinprogress&2 ){
+#ifdef RENEWAL
+ clif->msg(sd, 0x783); // TODO look for the client date that has this message.
+#endif
+ return;
+ }
if ( pc_cant_act2(sd) || !(bl = iMap->id2bl(RFIFOL(fd,2))) )
return;
@@ -10761,8 +10798,10 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd)
clif->pActionRequest_sub(sd, 0x07, bl->id, iTimer->gettick());
break;
case BL_NPC:
- if( sd->ud.skilltimer != INVALID_TIMER ) {
- clif->colormes(fd,COLOR_WHITE,msg_txt(1476));
+ if( sd->ud.skill_id < RK_ENCHANTBLADE && sd->ud.skilltimer != INVALID_TIMER ) {// TODO: should only work with none 3rd job skills
+#ifdef RENEWAL
+ clif->msg(sd, 0x783);
+#endif
break;
}
if( bl->m != -1 )// the user can't click floating npcs directly (hack attempt)
@@ -11270,7 +11309,7 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
// Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex]
sd->idletime = last_tick;
- if( sd->npc_id ){
+ if( sd->npc_id || sd->state.workinprogress&1 ){
#ifdef RENEWAL
clif->msg(sd, 0x783); // TODO look for the client date that has this message.
#endif
@@ -11563,6 +11602,8 @@ void clif_parse_WeaponRefine(int fd, struct map_session_data *sd)
{
int idx;
+ sd->state.prerefining = 0;
+
if (sd->menuskill_id != WS_WEAPONREFINE) //Packet exploit?
return;
if (pc_istrading(sd)) {
@@ -11664,6 +11705,8 @@ void clif_parse_ItemIdentify(int fd,struct map_session_data *sd)
if (sd->menuskill_id != MC_IDENTIFY)
return;
if( idx == -1 ) {// cancel pressed
+ sd->state.workinprogress = 0;
+ clif->item_identified(sd,idx-2,1);
clif_menuskill_clear(sd);
return;
}
@@ -12096,7 +12139,7 @@ void clif_parse_PartyMessage(int fd, struct map_session_data* sd)
if( atcommand->parse(fd, sd, message, 1) )
return;
- if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEPSLEEP] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
+ if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
return;
if( battle_config.min_chat_delay )
@@ -12658,7 +12701,7 @@ void clif_parse_OpenVending(int fd, struct map_session_data* sd)
const uint8* data = (uint8*)RFIFOP(fd,85);
if( !flag )
- sd->state.prevend = 0;
+ sd->state.prevend = sd->state.workinprogress = 0;
if( sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM )
return;
@@ -12937,7 +12980,7 @@ void clif_parse_GuildMessage(int fd, struct map_session_data* sd)
if( atcommand->parse(fd, sd, message, 1) )
return;
- if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEPSLEEP] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
+ if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
return;
if( battle_config.min_chat_delay )
@@ -15790,7 +15833,7 @@ void clif_parse_BattleChat(int fd, struct map_session_data* sd)
if( atcommand->parse(fd, sd, message, 1) )
return;
- if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC_DEEPSLEEP] || sd->sc.data[SC__BLOODYLUST] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
+ if( sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] || sd->sc.data[SC_DEEP_SLEEP] || (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOCHAT) )
return;
if( battle_config.min_chat_delay ) {
@@ -16735,7 +16778,7 @@ int clif_spellbook_list(struct map_session_data *sd)
if( itemdb_is_spellbook(sd->status.inventory[i].nameid) )
{
WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid;
- c ++;
+ c++;
}
}
@@ -16926,7 +16969,7 @@ void clif_parse_SkillSelectMenu(int fd, struct map_session_data *sd) {
/*==========================================
* Kagerou/Oboro amulet spirit
*------------------------------------------*/
-void clif_talisman(struct map_session_data *sd,short type)
+void clif_charm(struct map_session_data *sd,short type)
{
unsigned char buf[10];
@@ -16935,7 +16978,7 @@ void clif_talisman(struct map_session_data *sd,short type)
WBUFW(buf,0)=0x08cf;
WBUFL(buf,2)=sd->bl.id;
WBUFW(buf,6)=type;
- WBUFW(buf,8)=sd->talisman[type];
+ WBUFW(buf,8)=sd->charm[type];
clif->send(buf,packet_len(0x08cf),&sd->bl,AREA);
}
/// Move Item from or to Personal Tab (CZ_WHATSOEVER) [FE]
@@ -17744,7 +17787,7 @@ void clif_defaults(void) {
clif->skill_fail = clif_skill_fail;
clif->skill_cooldown = clif_skill_cooldown;
clif->skill_memomessage = clif_skill_memomessage;
- clif->skill_teleportmessage = clif_skill_teleportmessage;
+ clif->skill_mapinfomessage = clif_skill_mapinfomessage;
clif->skill_produce_mix_list = clif_skill_produce_mix_list;
clif->cooking_list = clif_cooking_list;
clif->autospell = clif_autospell;
@@ -17845,8 +17888,8 @@ void clif_defaults(void) {
clif->specialeffect_single = clif_specialeffect_single;
clif->specialeffect_value = clif_specialeffect_value;
clif->millenniumshield = clif_millenniumshield;
- clif->talisman = clif_talisman;
- clif->talisman_single = clif_talisman_single;
+ clif->charm = clif_charm;
+ clif->charm_single = clif_charm_single;
clif->snap = clif_snap;
clif->weather_check = clif_weather_check;
/* sound effects client-side */
diff --git a/src/map/clif.h b/src/map/clif.h
index 5393ef5b7..b447687ea 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -231,7 +231,7 @@ enum map_type { // clif_map_type
MAPTYPE_UNUSED = 29,
};
-enum useskill_fail_cause { // clif_skill_fail
+typedef enum useskill_fail_cause { // clif_skill_fail
USESKILL_FAIL_LEVEL = 0,
USESKILL_FAIL_SP_INSUFFICIENT = 1,
USESKILL_FAIL_HP_INSUFFICIENT = 2,
@@ -272,7 +272,7 @@ enum useskill_fail_cause { // clif_skill_fail
USESKILL_FAIL_CANONBALL = 37,
//XXX_USESKILL_FAIL_II_MADOGEAR_ACCELERATION = 38,
//XXX_USESKILL_FAIL_II_MADOGEAR_HOVERING_BOOSTER = 39,
- USESKILL_FAIL_MADOGEAR_HOVERING = 40,
+ //XXX_USESKILL_FAIL_MADOGEAR_HOVERING = 40,
//XXX_USESKILL_FAIL_II_MADOGEAR_SELFDESTRUCTION_DEVICE = 41,
//XXX_USESKILL_FAIL_II_MADOGEAR_SHAPESHIFTER = 42,
USESKILL_FAIL_GUILLONTINE_POISON = 43,
@@ -316,7 +316,7 @@ enum useskill_fail_cause { // clif_skill_fail
USESKILL_FAIL_STYLE_CHANGE_FIGHTER = 81,
USESKILL_FAIL_STYLE_CHANGE_GRAPPLER = 82,
USESKILL_FAIL_THERE_ARE_NPC_AROUND = 83,
-};
+}useskill_fail_cause;
enum clif_messages {
SKILL_CANT_USE_AREA = 0x536,
@@ -571,7 +571,7 @@ struct clif_interface {
void (*skill_fail) (struct map_session_data *sd,uint16 skill_id,enum useskill_fail_cause cause,int btype);
void (*skill_cooldown) (struct map_session_data *sd, uint16 skill_id, unsigned int tick);
void (*skill_memomessage) (struct map_session_data* sd, int type);
- void (*skill_teleportmessage) (struct map_session_data *sd, int type);
+ void (*skill_mapinfomessage) (struct map_session_data *sd, int type);
void (*skill_produce_mix_list) (struct map_session_data *sd, int skill_id, int trigger);
void (*cooking_list) (struct map_session_data *sd, int trigger, uint16 skill_id, int qty, int list_type);
void (*autospell) (struct map_session_data *sd,uint16 skill_lv);
@@ -672,8 +672,8 @@ struct clif_interface {
void (*specialeffect_single) (struct block_list* bl, int type, int fd);
void (*specialeffect_value) (struct block_list* bl, int effect_id, int num, send_target target);
void (*millenniumshield) (struct map_session_data *sd, short shields );
- void (*talisman) (struct map_session_data *sd, short type);
- void (*talisman_single) (int fd, struct map_session_data *sd, short type);
+ void (*charm) (struct map_session_data *sd, short type);
+ void (*charm_single) (int fd, struct map_session_data *sd, short type);
void (*snap) ( struct block_list *bl, short x, short y );
void (*weather_check) (struct map_session_data *sd);
/* sound effects client-side */
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index c441de26a..ea478d135 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -22,11 +22,13 @@
#define MAX_ITEMS_PER_COMBO 6
enum item_itemid {
+ ITEMID_HOLY_WATER = 523,
ITEMID_EMPERIUM = 714,
ITEMID_YELLOW_GEMSTONE = 715,
ITEMID_RED_GEMSTONE = 716,
ITEMID_BLUE_GEMSTONE = 717,
ITEMID_TRAP = 1065,
+ ITEMID_FACE_PAINT = 6120,
ITEMID_STONE = 7049,
ITEMID_SKULL_ = 7420,
ITEMID_TOKEN_OF_SIEGFRIED = 7621,
@@ -66,6 +68,7 @@ enum {
ITEMID_CAMOUFLAGE_GENERATOR,
ITEMID_HIGH_QUALITY_COOLER,
ITEMID_SPECIAL_COOLER,
+ ITEMID_MONKEY_SPANNER = 6186,
} mecha_item_list;
enum {
diff --git a/src/map/map.c b/src/map/map.c
index 0dab56d21..510f36109 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -358,10 +358,10 @@ int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick)
sc = status_get_sc(bl);
skill->unit_move(bl,tick,2);
- status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
- status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
+ status_change_end(bl, SC_RG_CCONFINE_M, INVALID_TIMER);
+ status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER);
// status_change_end(bl, SC_BLADESTOP, INVALID_TIMER); //Won't stop when you are knocked away, go figure...
- status_change_end(bl, SC_TATAMIGAESHI, INVALID_TIMER);
+ status_change_end(bl, SC_NJ_TATAMIGAESHI, INVALID_TIMER);
status_change_end(bl, SC_MAGICROD, INVALID_TIMER);
if (sc->data[SC_PROPERTYWALK] &&
sc->data[SC_PROPERTYWALK]->val3 >= skill->get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2) )
@@ -1667,45 +1667,19 @@ int map_quit(struct map_session_data *sd) {
//(changing map-servers invokes unit_free but bypasses iMap->quit)
if( sd->sc.count ) {
//Status that are not saved...
- status_change_end(&sd->bl, SC_BOSSMAPINFO, INVALID_TIMER);
- status_change_end(&sd->bl, SC_AUTOTRADE, INVALID_TIMER);
- status_change_end(&sd->bl, SC_SPURT, INVALID_TIMER);
- status_change_end(&sd->bl, SC_BERSERK, INVALID_TIMER);
- status_change_end(&sd->bl, SC__BLOODYLUST, INVALID_TIMER);
- status_change_end(&sd->bl, SC_TRICKDEAD, INVALID_TIMER);
- status_change_end(&sd->bl, SC_LEADERSHIP, INVALID_TIMER);
- status_change_end(&sd->bl, SC_GLORYWOUNDS, INVALID_TIMER);
- status_change_end(&sd->bl, SC_SOULCOLD, INVALID_TIMER);
- status_change_end(&sd->bl, SC_HAWKEYES, INVALID_TIMER);
- if(sd->sc.data[SC_ENDURE] && sd->sc.data[SC_ENDURE]->val4)
- status_change_end(&sd->bl, SC_ENDURE, INVALID_TIMER); //No need to save infinite endure.
- status_change_end(&sd->bl, SC_WEIGHT50, INVALID_TIMER);
- status_change_end(&sd->bl, SC_WEIGHT90, INVALID_TIMER);
- status_change_end(&sd->bl, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
- status_change_end(&sd->bl, SC_KYOUGAKU, INVALID_TIMER);
- if (battle_config.debuff_on_logout&1) {
- status_change_end(&sd->bl, SC_ORCISH, INVALID_TIMER);
- status_change_end(&sd->bl, SC_STRIPWEAPON, INVALID_TIMER);
- status_change_end(&sd->bl, SC_STRIPARMOR, INVALID_TIMER);
- status_change_end(&sd->bl, SC_STRIPSHIELD, INVALID_TIMER);
- status_change_end(&sd->bl, SC_STRIPHELM, INVALID_TIMER);
- status_change_end(&sd->bl, SC_EXTREMITYFIST, INVALID_TIMER);
- status_change_end(&sd->bl, SC_EXPLOSIONSPIRITS, INVALID_TIMER);
- if(sd->sc.data[SC_REGENERATION] && sd->sc.data[SC_REGENERATION]->val4)
- status_change_end(&sd->bl, SC_REGENERATION, INVALID_TIMER);
- //TO-DO Probably there are way more NPC_type negative status that are removed
- status_change_end(&sd->bl, SC_CHANGEUNDEAD, INVALID_TIMER);
- // Both these statuses are removed on logout. [L0ne_W0lf]
- status_change_end(&sd->bl, SC_SLOWCAST, INVALID_TIMER);
- status_change_end(&sd->bl, SC_CRITICALWOUND, INVALID_TIMER);
- }
- if (battle_config.debuff_on_logout&2) {
- status_change_end(&sd->bl, SC_MAXIMIZEPOWER, INVALID_TIMER);
- status_change_end(&sd->bl, SC_MAXOVERTHRUST, INVALID_TIMER);
- status_change_end(&sd->bl, SC_STEELBODY, INVALID_TIMER);
- status_change_end(&sd->bl, SC_PRESERVE, INVALID_TIMER);
- status_change_end(&sd->bl, SC_KAAHI, INVALID_TIMER);
- status_change_end(&sd->bl, SC_SPIRIT, INVALID_TIMER);
+ for(i=0; i < SC_MAX; i++){
+ if ( status_get_sc_type(i)&SC_NO_SAVE ){
+ if ( !sd->sc.data[i] )
+ continue;
+ switch( i ){
+ case SC_ENDURE:
+ case SC_GDSKILL_REGENERATION:
+ if( !sd->sc.data[i]->val4 )
+ break;
+ default:
+ status_change_end(&sd->bl, (sc_type)i, INVALID_TIMER);
+ }
+ }
}
}
diff --git a/src/map/mercenary.c b/src/map/mercenary.c
index 91d685a49..566f68409 100644
--- a/src/map/mercenary.c
+++ b/src/map/mercenary.c
@@ -361,7 +361,7 @@ int mercenary_dead(struct mercenary_data *md)
int mercenary_killbonus(struct mercenary_data *md)
{
- const enum sc_type scs[] = { SC_MERC_FLEEUP, SC_MERC_ATKUP, SC_MERC_HPUP, SC_MERC_SPUP, SC_MERC_HITUP };
+ 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);
diff --git a/src/map/mob.c b/src/map/mob.c
index 04c4bba38..6bb40478f 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -1461,7 +1461,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
if( !battle->check_range(&md->bl, tbl, md->status.rhw.range)
&& ( //Can't attack back and can't reach back.
(!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || (md->sc.data[SC_SPIDERWEB] && md->sc.data[SC_SPIDERWEB]->val1)
- || md->sc.data[SC_BITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNSTRAP]
+ || md->sc.data[SC_WUGBITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNS_TRAP]
|| md->sc.data[SC__MANHOLE])) // Not yet confirmed if boss will teleport once it can't reach target.
|| !mob_can_reach(md, tbl, md->min_chase, MSS_RUSH)
)
@@ -1484,7 +1484,7 @@ static bool mob_ai_sub_hard(struct mob_data *md, unsigned int tick)
|| (!battle->check_range(&md->bl, abl, md->status.rhw.range) // Not on Melee Range and ...
&& ( // Reach check
(!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0 && (battle_config.mob_ai&0x2 || (md->sc.data[SC_SPIDERWEB] && md->sc.data[SC_SPIDERWEB]->val1)
- || md->sc.data[SC_BITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNSTRAP]
+ || md->sc.data[SC_WUGBITE] || md->sc.data[SC_VACUUM_EXTREME] || md->sc.data[SC_THORNS_TRAP]
|| md->sc.data[SC__MANHOLE])) // Not yet confirmed if boss will teleport once it can't reach target.
|| !mob_can_reach(md, abl, dist+md->db->range3, MSS_RUSH)
)
@@ -2360,9 +2360,9 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
(int)(md->level - sd->status.base_level) >= 20)
drop_rate = (int)(drop_rate*1.25); // pk_mode increase drops if 20 level difference [Valaris]
- // Increase drop rate if user has SC_ITEMBOOST
- if (sd && sd->sc.data[SC_ITEMBOOST]) // now rig the drop rate to never be over 90% unless it is originally >90%.
- drop_rate = max(drop_rate,cap_value((int)(0.5+drop_rate*(sd->sc.data[SC_ITEMBOOST]->val1)/100.),0,9000));
+ // Increase drop rate if user has SC_CASH_RECEIVEITEM
+ if (sd && sd->sc.data[SC_CASH_RECEIVEITEM]) // now rig the drop rate to never be over 90% unless it is originally >90%.
+ drop_rate = max(drop_rate,cap_value((int)(0.5+drop_rate*(sd->sc.data[SC_CASH_RECEIVEITEM]->val1)/100.),0,9000));
#ifdef RENEWAL_DROP
if( drop_modifier != 100 ) {
drop_rate = drop_rate * drop_modifier / 100;
diff --git a/src/map/packets.h b/src/map/packets.h
index 4f2b119fb..bcce36040 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -2091,6 +2091,7 @@ packet(0x020d,-1);
// New Packets
packet(0x0998,8,clif->pEquipItem,2,4);
packet(0x0447,2); // PACKET_CZ_BLOCKING_PLAY_CANCEL
+ packet(0x099f,24);
// New Packets End
#endif
diff --git a/src/map/party.c b/src/map/party.c
index e30d16c07..adcb35c5a 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -840,7 +840,7 @@ int party_skill_check(struct map_session_data *sd, int party_id, uint16 skill_id
break;
case MO_COMBOFINISH: //Increase Counter rate of Star Gladiators
if((p_sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR
- && sd->sc.data[SC_READYCOUNTER]
+ && sd->sc.data[SC_COUNTERKICK_READY]
&& pc->checkskill(p_sd,SG_FRIEND)) {
sc_start4(&p_sd->bl,SC_SKILLRATE_UP,100,TK_COUNTER,
50+50*pc->checkskill(p_sd,SG_FRIEND), //+100/150/200% rate
diff --git a/src/map/pc.c b/src/map/pc.c
index 170de63ff..155812836 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -868,20 +868,20 @@ int pc_isequip(struct map_session_data *sd,int n)
if (sd->sc.count) {
- if(item->equip & EQP_ARMS && item->type == IT_WEAPON && sd->sc.data[SC_STRIPWEAPON]) // Also works with left-hand weapons [DracoRPG]
+ if(item->equip & EQP_ARMS && item->type == IT_WEAPON && sd->sc.data[SC_NOEQUIPWEAPON]) // Also works with left-hand weapons [DracoRPG]
return 0;
- if(item->equip & EQP_SHIELD && item->type == IT_ARMOR && sd->sc.data[SC_STRIPSHIELD])
+ if(item->equip & EQP_SHIELD && item->type == IT_ARMOR && sd->sc.data[SC_NOEQUIPSHIELD])
return 0;
- if(item->equip & EQP_ARMOR && sd->sc.data[SC_STRIPARMOR])
+ if(item->equip & EQP_ARMOR && sd->sc.data[SC_NOEQUIPARMOR])
return 0;
- if(item->equip & EQP_HEAD_TOP && sd->sc.data[SC_STRIPHELM])
+ if(item->equip & EQP_HEAD_TOP && sd->sc.data[SC_NOEQUIPHELM])
return 0;
- if(item->equip & EQP_ACC && sd->sc.data[SC__STRIPACCESSORY])
+ if(item->equip & EQP_ACC && sd->sc.data[SC__STRIPACCESSARY])
return 0;
if(item->equip && sd->sc.data[SC_KYOUGAKU])
return 0;
- if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SUPERNOVICE) {
+ if (sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_SUPERNOVICE) {
//Spirit of Super Novice equip bonuses. [Skotlex]
if (sd->status.base_level > 90 && item->equip & EQP_HELM)
return 1; //Can equip all helms
@@ -1338,7 +1338,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
sd->status.skill[i].flag = SKILL_FLAG_PERMANENT;
}
- if( sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER && skill_db[i].nameid >= DC_HUMMING && skill_db[i].nameid <= DC_SERVICEFORYOU )
+ if( sd->sc.count && sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_BARDDANCER && skill_db[i].nameid >= DC_HUMMING && skill_db[i].nameid <= DC_SERVICEFORYOU )
{ //Enable Bard/Dancer spirit linked skills.
if( sd->status.sex )
{ //Link dancer skills to bard.
@@ -1427,7 +1427,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
if(!sd->status.skill[idx].lv && (
(inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
inf2&INF2_WEDDING_SKILL ||
- (inf2&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
+ (inf2&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SOULLINK])
))
continue; //Cannot be learned via normal means. Note this check DOES allows raising already known skills.
@@ -1459,7 +1459,7 @@ int pc_calc_skilltree(struct map_session_data *sd)
if( sd->status.skill[idx].id == 0 ) {
sd->status.skill[idx].id = id;
sd->status.skill[idx].flag = SKILL_FLAG_TEMPORARY; // So it is not saved, and tagged as a "bonus" skill.
- } else if( id != NV_BASIC) {
+ } else if( id != NV_BASIC ) {
sd->status.skill[idx].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[idx].lv; // Remember original level
}
@@ -1518,7 +1518,7 @@ static void pc_check_skilltree(struct map_session_data *sd, int skill_id)
if( !sd->status.skill[idx].lv && (
(j&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) ||
j&INF2_WEDDING_SKILL ||
- (j&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT])
+ (j&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SOULLINK])
) )
continue; //Cannot be learned via normal means.
@@ -1620,7 +1620,7 @@ int pc_calc_skilltree_normalize_job(struct map_session_data *sd)
*------------------------------------------
* 1: overweight 50%
* 2: overweight 90%
- * It's assumed that SC_WEIGHT50 and SC_WEIGHT90 are only started/stopped here.
+ * It's assumed that SC_WEIGHTOVER50 and SC_WEIGHTOVER90 are only started/stopped here.
*/
int pc_updateweightstatus(struct map_session_data *sd)
{
@@ -1629,7 +1629,7 @@ int pc_updateweightstatus(struct map_session_data *sd)
nullpo_retr(1, sd);
- old_overweight = (sd->sc.data[SC_WEIGHT90]) ? 2 : (sd->sc.data[SC_WEIGHT50]) ? 1 : 0;
+ old_overweight = (sd->sc.data[SC_WEIGHTOVER90]) ? 2 : (sd->sc.data[SC_WEIGHTOVER50]) ? 1 : 0;
new_overweight = (pc_is90overweight(sd)) ? 2 : (pc_is50overweight(sd)) ? 1 : 0;
if( old_overweight == new_overweight )
@@ -1637,15 +1637,15 @@ int pc_updateweightstatus(struct map_session_data *sd)
// stop old status change
if( old_overweight == 1 )
- status_change_end(&sd->bl, SC_WEIGHT50, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_WEIGHTOVER50, INVALID_TIMER);
else if( old_overweight == 2 )
- status_change_end(&sd->bl, SC_WEIGHT90, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_WEIGHTOVER90, INVALID_TIMER);
// start new status change
if( new_overweight == 1 )
- sc_start(&sd->bl, SC_WEIGHT50, 100, 0, 0);
+ sc_start(&sd->bl, SC_WEIGHTOVER50, 100, 0, 0);
else if( new_overweight == 2 )
- sc_start(&sd->bl, SC_WEIGHT90, 100, 0, 0);
+ sc_start(&sd->bl, SC_WEIGHTOVER90, 100, 0, 0);
// update overweight status
sd->regen.state.overweight = new_overweight;
@@ -2070,12 +2070,13 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
break;
case SP_BASE_ATK:
if(sd->state.lr_flag != 2) {
- //#ifdef RENEWAL
- // sd->bonus.eatk += val;
- //#else
+#ifdef RENEWAL
+ sd->bonus.eatk += val;
+ clif->updatestatus(sd,SP_ATK2);
+#else
bonus = status->batk + val;
status->batk = cap_value(bonus, 0, USHRT_MAX);
- //#endif
+#endif
}
break;
case SP_DEF1:
@@ -2431,7 +2432,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
case SP_INTRAVISION: // Maya Purple Card effect allowing to see Hiding/Cloaking people [DracoRPG]
if(sd->state.lr_flag != 2) {
sd->special_state.intravision = 1;
- clif->status_change(&sd->bl, SI_INTRAVISION, 1, 0, 0, 0, 0);
+ clif->status_change(&sd->bl, SI_CLAIRVOYANCE, 1, 0, 0, 0, 0);
}
break;
case SP_NO_KNOCKBACK:
@@ -4122,7 +4123,7 @@ int pc_isUseitem(struct map_session_data *sd,int n)
case 12212: // Giant Fly Wing
if( map[sd->bl.m].flag.noteleport || map_flag_gvg(sd->bl.m) )
{
- clif->skill_teleportmessage(sd,0);
+ clif->skill_mapinfomessage(sd,0);
return 0;
}
case 602: // ButterFly Wing
@@ -4150,7 +4151,7 @@ int pc_isUseitem(struct map_session_data *sd,int n)
break;
case 12210: // Bubble Gum
case 12264: // Comp Bubble Gum
- if( sd->sc.data[SC_ITEMBOOST] )
+ if( sd->sc.data[SC_CASH_RECEIVEITEM] )
return 0;
break;
case 12208: // Battle Manual
@@ -4160,11 +4161,11 @@ int pc_isUseitem(struct map_session_data *sd,int n)
case 14532: // Battle_Manual25
case 14533: // Battle_Manual100
case 14545: // Battle_Manual300
- if( sd->sc.data[SC_EXPBOOST] )
+ if( sd->sc.data[SC_CASH_PLUSEXP] )
return 0;
break;
case 14592: // JOB_Battle_Manual
- if( sd->sc.data[SC_JEXPBOOST] )
+ if( sd->sc.data[SC_CASH_PLUSONLYJOBEXP] )
return 0;
break;
@@ -4177,7 +4178,7 @@ int pc_isUseitem(struct map_session_data *sd,int n)
case 12243: // Mercenary's Berserk Potion
if( sd->md == NULL || sd->md->db == NULL )
return 0;
- if (sd->md->sc.data[SC_BERSERK] || sd->md->sc.data[SC_SATURDAYNIGHTFEVER] || sd->md->sc.data[SC__BLOODYLUST])
+ if (sd->md->sc.data[SC_BERSERK] || sd->md->sc.data[SC_SATURDAY_NIGHT_FEVER] || sd->md->sc.data[SC__BLOODYLUST])
return 0;
if( nameid == 12242 && sd->md->db->lv < 40 )
return 0;
@@ -4281,7 +4282,8 @@ int pc_useitem(struct map_session_data *sd,int n)
sd->sc.data[SC_HIDING] ||
sd->sc.data[SC__SHADOWFORM] ||
sd->sc.data[SC__MANHOLE] ||
- sd->sc.data[SC_KAGEHUMI] ||
+ sd->sc.data[SC_KG_KAGEHUMI] ||
+ sd->sc.data[SC_WHITEIMPRISON] ||
(sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOITEM)
))
return 0;
@@ -4315,16 +4317,7 @@ int pc_useitem(struct map_session_data *sd,int n)
if( sd->item_delay[i].nameid ) {// found
if( DIFF_TICK(sd->item_delay[i].tick, tick) > 0 ) {
int e_tick = DIFF_TICK(sd->item_delay[i].tick, tick)/1000;
- char e_msg[100];
- if( e_tick > 99 )
- sprintf(e_msg,"Item Failed. [%s] is cooling down. wait %.1f minutes.",
- itemdb_jname(sd->status.inventory[n].nameid),
- (double)e_tick / 60);
- else
- sprintf(e_msg,"Item Failed. [%s] is cooling down. wait %d seconds.",
- itemdb_jname(sd->status.inventory[n].nameid),
- e_tick+1);
- clif->colormes(sd->fd,COLOR_RED,e_msg);
+ clif->msgtable_num(sd->fd, 0x746, e_tick + 1); // [%d] seconds left until you can use
return 0; // Delay has not expired yet
}
} else {// not yet used item (all slots are initially empty)
@@ -4375,7 +4368,7 @@ int pc_useitem(struct map_session_data *sd,int n)
pc->famerank(MakeDWord(sd->status.inventory[n].card[2],sd->status.inventory[n].card[3]), MAPID_ALCHEMIST))
{
potion_flag = 2; // Famous player's potions have 50% more efficiency
- if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_ROGUE)
+ if (sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_ROGUE)
potion_flag = 3; //Even more effective potions.
}
@@ -4781,7 +4774,7 @@ int pc_setpos(struct map_session_data* sd, unsigned short mapindex, int x, int y
if (sd->sc.count) { // Cancel some map related stuff.
if (sd->sc.data[SC_JAILED])
return 1; //You may not get out!
- status_change_end(&sd->bl, SC_BOSSMAPINFO, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_CASH_BOSS_ALARM, INVALID_TIMER);
status_change_end(&sd->bl, SC_WARM, INVALID_TIMER);
status_change_end(&sd->bl, SC_SUN_COMFORT, INVALID_TIMER);
status_change_end(&sd->bl, SC_MOON_COMFORT, INVALID_TIMER);
@@ -4947,7 +4940,7 @@ int pc_memo(struct map_session_data* sd, int pos)
// check mapflags
if( sd->bl.m >= 0 && (map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) ) {
- clif->skill_teleportmessage(sd, 1); // "Saved point cannot be memorized."
+ clif->skill_mapinfomessage(sd, 1); // "Saved point cannot be memorized."
return 0;
}
@@ -5038,21 +5031,24 @@ int pc_checkallowskill(struct map_session_data *sd)
{
const enum sc_type scw_list[] = {
SC_TWOHANDQUICKEN,
- SC_ONEHAND,
+ SC_ONEHANDQUICKEN,
SC_AURABLADE,
SC_PARRYING,
SC_SPEARQUICKEN,
SC_ADRENALINE,
SC_ADRENALINE2,
SC_DANCING,
- SC_GATLINGFEVER,
+ SC_GS_GATLINGFEVER,
+#ifdef RENEWAL
+ SC_EDP,
+#endif
SC_FEARBREEZE
};
const enum sc_type scs_list[] = {
SC_AUTOGUARD,
SC_DEFENDER,
SC_REFLECTSHIELD,
- SC_REFLECTDAMAGE
+ SC_LG_REFLECTDAMAGE
};
int i;
nullpo_ret(sd);
@@ -5069,9 +5065,9 @@ int pc_checkallowskill(struct map_session_data *sd)
status_change_end(&sd->bl, scw_list[i], INVALID_TIMER);
}
- if(sd->sc.data[SC_SPURT] && sd->status.weapon)
+ if(sd->sc.data[SC_STRUP] && sd->status.weapon)
// Spurt requires bare hands (feet, in fact xD)
- status_change_end(&sd->bl, SC_SPURT, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_STRUP, INVALID_TIMER);
if(sd->status.shield <= 0) { // Skills requiring a shield
for (i = 0; i < ARRAYLENGTH(scs_list); i++)
@@ -5755,7 +5751,7 @@ int pc_checkjoblevelup(struct map_session_data *sd)
status_calc_pc(sd,0);
clif->misceffect(&sd->bl,1);
if (pc->checkskill(sd, SG_DEVIL) && !pc->nextjobexp(sd))
- clif->status_change(&sd->bl,SI_DEVIL, 1, 0, 0, 0, 1); //Permanent blind effect from SG_DEVIL.
+ clif->status_change(&sd->bl,SI_DEVIL1, 1, 0, 0, 0, 1); //Permanent blind effect from SG_DEVIL.
npc_script_event(sd, NPCE_JOBLVUP);
return 1;
@@ -5777,13 +5773,13 @@ static void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsi
(int)(status_get_lv(src) - sd->status.base_level) >= 20)
bonus += 15; // pk_mode additional exp if monster >20 levels [Valaris]
- if (sd->sc.data[SC_EXPBOOST])
- bonus += sd->sc.data[SC_EXPBOOST]->val1;
+ if (sd->sc.data[SC_CASH_PLUSEXP])
+ bonus += sd->sc.data[SC_CASH_PLUSEXP]->val1;
*base_exp = (unsigned int) cap_value(*base_exp + (double)*base_exp * bonus/100., 1, UINT_MAX);
- if (sd->sc.data[SC_JEXPBOOST])
- bonus += sd->sc.data[SC_JEXPBOOST]->val1;
+ if (sd->sc.data[SC_CASH_PLUSONLYJOBEXP])
+ bonus += sd->sc.data[SC_CASH_PLUSONLYJOBEXP]->val1;
*job_exp = (unsigned int) cap_value(*job_exp + (double)*job_exp * bonus/100., 1, UINT_MAX);
@@ -6134,6 +6130,19 @@ int pc_skillup(struct map_session_data *sd,uint16 skill_id) {
clif->updatestatus(sd,SP_CARTINFO);
if (!pc_has_permission(sd, PC_PERM_ALL_SKILL)) // may skill everything at any time anyways, and this would cause a huge slowdown
clif->skillinfoblock(sd);
+ }else if( battle_config.skillup_limit ){
+ int pts = 0, i, id;
+ for(i = 0; i < MAX_SKILL_TREE && (id=skill_tree[pc_class2idx(sd->status.class_)][i].id) > 0 ; i++){
+ int inf2 = skill->get_inf2(id);
+ if ( inf2&INF2_QUEST_SKILL || (inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) || id == NV_BASIC )
+ continue;
+ if( sd->status.skill[id].id && sd->status.skill[id].flag == SKILL_FLAG_PERMANENT )
+ pts += pc_checkskill(sd, id);
+ }
+ if( pts < sd->change_level_2nd )
+ clif->msg_value(sd, 0x61E, sd->change_level_2nd-pts);
+ else if( pts < (sd->change_level_3rd + sd->change_level_2nd) )
+ clif->msg_value(sd, 0x61F, sd->change_level_3rd - (pts - sd->change_level_2nd));
}
return 0;
@@ -6370,7 +6379,7 @@ int pc_resetskill(struct map_session_data* sd, int flag)
return 0;
if( pc->checkskill(sd, SG_DEVIL) && !pc->nextjobexp(sd) ) //Remove perma blindness due to skill-reset. [Skotlex]
- clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_DEVIL);
+ clif->sc_end(&sd->bl, sd->bl.id, SELF, SI_DEVIL1);
i = sd->sc.option;
if( i&OPTION_RIDING && (!pc->checkskill(sd, KN_RIDING) || (sd->class_&MAPID_THIRDMASK) == MAPID_RUNE_KNIGHT) )
i &= ~OPTION_RIDING;
@@ -6691,7 +6700,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
pc->delspiritball(sd,sd->spiritball,0);
for(i = 1; i < 5; i++)
- pc->del_talisman(sd, sd->talisman[i], i);
+ pc->del_charm(sd, sd->charm[i], i);
if (src) {
switch (src->type) {
@@ -6801,7 +6810,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
if(battle_config.death_penalty_type
&& (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE // only novices will receive no penalty
&& !map[sd->bl.m].flag.noexppenalty && !map_flag_gvg(sd->bl.m)
- && !sd->sc.data[SC_BABY] && !sd->sc.data[SC_LIFEINSURANCE])
+ && !sd->sc.data[SC_BABY] && !sd->sc.data[SC_CASH_DEATHPENALTY])
{
unsigned int base_penalty =0;
if (battle_config.death_penalty_base > 0) {
@@ -7304,8 +7313,8 @@ int pc_itemheal(struct map_session_data *sd,int itemid, int hp,int sp)
hp = hp * bonus / 100;
// Recovery Potion
- if( sd->sc.data[SC_INCHEALRATE] )
- hp += (int)(hp * sd->sc.data[SC_INCHEALRATE]->val1/100.);
+ if( sd->sc.data[SC_HEALPLUS] )
+ hp += (int)(hp * sd->sc.data[SC_HEALPLUS]->val1/100.);
}
if(sp) {
bonus = 100 + (sd->battle_status.int_<<1)
@@ -7529,7 +7538,7 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
//Remove peco/cart/falcon
i = sd->sc.option;
- if( i&OPTION_RIDING && !pc->checkskill(sd, KN_RIDING) )
+ if( i&OPTION_RIDING && (!pc->checkskill(sd, KN_RIDING) || (sd->class_&MAPID_THIRDMASK) == MAPID_RUNE_KNIGHT) )
i&=~OPTION_RIDING;
if( i&OPTION_FALCON && !pc->checkskill(sd, HT_FALCON) )
i&=~OPTION_FALCON;
@@ -7715,22 +7724,23 @@ int pc_setoption(struct map_session_data *sd,int type)
}
}
if( (sd->class_&MAPID_THIRDMASK) == MAPID_MECHANIC ) {
- if( type&OPTION_MADOGEAR && !(p_type&OPTION_MADOGEAR) ) {
+ int i;
+ if( type&OPTION_MADOGEAR && !(p_type&OPTION_MADOGEAR) )
status_calc_pc(sd, 0);
- status_change_end(&sd->bl,SC_MAXIMIZEPOWER,INVALID_TIMER);
- status_change_end(&sd->bl,SC_OVERTHRUST,INVALID_TIMER);
- status_change_end(&sd->bl,SC_WEAPONPERFECTION,INVALID_TIMER);
- status_change_end(&sd->bl,SC_ADRENALINE,INVALID_TIMER);
- status_change_end(&sd->bl,SC_CARTBOOST,INVALID_TIMER);
- status_change_end(&sd->bl,SC_MELTDOWN,INVALID_TIMER);
- status_change_end(&sd->bl,SC_MAXOVERTHRUST,INVALID_TIMER);
- } else if( !(type&OPTION_MADOGEAR) && p_type&OPTION_MADOGEAR ) {
+ else if( !(type&OPTION_MADOGEAR) && p_type&OPTION_MADOGEAR )
status_calc_pc(sd, 0);
- status_change_end(&sd->bl,SC_SHAPESHIFT,INVALID_TIMER);
- status_change_end(&sd->bl,SC_HOVERING,INVALID_TIMER);
- status_change_end(&sd->bl,SC_ACCELERATION,INVALID_TIMER);
- status_change_end(&sd->bl,SC_OVERHEAT_LIMITPOINT,INVALID_TIMER);
- status_change_end(&sd->bl,SC_OVERHEAT,INVALID_TIMER);
+ for( i = 0; i < SC_MAX; i++ ){
+ if ( !sd->sc.data[i] || !status_get_sc_type(i) )
+ continue;
+ if ( status_get_sc_type(i)&SC_MADO_NO_RESET )
+ continue;
+ switch (i) {
+ case SC_BERSERK:
+ case SC_SATURDAY_NIGHT_FEVER:
+ sd->sc.data[i]->val2 = 0;
+ break;
+ }
+ status_change_end(&sd->bl, (sc_type)i, INVALID_TIMER);
}
}
@@ -8503,7 +8513,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_SATURDAYNIGHTFEVER] || sd->sc.data[SC__BLOODYLUST])
+ if (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAY_NIGHT_FEVER] || sd->sc.data[SC__BLOODYLUST])
{
clif->equipitemack(sd,n,0,0); // fail
return 0;
@@ -8699,7 +8709,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_SATURDAYNIGHTFEVER] || sd->sc.data[SC__BLOODYLUST]))
+ if (!(flag & 2) && sd->sc.count && (sd->sc.data[SC_BERSERK] || sd->sc.data[SC_SATURDAY_NIGHT_FEVER] || sd->sc.data[SC__BLOODYLUST]))
{
clif->unequipitemack(sd,n,0,0);
return 0;
@@ -8780,7 +8790,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
clif->unequipitemack(sd,n,sd->status.inventory[n].equip,1);
if((sd->status.inventory[n].equip & EQP_ARMS) &&
- sd->weapontype1 == 0 && sd->weapontype2 == 0 && (!sd->sc.data[SC_SEVENWIND] || sd->sc.data[SC_ASPERSIO])) //Check for seven wind (but not level seven!)
+ sd->weapontype1 == 0 && sd->weapontype2 == 0 && (!sd->sc.data[SC_TK_SEVENWIND] || sd->sc.data[SC_ASPERSIO])) //Check for seven wind (but not level seven!)
skill->enchant_elemental_end(&sd->bl,-1);
if(sd->status.inventory[n].equip & EQP_ARMOR) {
@@ -8822,8 +8832,8 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
status_calc_pc(sd,0);
}
- if(sd->sc.data[SC_SIGNUMCRUCIS] && !battle->check_undead(sd->battle_status.race,sd->battle_status.def_ele))
- status_change_end(&sd->bl, SC_SIGNUMCRUCIS, INVALID_TIMER);
+ if(sd->sc.data[SC_CRUCIS] && !battle->check_undead(sd->battle_status.race,sd->battle_status.def_ele))
+ status_change_end(&sd->bl, SC_CRUCIS, INVALID_TIMER);
//OnUnEquip script [Skotlex]
if (sd->inventory_data[n]) {
@@ -9209,7 +9219,7 @@ int pc_autosave(int tid, unsigned int tick, int id, intptr_t data)
static int pc_daynight_timer_sub(struct map_session_data *sd,va_list ap)
{
if (sd->state.night != iMap->night_flag && map[sd->bl.m].flag.nightenabled) { //Night/day state does not match.
- clif->status_change(&sd->bl, SI_NIGHT, iMap->night_flag, 0, 0, 0, 0); //New night effect by dynamix [Skotlex]
+ clif->status_change(&sd->bl, SI_SKE, iMap->night_flag, 0, 0, 0, 0); //New night effect by dynamix [Skotlex]
sd->state.night = iMap->night_flag;
return 1;
}
@@ -9313,7 +9323,7 @@ bool pc_can_use_command(struct map_session_data *sd, const char *command) {
return atcommand->can_use(sd,command);
}
-static int pc_talisman_timer(int tid, unsigned int tick, int id, intptr_t data)
+static int pc_charm_timer(int tid, unsigned int tick, int id, intptr_t data)
{
struct map_session_data *sd;
int i, type;
@@ -9321,33 +9331,33 @@ static int pc_talisman_timer(int tid, unsigned int tick, int id, intptr_t data)
if( (sd=(struct map_session_data *)iMap->id2sd(id)) == NULL || sd->bl.type!=BL_PC )
return 1;
- ARR_FIND(1, 5, type, sd->talisman[type] > 0);
+ ARR_FIND(1, 5, type, sd->charm[type] > 0);
- if( sd->talisman[type] <= 0 )
+ if( sd->charm[type] <= 0 )
{
- ShowError("pc_talisman_timer: %d talisman's available. (aid=%d cid=%d tid=%d)\n", sd->talisman[type], sd->status.account_id, sd->status.char_id, tid);
- sd->talisman[type] = 0;
+ ShowError("pc_charm_timer: %d charm's available. (aid=%d cid=%d tid=%d)\n", sd->charm[type], sd->status.account_id, sd->status.char_id, tid);
+ sd->charm[type] = 0;
return 0;
}
- ARR_FIND(0, sd->talisman[type], i, sd->talisman_timer[type][i] == tid);
- if( i == sd->talisman[type] )
+ ARR_FIND(0, sd->charm[type], i, sd->charm_timer[type][i] == tid);
+ if( i == sd->charm[type] )
{
- ShowError("pc_talisman_timer: timer not found (aid=%d cid=%d tid=%d)\n", sd->status.account_id, sd->status.char_id, tid);
+ ShowError("pc_charm_timer: timer not found (aid=%d cid=%d tid=%d)\n", sd->status.account_id, sd->status.char_id, tid);
return 0;
}
- sd->talisman[type]--;
- if( i != sd->talisman[type] )
- memmove(sd->talisman_timer[type]+i, sd->talisman_timer[type]+i+1, (sd->talisman[type]-i)*sizeof(int));
- sd->talisman_timer[type][sd->talisman[type]] = INVALID_TIMER;
+ sd->charm[type]--;
+ if( i != sd->charm[type] )
+ memmove(sd->charm_timer[type]+i, sd->charm_timer[type]+i+1, (sd->charm[type]-i)*sizeof(int));
+ sd->charm_timer[type][sd->charm[type]] = INVALID_TIMER;
- clif->talisman(sd, type);
+ clif->charm(sd, type);
return 0;
}
-int pc_add_talisman(struct map_session_data *sd,int interval,int max,int type)
+int pc_add_charm(struct map_session_data *sd,int interval,int max,int type)
{
int tid, i;
@@ -9355,61 +9365,61 @@ int pc_add_talisman(struct map_session_data *sd,int interval,int max,int type)
if(max > 10)
max = 10;
- if(sd->talisman[type] < 0)
- sd->talisman[type] = 0;
+ if(sd->charm[type] < 0)
+ sd->charm[type] = 0;
- if( sd->talisman[type] && sd->talisman[type] >= max )
+ if( sd->charm[type] && sd->charm[type] >= max )
{
- if(sd->talisman_timer[type][0] != INVALID_TIMER)
- iTimer->delete_timer(sd->talisman_timer[type][0],pc_talisman_timer);
- sd->talisman[type]--;
- if( sd->talisman[type] != 0 )
- memmove(sd->talisman_timer[type]+0, sd->talisman_timer[type]+1, (sd->talisman[type])*sizeof(int));
- sd->talisman_timer[type][sd->talisman[type]] = INVALID_TIMER;
- }
-
- tid = iTimer->add_timer(iTimer->gettick()+interval, pc_talisman_timer, sd->bl.id, 0);
- ARR_FIND(0, sd->talisman[type], i, sd->talisman_timer[type][i] == INVALID_TIMER || DIFF_TICK(iTimer->get_timer(tid)->tick,iTimer->get_timer(sd->talisman_timer[type][i])->tick) < 0);
- if( i != sd->talisman[type] )
- memmove(sd->talisman_timer[type]+i+1, sd->talisman_timer[type]+i, (sd->talisman[type]-i)*sizeof(int));
- sd->talisman_timer[type][i] = tid;
- sd->talisman[type]++;
-
- clif->talisman(sd, type);
+ if(sd->charm_timer[type][0] != INVALID_TIMER)
+ iTimer->delete_timer(sd->charm_timer[type][0],pc_charm_timer);
+ sd->charm[type]--;
+ if( sd->charm[type] != 0 )
+ memmove(sd->charm_timer[type]+0, sd->charm_timer[type]+1, (sd->charm[type])*sizeof(int));
+ sd->charm_timer[type][sd->charm[type]] = INVALID_TIMER;
+ }
+
+ tid = iTimer->add_timer(iTimer->gettick()+interval, pc_charm_timer, sd->bl.id, 0);
+ ARR_FIND(0, sd->charm[type], i, sd->charm_timer[type][i] == INVALID_TIMER || DIFF_TICK(iTimer->get_timer(tid)->tick, iTimer->get_timer(sd->charm_timer[type][i])->tick) < 0);
+ if( i != sd->charm[type] )
+ memmove(sd->charm_timer[type]+i+1, sd->charm_timer[type]+i, (sd->charm[type]-i)*sizeof(int));
+ sd->charm_timer[type][i] = tid;
+ sd->charm[type]++;
+
+ clif->charm(sd, type);
return 0;
}
-int pc_del_talisman(struct map_session_data *sd,int count,int type)
+int pc_del_charm(struct map_session_data *sd,int count,int type)
{
int i;
nullpo_ret(sd);
- if( sd->talisman[type] <= 0 ) {
- sd->talisman[type] = 0;
+ if( sd->charm[type] <= 0 ) {
+ sd->charm[type] = 0;
return 0;
}
if( count <= 0 )
return 0;
- if( count > sd->talisman[type] )
- count = sd->talisman[type];
- sd->talisman[type] -= count;
+ if( count > sd->charm[type] )
+ count = sd->charm[type];
+ sd->charm[type] -= count;
if( count > 10 )
count = 10;
for(i = 0; i < count; i++) {
- if(sd->talisman_timer[type][i] != INVALID_TIMER) {
- iTimer->delete_timer(sd->talisman_timer[type][i],pc_talisman_timer);
- sd->talisman_timer[type][i] = INVALID_TIMER;
+ if(sd->charm_timer[type][i] != INVALID_TIMER) {
+ iTimer->delete_timer(sd->charm_timer[type][i],pc_charm_timer);
+ sd->charm_timer[type][i] = INVALID_TIMER;
}
}
for(i = count; i < 10; i++) {
- sd->talisman_timer[type][i-count] = sd->talisman_timer[type][i];
- sd->talisman_timer[type][i] = INVALID_TIMER;
+ sd->charm_timer[type][i-count] = sd->charm_timer[type][i];
+ sd->charm_timer[type][i] = INVALID_TIMER;
}
- clif->talisman(sd, type);
+ clif->charm(sd, type);
return 0;
}
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
@@ -9854,7 +9864,7 @@ int do_init_pc(void) {
iTimer->add_timer_func_list(pc_spiritball_timer, "pc_spiritball_timer");
iTimer->add_timer_func_list(pc_follow_timer, "pc_follow_timer");
iTimer->add_timer_func_list(pc->endautobonus, "pc->endautobonus");
- iTimer->add_timer_func_list(pc_talisman_timer, "pc_talisman_timer");
+ iTimer->add_timer_func_list(pc_charm_timer, "pc_charm_timer");
iTimer->add_timer(iTimer->gettick() + iMap->autosave_interval, pc_autosave, 0, 0);
@@ -10087,8 +10097,8 @@ void pc_defaults(void) {
pc->load_combo = pc_load_combo;
- pc->add_talisman = pc_add_talisman;
- pc->del_talisman = pc_del_talisman;
+ pc->add_charm = pc_add_charm;
+ pc->del_charm = pc_del_charm;
pc->baselevelchanged = pc_baselevelchanged;
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
diff --git a/src/map/pc.h b/src/map/pc.h
index ebf474823..cd2a45a6b 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -160,6 +160,8 @@ struct map_session_data {
unsigned int warping : 1;//states whether you're in the middle of a warp processing
unsigned int permanent_speed : 1; // When 1, speed cannot be changed through status_calc_pc().
unsigned int dialog : 1;
+ unsigned int prerefining : 1;
+ unsigned int workinprogress : 3; // 1 = disable skill/item, 2 = disable npc interaction, 3 = disable both
} state;
struct {
unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
@@ -190,7 +192,7 @@ struct map_session_data {
unsigned char head_dir; //0: Look forward. 1: Look right, 2: Look left.
unsigned int client_tick;
int npc_id,areanpc_id,npc_shopid,touching_id; //for script follow scriptoid; ,npcid
- int npc_item_flag; //Marks the npc_id with which you can use items during interactions with said npc (see script command enable_itemuse)
+ int npc_item_flag; //Marks the npc_id with which you can change equipments during interactions with said npc (see script command enable_itemuse)
int npc_menu; // internal variable, used in npc menu handling
int npc_amount;
struct script_state *st;
@@ -324,7 +326,7 @@ struct map_session_data {
int fixcastrate,varcastrate;
int add_fixcast,add_varcast;
int ematk; // matk bonus from equipment
-// int eatk; // atk bonus from equipment
+ int eatk; // atk bonus from equipment
} bonus;
// zeroed vars end here.
int castrate,delayrate,hprate,sprate,dsprate;
@@ -336,8 +338,8 @@ struct map_session_data {
short catch_target_class; // pet catching, stores a pet class to catch (short now) [zzo]
short spiritball, spiritball_old;
int spirit_timer[MAX_SPIRITBALL];
- short talisman[ELE_POISON+1]; // There are actually 5 talisman Fire, Ice, Wind, Earth & Poison maybe because its color violet.
- int talisman_timer[ELE_POISON+1][10];
+ short charm[ELE_POISON+1]; // There are actually 5 charm Fire, Ice, Wind, Earth & Poison maybe because its color violet.
+ int charm_timer[ELE_POISON+1][10];
unsigned char potion_success_counter; //Potion successes in row counter
unsigned char mission_count; //Stores the bounty kill count for TK_MISSION
short mission_mobid; //Stores the target mob_id for TK_MISSION
@@ -650,13 +652,13 @@ enum equip_pos {
// clientside display macros (values to the left/right of the "+")
#ifdef RENEWAL
#define pc_leftside_atk(sd) ((sd)->battle_status.batk)
- #define pc_rightside_atk(sd) ((sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk + (sd)->battle_status.rhw.atk2 + (sd)->battle_status.lhw.atk2)
+ #define pc_rightside_atk(sd) ((sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk + (sd)->battle_status.rhw.atk2 + (sd)->battle_status.lhw.atk2 + (sd)->bonus.eatk )
#define pc_leftside_def(sd) ((sd)->battle_status.def2)
#define pc_rightside_def(sd) ((sd)->battle_status.def)
#define pc_leftside_mdef(sd) ((sd)->battle_status.mdef2)
#define pc_rightside_mdef(sd) ((sd)->battle_status.mdef)
#define pc_leftside_matk(sd) (status_base_matk(status_get_status_data(&(sd)->bl), (sd)->status.base_level))
-#define pc_rightside_matk(sd) ((sd)->battle_status.rhw.matk+(sd)->bonus.ematk)
+#define pc_rightside_matk(sd) ((sd)->battle_status.rhw.matk+(sd)->battle_status.lhw.matk+(sd)->bonus.ematk)
#else
#define pc_leftside_atk(sd) ((sd)->battle_status.batk + (sd)->battle_status.rhw.atk + (sd)->battle_status.lhw.atk)
#define pc_rightside_atk(sd) ((sd)->battle_status.rhw.atk2 + (sd)->battle_status.lhw.atk2)
@@ -940,8 +942,8 @@ struct pc_interface {
int (*load_combo) (struct map_session_data *sd);
- int (*add_talisman) (struct map_session_data *sd,int interval,int max,int type);
- int (*del_talisman) (struct map_session_data *sd,int count,int type);
+ int (*add_charm) (struct map_session_data *sd,int interval,int max,int type);
+ int (*del_charm) (struct map_session_data *sd,int count,int type);
void (*baselevelchanged) (struct map_session_data *sd);
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
diff --git a/src/map/script.c b/src/map/script.c
index e1015a718..a01372385 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -9581,8 +9581,8 @@ BUILDIN(sc_end)
switch (type)
{
- case SC_WEIGHT50:
- case SC_WEIGHT90:
+ case SC_WEIGHTOVER50:
+ case SC_WEIGHTOVER90:
case SC_NOCHAT:
case SC_PUSH_CART:
return true;
diff --git a/src/map/skill.c b/src/map/skill.c
index 15c133dc1..dcc422da5 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -346,7 +346,6 @@ int skill_get_range2 (struct block_list *bl, uint16 skill_id, uint16 skill_lv) {
**/
case WL_WHITEIMPRISON:
case WL_SOULEXPANSION:
- case WL_FROSTMISTY:
case WL_MARSHOFABYSS:
case WL_SIENNAEXECRATE:
case WL_DRAINLIFE:
@@ -355,6 +354,7 @@ int skill_get_range2 (struct block_list *bl, uint16 skill_id, uint16 skill_lv) {
case WL_COMET:
case WL_CHAINLIGHTNING:
case WL_TETRAVORTEX:
+ case WL_EARTHSTRAIN:
case WL_RELEASE:
if( bl->type == BL_PC )
range += pc->checkskill((TBL_PC*)bl, WL_RADIUS);
@@ -385,13 +385,13 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
struct status_change* sc;
switch( skill_id ) {
- case BA_APPLEIDUN:
+ case BA_APPLEIDUN:
#ifdef RENEWAL
- hp = 100+5*skill_lv+5*(status_get_vit(src)/10); // HP recovery
+ hp = 100+5*skill_lv+5*(status_get_vit(src)/10); // HP recovery
#else
- hp = 30+5*skill_lv+5*(status_get_vit(src)/10); // HP recovery
+ hp = 30+5*skill_lv+5*(status_get_vit(src)/10); // HP recovery
#endif
- if( sd )
+ if( sd )
hp += 5*pc->checkskill(sd,BA_MUSICALLESSON);
break;
case PR_SANCTUARY:
@@ -406,7 +406,7 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
#ifdef RENEWAL
/**
* Renewal Heal Formula
- * Formula: ( [(Base Level + INT) / 5] � 30 ) � (Heal Level / 10) � (Modifiers) + MATK
+ * Formula: ( [(Base Level + INT) / 5] ? 30 ) ? (Heal Level / 10) ? (Modifiers) + MATK
**/
hp = (status_get_lv(src) + status_get_int(src)) / 5 * 30 * skill_lv / 10;
#else
@@ -434,10 +434,12 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
hp -= hp * sc->data[SC_CRITICALWOUND]->val2/100;
if( sc->data[SC_DEATHHURT] && heal )
hp -= hp * 20/100;
- if( sc->data[SC_INCHEALRATE] && skill_id != NPC_EVILLAND && skill_id != BA_APPLEIDUN )
- hp += hp * sc->data[SC_INCHEALRATE]->val1/100; // Only affects Heal, Sanctuary and PotionPitcher.(like bHealPower) [Inkfish]
+ if( sc->data[SC_HEALPLUS] && skill_id != NPC_EVILLAND && skill_id != BA_APPLEIDUN )
+ 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;
}
#ifdef RENEWAL
@@ -447,32 +449,7 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
case BA_APPLEIDUN: case PR_SANCTUARY:
case NPC_EVILLAND: break;
default:
- {
- struct status_data *status = status_get_status_data(src);
- int min, max;
-
- min = max = status_base_matk(status, status_get_lv(src));
- if( status->rhw.matk > 0 ){
- int wMatk, variance;
- wMatk = status->rhw.matk;
- variance = wMatk * status->rhw.wlv / 10;
- min += wMatk - variance;
- max += wMatk + variance;
- }
-
- if( sc && sc->data[SC_RECOGNIZEDSPELL] )
- min = max;
-
- if( sd && sd->right_weapon.overrefine > 0 ){
- min++;
- max += sd->right_weapon.overrefine - 1;
- }
-
- if(max > min)
- hp += min+rnd()%(max-min);
- else
- hp += min;
- }
+ hp += status_get_matk(src, 3);
}
#endif
return hp;
@@ -557,7 +534,7 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd)
case RETURN_TO_ELDICASTES:
case ALL_GUARDIAN_RECALL:
if(map[m].flag.nowarp) {
- clif->skill_teleportmessage(sd,0);
+ clif->skill_mapinfomessage(sd,0);
return 1;
}
return 0;
@@ -565,7 +542,7 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd)
case SC_FATALMENACE:
case SC_DIMENSIONDOOR:
if(map[m].flag.noteleport) {
- clif->skill_teleportmessage(sd,0);
+ clif->skill_mapinfomessage(sd,0);
return 1;
}
return 0; // gonna be checked in 'skill->castend_nodamage_id'
@@ -573,7 +550,7 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd)
case WE_CALLPARENT:
case WE_CALLBABY:
if (map[m].flag.nomemo) {
- clif->skill_teleportmessage(sd,1);
+ clif->skill_mapinfomessage(sd,1);
return 1;
}
break;
@@ -625,7 +602,7 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd)
* These skills cannot be used while in mado gear (credits to Xantara)
**/
if( pc_ismadogear(sd) ) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_MADOGEAR_RIDE,0);
return 1;
}
break;
@@ -636,7 +613,7 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd)
case WM_LULLABY_DEEPSLEEP:
case WM_SATURDAY_NIGHT_FEVER:
if( !map_flag_vs(m) ) {
- clif->skill_teleportmessage(sd,2); // This skill uses this msg instead of skill fails.
+ clif->skill_mapinfomessage(sd,2); // This skill uses this msg instead of skill fails.
return 1;
}
break;
@@ -815,12 +792,12 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
if(sd) {
// Automatic trigger of Blitz Beat
if (pc_isfalcon(sd) && sd->status.weapon == W_BOW && (temp=pc->checkskill(sd,HT_BLITZBEAT))>0 &&
- rnd()%1000 <= sstatus->luk*10/3+1 ) {
- rate=(sd->status.job_level+9)/10;
+ rnd()%1000 <= sstatus->luk*3 ) {
+ rate = sd->status.job_level / 10 + 1;
skill->castend_damage_id(src,bl,HT_BLITZBEAT,(temp<rate)?temp:rate,tick,SD_LEVEL);
}
// Automatic trigger of Warg Strike [Jobbie]
- if( pc_iswug(sd) && (sd->status.weapon == W_BOW || sd->status.weapon == W_FIST) && (temp=pc->checkskill(sd,RA_WUGSTRIKE)) > 0 && rnd()%1000 <= sstatus->luk*10/3+1 )
+ if( pc_iswug(sd) && (temp=pc->checkskill(sd,RA_WUGSTRIKE)) > 0 && rnd()%1000 <= sstatus->luk*3 )
skill->castend_damage_id(src,bl,RA_WUGSTRIKE,temp,tick,0);
// Gank
if(dstmd && sd->status.weapon != W_BOW &&
@@ -832,26 +809,26 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
clif->skill_fail(sd,RG_SNATCHER,USESKILL_FAIL_LEVEL,0);
}
// Chance to trigger Taekwon kicks [Dralnu]
- if(sc && !sc->data[SC_COMBO]) {
- if(sc->data[SC_READYSTORM] &&
- sc_start(src,SC_COMBO, 15, TK_STORMKICK,
+ if(sc && !sc->data[SC_COMBOATTACK]) {
+ if(sc->data[SC_STORMKICK_READY] &&
+ sc_start(src,SC_COMBOATTACK, 15, TK_STORMKICK,
(2000 - 4*sstatus->agi - 2*sstatus->dex)))
; //Stance triggered
- else if(sc->data[SC_READYDOWN] &&
- sc_start(src,SC_COMBO, 15, TK_DOWNKICK,
+ else if(sc->data[SC_DOWNKICK_READY] &&
+ sc_start(src,SC_COMBOATTACK, 15, TK_DOWNKICK,
(2000 - 4*sstatus->agi - 2*sstatus->dex)))
; //Stance triggered
- else if(sc->data[SC_READYTURN] &&
- sc_start(src,SC_COMBO, 15, TK_TURNKICK,
+ else if(sc->data[SC_TURNKICK_READY] &&
+ sc_start(src,SC_COMBOATTACK, 15, TK_TURNKICK,
(2000 - 4*sstatus->agi - 2*sstatus->dex)))
; //Stance triggered
- else if (sc->data[SC_READYCOUNTER]) { //additional chance from SG_FRIEND [Komurka]
+ else if (sc->data[SC_COUNTERKICK_READY]) { //additional chance from SG_FRIEND [Komurka]
rate = 20;
if (sc->data[SC_SKILLRATE_UP] && sc->data[SC_SKILLRATE_UP]->val1 == TK_COUNTER) {
rate += rate*sc->data[SC_SKILLRATE_UP]->val2/100;
status_change_end(src, SC_SKILLRATE_UP, INVALID_TIMER);
}
- sc_start2(src, SC_COMBO, rate, TK_COUNTER, bl->id,
+ sc_start2(src, SC_COMBOATTACK, rate, TK_COUNTER, bl->id,
(2000 - 4*sstatus->agi - 2*sstatus->dex));
}
}
@@ -862,7 +839,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
if (sc) {
struct status_change_entry *sce;
// Enchant Poison gives a chance to poison attacked enemies
- if((sce=sc->data[SC_ENCPOISON])) //Don't use sc_start since chance comes in 1/10000 rate.
+ 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,
skill->get_time2(AS_ENCHANTPOISON,sce->val1),0);
// Enchant Deadly Poison gives a chance to deadly poison attacked enemies
@@ -871,7 +848,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
skill->get_time2(ASC_EDP,sce->val1));
}
}
- break;
+ break;
case SM_BASH:
if( sd && skill_lv > 5 && pc->checkskill(sd,SM_FATALBLOW)>0 ){
@@ -990,7 +967,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
break;
case AM_ACIDTERROR:
- sc_start2(bl,SC_BLEEDING,(skill_lv*3),skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
+ sc_start2(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;
@@ -1062,14 +1039,12 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
sc_start(bl,status_skill2sc(skill_id),70,skill_lv,skill->get_time2(skill_id,skill_lv));
break;
case NPC_BLEEDING:
- sc_start2(bl,SC_BLEEDING,(20*skill_lv),skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
+ sc_start2(bl,SC_BLOODING,(20*skill_lv),skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
break;
case NPC_MENTALBREAKER:
{ //Based on observations by Tharis, Mental Breaker should do SP damage
- //equal to Matk*skLevel.
- rate = sstatus->matk_min;
- if (rate < sstatus->matk_max)
- rate += rnd()%(sstatus->matk_max - sstatus->matk_min);
+ //equal to Matk*skLevel.
+ rate = status_get_matk(src, 2);
rate*=skill_lv;
status_zap(bl, 0, rate);
break;
@@ -1108,7 +1083,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
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_BLEEDING,50, skill_lv, src->id, skill->get_time2(skill_id,skill_lv));
+ sc_start2(bl, SC_BLOODING,50, skill_lv, src->id, skill->get_time2(skill_id,skill_lv));
break;
case LK_JOINTBEAT:
@@ -1128,8 +1103,8 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
sc_start(bl,SC_STUN,(5+skill_lv*5),skill_lv,skill->get_time2(skill_id,2));
break;
default:
- sc_start2(bl,SC_BLEEDING,(5+skill_lv*5),skill_lv,src->id,skill->get_time2(skill_id,3));
- }
+ sc_start2(bl,SC_BLOODING,(5+skill_lv*5),skill_lv,src->id,skill->get_time2(skill_id,3));
+ }
break;
case HW_NAPALMVULCAN:
@@ -1151,12 +1126,12 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
case TK_JUMPKICK:
if( dstsd && dstsd->class_ != MAPID_SOUL_LINKER && !tsc->data[SC_PRESERVE] )
{// debuff the following statuses
- status_change_end(bl, SC_SPIRIT, INVALID_TIMER);
+ status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
status_change_end(bl, SC_KAITE, INVALID_TIMER);
status_change_end(bl, SC_KAAHI, INVALID_TIMER);
- status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
+ status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
}
break;
case TK_TURNKICK:
@@ -1169,7 +1144,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
status_change_start(bl,SC_COMA,10,skill_lv,0,src->id,0,0,0);
break;
case GS_PIERCINGSHOT:
- sc_start2(bl,SC_BLEEDING,(skill_lv*3),skill_lv,src->id,skill->get_time2(skill_id,skill_lv));
+ sc_start2(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));
@@ -1204,34 +1179,37 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
sc_start(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,1000,src->id,0,skill->get_time(skill_id,skill_lv));
+ sc_start4(bl,SC_BURNING,5+5*skill_lv,skill_lv,0,src->id,0,skill->get_time(skill_id,skill_lv));
+ break;
+ case RK_DRAGONBREATH_WATER:
+ sc_start4(bl,SC_FROSTMISTY,5+5*skill_lv,skill_lv,0,src->id,0,skill->get_time(skill_id,skill_lv));
break;
case AB_ADORAMUS:
- if( tsc && !tsc->data[SC_DECREASEAGI] ) //Prevent duplicate agi-down effect.
+ 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));
break;
case WL_CRIMSONROCK:
sc_start(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,1000,src->id,0,skill->get_time(skill_id,skill_lv));
+ sc_start4(bl,SC_BURNING,100,skill_lv,0,src->id,0,skill->get_time2(skill_id,skill_lv));
break;
case WL_EARTHSTRAIN:
{
- int rate = 0, i;
- const int pos[5] = { EQP_WEAPON, EQP_HELM, EQP_SHIELD, EQP_ARMOR, EQP_ACC };
- rate = 6 * skill_lv + sstatus->dex / 10 + (sd? sd->status.job_level / 4 : 0) - tstatus->dex /5;// The tstatus->dex / 5 part is unofficial, but players gotta have some kind of way to have resistance. [Rytech]
- //rate -= rate * tstatus->dex / 200; // Disabled until official resistance is found.
-
- for( i = 0; i < skill_lv; i++ )
- skill->strip_equip(bl,pos[i],rate,skill_lv,skill->get_time2(skill_id,skill_lv));
+ // lv 1 & 2 = Strip Helm, lv 3 = Strip Armor, lv 4 = Strip Weapon and lv 5 = Strip Accessory. [malufett]
+ const int pos[5] = { EQP_HELM, EQP_HELM, EQP_ARMOR, EQP_WEAPON, EQP_ACC };
+ skill->strip_equip(bl, pos[skill_lv], 6 * skill_lv + status_get_lv(src) / 4 + status_get_dex(src) / 10,
+ skill_lv, skill->get_time2(skill_id,skill_lv));
}
break;
case WL_JACKFROST:
sc_start(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));
+ break;
case RA_WUGBITE:
- sc_start(bl, SC_BITE, (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)) );
+ 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)) );
break;
case RA_SENSITIVEKEEN:
if( rnd()%100 < 8 * skill_lv )
@@ -1239,7 +1217,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
break;
case RA_FIRINGTRAP:
case RA_ICEBOUNDTRAP:
- sc_start(bl, (skill_id == RA_FIRINGTRAP) ? SC_BURNING:SC_FREEZING, 40 + 10 * skill_lv, skill_lv, skill->get_time2(skill_id, skill_lv));
+ 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));
break;
case NC_PILEBUNKER:
if( rnd()%100 < 5 + 15*skill_lv )
@@ -1252,20 +1230,27 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
}
break;
case NC_FLAMELAUNCHER:
- sc_start4(bl, SC_BURNING, 50 + 10 * skill_lv, skill_lv, 1000, src->id, 0, skill->get_time2(skill_id, skill_lv));
+ sc_start4(bl, SC_BURNING, 50 + 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_FREEZING, 20 + 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));
break;
case NC_POWERSWING:
sc_start(bl, SC_STUN, 5*skill_lv, skill_lv, skill->get_time(skill_id, skill_lv));
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));
+ 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));
+ break;
case LG_SHIELDPRESS:
sc_start(bl, SC_STUN, 30 + 8 * skill_lv, skill_lv, skill->get_time(skill_id,skill_lv));
break;
@@ -1273,7 +1258,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
rate = 30 + (((5 * (sd?pc->checkskill(sd,LG_PINPOINTATTACK):skill_lv)) + (sstatus->agi + status_get_lv(src))) / 10);
switch( skill_lv ) {
case 1:
- sc_start2(bl,SC_BLEEDING,rate,skill_lv,src->id,skill->get_time(skill_id,skill_lv));
+ sc_start2(bl,SC_BLOODING,rate,skill_lv,src->id,skill->get_time(skill_id,skill_lv));
break;
case 2:
if( dstsd && dstsd->spiritball && rnd()%100 < rate )
@@ -1335,25 +1320,25 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
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_SERVICE4U, INVALID_TIMER);
+ status_change_end(bl, SC_SERVICEFORYOU, INVALID_TIMER);
status_change_end(bl, SC_LONGING, INVALID_TIMER);
- status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
- status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
- status_change_end(bl, SC_MOONLITSERENADE, INVALID_TIMER);
- status_change_end(bl, SC_RUSHWINDMILL, 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_WINKCHARM, INVALID_TIMER);
- status_change_end(bl, SC_SONGOFMANA, INVALID_TIMER);
- status_change_end(bl, SC_DANCEWITHWUG, INVALID_TIMER);
- status_change_end(bl, SC_LERADSDEW, 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_BEYONDOFWARCRY, INVALID_TIMER);
- status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, 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_EARTHGRAVE:
- sc_start2(bl, SC_BLEEDING, 5 * skill_lv, skill_lv, src->id, skill->get_time2(skill_id, skill_lv)); // Need official rate. [LimitLine]
+ sc_start2(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;
@@ -1369,14 +1354,14 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
switch( sd->itemid ) { // Starting SCs here instead of do it in skill->additional_effect to simplify the code.
case 13261:
sc_start(bl, SC_STUN, 100, skill_lv, skill->get_time2(GN_SLINGITEM, skill_lv));
- sc_start2(bl, SC_BLEEDING, 100, skill_lv, src->id, skill->get_time2(GN_SLINGITEM, skill_lv));
+ sc_start2(bl, SC_BLOODING, 100, skill_lv, src->id, skill->get_time2(GN_SLINGITEM, skill_lv));
break;
case 13262:
sc_start(bl, SC_MELON_BOMB, 100, skill_lv, skill->get_time(GN_SLINGITEM, skill_lv)); // Reduces ASPD and moviment speed
break;
case 13264:
sc_start(bl, SC_BANANA_BOMB, 100, skill_lv, skill->get_time(GN_SLINGITEM, skill_lv)); // Reduces LUK ??Needed confirm it, may be it's bugged in kRORE?
- sc_start(bl, SC_BANANA_BOMB_SITDOWN, 75, skill_lv, skill->get_time(GN_SLINGITEM_RANGEMELEEATK,skill_lv)); // Sitdown for 3 seconds.
+ sc_start(bl, SC_BANANA_BOMB_SITDOWN_POSTDELAY, 75, skill_lv, skill->get_time(GN_SLINGITEM_RANGEMELEEATK,skill_lv)); // Sitdown for 3 seconds.
break;
}
sd->itemid = -1;
@@ -1384,10 +1369,10 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
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_BLEEDING, 20 + 10 * skill_lv, skill_lv, src->id,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));
break;
case EL_WIND_SLASH: // Non confirmed rate.
- sc_start2(bl, SC_BLEEDING, 25, skill_lv, src->id, skill->get_time(skill_id,skill_lv));
+ sc_start2(bl, SC_BLOODING, 25, skill_lv, src->id, skill->get_time(skill_id,skill_lv));
break;
case EL_STONE_HAMMER:
rate = 10 * skill_lv;
@@ -1400,20 +1385,20 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
case EL_TYPOON_MIS:
sc_start(bl,SC_SILENCE,10*skill_lv,skill_lv,skill->get_time(skill_id,skill_lv));
break;
- case KO_JYUMONJIKIRI: // needs more info
- sc_start(bl,SC_JYUMONJIKIRI,25,skill_lv,skill->get_time(skill_id,skill_lv));
+ case KO_JYUMONJIKIRI:
+ sc_start(bl,SC_KO_JYUMONJIKIRI,90,skill_lv,skill->get_time(skill_id,skill_lv));
break;
case KO_MAKIBISHI:
- sc_start(bl, SC_STUN, 100, skill_lv, skill->get_time2(skill_id,skill_lv));
+ sc_start(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, 1000, src->id, 0, skill->get_time(skill_id, skill_lv));
+ 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));
break;
case MH_STAHL_HORN:
sc_start(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_PARALYSIS, 40 + (5*skill_lv), skill_lv, skill->get_time(skill_id, skill_lv));
+ sc_start(bl, SC_NEEDLE_OF_PARALYZE, 40 + (5*skill_lv), skill_lv, skill->get_time(skill_id, skill_lv));
break;
}
@@ -1442,7 +1427,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
rate += 10;
if(sc->data[SC_OVERTHRUST])
rate += 10;
- if(sc->data[SC_MAXOVERTHRUST])
+ if(sc->data[SC_OVERTHRUSTMAX])
rate += 10;
}
if( rate )
@@ -1492,7 +1477,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
if (DIFF_TICK(ud->canact_tick, tick + rate) < 0){
ud->canact_tick = tick+rate;
if ( battle_config.display_status_timers )
- clif->status_change(src, SI_ACTIONDELAY, 1, rate, 0, 0, 0);
+ clif->status_change(src, SI_POSTDELAY, 1, rate, 0, 0, 0);
}
}
}
@@ -1589,7 +1574,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, uint
if (DIFF_TICK(ud->canact_tick, tick + rate) < 0){
ud->canact_tick = tick+rate;
if ( battle_config.display_status_timers && sd )
- clif->status_change(src, SI_ACTIONDELAY, 1, rate, 0, 0, 0);
+ clif->status_change(src, SI_POSTDELAY, 1, rate, 0, 0, 0);
}
}
}
@@ -1828,10 +1813,10 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
if( skill_id == WZ_WATERBALL ) {//(bugreport:5303)
struct status_change *sc = NULL;
if( ( sc = status_get_sc(src) ) ) {
- if(sc->data[SC_SPIRIT] &&
- sc->data[SC_SPIRIT]->val2 == SL_WIZARD &&
- sc->data[SC_SPIRIT]->val3 == WZ_WATERBALL)
- sc->data[SC_SPIRIT]->val3 = 0; //Clear bounced spell check.
+ if(sc->data[SC_SOULLINK] &&
+ sc->data[SC_SOULLINK]->val2 == SL_WIZARD &&
+ sc->data[SC_SOULLINK]->val3 == WZ_WATERBALL)
+ sc->data[SC_SOULLINK]->val3 = 0; //Clear bounced spell check.
}
}
}
@@ -1925,7 +1910,7 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
if (DIFF_TICK(ud->canact_tick, tick + rate) < 0){
ud->canact_tick = tick+rate;
if ( battle_config.display_status_timers && dstsd )
- clif->status_change(bl, SI_ACTIONDELAY, 1, rate, 0, 0, 0);
+ clif->status_change(bl, SI_POSTDELAY, 1, rate, 0, 0, 0);
}
}
}
@@ -1957,8 +1942,8 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
--------------------------------------------------------------------------*/
int skill_break_equip (struct block_list *bl, unsigned short where, int rate, int flag) {
const int where_list[4] = {EQP_WEAPON, EQP_ARMOR, EQP_SHIELD, EQP_HELM};
- const enum sc_type scatk[4] = {SC_STRIPWEAPON, SC_STRIPARMOR, SC_STRIPSHIELD, SC_STRIPHELM};
- const enum sc_type scdef[4] = {SC_CP_WEAPON, SC_CP_ARMOR, SC_CP_SHIELD, SC_CP_HELM};
+ const enum sc_type scatk[4] = {SC_NOEQUIPWEAPON, SC_NOEQUIPARMOR, SC_NOEQUIPSHIELD, SC_NOEQUIPHELM};
+ const enum sc_type scdef[4] = {SC_PROTECTWEAPON, SC_PROTECTARMOR, SC_PROTECTSHIELD, SC_PROTECTHELM};
struct status_change *sc = status_get_sc(bl);
int i,j;
TBL_PC *sd;
@@ -2048,8 +2033,8 @@ int skill_break_equip (struct block_list *bl, unsigned short where, int rate, in
int skill_strip_equip(struct block_list *bl, unsigned short where, int rate, int lv, int time) {
struct status_change *sc;
const int pos[5] = {EQP_WEAPON, EQP_SHIELD, EQP_ARMOR, EQP_HELM, EQP_ACC};
- const enum sc_type sc_atk[5] = {SC_STRIPWEAPON, SC_STRIPSHIELD, SC_STRIPARMOR, SC_STRIPHELM, SC__STRIPACCESSORY};
- const enum sc_type sc_def[5] = {SC_CP_WEAPON, SC_CP_SHIELD, SC_CP_ARMOR, SC_CP_HELM, 0};
+ const enum sc_type sc_atk[5] = {SC_NOEQUIPWEAPON, SC_NOEQUIPSHIELD, SC_NOEQUIPARMOR, SC_NOEQUIPHELM, SC__STRIPACCESSARY};
+ const enum sc_type sc_def[5] = {SC_PROTECTWEAPON, SC_PROTECTSHIELD, SC_PROTECTARMOR, SC_PROTECTHELM, 0};
int i;
if (rnd()%100 >= rate)
@@ -2182,7 +2167,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
struct status_data *sstatus, *tstatus;
struct status_change *sc;
struct map_session_data *sd, *tsd;
- int type,damage,rdamage=0;
+ int type,damage;
int8 rmdamage=0;//magic reflected
bool additional_effects = true;
@@ -2253,15 +2238,15 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
flag |= 2;
//Spirit of Wizard blocks Kaite's reflection
- if( type == 2 && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD )
+ if( type == 2 && sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_WIZARD )
{ //Consume one Fragment per hit of the casted skill? [Skotlex]
type = tsd?pc->search_inventory (tsd, 7321):0;
if (type >= 0) {
if ( tsd ) pc->delitem(tsd, type, 1, 0, 1, LOG_TYPE_CONSUME);
dmg.damage = dmg.damage2 = 0;
dmg.dmg_lv = ATK_MISS;
- sc->data[SC_SPIRIT]->val3 = skill_id;
- sc->data[SC_SPIRIT]->val4 = dsrc->id;
+ sc->data[SC_SOULLINK]->val3 = skill_id;
+ sc->data[SC_SOULLINK]->val4 = dsrc->id;
}
} else if( type != 2 ) /* Kaite bypasses */
additional_effects = false;
@@ -2311,19 +2296,15 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
if( (skill_id == AL_INCAGI || skill_id == AL_BLESSING ||
skill_id == CASH_BLESSING || skill_id == CASH_INCAGI ||
- skill_id == MER_INCAGI || skill_id == MER_BLESSING) && tsd->sc.data[SC_CHANGEUNDEAD] )
+ skill_id == MER_INCAGI || skill_id == MER_BLESSING) && tsd->sc.data[SC_PROPERTYUNDEAD] )
damage = 1;
- if( damage > 0 && (( dmg.flag&BF_WEAPON && src != bl && ( src == dsrc || ( dsrc->type == BL_SKILL && ( skill_id == SG_SUN_WARM || skill_id == SG_MOON_WARM || skill_id == SG_STAR_WARM ) ) ))
- || (sc && sc->data[SC_REFLECTDAMAGE])) )
- rdamage = battle->calc_return_damage(bl,src, &damage, dmg.flag, skill_id);
-
if( damage && sc && sc->data[SC_GENSOU] && dmg.flag&BF_MAGIC ){
struct block_list *nbl;
nbl = battle->get_enemy_area(bl,bl->x,bl->y,2,BL_CHAR,bl->id);
if( nbl ){ // Only one target is chosen.
- damage = damage / 2; // Deflect half of the damage to a target nearby
- clif->skill_damage(bl, nbl, tick, status_get_amotion(src), 0, status_fix_damage(bl,nbl,damage,0), dmg.div_, OB_OBOROGENSOU_TRANSITION_ATK, -1, 6);
+ int temp = (int)(damage / (float)(10 / skill_lv));
+ clif->skill_damage(bl, nbl, tick, status_get_amotion(src), 0, status_fix_damage(bl,nbl,temp,0), 1, OB_OBOROGENSOU_TRANSITION_ATK, -1, 6);
}
}
@@ -2348,7 +2329,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
if(sd) {
int flag = 0; //Used to signal if this skill can be combo'ed later on.
struct status_change_entry *sce;
- if ((sce = sd->sc.data[SC_COMBO])) {//End combo state after skill is invoked. [Skotlex]
+ if ((sce = sd->sc.data[SC_COMBOATTACK])) {//End combo state after skill is invoked. [Skotlex]
switch (skill_id) {
case TK_TURNKICK:
case TK_STORMKICK:
@@ -2359,14 +2340,14 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
sce->val3 = skill_id;
if( sce->timer != INVALID_TIMER )
iTimer->delete_timer(sce->timer, status_change_timer);
- sce->timer = iTimer->add_timer(tick+sce->val4, status_change_timer, src->id, SC_COMBO);
+ sce->timer = iTimer->add_timer(tick+sce->val4, status_change_timer, src->id, SC_COMBOATTACK);
break;
}
unit_cancel_combo(src); // Cancel combo wait
break;
default:
if( src == dsrc ) // Ground skills are exceptions. [Inkfish]
- status_change_end(src, SC_COMBO, INVALID_TIMER);
+ status_change_end(src, SC_COMBOATTACK, INVALID_TIMER);
}
}
switch(skill_id) {
@@ -2394,7 +2375,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
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_COMBO,100,HT_POWER,bl->id,2000);
+ sc_start2(src,SC_COMBOATTACK,100,HT_POWER,bl->id,2000);
clif->combo_delay(src,2000);
}
break;
@@ -2407,8 +2388,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
break;
case SL_STIN:
case SL_STUN:
- if (skill_lv >= 7 && !sd->sc.data[SC_SMA])
- sc_start(src,SC_SMA,100,skill_lv,skill->get_time(SL_SMA, skill_lv));
+ 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));
break;
case GS_FULLBUSTER:
//Can't attack nor use items until skill's delay expires. [Skotlex]
@@ -2425,7 +2406,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
} //Switch End
if (flag) { //Possible to chain
if ( (flag = DIFF_TICK(sd->ud.canact_tick, tick)) < 50 ) flag = 50;/* less is a waste. */
- sc_start2(src,SC_COMBO,100,skill_id,bl->id,flag);
+ sc_start2(src,SC_COMBOATTACK,100,skill_id,bl->id,flag);
clif->combo_delay(src, flag);
}
}
@@ -2459,9 +2440,11 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
case SR_EARTHSHAKER:
dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skill_id,-2,6);
break;
+ case KO_MUCHANAGE:
+ if( dmg.dmg_lv == ATK_FLEE )
+ break;
case WL_SOULEXPANSION:
case WL_COMET:
- case KO_MUCHANAGE:
case NJ_HUUMA:
dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,skill_lv,8);
break;
@@ -2488,6 +2471,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
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:
@@ -2503,6 +2487,12 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
case WM_REVERBERATION_MAGIC:
dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,WM_REVERBERATION,-2,6);
break;
+ case WL_TETRAVORTEX_FIRE:
+ case WL_TETRAVORTEX_WATER:
+ case WL_TETRAVORTEX_WIND:
+ case WL_TETRAVORTEX_GROUND:
+ dmg.dmotion = clif->skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_, WL_TETRAVORTEX,-1,5);
+ break;
case HT_CLAYMORETRAP:
case HT_BLASTMINE:
case HT_FLASHER:
@@ -2518,7 +2508,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
break;
case WZ_SIGHTBLASTER:
dmg.dmotion = clif->skill_damage(src,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, flag&SD_LEVEL?-1:skill_lv, 5);
- break;
+ break;
case AB_DUPLELIGHT_MELEE:
case AB_DUPLELIGHT_MAGIC:
dmg.amotion = 300;/* makes the damage value not overlap with previous damage (when displayed by the client) */
@@ -2643,8 +2633,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
skill->counter_additional_effect(src,bl,skill_id,skill_lv,dmg.flag,tick);
}
// Hell Inferno burning status only starts if Fire part hits.
- if( skill_id == WL_HELLINFERNO && dmg.damage > 0 )
- sc_start4(bl,SC_BURNING,55+5*skill_lv,skill_lv,1000,src->id,0,skill->get_time(skill_id,skill_lv));
+ 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));
// Apply knock back chance in SC_TRIANGLESHOT skill.
else if( skill_id == SC_TRIANGLESHOT && rnd()%100 > (1 + skill_lv) )
dmg.blewcount = 0;
@@ -2753,7 +2743,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
dmg.flag |= BF_WEAPON;
if( sd && src != bl && damage > 0 && ( dmg.flag&BF_WEAPON ||
- (dmg.flag&BF_MISC && (skill_id == RA_CLUSTERBOMB || skill_id == RA_FIRINGTRAP || skill_id == RA_ICEBOUNDTRAP || skill_id == RK_DRAGONBREATH)) ) )
+ (dmg.flag&BF_MISC && (skill_id == RA_CLUSTERBOMB || skill_id == RA_FIRINGTRAP || skill_id == RA_ICEBOUNDTRAP || skill_id == RK_DRAGONBREATH || skill_id == RK_DRAGONBREATH_WATER)) ) )
{
if (battle_config.left_cardfix_to_right)
battle->drain(sd, bl, dmg.damage, dmg.damage, tstatus->race, tstatus->mode&MD_BOSS);
@@ -2761,30 +2751,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
battle->drain(sd, bl, dmg.damage, dmg.damage2, tstatus->race, tstatus->mode&MD_BOSS);
}
- if( rdamage > 0 ) {
- if( sc && sc->data[SC_REFLECTDAMAGE] ) {
- if( src != bl ) {// Don't reflect your own damage (Grand Cross)
- bool change = false;
- if( sd && !sd->state.autocast )
- change = true;
- if( change )
- sd->state.autocast = 1;
- iMap->foreachinshootrange(battle->damage_area,bl,skill->get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,bl,dmg.amotion,sstatus->dmotion,rdamage,tstatus->race);
- if( change )
- sd->state.autocast = 0;
- }
- } else {
- if( dmg.amotion )
- battle->delay_damage(tick, dmg.amotion,bl,src,0,CR_REFLECTSHIELD,0,rdamage,ATK_DEF,0,additional_effects);
- else
- status_fix_damage(bl,src,rdamage,0);
- clif->damage(src,src,tick, dmg.amotion,0,rdamage,1,4,0); // in aegis damage reflected is shown in single hit.
- //Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
- if( tsd && src != bl )
- battle->drain(tsd, src, rdamage, rdamage, sstatus->race, is_boss(src));
- skill->additional_effect(bl, src, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
- }
- }
+
if( damage > 0 ) {
/**
* Post-damage effects
@@ -2818,8 +2785,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
skill_id == MG_COLDBOLT || skill_id == MG_FIREBOLT || skill_id == MG_LIGHTNINGBOLT
) &&
(sc = status_get_sc(src)) &&
- sc->data[SC_DOUBLECAST] &&
- rnd() % 100 < sc->data[SC_DOUBLECAST]->val2)
+ sc->data[SC_DOUBLECASTING] &&
+ rnd() % 100 < sc->data[SC_DOUBLECASTING]->val2)
{
// skill->addtimerskill(src, tick + dmg.div_*dmg.amotion, bl->id, 0, 0, skill_id, skill_lv, BF_MAGIC, flag|2);
skill->addtimerskill(src, tick + dmg.amotion, bl->id, 0, 0, skill_id, skill_lv, BF_MAGIC, flag|2);
@@ -3101,7 +3068,7 @@ int skill_check_condition_mercenary(struct block_list *bl, int skill_id, int lv,
index[i] = pc->search_inventory(sd, itemid[i]);
if( index[i] < 0 || sd->status.inventory[index[i]].amount < amount[i] )
{
- clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_NEED_ITEM, amount[i]|(itemid[i] << 16));
return 0;
}
}
@@ -3193,10 +3160,10 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
} else {
struct status_change *sc = status_get_sc(src);
if(sc) {
- if(sc->data[SC_SPIRIT] &&
- sc->data[SC_SPIRIT]->val2 == SL_WIZARD &&
- sc->data[SC_SPIRIT]->val3 == skl->skill_id)
- sc->data[SC_SPIRIT]->val3 = 0; //Clear bounced spell check.
+ if(sc->data[SC_SOULLINK] &&
+ sc->data[SC_SOULLINK]->val2 == SL_WIZARD &&
+ sc->data[SC_SOULLINK]->val3 == skl->skill_id)
+ sc->data[SC_SOULLINK]->val3 = 0; //Clear bounced spell check.
}
}
break;
@@ -3205,48 +3172,33 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
**/
case WL_CHAINLIGHTNING_ATK: {
struct block_list *nbl = NULL; // Next Target of Chain
- skill->attack(BF_MAGIC,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag); // Hit a Lightning on the current Target
+ skill->attack(BF_MAGIC, src, src, target, skl->skill_id, skl->skill_lv, tick, (9-skl->type)); // Hit a Lightning on the current Target
skill->toggle_magicpower(src, skl->skill_id); // only the first hit will be amplify
- if( skl->type > 1 ) { // Remaining Chains Hit
- nbl = battle->get_enemy_area(src,target->x,target->y,2,BL_CHAR|BL_SKILL,target->id); // Search for a new Target around current one...
- if( nbl == NULL && skl->x > 1 ) {
- nbl = target;
- skl->x--;
- } else
- skl->x = 3;
+
+ if( skl->type < (4 + skl->skill_lv - 1) && skl->x < 3 )
+ { // Remaining Chains Hit
+ nbl = battle->get_enemy_area(src, target->x, target->y, (skl->type>2)?2:3, // After 2 bounces, it will bounce to other targets in 7x7 range.
+ BL_CHAR|BL_SKILL, target->id); // Search for a new Target around current one...
+ if( nbl == NULL)
+ skl->x++;
+ else
+ skl->x = 0;
+
+ skill->addtimerskill(src, tick + 651, (nbl?nbl:target)->id, skl->x, 0, WL_CHAINLIGHTNING_ATK, skl->skill_lv, skl->type + 1, skl->flag);
}
-
- if( nbl )
- skill->addtimerskill(src,tick+status_get_adelay(src),nbl->id,skl->x,0,WL_CHAINLIGHTNING_ATK,skl->skill_lv,skl->type-1,skl->flag);
}
break;
case WL_TETRAVORTEX_FIRE:
case WL_TETRAVORTEX_WATER:
case WL_TETRAVORTEX_WIND:
case WL_TETRAVORTEX_GROUND:
- skill->attack(BF_MAGIC,src,src,target,skl->skill_id,skl->skill_lv,tick,skl->flag|SD_ANIMATION);
+ clif->skill_nodamage(src, target, skl->skill_id, skl->skill_lv, 1);
+ skill_attack(BF_MAGIC, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag);
skill->toggle_magicpower(src, skl->skill_id); // only the first hit will be amplify
- if( skl->type >= 3 ) { // Final Hit
- if( !status_isdead(target) ) { // Final Status Effect
- int effects[4] = { SC_BURNING, SC_FREEZING, SC_BLEEDING, SC_STUN },
- applyeffects[4] = { 0, 0, 0, 0 },
- i, j = 0, k = 0;
- for( i = 1; i <= 8; i = i + i ) {
- if( skl->x&i )
- {
- applyeffects[j] = effects[k];
- j++;
- }
- k++;
- }
- if( j ) {
- i = applyeffects[rnd()%j];
- status_change_start(target, i, 10000, skl->skill_lv,
- (i == SC_BURNING ? 1000 : (i == SC_BLEEDING ? src->id : 0)),
- (i == SC_BURNING ? src->id : 0),
- 0, skill->get_time(WL_TETRAVORTEX,skl->skill_lv), 0);
- }
- }
+ 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));
}
break;
case WM_REVERBERATION_MELEE:
@@ -3282,6 +3234,19 @@ int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) {
iMap->foreachinrange(skill->area_sub, target, skill->get_splash(skl->skill_id, skl->skill_lv), BL_CHAR,
src, skl->skill_id, skl->skill_lv, 0, skl->flag|1|BCT_ENEMY, skill->castend_damage_id);
break;
+ case SR_FLASHCOMBO_ATK_STEP1:
+ case SR_FLASHCOMBO_ATK_STEP2:
+ case SR_FLASHCOMBO_ATK_STEP3:
+ case SR_FLASHCOMBO_ATK_STEP4:
+ if( src->type == BL_PC ) {
+ struct map_session_data *sd = NULL;
+ 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];
+ skill->castend_damage_id(src, target, cid, pc->checkskill(sd, cid), tick, 0);
+ }
+ }
+ break;
case CH_PALMSTRIKE:
{
struct status_change* tsc = status_get_sc(target);
@@ -3525,7 +3490,9 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case GS_FULLBUSTER:
case NJ_SYURIKEN:
case NJ_KUNAI:
+#ifndef RENEWAL
case ASC_BREAKER:
+#endif
case HFLI_MOON: //[orn]
case HFLI_SBR44: //[orn]
case NPC_BLEEDING:
@@ -3533,6 +3500,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case NPC_HELLPOWER:
case RK_SONICWAVE:
case RK_HUNDREDSPEAR:
+ case RK_STORMBLAST:
+ case RK_CRUSHSTRIKE:
case AB_DUPLELIGHT_MELEE:
case RA_AIMEDBOLT:
case NC_AXEBOOMERANG:
@@ -3555,7 +3524,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case GN_SLINGITEM_RANGEMELEEATK:
case KO_JYUMONJIKIRI:
case KO_SETSUDAN:
- case KO_KAIHOU:
+ case GC_DARKCROW:
skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
break;
@@ -3588,7 +3557,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
case MO_COMBOFINISH:
- if (!(flag&1) && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_MONK)
+ if (!(flag&1) && sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_MONK)
{ //Becomes a splash attack when Soul Linked.
iMap->foreachinrange(skill->area_sub, bl,
skill->get_splash(skill_id, skill_lv),splash_target(src),
@@ -3687,9 +3656,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
case NJ_ISSEN:
- status_change_end(src, SC_NEN, INVALID_TIMER);
- status_change_end(src, SC_HIDING, INVALID_TIMER);
- // fall through
case MO_EXTREMITYFIST:
{
short x, y, i = 2; // Move 2 cells for Issen(from target)
@@ -3708,7 +3674,9 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
#ifdef RENEWAL
sc_start(src,SC_EXTREMITYFIST2,100,skill_lv,skill->get_time(skill_id,skill_lv));
#endif
- }else
+ }else{
+ status_change_end(src, SC_NJ_NEN, INVALID_TIMER);
+ status_change_end(src, SC_HIDING, INVALID_TIMER);
status_set_hp(src,
#ifdef RENEWAL
max(status_get_max_hp(src)/100, 1)
@@ -3716,7 +3684,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
1
#endif
, 0);
-
+ }
dir = iMap->calc_dir(src,bl->x,bl->y);
if( dir > 0 && dir < 4) x = -i;
else if( dir > 4 ) x = i;
@@ -3945,6 +3913,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case AB_DUPLELIGHT_MAGIC:
case WM_METALICSOUND:
case MH_ERASER_CUTTER:
+ case KO_KAIHOU:
skill->attack(BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag);
break;
@@ -4011,7 +3980,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
case SL_SMA:
- status_change_end(src, SC_SMA, INVALID_TIMER);
+ status_change_end(src, SC_SMA_READY, INVALID_TIMER);
case SL_STIN:
case SL_STUN:
if (sd && !battle_config.allow_es_magic_pc && bl->type != BL_MOB) {
@@ -4033,11 +4002,15 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case NJ_ZENYNAGE:
case GN_THORNS_TRAP:
case GN_HELLS_PLANT_ATK:
+#ifdef RENEWAL
+ case ASC_BREAKER:
+#endif
skill->attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag);
break;
/**
* Rune Knight
**/
+ case RK_DRAGONBREATH_WATER:
case RK_DRAGONBREATH: {
struct status_change *tsc = NULL;
if( (tsc = status_get_sc(bl)) && (tsc->data[SC_HIDING] )) {
@@ -4112,16 +4085,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
break;
- case RK_STORMBLAST:
- case RK_CRUSHSTRIKE:
- if( sd ) {
- if( pc->checkskill(sd,RK_RUNEMASTERY) >= ( skill_id == RK_CRUSHSTRIKE ? 7 : 3 ) )
- skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
- else
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- } else //non-sd support
- skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
- break;
case GC_DARKILLUSION:
{
short x, y;
@@ -4145,9 +4108,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
}
break;
-
case GC_WEAPONCRUSH:
- if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == GC_WEAPONBLOCKING )
+ if( sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == GC_WEAPONBLOCKING )
skill->attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
else if( sd )
clif->skill_fail(sd,skill_id,USESKILL_FAIL_GC_WEAPONBLOCKING,0);
@@ -4173,7 +4135,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
case WL_CHAINLIGHTNING:
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
- skill->addtimerskill(src,tick + 150,bl->id,3,0,WL_CHAINLIGHTNING_ATK,skill_lv,4+skill_lv,flag);
+ skill->addtimerskill(src,tick+status_get_amotion(src),bl->id,0,0,WL_CHAINLIGHTNING_ATK,skill_lv,0,flag);
break;
case WL_DRAINLIFE:
{
@@ -4182,7 +4144,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
heal = heal * (5 + 5 * skill_lv) / 100;
- if( bl->type == BL_SKILL )
+ if( bl->type == BL_SKILL || status_get_hp(src) == status_get_max_hp(src)) // Don't absorb when caster was in full HP
heal = 0; // Don't absorb heal from Ice Walls or other skill units.
if( heal && rnd()%100 < rate )
@@ -4194,61 +4156,43 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
case WL_TETRAVORTEX:
- if( sd ) {
- int spheres[5] = { 0, 0, 0, 0, 0 },
- positions[5] = {-1,-1,-1,-1,-1 },
- i, j = 0, k, subskill = 0;
-
- for( i = SC_SPHERE_1; i <= SC_SPHERE_5; i++ )
- if( sc && sc->data[i] )
- {
- spheres[j] = i;
- positions[j] = sc->data[i]->val2;
- j++; //
- }
-
- if( j < 4 )
- { // Need 4 spheres minimum
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- break;
- }
-
- // Sphere Sort, this time from new to old
- for( i = 0; i <= j - 2; i++ )
- for( k = i + 1; k <= j - 1; k++ )
- if( positions[i] < positions[k] )
- {
- swap(positions[i],positions[k]);
- swap(spheres[i],spheres[k]);
+ if( sc ){
+ int i = SC_SUMMON5, x = 0;
+ int types[][2] = {{0, 0}, {0, 0}, {0, 0}, {0, 0}};
+ for(; i >= SC_SUMMON1; i--){
+ if( sc->data[i] ){
+ int skillid = WL_TETRAVORTEX_FIRE + (sc->data[i]->val1 - WLS_FIRE) + (sc->data[i]->val1 == WLS_WIND) - (sc->data[i]->val1 == WLS_WATER), sc_index = 0, rate = 0;
+ if( x < 4 ){
+ types[x][0] = (sc->data[i]->val1 - WLS_FIRE) + 1;
+ types[x][1] = 25; // 25% each for equal sharing
+ if( x == 3 ){
+ x = 0;
+ sc_index = types[rand()%4][0];
+ for(; x < 4; x++)
+ if(types[x][0] == sc_index)
+ rate += types[x][1];
+ }
+ skill->addtimerskill(src, tick + (SC_SUMMON5-i) * 206, bl->id, sc_index, rate, skillid, skill_lv, x, flag);
}
-
- k = 0;
- for( i = 0; i < 4; i++ )
- {
- switch( sc->data[spheres[i]]->val1 )
- {
- case WLS_FIRE: subskill = WL_TETRAVORTEX_FIRE; k |= 1; break;
- case WLS_WIND: subskill = WL_TETRAVORTEX_WIND; k |= 4; break;
- case WLS_WATER: subskill = WL_TETRAVORTEX_WATER; k |= 2; break;
- case WLS_STONE: subskill = WL_TETRAVORTEX_GROUND; k |= 8; break;
+ status_change_end(src, (sc_type)i, INVALID_TIMER);
+ x++;
}
- skill->addtimerskill(src, tick + i * 200, bl->id, k, 0, subskill, skill_lv, i, flag);
- clif->skill_nodamage(src, bl, subskill, skill_lv, 1);
- status_change_end(src, spheres[i], INVALID_TIMER);
}
}
break;
case WL_RELEASE:
if( sd ) {
- int i;
+ int i, cooldown;
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
+ skill->toggle_magicpower(src, skill_id);
// Priority is to release SpellBook
if( sc && sc->data[SC_READING_SB] ) { // SpellBook
uint16 skill_id, skill_lv, point, s = 0;
- int spell[SC_MAXSPELLBOOK-SC_SPELLBOOK1 + 1];
+ int spell[SC_SPELLBOOK7-SC_SPELLBOOK1 + 1];
- for(i = SC_MAXSPELLBOOK; i >= SC_SPELLBOOK1; i--) // List all available spell to be released
- if( sc->data[i] ) spell[s++] = i;
+ for(i = SC_SPELLBOOK7; i >= SC_SPELLBOOK1; i--) // List all available spell to be released
+ if( sc->data[i] ) spell[s++] = i;
if ( s == 0 )
break;
@@ -4261,13 +4205,12 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
status_change_end(src, (sc_type)i, INVALID_TIMER);
}else //something went wrong :(
break;
-
+
if( sc->data[SC_READING_SB]->val2 > point )
sc->data[SC_READING_SB]->val2 -= point;
else // Last spell to be released
status_change_end(src, SC_READING_SB, INVALID_TIMER);
- if( bl->type != BL_SKILL ) /* skill types will crash the client */
- clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
+
if( !skill->check_condition_castbegin(sd, skill_id, skill_lv) )
break;
@@ -4284,47 +4227,32 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
}
sd->ud.canact_tick = tick + skill->delay_fix(src, skill_id, skill_lv);
- clif->status_change(src, SI_ACTIONDELAY, 1, skill->delay_fix(src, skill_id, skill_lv), 0, 0, 0);
- } else { // Summon Balls
- int j = 0, k, skele;
- int spheres[5] = { 0, 0, 0, 0, 0 },
- positions[5] = {-1,-1,-1,-1,-1 };
-
- for( i = SC_SPHERE_1; i <= SC_SPHERE_5; i++ )
- if( sc && sc->data[i] ) {
- spheres[j] = i;
- positions[j] = sc->data[i]->val2;
- sc->data[i]->val2--; // Prepares for next position
- j++;
- }
+ clif->status_change(src, SI_POSTDELAY, 1, skill->delay_fix(src, skill_id, skill_lv), 0, 0, 0);
- if( j == 0 ) { // No Spheres
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_SUMMON_NONE,0);
- break;
+ cooldown = skill_get_cooldown(skill_id, skill_lv);
+ for (i = 0; i < ARRAYLENGTH(sd->skillcooldown) && sd->skillcooldown[i].id; i++) {
+ if (sd->skillcooldown[i].id == skill_id){
+ cooldown += sd->skillcooldown[i].val;
+ break;
+ }
}
-
- // Sphere Sort
- for( i = 0; i <= j - 2; i++ )
- for( k = i + 1; k <= j - 1; k++ )
- if( positions[i] > positions[k] ) {
- swap(positions[i],positions[k]);
- swap(spheres[i],spheres[k]);
- }
-
- if( skill_lv == 1 ) j = 1; // Limit only to one ball
- for( i = 0; i < j; i++ ) {
- skele = WL_RELEASE - 5 + sc->data[spheres[i]]->val1 - WLS_FIRE; // Convert Ball Element into Skill ATK for balls
- // WL_SUMMON_ATK_FIRE, WL_SUMMON_ATK_WIND, WL_SUMMON_ATK_WATER, WL_SUMMON_ATK_GROUND
- skill->addtimerskill(src,tick+status_get_adelay(src)*i,bl->id,0,0,skele,sc->data[spheres[i]]->val3,BF_MAGIC,flag|SD_LEVEL);
- status_change_end(src, spheres[i], INVALID_TIMER); // Eliminate ball
+ if(cooldown)
+ skill->blockpc_start(sd, skill_id, cooldown, false);
+ }else if( sc ){ // Summon Balls
+ int i = SC_SUMMON5;
+ for(; i >= SC_SUMMON1; i--){
+ if( sc->data[i] ){
+ int skillid = WL_SUMMON_ATK_FIRE + (sc->data[i]->val1 - WLS_FIRE);
+ skill->addtimerskill(src, tick + status_get_adelay(src) * (SC_SUMMON5 - i), bl->id, 0, 0, skillid, skill_lv, BF_MAGIC, flag);
+ status_change_end(src, (sc_type)i, INVALID_TIMER);
+ if(skill_lv == 1)
+ break;
+ }
}
- clif->skill_nodamage(src,bl,skill_id,0,1);
}
}
break;
case WL_FROSTMISTY:
- // Causes Freezing status through walls.
- sc_start(bl,status_skill2sc(skill_id),20+12*skill_lv+(sd ? sd->status.job_level : 50)/5,skill_lv,skill->get_time(skill_id,skill_lv));
// Doesn't deal damage through non-shootable walls.
if( path_search(NULL,src->m,src->x,src->y,bl->x,bl->y,1,CELL_CHKWALL) )
skill->attack(BF_MAGIC,src,src,bl,skill_id,skill_lv,tick,flag|SD_ANIMATION);
@@ -4453,19 +4381,19 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
break;
case SR_HOWLINGOFLION:
- status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
- status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
- status_change_end(bl, SC_MOONLITSERENADE, INVALID_TIMER);
- status_change_end(bl, SC_RUSHWINDMILL, 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_SIRCLEOFNATURE, INVALID_TIMER);
- status_change_end(bl, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
- status_change_end(bl, SC_DANCEWITHWUG, INVALID_TIMER);
- status_change_end(bl, SC_LERADSDEW, INVALID_TIMER);
+ status_change_end(bl, SC_SATURDAY_NIGHT_FEVER, 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_BEYONDOFWARCRY, INVALID_TIMER);
- status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, INVALID_TIMER);
+ status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER);
+ status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER);
skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag|SD_ANIMATION);
break;
@@ -4573,7 +4501,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
}
break;
-
//recursive homon skill
case MH_MAGMA_FLOW:
case MH_XENO_SLASHER:
@@ -4589,8 +4516,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
case MH_NEEDLE_OF_PARALYZE:
skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
break;
- case MH_TINDER_BREAKER:
- if (unit_movepos(src, bl->x, bl->y, 1, 1)) {
+ case MH_TINDER_BREAKER:
+ if (unit_movepos(src, bl->x, bl->y, 1, 1)) {
#if PACKETVER >= 20111005
clif->snap(src, bl->x, bl->y);
#else
@@ -4598,7 +4525,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
#endif
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start4(bl,SC_CLOSECONFINE2,100,skill_lv,src->id,0,0,skill->get_time(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)));
skill->attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
break;
@@ -4651,6 +4578,333 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
/*==========================================
*
*------------------------------------------*/
+int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
+{
+ struct block_list *target, *src;
+ struct map_session_data *sd;
+ struct mob_data *md;
+ struct unit_data *ud;
+ struct status_change *sc = NULL;
+ int inf,inf2,flag = 0;
+
+ src = iMap->id2bl(id);
+ if( src == NULL )
+ {
+ ShowDebug("skill_castend_id: src == NULL (tid=%d, id=%d)\n", tid, id);
+ return 0;// not found
+ }
+
+ ud = unit_bl2ud(src);
+ if( ud == NULL )
+ {
+ ShowDebug("skill_castend_id: ud == NULL (tid=%d, id=%d)\n", tid, id);
+ return 0;// ???
+ }
+
+ sd = BL_CAST(BL_PC, src);
+ md = BL_CAST(BL_MOB, src);
+
+ if( src->prev == NULL ) {
+ ud->skilltimer = INVALID_TIMER;
+ return 0;
+ }
+
+ if(ud->skill_id != SA_CASTCANCEL && ud->skill_id != SO_SPELLFIST) {// otherwise handled in unit_skillcastcancel()
+ if( ud->skilltimer != tid ) {
+ ShowError("skill_castend_id: Timer mismatch %d!=%d!\n", ud->skilltimer, tid);
+ ud->skilltimer = INVALID_TIMER;
+ return 0;
+ }
+
+ if( sd && ud->skilltimer != INVALID_TIMER && (pc->checkskill(sd,SA_FREECAST) > 0 || ud->skill_id == LG_EXEEDBREAK) )
+ {// restore original walk speed
+ ud->skilltimer = INVALID_TIMER;
+ status_calc_bl(&sd->bl, SCB_SPEED);
+ }
+
+ ud->skilltimer = INVALID_TIMER;
+ }
+
+ if (ud->skilltarget == id)
+ target = src;
+ else
+ target = iMap->id2bl(ud->skilltarget);
+
+ // Use a do so that you can break out of it when the skill fails.
+ do {
+ if(!target || target->prev==NULL) break;
+
+ if(src->m != target->m || status_isdead(src)) break;
+
+ switch (ud->skill_id) {
+ //These should become skill_castend_pos
+ case WE_CALLPARTNER:
+ if(sd) clif->callpartner(sd);
+ case WE_CALLPARENT:
+ case WE_CALLBABY:
+ case AM_RESURRECTHOMUN:
+ case PF_SPIDERWEB:
+ //Find a random spot to place the skill. [Skotlex]
+ inf2 = skill->get_splash(ud->skill_id, ud->skill_lv);
+ ud->skillx = target->x + inf2;
+ ud->skilly = target->y + inf2;
+ if (inf2 && !iMap->random_dir(target, &ud->skillx, &ud->skilly)) {
+ ud->skillx = target->x;
+ ud->skilly = target->y;
+ }
+ ud->skilltimer=tid;
+ return skill->castend_pos(tid,tick,id,data);
+ case GN_WALLOFTHORN:
+ ud->skillx = target->x;
+ ud->skilly = target->y;
+ ud->skilltimer = tid;
+ return skill->castend_pos(tid,tick,id,data);
+ }
+
+ if(ud->skill_id == RG_BACKSTAP) {
+ uint8 dir = iMap->calc_dir(src,target->x,target->y),t_dir = unit_getdir(target);
+ if(check_distance_bl(src, target, 0) || iMap->check_dir(dir,t_dir)) {
+ break;
+ }
+ }
+
+ if( ud->skill_id == PR_TURNUNDEAD ) {
+ struct status_data *tstatus = status_get_status_data(target);
+ if( !battle->check_undead(tstatus->race, tstatus->def_ele) )
+ break;
+ }
+
+ if( ud->skill_id == RA_WUGSTRIKE ){
+ if( !path_search(NULL,src->m,src->x,src->y,target->x,target->y,1,CELL_CHKNOREACH))
+ break;
+ }
+
+ if( ud->skill_id == PR_LEXDIVINA || ud->skill_id == MER_LEXDIVINA )
+ {
+ sc = status_get_sc(target);
+ if( battle->check_target(src,target, BCT_ENEMY) <= 0 && (!sc || !sc->data[SC_SILENCE]) )
+ { //If it's not an enemy, and not silenced, you can't use the skill on them. [Skotlex]
+ clif->skill_nodamage (src, target, ud->skill_id, ud->skill_lv, 0);
+ break;
+ }
+ }
+ else
+ { // Check target validity.
+ inf = skill->get_inf(ud->skill_id);
+ inf2 = skill->get_inf2(ud->skill_id);
+
+ if(inf&INF_ATTACK_SKILL ||
+ (inf&INF_SELF_SKILL && inf2&INF2_NO_TARGET_SELF) //Combo skills
+ ) // Casted through combo.
+ inf = BCT_ENEMY; //Offensive skill.
+ else if(inf2&INF2_NO_ENEMY)
+ inf = BCT_NOENEMY;
+ else
+ inf = 0;
+
+ if(inf2 & (INF2_PARTY_ONLY|INF2_GUILD_ONLY) && src != target)
+ {
+ inf |=
+ (inf2&INF2_PARTY_ONLY?BCT_PARTY:0)|
+ (inf2&INF2_GUILD_ONLY?BCT_GUILD:0);
+ //Remove neutral targets (but allow enemy if skill is designed to be so)
+ inf &= ~BCT_NEUTRAL;
+ }
+
+ if( sd && (inf2&INF2_CHORUS_SKILL) && skill->check_pc_partner(sd, ud->skill_id, &ud->skill_lv, 1, 0) < 1 ) {
+ clif->skill_fail(sd, ud->skill_id, USESKILL_FAIL_NEED_HELPER, 0);
+ break;
+ }
+
+ if( ud->skill_id >= SL_SKE && ud->skill_id <= SL_SKA && target->type == BL_MOB )
+ {
+ if( ((TBL_MOB*)target)->class_ == MOBID_EMPERIUM )
+ break;
+ }
+ else if (inf && battle->check_target(src, target, inf) <= 0){
+ if (sd) clif->skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0);
+ break;
+ }
+
+ if(inf&BCT_ENEMY && (sc = status_get_sc(target)) &&
+ sc->data[SC_FOGWALL] &&
+ rnd() % 100 < 75) { //Fogwall makes all offensive-type targetted skills fail at 75%
+ if (sd) clif->skill_fail(sd, ud->skill_id, USESKILL_FAIL_LEVEL, 0);
+ break;
+ }
+ }
+
+ //Avoid doing double checks for instant-cast skills.
+ if (tid != INVALID_TIMER && !status_check_skilluse(src, target, ud->skill_id, 1))
+ break;
+
+ if(md) {
+ md->last_thinktime=tick +MIN_MOBTHINKTIME;
+ if(md->skill_idx >= 0 && md->db->skill[md->skill_idx].emotion >= 0)
+ clif->emotion(src, md->db->skill[md->skill_idx].emotion);
+ }
+
+ if(src != target && battle_config.skill_add_range &&
+ !check_distance_bl(src, target, skill->get_range2(src,ud->skill_id,ud->skill_lv)+battle_config.skill_add_range))
+ {
+ if (sd) {
+ clif->skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0);
+ if(battle_config.skill_out_range_consume) //Consume items anyway. [Skotlex]
+ skill->consume_requirement(sd,ud->skill_id,ud->skill_lv,3);
+ }
+ break;
+ }
+
+ if( sd )
+ {
+ if( !skill->check_condition_castend(sd, ud->skill_id, ud->skill_lv) )
+ break;
+ else
+ skill->consume_requirement(sd,ud->skill_id,ud->skill_lv,1);
+ }
+#ifdef OFFICIAL_WALKPATH
+ if( !path_search_long(NULL, src->m, src->x, src->y, target->x, target->y, CELL_CHKWALL) )
+ break;
+#endif
+ if( (src->type == BL_MER || src->type == BL_HOM) && !skill->check_condition_mercenary(src, ud->skill_id, ud->skill_lv, 1) )
+ break;
+
+ if (ud->state.running && ud->skill_id == TK_JUMPKICK) {
+ ud->state.running = 0;
+ status_change_end(src, SC_RUN, INVALID_TIMER);
+ flag = 1;
+ }
+
+ if (ud->walktimer != INVALID_TIMER && ud->skill_id != TK_RUN && ud->skill_id != RA_WUGDASH)
+ unit_stop_walking(src,1);
+
+ if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) )
+ ud->canact_tick = tick + skill->delay_fix(src, ud->skill_id, ud->skill_lv); //Tests show wings don't overwrite the delay but skill scrolls do. [Inkfish]
+ if (sd) { //Cooldown application
+ int i, cooldown = skill->get_cooldown(ud->skill_id, ud->skill_lv);
+ for (i = 0; i < ARRAYLENGTH(sd->skillcooldown) && sd->skillcooldown[i].id; i++) { // Increases/Decreases cooldown of a skill by item/card bonuses.
+ if (sd->skillcooldown[i].id == ud->skill_id){
+ cooldown += sd->skillcooldown[i].val;
+ break;
+ }
+ }
+ if(cooldown)
+ skill->blockpc_start(sd, ud->skill_id, cooldown, false);
+ }
+ if( battle_config.display_status_timers && sd )
+ clif->status_change(src, SI_POSTDELAY, 1, skill->delay_fix(src, ud->skill_id, ud->skill_lv), 0, 0, 0);
+ if( sd )
+ {
+ switch( ud->skill_id )
+ {
+ case GS_DESPERADO:
+ sd->canequip_tick = tick + skill->get_time(ud->skill_id, ud->skill_lv);
+ break;
+ case CR_GRANDCROSS:
+ case NPC_GRANDDARKNESS:
+ if( (sc = status_get_sc(src)) && sc->data[SC_NOEQUIPSHIELD] )
+ {
+ const struct TimerData *timer = iTimer->get_timer(sc->data[SC_NOEQUIPSHIELD]->timer);
+ if( timer && timer->func == status_change_timer && DIFF_TICK(timer->tick,iTimer->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));
+ break;
+ }
+ }
+ if (skill->get_state(ud->skill_id) != ST_MOVE_ENABLE)
+ unit_set_walkdelay(src, tick, battle_config.default_walk_delay+skill->get_walkdelay(ud->skill_id, ud->skill_lv), 1);
+
+ if(battle_config.skill_log && battle_config.skill_log&src->type)
+ ShowInfo("Type %d, ID %d skill castend id [id =%d, lv=%d, target ID %d]\n",
+ src->type, src->id, ud->skill_id, ud->skill_lv, target->id);
+
+ iMap->freeblock_lock();
+
+ // SC_MAGICPOWER needs to switch states before any damage is actually dealt
+ skill->toggle_magicpower(src, ud->skill_id);
+ 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);
+ else
+ skill->castend_damage_id(src,target,ud->skill_id,ud->skill_lv,tick,flag);
+
+ sc = status_get_sc(src);
+ if(sc && sc->count) {
+ if(sc->data[SC_SOULLINK] &&
+ sc->data[SC_SOULLINK]->val2 == SL_WIZARD &&
+ sc->data[SC_SOULLINK]->val3 == ud->skill_id &&
+ ud->skill_id != WZ_WATERBALL)
+ sc->data[SC_SOULLINK]->val3 = 0; //Clear bounced spell check.
+
+ if( sc->data[SC_DANCING] && skill->get_inf2(ud->skill_id)&INF2_SONG_DANCE && sd )
+ skill->blockpc_start(sd,BD_ADAPTATION,3000, false);
+ }
+
+ if( sd && ud->skill_id != SA_ABRACADABRA && ud->skill_id != WM_RANDOMIZESPELL ) // they just set the data so leave it as it is.[Inkfish]
+ sd->skillitem = sd->skillitemlv = 0;
+
+ if (ud->skilltimer == INVALID_TIMER) {
+ if(md) md->skill_idx = -1;
+ else ud->skill_id = 0; //mobs can't clear this one as it is used for skill condition 'afterskill'
+ ud->skill_lv = ud->skilltarget = 0;
+ }
+ iMap->freeblock_unlock();
+ return 1;
+ } while(0);
+
+ //Skill failed.
+ if (ud->skill_id == MO_EXTREMITYFIST && sd && !(sc && sc->data[SC_FOGWALL]))
+ { //When Asura fails... (except when it fails from Fog of Wall)
+ //Consume SP/spheres
+ skill->consume_requirement(sd,ud->skill_id, ud->skill_lv,1);
+ status_set_sp(src, 0, 0);
+ sc = &sd->sc;
+ if (sc->count)
+ { //End states
+ 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));
+#endif
+ }
+ if (target && target->m == src->m)
+ { //Move character to target anyway.
+ int dir, x, y;
+ dir = iMap->calc_dir(src,target->x,target->y);
+ if( dir > 0 && dir < 4) x = -2;
+ else if( dir > 4 ) x = 2;
+ else x = 0;
+ if( dir > 2 && dir < 6 ) y = -2;
+ else if( dir == 7 || dir < 2 ) y = 2;
+ else y = 0;
+ if (unit_movepos(src, src->x+x, src->y+y, 1, 1))
+ { //Display movement + animation.
+ clif->slide(src,src->x,src->y);
+ clif->skill_damage(src,target,tick,sd->battle_status.amotion,0,0,1,ud->skill_id, ud->skill_lv, 5);
+ }
+ clif->skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0);
+ }
+ }
+
+ ud->skill_id = ud->skill_lv = ud->skilltarget = 0;
+ if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) )
+ ud->canact_tick = tick;
+ //You can't place a skill failed packet here because it would be
+ //sent in ALL cases, even cases where skill_check_condition fails
+ //which would lead to double 'skill failed' messages u.u [Skotlex]
+ if(sd)
+ sd->skillitem = sd->skillitemlv = 0;
+ else if(md)
+ md->skill_idx = -1;
+ return 0;
+}
+
+/*==========================================
+ *
+ *------------------------------------------*/
int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, uint16 skill_id, uint16 skill_lv, unsigned int tick, int flag)
{
struct map_session_data *sd, *dstsd;
@@ -4742,6 +4996,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
return ret;
}
break;
+ case RK_MILLENNIUMSHIELD:
+ case RK_CRUSHSTRIKE:
+ case RK_REFRESH:
+ case RK_GIANTGROWTH:
+ case RK_STONEHARDSKIN:
+ case RK_VITALITYACTIVATION:
+ case RK_STORMBLAST:
+ 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) ){
+ skill->consume_requirement(sd,skill_id,skill_lv,2);
+ iMap->freeblock_unlock();
+ return 0;
+ }
+ }
+ break;
default:
//Skill is actually ground placed.
if (src == bl && skill->get_unit_id(skill_id,0))
@@ -4794,7 +5065,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
dstsd = sd;
}
}
- else if (tsc->data[SC_BERSERK] || tsc->data[SC_SATURDAYNIGHTFEVER] || tsc->data[SC__BLOODYLUST])
+ else if (tsc->data[SC_BERSERK] || tsc->data[SC_SATURDAY_NIGHT_FEVER] || tsc->data[SC__BLOODYLUST])
heal = 0; //Needed so that it actually displays 0 when healing.
}
clif->skill_nodamage (src, bl, skill_id, heal, 1);
@@ -5019,7 +5290,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
mob_class_change(dstmd,class_);
if( tsc && dstmd->status.mode&MD_BOSS )
{
- const enum sc_type scs[] = { SC_QUAGMIRE, SC_PROVOKE, SC_ROKISWEIL, SC_GRAVITATION, SC_SUITON, SC_STRIPWEAPON, SC_STRIPSHIELD, SC_STRIPARMOR, SC_STRIPHELM, SC_BLADESTOP };
+ const enum sc_type scs[] = { SC_QUAGMIRE, SC_PROVOKE, SC_ROKISWEIL, SC_GRAVITATION, SC_NJ_SUITON, SC_NOEQUIPWEAPON, SC_NOEQUIPSHIELD, SC_NOEQUIPARMOR, SC_NOEQUIPHELM, SC_BLADESTOP };
for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++)
if (tsc->data[i]) status_change_end(bl, (sc_type)i, INVALID_TIMER);
for (i = 0; i < ARRAYLENGTH(scs); i++)
@@ -5078,18 +5349,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( sc && tsc )
{
- if( !sc->data[SC_MARIONETTE] && !tsc->data[SC_MARIONETTE2] )
+ if( !sc->data[SC_MARIONETTE_MASTER] && !tsc->data[SC_MARIONETTE] )
{
- sc_start(src,SC_MARIONETTE,100,bl->id,skill->get_time(skill_id,skill_lv));
- sc_start(bl,SC_MARIONETTE2,100,src->id,skill->get_time(skill_id,skill_lv));
+ 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));
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
}
else
- if( sc->data[SC_MARIONETTE ] && sc->data[SC_MARIONETTE ]->val1 == bl->id &&
- tsc->data[SC_MARIONETTE2] && tsc->data[SC_MARIONETTE2]->val1 == src->id )
+ 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 )
{
- status_change_end(src, SC_MARIONETTE, INVALID_TIMER);
- status_change_end(bl, SC_MARIONETTE2, INVALID_TIMER);
+ status_change_end(src, SC_MARIONETTE_MASTER, INVALID_TIMER);
+ status_change_end(bl, SC_MARIONETTE, INVALID_TIMER);
}
else
{
@@ -5115,13 +5386,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if(dstsd->status.weapon == W_FIST ||
(dstsd->sc.count && !dstsd->sc.data[type] &&
( //Allow re-enchanting to lenghten time. [Skotlex]
- dstsd->sc.data[SC_FIREWEAPON] ||
- dstsd->sc.data[SC_WATERWEAPON] ||
- dstsd->sc.data[SC_WINDWEAPON] ||
- dstsd->sc.data[SC_EARTHWEAPON] ||
- dstsd->sc.data[SC_SHADOWWEAPON] ||
- dstsd->sc.data[SC_GHOSTWEAPON] ||
- dstsd->sc.data[SC_ENCPOISON]
+ dstsd->sc.data[SC_PROPERTYFIRE] ||
+ dstsd->sc.data[SC_PROPERTYWATER] ||
+ dstsd->sc.data[SC_PROPERTYWIND] ||
+ dstsd->sc.data[SC_PROPERTYGROUND] ||
+ dstsd->sc.data[SC_PROPERTYDARK] ||
+ dstsd->sc.data[SC_PROPERTYTELEKINESIS] ||
+ dstsd->sc.data[SC_ENCHANTPOISON]
))
) {
if (sd) clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
@@ -5155,18 +5426,18 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case TK_SEVENWIND:
switch(skill->get_ele(skill_id,skill_lv)) {
- case ELE_EARTH : type = SC_EARTHWEAPON; break;
- case ELE_WIND : type = SC_WINDWEAPON; break;
- case ELE_WATER : type = SC_WATERWEAPON; break;
- case ELE_FIRE : type = SC_FIREWEAPON; break;
- case ELE_GHOST : type = SC_GHOSTWEAPON; break;
- case ELE_DARK : type = SC_SHADOWWEAPON; break;
+ case ELE_EARTH : type = SC_PROPERTYGROUND; break;
+ case ELE_WIND : type = SC_PROPERTYWIND; break;
+ case ELE_WATER : type = SC_PROPERTYWATER; break;
+ case ELE_FIRE : type = SC_PROPERTYFIRE; break;
+ case ELE_GHOST : type = SC_PROPERTYTELEKINESIS; break;
+ case ELE_DARK : type = SC_PROPERTYDARK; break;
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(bl,SC_SEVENWIND,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));
break;
@@ -5208,7 +5479,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case AL_BLESSING:
case MER_INCAGI:
case MER_BLESSING:
- if (dstsd != NULL && tsc->data[SC_CHANGEUNDEAD]) {
+ if (dstsd != NULL && tsc->data[SC_PROPERTYUNDEAD]) {
skill->attack(BF_MISC,src,src,bl,skill_id,skill_lv,tick,flag);
break;
}
@@ -5279,6 +5550,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SR_GENTLETOUCH_ENERGYGAIN:
case GN_CARTBOOST:
case KO_MEIKYOUSISUI:
+ case ALL_FULL_THROTTLE:
+ case RA_UNLIMIT:
+ case WL_TELEKINESIS_INTENSE:
+ case AB_OFFERTORIUM:
+ case RK_GIANTGROWTH:
+ case RK_VITALITYACTIVATION:
+ case RK_ABUNDANCE:
+ case RK_CRUSHSTRIKE:
clif->skill_nodamage(src,bl,skill_id,skill_lv,
sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
break;
@@ -5326,7 +5605,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
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)));
- status_change_end(bl, SC_NEN, INVALID_TIMER);
+ status_change_end(bl, SC_NJ_NEN, INVALID_TIMER);
break;
/* Was modified to only affect targetted char. [Skotlex]
case HP_ASSUMPTIO:
@@ -5351,13 +5630,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case AS_ENCHANTPOISON: // Prevent spamming [Valaris]
if (sd && dstsd && dstsd->sc.count) {
- if (dstsd->sc.data[SC_FIREWEAPON] ||
- dstsd->sc.data[SC_WATERWEAPON] ||
- dstsd->sc.data[SC_WINDWEAPON] ||
- dstsd->sc.data[SC_EARTHWEAPON] ||
- dstsd->sc.data[SC_SHADOWWEAPON] ||
- dstsd->sc.data[SC_GHOSTWEAPON]
- // dstsd->sc.data[SC_ENCPOISON] //People say you should be able to recast to lengthen the timer. [Skotlex]
+ if (dstsd->sc.data[SC_PROPERTYFIRE] ||
+ dstsd->sc.data[SC_PROPERTYWATER] ||
+ dstsd->sc.data[SC_PROPERTYWIND] ||
+ dstsd->sc.data[SC_PROPERTYGROUND] ||
+ dstsd->sc.data[SC_PROPERTYDARK] ||
+ dstsd->sc.data[SC_PROPERTYTELEKINESIS]
+ // dstsd->sc.data[SC_ENCHANTPOISON] //People say you should be able to recast to lengthen the timer. [Skotlex]
) {
clif->skill_nodamage(src,bl,skill_id,skill_lv,0);
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
@@ -5665,6 +5944,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case CASH_BLESSING:
case CASH_INCAGI:
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)));
else if( sd )
@@ -5724,7 +6004,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SL_KAUPE:
if (sd) {
if (!dstsd || !(
- (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SOULLINKER) ||
+ (sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_SOULLINKER) ||
(dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER ||
dstsd->status.char_id == sd->status.char_id ||
dstsd->status.char_id == sd->status.partner_id ||
@@ -5948,7 +6228,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
break;
case MER_COMPRESS:
- status_change_end(bl, SC_BLEEDING, INVALID_TIMER);
+ status_change_end(bl, SC_BLOODING, INVALID_TIMER);
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
break;
case MER_MENTALCURE:
@@ -6019,8 +6299,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
// Weapon Refining [Celest]
case WS_WEAPONREFINE:
- if(sd)
+ if(sd){
+ sd->state.prerefining = 1;
clif->item_refine_list(sd);
+ }
break;
case MC_VENDING:
@@ -6029,7 +6311,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if ( !pc->can_give_items(sd) )
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
else {
- sd->state.prevend = 1;
+ sd->state.prevend = sd->state.workinprogress = 3;
clif->openvendingreq(sd,2+skill_lv);
}
}
@@ -6039,7 +6321,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if(sd)
{
if (map[bl->m].flag.noteleport && skill_lv <= 2) {
- clif->skill_teleportmessage(sd,0);
+ clif->skill_mapinfomessage(sd,0);
break;
}
if(!battle_config.duel_allow_teleport && sd->duel_group && skill_lv <= 2) { // duel restriction [LuzZza]
@@ -6162,7 +6444,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
//Special message when trying to use strip on FCP [Jobbie]
- if( sd && skill_id == ST_FULLSTRIP && tsc && tsc->data[SC_CP_WEAPON] && tsc->data[SC_CP_HELM] && tsc->data[SC_CP_ARMOR] && tsc->data[SC_CP_SHIELD])
+ if( sd && skill_id == ST_FULLSTRIP && tsc && tsc->data[SC_PROTECTWEAPON] && tsc->data[SC_PROTECTHELM] && tsc->data[SC_PROTECTARMOR] && tsc->data[SC_PROTECTSHIELD])
{
clif->gospel_info(sd, 0x28);
break;
@@ -6212,7 +6494,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
potion_target = bl->id;
run_script(sd->inventory_data[i]->script,0,sd->bl.id,0);
potion_flag = potion_target = 0;
- if( sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_ALCHEMIST )
+ if( sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_ALCHEMIST )
bonus += sd->status.base_level;
if( potion_per_hp > 0 || potion_per_sp > 0 ) {
hp = tstatus->max_hp * potion_per_hp / 100;
@@ -6339,9 +6621,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
{
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
if((dstsd && (dstsd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER)
- || (tsc && tsc->data[SC_SPIRIT] && tsc->data[SC_SPIRIT]->val2 == SL_ROGUE) //Rogue's spirit defends againt dispel.
- || rnd()%100 >= 50+10*skill_lv
- || ( tsc && tsc->option&OPTION_MADOGEAR ) )//Mado Gear is immune to dispell according to bug report 49 [Ind]
+ || (tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SL_ROGUE) //Rogue's spirit defends againt dispel.
+ || rnd()%100 >= 50+10*skill_lv )
{
if (sd)
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
@@ -6354,78 +6635,39 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
}
-
- for(i=0;i<SC_MAX;i++)
+
+ for(i = 0; i < SC_MAX; i++)
{
- if (!tsc->data[i])
- continue;
- switch (i) {
- case SC_WEIGHT50: case SC_WEIGHT90: case SC_HALLUCINATION:
- case SC_STRIPWEAPON: case SC_STRIPSHIELD: case SC_STRIPARMOR:
- case SC_STRIPHELM: case SC_CP_WEAPON: case SC_CP_SHIELD:
- case SC_CP_ARMOR: case SC_CP_HELM: case SC_COMBO:
- case SC_STRFOOD: case SC_AGIFOOD: case SC_VITFOOD:
- case SC_INTFOOD: case SC_DEXFOOD: case SC_LUKFOOD:
- case SC_HITFOOD: case SC_FLEEFOOD: case SC_BATKFOOD:
- case SC_WATKFOOD: case SC_MATKFOOD: case SC_DANCING:
- case SC_EDP: case SC_AUTOBERSERK:
- case SC_CARTBOOST: case SC_MELTDOWN: case SC_SAFETYWALL:
- case SC_SMA: case SC_SPEEDUP0: case SC_NOCHAT:
- case SC_ANKLE: case SC_SPIDERWEB: case SC_JAILED:
- case SC_ITEMBOOST: case SC_EXPBOOST: case SC_LIFEINSURANCE:
- case SC_BOSSMAPINFO: case SC_PNEUMA: case SC_AUTOSPELL:
- case SC_INCHITRATE: case SC_INCATKRATE: case SC_NEN:
- case SC_READYSTORM: case SC_READYDOWN: case SC_READYTURN:
- case SC_READYCOUNTER: case SC_DODGE: case SC_WARM:
- case SC_SPEEDUP1: case SC_AUTOTRADE: case SC_CRITICALWOUND:
- case SC_JEXPBOOST: case SC_INVINCIBLE: case SC_INVINCIBLEOFF:
- case SC_HELLPOWER: case SC_MANU_ATK: case SC_MANU_DEF:
- case SC_SPL_ATK: case SC_SPL_DEF: case SC_MANU_MATK:
- case SC_SPL_MATK: case SC_RICHMANKIM: case SC_ETERNALCHAOS:
- case SC_DRUMBATTLE: case SC_NIBELUNGEN: case SC_ROKISWEIL:
- case SC_INTOABYSS: case SC_SIEGFRIED: case SC_FOOD_STR_CASH:
- case SC_FOOD_AGI_CASH: case SC_FOOD_VIT_CASH: case SC_FOOD_DEX_CASH:
- case SC_FOOD_INT_CASH: case SC_FOOD_LUK_CASH: case SC_SEVENWIND:
- case SC_MIRACLE: case SC_S_LIFEPOTION: case SC_L_LIFEPOTION:
- case SC_INCHEALRATE: case SC_ELECTRICSHOCKER: case SC__STRIPACCESSORY:
- //case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD: case SC_MINOR_BBQ:
- //case SC_SIROMA_ICE_TEA: case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES:
- case SC_NEUTRALBARRIER_MASTER: case SC_NEUTRALBARRIER: case SC_STEALTHFIELD_MASTER:
- case SC_STEALTHFIELD: case SC_GIANTGROWTH: case SC_MILLENNIUMSHIELD:
- case SC_REFRESH: case SC_STONEHARDSKIN: case SC_VITALITYACTIVATION:
- case SC_FIGHTINGSPIRIT: case SC_ABUNDANCE: case SC__SHADOWFORM:
- case SC_LEADERSHIP: case SC_GLORYWOUNDS: case SC_SOULCOLD:
- case SC_HAWKEYES: case SC_GUILDAURA: case SC_PUSH_CART:
- case SC_RAISINGDRAGON: case SC_GT_ENERGYGAIN: case SC_GT_CHANGE:
- case SC_GT_REVITALIZE: case SC_REFLECTDAMAGE: case SC_INSPIRATION:
- case SC_EXEEDBREAK: case SC_FORCEOFVANGUARD: case SC_BANDING:
- case SC_DUPLELIGHT: case SC_EXPIATIO: case SC_LAUDAAGNUS:
- case SC_LAUDARAMUS: case SC_GATLINGFEVER: case SC_INCREASING:
- case SC_ADJUSTMENT: case SC_MADNESSCANCEL: case SC_ALL_RIDING:
- #ifdef RENEWAL
- case SC_EXTREMITYFIST2:
- #endif
- continue;
- /**
- * bugreport:4888 these songs may only be dispelled if you're not in their song area anymore
- **/
- case SC_WHISTLE:
- case SC_ASSNCROS:
- case SC_POEMBRAGI:
- case SC_APPLEIDUN:
- case SC_HUMMING:
- case SC_DONTFORGETME:
- case SC_FORTUNE:
- case SC_SERVICE4U:
- if( !tsc->data[i]->val4 ) //val4 = out-of-song-area
+ if ( !tsc->data[i] )
continue;
- break;
- case SC_ASSUMPTIO:
- if( bl->type == BL_MOB )
+ if( SC_COMMON_MAX < i ){
+ if ( status_get_sc_type(i)&SC_NO_DISPELL )
continue;
- break;
}
- if(i==SC_BERSERK || i==SC_SATURDAYNIGHTFEVER) tsc->data[i]->val2=0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
+ switch (i) {
+ /**
+ * bugreport:4888 these songs may only be dispelled if you're not in their song area anymore
+ **/
+ case SC_WHISTLE:
+ case SC_ASSNCROS:
+ case SC_POEMBRAGI:
+ case SC_APPLEIDUN:
+ case SC_HUMMING:
+ case SC_DONTFORGETME:
+ case SC_FORTUNE:
+ case SC_SERVICEFORYOU:
+ if( tsc->data[i]->val4 ) //val4 = out-of-song-area
+ continue;
+ break;
+ case SC_ASSUMPTIO:
+ if( bl->type == BL_MOB )
+ continue;
+ break;
+ case SC_BERSERK:
+ case SC_SATURDAY_NIGHT_FEVER:
+ tsc->data[i]->val2=0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
+ break;
+ }
status_change_end(bl, (sc_type)i, INVALID_TIMER);
}
break;
@@ -6537,7 +6779,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
static const int spellarray[3] = { MG_COLDBOLT,MG_FIREBOLT,MG_LIGHTNINGBOLT };
if(skill_lv >= 10) {
spellid = MG_FROSTDIVER;
- // if (tsc && tsc->data[SC_SPIRIT] && tsc->data[SC_SPIRIT]->val2 == SA_SAGE)
+ // if (tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SA_SAGE)
// maxlv = 10;
// else
maxlv = skill_lv - 9;
@@ -6665,9 +6907,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case NPC_SPEEDUP:
{
// or does it increase casting rate? just a guess xD
- int i = SC_ASPDPOTION0 + skill_lv - 1;
- if (i > SC_ASPDPOTION3)
- i = SC_ASPDPOTION3;
+ int i = SC_ATTHASTE_POTION1 + skill_lv - 1;
+ 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));
}
@@ -6739,7 +6981,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case NPC_AGIUP:
- sc_start(bl,SC_SPEEDUP1,100,skill_lv,skill->get_time(skill_id, skill_lv));
+ sc_start(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)));
break;
@@ -7018,7 +7260,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
for (i=0 ; i<4; i++) {
if( bl->type != BL_PC || ( dstsd && pc->checkequip(dstsd,equip[i]) < 0 ) )
continue;
- sc_start(bl,(sc_type)(SC_CP_WEAPON + i),100,skill_lv,skilltime);
+ sc_start(bl,(sc_type)(SC_PROTECTWEAPON + i),100,skill_lv,skilltime);
s++;
}
if( sd && !s ){
@@ -7048,6 +7290,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case CG_TAROTCARD:
{
int eff, count = -1;
+ if( tsc && tsc->data[type] ){
+ iMap->freeblock_unlock();
+ return 0;
+ }
if( rnd() % 100 > skill_lv * 8 || (dstmd && ((dstmd->guardian_data && dstmd->class_ == MOBID_EMPERIUM) || mob_is_battleground(dstmd))) )
{
if( sd )
@@ -7059,7 +7305,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
status_zap(src,0,skill_db[skill->get_index(skill_id)].sp[skill_lv]); // consume sp only if succeeded [Inkfish]
do {
eff = rnd() % 14;
- clif->specialeffect(bl, 523 + eff, AREA);
+ if( eff == 5 )
+ clif->specialeffect(src, 528, AREA);
+ else
+ clif->specialeffect(bl, 523 + eff, AREA);
switch (eff)
{
case 0: // heals SP to 0
@@ -7129,6 +7378,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
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));
break;
default:
break;
@@ -7153,7 +7403,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SL_STAR:
case SL_SUPERNOVICE:
case SL_WIZARD:
- //NOTE: here, 'type' has the value of the associated MAPID, not of the SC_SPIRIT constant.
+ //NOTE: here, 'type' has the value of the associated MAPID, not of the SC_SOULLINK constant.
if (sd && !(dstsd && (dstsd->class_&MAPID_UPPERMASK) == type)) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
break;
@@ -7163,11 +7413,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
dstsd->die_counter = 0;
pc_setglobalreg(dstsd,"PC_DIE_COUNTER", 0);
clif->specialeffect(bl, 0x152, AREA);
- //SC_SPIRIT invokes status_calc_pc for us.
+ //SC_SOULLINK invokes status_calc_pc for us.
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start4(bl,SC_SPIRIT,100,skill_lv,skill_id,0,0,skill->get_time(skill_id,skill_lv)));
- sc_start(src,SC_SMA,100,skill_lv,skill->get_time(SL_SMA,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));
break;
case SL_HIGH:
if (sd && !(dstsd && (dstsd->class_&JOBL_UPPER) && !(dstsd->class_&JOBL_2) && dstsd->status.base_level < 70)) {
@@ -7176,7 +7426,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,
sc_start4(bl,type,100,skill_lv,skill_id,0,0,skill->get_time(skill_id,skill_lv)));
- sc_start(src,SC_SMA,100,skill_lv,skill->get_time(SL_SMA,skill_lv));
+ sc_start(src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA,skill_lv));
break;
case SL_SWOO:
@@ -7196,7 +7446,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
if (skill_id == SL_SKE)
- sc_start(src,SC_SMA,100,skill_lv,skill->get_time(SL_SMA,skill_lv));
+ sc_start(src,SC_SMA_READY,100,skill_lv,skill->get_time(SL_SMA,skill_lv));
break;
// New guild skills [Celest]
@@ -7385,7 +7635,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case NPC_DRAGONFEAR:
if (flag&1) {
- const enum sc_type sc[] = { SC_STUN, SC_SILENCE, SC_CONFUSION, SC_BLEEDING };
+ const enum sc_type sc[] = { SC_STUN, SC_SILENCE, SC_CONFUSION, SC_BLOODING };
int j;
j = i = rnd()%ARRAYLENGTH(sc);
while ( !sc_start2(bl,sc[i],100,skill_lv,src->id,skill->get_time2(skill_id,i+1)) ) {
@@ -7482,7 +7732,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
break;
case RK_STONEHARDSKIN:
- if( sd && pc->checkskill(sd,RK_RUNEMASTERY) >= 4 )
+ if( sd )
{
int heal = sstatus->hp / 4; // 25% HP
if( status_charge(bl,heal,0) )
@@ -7492,7 +7742,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
break;
case RK_REFRESH:
- if( sd && pc->checkskill(sd,RK_RUNEMASTERY) >= 8 )
{
int heal = status_get_max_hp(bl) * 25 / 100;
clif->skill_nodamage(src,bl,skill_id,skill_lv,
@@ -7503,8 +7752,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case RK_MILLENNIUMSHIELD:
- if( sd && pc->checkskill(sd,RK_RUNEMASTERY) >= 9 )
- {
+ if( sd ){
short shields = (rnd()%100<50) ? 4 : ((rnd()%100<80) ? 3 : 2);
sc_start4(bl,type,100,skill_lv,shields,1000,0,skill->get_time(skill_id,skill_lv));
clif->millenniumshield(sd,shields);
@@ -7512,31 +7760,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
break;
- case RK_GIANTGROWTH:
- case RK_VITALITYACTIVATION:
- case RK_ABUNDANCE:
- case RK_CRUSHSTRIKE:
- if( sd )
- {
- int lv = 1; // RK_GIANTGROWTH
- if( skill_id == RK_VITALITYACTIVATION )
- lv = 2;
- else if( skill_id == RK_ABUNDANCE )
- lv = 6;
- else if( skill_id == RK_CRUSHSTRIKE )
- lv = 7;
- if( pc->checkskill(sd,RK_RUNEMASTERY) >= lv )
- clif->skill_nodamage(src,bl,skill_id,skill_lv,sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv)));
- }
- break;
-
case RK_FIGHTINGSPIRIT:
if( flag&1 ) {
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));
else
sc_start(bl,type,100,skill_area_temp[5]/4,skill->get_time(skill_id,skill_lv));
- } else if( sd && pc->checkskill(sd,RK_RUNEMASTERY) >= 5 ) {
+ } else if( sd ) {
if( sd->status.party_id ) {
i = party_foreachsamemap(skill->area_sub,sd,skill->get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,BCT_PARTY,skill->area_sub_count);
skill_area_temp[5] = 7 * i; // ATK
@@ -7688,14 +7918,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case AB_LAUDAAGNUS:
if( flag&1 || sd == NULL ) {
if( tsc && (tsc->data[SC_FREEZE] || tsc->data[SC_STONE] || tsc->data[SC_BLIND] ||
- tsc->data[SC_BURNING] || tsc->data[SC_FREEZING] || tsc->data[SC_CRYSTALIZE])) {
+ tsc->data[SC_BURNING] || tsc->data[SC_FROSTMISTY] || tsc->data[SC_CRYSTALIZE])) {
// Success Chance: (40 + 10 * Skill Level) %
if( rnd()%100 > 40+10*skill_lv ) break;
status_change_end(bl, SC_FREEZE, INVALID_TIMER);
status_change_end(bl, SC_STONE, INVALID_TIMER);
status_change_end(bl, SC_BLIND, INVALID_TIMER);
status_change_end(bl, SC_BURNING, INVALID_TIMER);
- status_change_end(bl, SC_FREEZING, INVALID_TIMER);
+ status_change_end(bl, SC_FROSTMISTY, INVALID_TIMER);
status_change_end(bl, SC_CRYSTALIZE, 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,
@@ -7734,61 +7964,24 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
}
if(status_isimmune(bl) || !tsc || !tsc->count)
break;
- for(i=0;i<SC_MAX;i++)
+ for(i = 0; i < SC_MAX; i++)
{
- if (!tsc->data[i])
- continue;
- switch (i) {
- case SC_WEIGHT50: case SC_WEIGHT90: case SC_HALLUCINATION:
- case SC_STRIPWEAPON: case SC_STRIPSHIELD: case SC_STRIPARMOR:
- case SC_STRIPHELM: case SC_CP_WEAPON: case SC_CP_SHIELD:
- case SC_CP_ARMOR: case SC_CP_HELM: case SC_COMBO:
- case SC_STRFOOD: case SC_AGIFOOD: case SC_VITFOOD:
- case SC_INTFOOD: case SC_DEXFOOD: case SC_LUKFOOD:
- case SC_HITFOOD: case SC_FLEEFOOD: case SC_BATKFOOD:
- case SC_WATKFOOD: case SC_MATKFOOD: case SC_DANCING:
- case SC_SPIRIT: case SC_AUTOBERSERK:
- case SC_CARTBOOST: case SC_MELTDOWN: case SC_SAFETYWALL:
- case SC_SMA: case SC_SPEEDUP0: case SC_NOCHAT:
- case SC_ANKLE: case SC_SPIDERWEB: case SC_JAILED:
- case SC_ITEMBOOST: case SC_EXPBOOST: case SC_LIFEINSURANCE:
- case SC_BOSSMAPINFO: case SC_PNEUMA: case SC_AUTOSPELL:
- case SC_INCHITRATE: case SC_INCATKRATE: case SC_NEN:
- case SC_READYSTORM: case SC_READYDOWN: case SC_READYTURN:
- case SC_READYCOUNTER:case SC_DODGE: case SC_WARM:
- case SC_SPEEDUP1: case SC_AUTOTRADE: case SC_CRITICALWOUND:
- case SC_JEXPBOOST: case SC_INVINCIBLE: case SC_INVINCIBLEOFF:
- case SC_HELLPOWER: case SC_MANU_ATK: case SC_MANU_DEF:
- case SC_SPL_ATK: case SC_SPL_DEF: case SC_MANU_MATK:
- case SC_SPL_MATK: case SC_RICHMANKIM: case SC_ETERNALCHAOS:
- case SC_DRUMBATTLE: case SC_NIBELUNGEN: case SC_ROKISWEIL:
- case SC_INTOABYSS: case SC_SIEGFRIED: case SC_WHISTLE:
- case SC_ASSNCROS: case SC_POEMBRAGI: case SC_APPLEIDUN:
- case SC_HUMMING: case SC_DONTFORGETME: case SC_FORTUNE:
- case SC_SERVICE4U: case SC_FOOD_STR_CASH: case SC_FOOD_AGI_CASH:
- case SC_FOOD_VIT_CASH: case SC_FOOD_DEX_CASH: case SC_FOOD_INT_CASH:
- case SC_FOOD_LUK_CASH: case SC_ELECTRICSHOCKER: case SC_BITE:
- case SC__STRIPACCESSORY: case SC__ENERVATION: case SC__GROOMY:
- case SC__IGNORANCE: case SC__LAZINESS: case SC__UNLUCKY:
- case SC__WEAKNESS: //case SC_SAVAGE_STEAK: case SC_COCKTAIL_WARG_BLOOD:
- case SC_MAGNETICFIELD://case SC_MINOR_BBQ: case SC_SIROMA_ICE_TEA:
- //case SC_DROCERA_HERB_STEAMED: case SC_PUTTI_TAILS_NOODLES:
- case SC_NEUTRALBARRIER_MASTER: case SC_NEUTRALBARRIER:
- case SC_STEALTHFIELD_MASTER: case SC_STEALTHFIELD:
- case SC_LEADERSHIP: case SC_GLORYWOUNDS: case SC_SOULCOLD:
- case SC_HAWKEYES: case SC_GUILDAURA: case SC_PUSH_CART:
- case SC_PARTYFLEE: case SC_GT_REVITALIZE:
- case SC_RAISINGDRAGON: case SC_GT_ENERGYGAIN: case SC_GT_CHANGE:
- #ifdef RENEWAL
- case SC_EXTREMITYFIST2:
- #endif
- continue;
- case SC_ASSUMPTIO:
- if( bl->type == BL_MOB )
+ if( SC_COMMON_MAX > i ){
+ if ( !tsc->data[i] || !status_get_sc_type(i) )
continue;
- break;
+ if ( status_get_sc_type(i)&SC_NO_CLEARANCE )
+ continue;
+ }
+ switch (i) {
+ case SC_ASSUMPTIO:
+ if( bl->type == BL_MOB )
+ continue;
+ break;
+ case SC_BERSERK:
+ case SC_SATURDAY_NIGHT_FEVER:
+ tsc->data[i]->val2=0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
+ break;
}
- if(i==SC_BERSERK || i==SC_SATURDAYNIGHTFEVER) tsc->data[i]->val2=0; //Mark a dispelled berserk to avoid setting hp to 100 by setting hp penalty to 0.
status_change_end(bl,(sc_type)i,INVALID_TIMER);
}
break;
@@ -7830,7 +8023,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( !(tsc && tsc->data[type]) ){
i = sc_start2(bl,type,rate,skill_lv,src->id,(src == bl)?5000:(bl->type == BL_PC)?skill->get_time(skill_id,skill_lv):skill->get_time2(skill_id, skill_lv));
clif->skill_nodamage(src,bl,skill_id,skill_lv,i);
- if( !i )
+ if( sd && !i )
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
}
}else
@@ -7849,42 +8042,24 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case WL_MARSHOFABYSS:
- // Should marsh of abyss still apply half reduction to players after the 28/10 patch? [LimitLine]
clif->skill_nodamage(src, bl, skill_id, skill_lv,
- sc_start4(bl, type, 100, skill_lv, status_get_int(src), sd ? sd->status.job_level : 50, 0,
- skill->get_time(skill_id, skill_lv)));
+ sc_start(bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv)));
break;
case WL_SIENNAEXECRATE:
- if( status_isimmune(bl) || !tsc )
- break;
-
if( flag&1 ) {
- if( bl->id == skill_area_temp[1] )
- break; // Already work on this target
-
+ if( status_isimmune(bl) || !tsc )
+ break;
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,1000,skill->get_time(skill_id, skill_lv),2);
+ status_change_start(bl,SC_STONE,10000,skill_lv,0,0,500,skill->get_time(skill_id, skill_lv),2);
} else {
- int rate = 40 + 8 * skill_lv + ( sd? sd->status.job_level : 50 ) / 4;
- // IroWiki says Rate should be reduced by target stats, but currently unknown
- if( rnd()%100 < rate ) { // Success on First Target
- if( !tsc->data[SC_STONE] )
- rate = status_change_start(bl,SC_STONE,10000,skill_lv,0,0,1000,skill->get_time(skill_id, skill_lv),2);
- else {
- rate = 1;
- status_change_end(bl,SC_STONE,INVALID_TIMER);
- }
-
- if( rate ) {
- skill_area_temp[1] = bl->id;
- iMap->foreachinrange(skill->area_sub,bl,skill->get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_nodamage_id);
- }
- // Doesn't send failure packet if it fails on defense.
- }
- else if( sd ) // Failure on Rate
+ int rate = 45 + 5 * skill_lv;
+ if( rnd()%100 < rate ){
+ clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
+ iMap->foreachinrange(skill_area_sub,bl,skill->get_splash(skill_id,skill_lv),BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_nodamage_id);
+ }else if( sd ) // Failure on Rate
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
}
break;
@@ -7893,36 +8068,13 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case WL_SUMMONBL:
case WL_SUMMONWB:
case WL_SUMMONSTONE:
- {
- short element = 0, sctype = 0, pos = -1;
- struct status_change *sc = status_get_sc(src);
- if( !sc ) break;
-
- for( i = SC_SPHERE_1; i <= SC_SPHERE_5; i++ )
- {
- if( !sctype && !sc->data[i] )
- sctype = i; // Take the free SC
- if( sc->data[i] )
- pos = max(sc->data[i]->val2,pos);
- }
-
- if( !sctype )
- {
- if( sd ) // No free slots to put SC
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_SUMMON,0);
+ for( i = SC_SUMMON1; i <= SC_SUMMON5; i++ ){
+ if( tsc && !tsc->data[i] ){ // officially it doesn't work like a stack
+ int ele = WLS_FIRE + (skill_id - WL_SUMMONFB) - (skill_id == WL_SUMMONSTONE ? 4 : 0);
+ clif->skill_nodamage(src, bl, skill_id, skill_lv,
+ sc_start(bl, (sc_type)i, 100, ele, skill->get_time(skill_id, skill_lv)));
break;
}
-
- pos++; // Used in val2 for SC. Indicates the order of this ball
- switch( skill_id ) { // Set val1. The SC element for this ball
- case WL_SUMMONFB: element = WLS_FIRE; break;
- case WL_SUMMONBL: element = WLS_WIND; break;
- case WL_SUMMONWB: element = WLS_WATER; break;
- case WL_SUMMONSTONE: element = WLS_STONE; break;
- }
-
- sc_start4(src,sctype,100,element,pos,skill_lv,0,skill->get_time(skill_id,skill_lv));
- clif->skill_nodamage(src,bl,skill_id,0,0);
}
break;
@@ -7930,10 +8082,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( sd ) {
struct status_change *sc = status_get_sc(bl);
- for( i = SC_SPELLBOOK1; i <= SC_MAXSPELLBOOK; i++)
+ for( i = SC_SPELLBOOK1; i <= SC_SPELLBOOK7; i++)
if( sc && !sc->data[i] )
break;
- if( i == SC_MAXSPELLBOOK ) {
+ if( i == SC_SPELLBOOK7 ) {
clif->skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_READING, 0);
break;
}
@@ -7998,9 +8150,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case NC_B_SIDESLIDE:
{
uint8 dir = (skill_id == NC_F_SIDESLIDE) ? (unit_getdir(src)+4)%8 : unit_getdir(src);
- skill->blown(src,bl,skill->get_blewcount(skill_id,skill_lv),dir,0x1);
+ skill->blown(src,bl,skill->get_blewcount(skill_id,skill_lv),dir,0);
clif->slide(src,src->x,src->y);
- clif->fixpos(src); //Aegis sent this packet
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
}
break;
@@ -8266,7 +8417,34 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
}
break;
-
+ case LG_KINGS_GRACE:
+ if( flag&1 ){
+ sc_start(bl,type,100,skill_lv,skill->get_time(skill_id,skill_lv));
+ for(i=0; i<SC_MAX; i++)
+ {
+ if (!tsc->data[i])
+ continue;
+ switch(i){
+ 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_CRYSTALIZE: case SC_FROSTMISTY:
+ case SC_DEEP_SLEEP: case SC_FEAR:
+ case SC_MANDRAGORA:
+ status_change_end(bl, (sc_type)i, INVALID_TIMER);
+ }
+ }
+ }else {
+ skill_area_temp[2] = 0;
+ if( !map_flag_vs(src->m) && !map_flag_gvg(src->m) )
+ flag |= BCT_GUILD;
+ iMap->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);
+ clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
+ }
+ break;
case LG_INSPIRATION:
if( sd && !map[sd->bl.m].flag.noexppenalty && sd->status.base_level != MAX_LEVEL ) {
sd->status.base_exp -= min(sd->status.base_exp, pc->nextbaseexp(sd) * 1 / 100); // 1% penalty.
@@ -8358,9 +8536,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
status_change_end(bl, SC_POISON, INVALID_TIMER);
status_change_end(bl, SC_SILENCE, INVALID_TIMER);
status_change_end(bl, SC_BLIND, INVALID_TIMER);
- status_change_end(bl, SC_HALLUCINATION, INVALID_TIMER);
+ status_change_end(bl, SC_ILLUSION, INVALID_TIMER);
status_change_end(bl, SC_BURNING, INVALID_TIMER);
- status_change_end(bl, SC_FREEZING, INVALID_TIMER);
+ status_change_end(bl, SC_FROSTMISTY, INVALID_TIMER);
}
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
@@ -8371,6 +8549,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
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)));
break;
+ case SR_FLASHCOMBO:
+ 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 + 600 * (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) )
@@ -8586,7 +8769,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case SO_ARRULLO:
{
- // [(15 + 5 * Skill Level) + ( Caster�s INT / 5 ) + ( Caster�s Job Level / 5 ) - ( Target�s INT / 6 ) - ( Target�s LUK / 10 )] %
+ // [(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);
rate -= status_get_int(bl)/6 - status_get_luk(bl)/10;
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
@@ -8596,7 +8779,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
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)] %
+ //[(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));
@@ -8843,7 +9026,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if(sd) {
int ttype = skill->get_ele(skill_id, skill_lv);
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
- pc->add_talisman(sd, skill->get_time(skill_id, skill_lv), 10, ttype);
+ ARR_FIND(1, 6, i, sd->charm[i] > 0 && ttype != i);
+ if( i < 6 )
+ pc->del_charm(sd, sd->charm[i], i); // replace with a new one.
+ pc->add_charm(sd, skill->get_time(skill_id, skill_lv), 10, ttype);
}
break;
@@ -8868,45 +9054,50 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break;
case KO_KYOUGAKU:
- if( dstsd && tsc && !tsc->data[type] && rand()%100 < tstatus->int_/2 ){
- clif->skill_nodamage(src,bl,skill_id,skill_lv,
- sc_start(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);
+ {
+ int rate = max(5, (45 + 5 * skill_lv - status_get_int(bl) / 10));
+ if( sd && !map_flag_gvg(src->m) ){
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_SIZE, 0);
+ break;
+ }
+ 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)));
+ }else if( sd )
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
+ }
break;
case KO_JYUSATSU:
if( dstsd && tsc && !tsc->data[type] &&
- rand()%100 < ((45+5*skill_lv) + skill_lv*5 - status_get_int(bl)/2) ){//[(Base chance of success) + (Skill Level x 5) - (int / 2)]%.
- 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_zap(bl, tstatus->max_hp*skill_lv*5/100 , 0);
+ 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_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,10,skill_lv,0,src->id,0,0,0);
+ status_change_start(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);
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
break;
case KO_GENWAKU:
- if ( !map_flag_gvg(src->m) && ( dstsd || dstmd ) && battle->check_target(src,bl,BCT_ENEMY) > 0 ) {
+ if ( !map_flag_gvg(src->m) && ( dstsd || dstmd ) && !(tstatus->mode&MD_PLANT) && battle->check_target(src,bl,BCT_ENEMY) > 0 ) {
int x = src->x, y = src->y;
-
- if( sd && rnd()%100 > ((45+5*skill_lv) - status_get_int(bl)/10) ){//[(Base chance of success) - (Intelligence Objectives / 10)]%.
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ if( sd && rnd()%100 > max(5, (45 + 5 * skill_lv) - status_get_int(bl) / 10) ){//[(Base chance of success) - ( target's int / 10)]%.
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
break;
}
- 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,80,skill_lv,skill->get_time(skill_id,skill_lv));
- if (unit_movepos(bl,x,y,0,0))
+ 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));
+ if ( !is_boss(bl) && unit_stop_walking(&sd->bl, 1) && unit_movepos(bl, x, y, 0, 0) )
{
- clif->skill_damage(bl,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, -1, 6);
- if( bl->type == BL_PC && pc_issit((TBL_PC*)bl))
- clif->sitting(bl); //Avoid sitting sync problem
- clif->slide(bl,x,y) ;
- sc_start(bl,SC_CONFUSION,80,skill_lv,skill->get_time(skill_id,skill_lv));
+ 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));
}
}
}
@@ -8916,7 +9107,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
case OB_OBOROGENSOU:
if( sd && ( (skill_id == OB_OBOROGENSOU && bl->type == BL_MOB) // This skill does not work on monsters.
|| is_boss(bl) ) ){ // Does not work on Boss monsters.
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_TOTARGET_PLAYER, 0);
break;
}
case KO_IZAYOI:
@@ -8932,7 +9123,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
if( flag&1 ){
if(tsc && ( tsc->option&(OPTION_CLOAK|OPTION_HIDE) ||
tsc->data[SC_CAMOUFLAGE] || tsc->data[SC__SHADOWFORM] ||
- tsc->data[SC_MARIONETTE] || tsc->data[SC_HARMONIZE])){
+ 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));
status_change_end(bl, SC_HIDING, INVALID_TIMER);
@@ -8940,7 +9131,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
- status_change_end(bl, SC_MARIONETTE, INVALID_TIMER);
+ status_change_end(bl, SC_MARIONETTE_MASTER, INVALID_TIMER);
status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
}
if( skill_area_temp[2] == 1 ){
@@ -8957,7 +9148,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
struct status_change *ssc = status_get_sc(src);
struct block_list *m_bl = battle->get_master(src);
const enum sc_type scs[] = {
- SC_MANDRAGORA, SC_HARMONIZE, SC_DEEPSLEEP, SC_VOICEOFSIREN, SC_SLEEP, SC_CONFUSION, SC_HALLUCINATION
+ SC_MANDRAGORA, SC_HARMONIZE, SC_DEEP_SLEEP, SC_SIREN, SC_SLEEP, SC_CONFUSION, SC_ILLUSION
};
int heal;
if(tsc){
@@ -9084,333 +9275,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
/*==========================================
*
*------------------------------------------*/
-int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
-{
- struct block_list *target, *src;
- struct map_session_data *sd;
- struct mob_data *md;
- struct unit_data *ud;
- struct status_change *sc = NULL;
- int inf,inf2,flag = 0;
-
- src = iMap->id2bl(id);
- if( src == NULL )
- {
- ShowDebug("skill_castend_id: src == NULL (tid=%d, id=%d)\n", tid, id);
- return 0;// not found
- }
-
- ud = unit_bl2ud(src);
- if( ud == NULL )
- {
- ShowDebug("skill_castend_id: ud == NULL (tid=%d, id=%d)\n", tid, id);
- return 0;// ???
- }
-
- sd = BL_CAST(BL_PC, src);
- md = BL_CAST(BL_MOB, src);
-
- if( src->prev == NULL ) {
- ud->skilltimer = INVALID_TIMER;
- return 0;
- }
-
- if(ud->skill_id != SA_CASTCANCEL && ud->skill_id != SO_SPELLFIST) {// otherwise handled in unit_skillcastcancel()
- if( ud->skilltimer != tid ) {
- ShowError("skill_castend_id: Timer mismatch %d!=%d!\n", ud->skilltimer, tid);
- ud->skilltimer = INVALID_TIMER;
- return 0;
- }
-
- if( sd && ud->skilltimer != INVALID_TIMER && (pc->checkskill(sd,SA_FREECAST) > 0 || ud->skill_id == LG_EXEEDBREAK) )
- {// restore original walk speed
- ud->skilltimer = INVALID_TIMER;
- status_calc_bl(&sd->bl, SCB_SPEED);
- }
-
- ud->skilltimer = INVALID_TIMER;
- }
-
- if (ud->skilltarget == id)
- target = src;
- else
- target = iMap->id2bl(ud->skilltarget);
-
- // Use a do so that you can break out of it when the skill fails.
- do {
- if(!target || target->prev==NULL) break;
-
- if(src->m != target->m || status_isdead(src)) break;
-
- switch (ud->skill_id) {
- //These should become skill_castend_pos
- case WE_CALLPARTNER:
- if(sd) clif->callpartner(sd);
- case WE_CALLPARENT:
- case WE_CALLBABY:
- case AM_RESURRECTHOMUN:
- case PF_SPIDERWEB:
- //Find a random spot to place the skill. [Skotlex]
- inf2 = skill->get_splash(ud->skill_id, ud->skill_lv);
- ud->skillx = target->x + inf2;
- ud->skilly = target->y + inf2;
- if (inf2 && !iMap->random_dir(target, &ud->skillx, &ud->skilly)) {
- ud->skillx = target->x;
- ud->skilly = target->y;
- }
- ud->skilltimer=tid;
- return skill->castend_pos(tid,tick,id,data);
- case GN_WALLOFTHORN:
- ud->skillx = target->x;
- ud->skilly = target->y;
- ud->skilltimer = tid;
- return skill->castend_pos(tid,tick,id,data);
- }
-
- if(ud->skill_id == RG_BACKSTAP) {
- uint8 dir = iMap->calc_dir(src,target->x,target->y),t_dir = unit_getdir(target);
- if(check_distance_bl(src, target, 0) || iMap->check_dir(dir,t_dir)) {
- break;
- }
- }
-
- if( ud->skill_id == PR_TURNUNDEAD ) {
- struct status_data *tstatus = status_get_status_data(target);
- if( !battle->check_undead(tstatus->race, tstatus->def_ele) )
- break;
- }
-
- if( ud->skill_id == RA_WUGSTRIKE ){
- if( !path_search(NULL,src->m,src->x,src->y,target->x,target->y,1,CELL_CHKNOREACH))
- break;
- }
-
- if( ud->skill_id == PR_LEXDIVINA || ud->skill_id == MER_LEXDIVINA )
- {
- sc = status_get_sc(target);
- if( battle->check_target(src,target, BCT_ENEMY) <= 0 && (!sc || !sc->data[SC_SILENCE]) )
- { //If it's not an enemy, and not silenced, you can't use the skill on them. [Skotlex]
- clif->skill_nodamage (src, target, ud->skill_id, ud->skill_lv, 0);
- break;
- }
- }
- else
- { // Check target validity.
- inf = skill->get_inf(ud->skill_id);
- inf2 = skill->get_inf2(ud->skill_id);
-
- if(inf&INF_ATTACK_SKILL ||
- (inf&INF_SELF_SKILL && inf2&INF2_NO_TARGET_SELF) //Combo skills
- ) // Casted through combo.
- inf = BCT_ENEMY; //Offensive skill.
- else if(inf2&INF2_NO_ENEMY)
- inf = BCT_NOENEMY;
- else
- inf = 0;
-
- if(inf2 & (INF2_PARTY_ONLY|INF2_GUILD_ONLY) && src != target)
- {
- inf |=
- (inf2&INF2_PARTY_ONLY?BCT_PARTY:0)|
- (inf2&INF2_GUILD_ONLY?BCT_GUILD:0);
- //Remove neutral targets (but allow enemy if skill is designed to be so)
- inf &= ~BCT_NEUTRAL;
- }
-
- if( sd && (inf2&INF2_CHORUS_SKILL) && skill->check_pc_partner(sd, ud->skill_id, &ud->skill_lv, 1, 0) < 1 ) {
- clif->skill_fail(sd, ud->skill_id, USESKILL_FAIL_NEED_HELPER, 0);
- break;
- }
-
- if( ud->skill_id >= SL_SKE && ud->skill_id <= SL_SKA && target->type == BL_MOB )
- {
- if( ((TBL_MOB*)target)->class_ == MOBID_EMPERIUM )
- break;
- }
- else if (inf && battle->check_target(src, target, inf) <= 0){
- if (sd) clif->skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0);
- break;
- }
-
- if(inf&BCT_ENEMY && (sc = status_get_sc(target)) &&
- sc->data[SC_FOGWALL] &&
- rnd() % 100 < 75) { //Fogwall makes all offensive-type targetted skills fail at 75%
- if (sd) clif->skill_fail(sd, ud->skill_id, USESKILL_FAIL_LEVEL, 0);
- break;
- }
- }
-
- //Avoid doing double checks for instant-cast skills.
- if (tid != INVALID_TIMER && !status_check_skilluse(src, target, ud->skill_id, 1))
- break;
-
- if(md) {
- md->last_thinktime=tick +MIN_MOBTHINKTIME;
- if(md->skill_idx >= 0 && md->db->skill[md->skill_idx].emotion >= 0)
- clif->emotion(src, md->db->skill[md->skill_idx].emotion);
- }
-
- if(src != target && battle_config.skill_add_range &&
- !check_distance_bl(src, target, skill->get_range2(src,ud->skill_id,ud->skill_lv)+battle_config.skill_add_range))
- {
- if (sd) {
- clif->skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0);
- if(battle_config.skill_out_range_consume) //Consume items anyway. [Skotlex]
- skill->consume_requirement(sd,ud->skill_id,ud->skill_lv,3);
- }
- break;
- }
-
- if( sd )
- {
- if( !skill->check_condition_castend(sd, ud->skill_id, ud->skill_lv) )
- break;
- else
- skill->consume_requirement(sd,ud->skill_id,ud->skill_lv,1);
- }
-#ifdef OFFICIAL_WALKPATH
- if( !path_search_long(NULL, src->m, src->x, src->y, target->x, target->y, CELL_CHKWALL) )
- break;
-#endif
- if( (src->type == BL_MER || src->type == BL_HOM) && !skill->check_condition_mercenary(src, ud->skill_id, ud->skill_lv, 1) )
- break;
-
- if (ud->state.running && ud->skill_id == TK_JUMPKICK) {
- ud->state.running = 0;
- status_change_end(src, SC_RUN, INVALID_TIMER);
- flag = 1;
- }
-
- if (ud->walktimer != INVALID_TIMER && ud->skill_id != TK_RUN && ud->skill_id != RA_WUGDASH)
- unit_stop_walking(src,1);
-
- if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) )
- ud->canact_tick = tick + skill->delay_fix(src, ud->skill_id, ud->skill_lv); //Tests show wings don't overwrite the delay but skill scrolls do. [Inkfish]
- if (sd) { //Cooldown application
- int i, cooldown = skill->get_cooldown(ud->skill_id, ud->skill_lv);
- for (i = 0; i < ARRAYLENGTH(sd->skillcooldown) && sd->skillcooldown[i].id; i++) { // Increases/Decreases cooldown of a skill by item/card bonuses.
- if (sd->skillcooldown[i].id == ud->skill_id){
- cooldown += sd->skillcooldown[i].val;
- break;
- }
- }
- if(cooldown)
- skill->blockpc_start(sd, ud->skill_id, cooldown, false);
- }
- if( battle_config.display_status_timers && sd )
- clif->status_change(src, SI_ACTIONDELAY, 1, skill->delay_fix(src, ud->skill_id, ud->skill_lv), 0, 0, 0);
- if( sd )
- {
- switch( ud->skill_id )
- {
- case GS_DESPERADO:
- sd->canequip_tick = tick + skill->get_time(ud->skill_id, ud->skill_lv);
- break;
- case CR_GRANDCROSS:
- case NPC_GRANDDARKNESS:
- if( (sc = status_get_sc(src)) && sc->data[SC_STRIPSHIELD] )
- {
- const struct TimerData *timer = iTimer->get_timer(sc->data[SC_STRIPSHIELD]->timer);
- if( timer && timer->func == status_change_timer && DIFF_TICK(timer->tick,iTimer->gettick()+skill->get_time(ud->skill_id, ud->skill_lv)) > 0 )
- break;
- }
- sc_start2(src, SC_STRIPSHIELD, 100, 0, 1, skill->get_time(ud->skill_id, ud->skill_lv));
- break;
- }
- }
- if (skill->get_state(ud->skill_id) != ST_MOVE_ENABLE)
- unit_set_walkdelay(src, tick, battle_config.default_walk_delay+skill->get_walkdelay(ud->skill_id, ud->skill_lv), 1);
-
- if(battle_config.skill_log && battle_config.skill_log&src->type)
- ShowInfo("Type %d, ID %d skill castend id [id =%d, lv=%d, target ID %d]\n",
- src->type, src->id, ud->skill_id, ud->skill_lv, target->id);
-
- iMap->freeblock_lock();
-
- // SC_MAGICPOWER needs to switch states before any damage is actually dealt
- skill->toggle_magicpower(src, ud->skill_id);
- 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);
- else
- skill->castend_damage_id(src,target,ud->skill_id,ud->skill_lv,tick,flag);
-
- sc = status_get_sc(src);
- if(sc && sc->count) {
- if(sc->data[SC_SPIRIT] &&
- sc->data[SC_SPIRIT]->val2 == SL_WIZARD &&
- sc->data[SC_SPIRIT]->val3 == ud->skill_id &&
- ud->skill_id != WZ_WATERBALL)
- sc->data[SC_SPIRIT]->val3 = 0; //Clear bounced spell check.
-
- if( sc->data[SC_DANCING] && skill->get_inf2(ud->skill_id)&INF2_SONG_DANCE && sd )
- skill->blockpc_start(sd,BD_ADAPTATION,3000, false);
- }
-
- if( sd && ud->skill_id != SA_ABRACADABRA && ud->skill_id != WM_RANDOMIZESPELL ) // they just set the data so leave it as it is.[Inkfish]
- sd->skillitem = sd->skillitemlv = 0;
-
- if (ud->skilltimer == INVALID_TIMER) {
- if(md) md->skill_idx = -1;
- else ud->skill_id = 0; //mobs can't clear this one as it is used for skill condition 'afterskill'
- ud->skill_lv = ud->skilltarget = 0;
- }
- iMap->freeblock_unlock();
- return 1;
- } while(0);
-
- //Skill failed.
- if (ud->skill_id == MO_EXTREMITYFIST && sd && !(sc && sc->data[SC_FOGWALL]))
- { //When Asura fails... (except when it fails from Fog of Wall)
- //Consume SP/spheres
- skill->consume_requirement(sd,ud->skill_id, ud->skill_lv,1);
- status_set_sp(src, 0, 0);
- sc = &sd->sc;
- if (sc->count)
- { //End states
- 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));
-#endif
- }
- if (target && target->m == src->m)
- { //Move character to target anyway.
- int dir, x, y;
- dir = iMap->calc_dir(src,target->x,target->y);
- if( dir > 0 && dir < 4) x = -2;
- else if( dir > 4 ) x = 2;
- else x = 0;
- if( dir > 2 && dir < 6 ) y = -2;
- else if( dir == 7 || dir < 2 ) y = 2;
- else y = 0;
- if (unit_movepos(src, src->x+x, src->y+y, 1, 1))
- { //Display movement + animation.
- clif->slide(src,src->x,src->y);
- clif->skill_damage(src,target,tick,sd->battle_status.amotion,0,0,1,ud->skill_id, ud->skill_lv, 5);
- }
- clif->skill_fail(sd,ud->skill_id,USESKILL_FAIL_LEVEL,0);
- }
- }
-
- ud->skill_id = ud->skill_lv = ud->skilltarget = 0;
- if( !sd || sd->skillitem != ud->skill_id || skill->get_delay(ud->skill_id,ud->skill_lv) )
- ud->canact_tick = tick;
- //You can't place a skill failed packet here because it would be
- //sent in ALL cases, even cases where skill_check_condition fails
- //which would lead to double 'skill failed' messages u.u [Skotlex]
- if(sd)
- sd->skillitem = sd->skillitemlv = 0;
- else if(md)
- md->skill_idx = -1;
- return 0;
-}
-
-/*==========================================
- *
- *------------------------------------------*/
int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data)
{
struct block_list* src = iMap->id2bl(id);
@@ -9528,7 +9392,7 @@ int skill_castend_pos(int tid, unsigned int tick, int id, intptr_t data)
skill->blockpc_start(sd, ud->skill_id, cooldown, false);
}
if( battle_config.display_status_timers && sd )
- clif->status_change(src, SI_ACTIONDELAY, 1, skill->delay_fix(src, ud->skill_id, ud->skill_lv), 0, 0, 0);
+ clif->status_change(src, SI_POSTDELAY, 1, skill->delay_fix(src, ud->skill_id, ud->skill_lv), 0, 0, 0);
// if( sd )
// {
// switch( ud->skill_id )
@@ -9574,6 +9438,143 @@ static int skill_count_wos(struct block_list *bl,va_list ap) {
}
return 0;
}
+
+/*==========================================
+ *
+ *------------------------------------------*/
+int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char *map)
+{
+ nullpo_ret(sd);
+
+//Simplify skill_failed code.
+#define skill_failed(sd) { sd->menuskill_id = sd->menuskill_val = 0; }
+ if(skill_id != sd->menuskill_id)
+ return 0;
+
+ if( sd->bl.prev == NULL || pc_isdead(sd) ) {
+ skill_failed(sd);
+ return 0;
+ }
+
+ if( ( sd->sc.opt1 && sd->sc.opt1 != OPT1_BURNING ) || sd->sc.option&OPTION_HIDE ) {
+ skill_failed(sd);
+ return 0;
+ }
+ if(sd->sc.count && (
+ sd->sc.data[SC_SILENCE] ||
+ sd->sc.data[SC_ROKISWEIL] ||
+ sd->sc.data[SC_AUTOCOUNTER] ||
+ sd->sc.data[SC_STEELBODY] ||
+ (sd->sc.data[SC_DANCING] && skill_id < RK_ENCHANTBLADE && !pc->checkskill(sd, WM_LESSON)) ||
+ sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
+ sd->sc.data[SC_BASILICA] ||
+ sd->sc.data[SC_MARIONETTE_MASTER] ||
+ sd->sc.data[SC_WHITEIMPRISON] ||
+ (sd->sc.data[SC_STASIS] && skill->block_check(&sd->bl, SC_STASIS, skill_id)) ||
+ (sd->sc.data[SC_KG_KAGEHUMI] && skill->block_check(&sd->bl, SC_KG_KAGEHUMI, skill_id)) ||
+ sd->sc.data[SC_OBLIVIONCURSE] ||
+ sd->sc.data[SC__MANHOLE] ||
+ (sd->sc.data[SC_VOLCANIC_ASH] && rnd()%2) //50% fail chance under ASH
+ )) {
+ skill_failed(sd);
+ return 0;
+ }
+
+ pc_stop_attack(sd);
+ pc_stop_walking(sd,0);
+
+ if(battle_config.skill_log && battle_config.skill_log&BL_PC)
+ ShowInfo("PC %d skill castend skill =%d map=%s\n",sd->bl.id,skill_id,map);
+
+ if(strcmp(map,"cancel")==0) {
+ skill_failed(sd);
+ return 0;
+ }
+
+ switch(skill_id) {
+ case AL_TELEPORT:
+ if(strcmp(map,"Random")==0)
+ pc->randomwarp(sd,CLR_TELEPORT);
+ else if (sd->menuskill_val > 1) //Need lv2 to be able to warp here.
+ pc->setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
+ break;
+
+ case AL_WARP:
+ {
+ const struct point *p[4];
+ struct skill_unit_group *group;
+ int i, lv, wx, wy;
+ int maxcount=0;
+ int x,y;
+ unsigned short mapindex;
+
+ mapindex = mapindex_name2id((char*)map);
+ sd->state.workinprogress = 0;
+ if(!mapindex) { //Given map not found?
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ skill_failed(sd);
+ return 0;
+ }
+ p[0] = &sd->status.save_point;
+ p[1] = &sd->status.memo_point[0];
+ p[2] = &sd->status.memo_point[1];
+ p[3] = &sd->status.memo_point[2];
+
+ if((maxcount = skill->get_maxcount(skill_id, sd->menuskill_val)) > 0) {
+ for(i=0;i<MAX_SKILLUNITGROUP && sd->ud.skillunit[i] && maxcount;i++) {
+ if(sd->ud.skillunit[i]->skill_id == skill_id)
+ maxcount--;
+ }
+ if(!maxcount) {
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ skill_failed(sd);
+ return 0;
+ }
+ }
+
+ lv = sd->skillitem==skill_id?sd->skillitemlv:pc->checkskill(sd,skill_id);
+ wx = sd->menuskill_val>>16;
+ wy = sd->menuskill_val&0xffff;
+
+ if( lv <= 0 ) return 0;
+ if( lv > 4 ) lv = 4; // crash prevention
+
+ // check if the chosen map exists in the memo list
+ ARR_FIND( 0, lv, i, mapindex == p[i]->map );
+ if( i < lv ) {
+ x=p[i]->x;
+ y=p[i]->y;
+ } else {
+ skill_failed(sd);
+ return 0;
+ }
+
+ if(!skill->check_condition_castend(sd, sd->menuskill_id, lv)) { // This checks versus skill_id/skill_lv...
+ skill_failed(sd);
+ return 0;
+ }
+
+ skill->consume_requirement(sd,sd->menuskill_id,lv,2);
+ sd->skillitem = sd->skillitemlv = 0; // Clear data that's skipped in 'skill_castend_pos' [Inkfish]
+
+ if((group=skill->unitsetting(&sd->bl,skill_id,lv,wx,wy,0))==NULL) {
+ skill_failed(sd);
+ return 0;
+ }
+
+ group->val1 = (group->val1<<16)|(short)0;
+ // record the destination coordinates
+ group->val2 = (x<<16)|y;
+ group->val3 = mapindex;
+ }
+ break;
+ }
+
+ sd->menuskill_id = sd->menuskill_val = 0;
+ return 0;
+#undef skill_failed
+}
+
/*==========================================
*
*------------------------------------------*/
@@ -9740,6 +9741,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case NJ_HUUMA:
#endif
case NPC_EVILLAND:
+ case WL_COMET:
case RA_ELECTRICSHOCKER:
case RA_CLUSTERBOMB:
case RA_MAGENTATRAP:
@@ -9776,6 +9778,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case MH_POISON_MIST:
case MH_STEINWAND:
case MH_XENO_SLASHER:
+ case NC_MAGMA_ERUPTION:
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.
skill->unitsetting(src,skill_id,skill_lv,x,y,0);
@@ -10038,6 +10041,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case NC_COLDSLOWER:
case NC_ARMSCANNON:
case RK_DRAGONBREATH:
+ case RK_DRAGONBREATH_WATER:
i = skill->get_splash(skill_id,skill_lv);
iMap->foreachinarea(skill->area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),
src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
@@ -10070,17 +10074,6 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
iMap->foreachinarea(skill->area_sub, src->m, x - i, y - i, x + i, y + i, BL_CHAR, src, ALL_RESURRECTION, 1, tick, flag|BCT_NOENEMY|1,skill->castend_nodamage_id);
}
break;
- /**
- * Warlock
- **/
- case WL_COMET:
- if( sc ) {
- sc->comet_x = x;
- sc->comet_y = y;
- }
- i = skill->get_splash(skill_id,skill_lv);
- iMap->foreachinarea(skill->area_sub,src->m,x-i,y-i,x+i,y+i,splash_target(src),src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill->castend_damage_id);
- break;
case WL_EARTHSTRAIN:
{
@@ -10095,7 +10088,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
case 2: sx = x - i; break;
case 6: sx = x + i; break;
}
- skill->addtimerskill(src,iTimer->gettick() + (150 * i),0,sx,sy,skill_id,skill_lv,dir,flag&2);
+ skill->addtimerskill(src,iTimer->gettick() + (50 * i),0,sx,sy,skill_id,skill_lv,dir,flag&2);
}
}
break;
@@ -10142,10 +10135,10 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
break;
case SC_FEINTBOMB:
- clif->skill_nodamage(src,src,skill_id,skill_lv,1);
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,0);
+ skill->castend_nodamage_id(src,src,TF_HIDING,1,tick,0x2);
break;
case LG_OVERBRAND:
@@ -10279,141 +10272,6 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
return 0;
}
-/*==========================================
- *
- *------------------------------------------*/
-int skill_castend_map (struct map_session_data *sd, uint16 skill_id, const char *map)
-{
- nullpo_ret(sd);
-
-//Simplify skill_failed code.
-#define skill_failed(sd) { sd->menuskill_id = sd->menuskill_val = 0; }
- if(skill_id != sd->menuskill_id)
- return 0;
-
- if( sd->bl.prev == NULL || pc_isdead(sd) ) {
- skill_failed(sd);
- return 0;
- }
-
- if( ( sd->sc.opt1 && sd->sc.opt1 != OPT1_BURNING ) || sd->sc.option&OPTION_HIDE ) {
- skill_failed(sd);
- return 0;
- }
- if(sd->sc.count && (
- sd->sc.data[SC_SILENCE] ||
- sd->sc.data[SC_ROKISWEIL] ||
- sd->sc.data[SC_AUTOCOUNTER] ||
- sd->sc.data[SC_STEELBODY] ||
- (sd->sc.data[SC_DANCING] && skill_id < RK_ENCHANTBLADE && !pc->checkskill(sd, WM_LESSON)) ||
- sd->sc.data[SC_BERSERK] || sd->sc.data[SC__BLOODYLUST] ||
- sd->sc.data[SC_BASILICA] ||
- sd->sc.data[SC_MARIONETTE] ||
- sd->sc.data[SC_WHITEIMPRISON] ||
- (sd->sc.data[SC_STASIS] && skill->block_check(&sd->bl, SC_STASIS, skill_id)) ||
- (sd->sc.data[SC_KAGEHUMI] && skill->block_check(&sd->bl, SC_KAGEHUMI, skill_id)) ||
- sd->sc.data[SC_OBLIVIONCURSE] ||
- sd->sc.data[SC__MANHOLE] ||
- (sd->sc.data[SC_ASH] && rnd()%2) //50% fail chance under ASH
- )) {
- skill_failed(sd);
- return 0;
- }
-
- pc_stop_attack(sd);
- pc_stop_walking(sd,0);
-
- if(battle_config.skill_log && battle_config.skill_log&BL_PC)
- ShowInfo("PC %d skill castend skill =%d map=%s\n",sd->bl.id,skill_id,map);
-
- if(strcmp(map,"cancel")==0) {
- skill_failed(sd);
- return 0;
- }
-
- switch(skill_id) {
- case AL_TELEPORT:
- if(strcmp(map,"Random")==0)
- pc->randomwarp(sd,CLR_TELEPORT);
- else if (sd->menuskill_val > 1) //Need lv2 to be able to warp here.
- pc->setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
- break;
-
- case AL_WARP:
- {
- const struct point *p[4];
- struct skill_unit_group *group;
- int i, lv, wx, wy;
- int maxcount=0;
- int x,y;
- unsigned short mapindex;
-
- mapindex = mapindex_name2id((char*)map);
- if(!mapindex) { //Given map not found?
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- skill_failed(sd);
- return 0;
- }
- p[0] = &sd->status.save_point;
- p[1] = &sd->status.memo_point[0];
- p[2] = &sd->status.memo_point[1];
- p[3] = &sd->status.memo_point[2];
-
- if((maxcount = skill->get_maxcount(skill_id, sd->menuskill_val)) > 0) {
- for(i=0;i<MAX_SKILLUNITGROUP && sd->ud.skillunit[i] && maxcount;i++) {
- if(sd->ud.skillunit[i]->skill_id == skill_id)
- maxcount--;
- }
- if(!maxcount) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
- skill_failed(sd);
- return 0;
- }
- }
-
- lv = sd->skillitem==skill_id?sd->skillitemlv:pc->checkskill(sd,skill_id);
- wx = sd->menuskill_val>>16;
- wy = sd->menuskill_val&0xffff;
-
- if( lv <= 0 ) return 0;
- if( lv > 4 ) lv = 4; // crash prevention
-
- // check if the chosen map exists in the memo list
- ARR_FIND( 0, lv, i, mapindex == p[i]->map );
- if( i < lv ) {
- x=p[i]->x;
- y=p[i]->y;
- } else {
- skill_failed(sd);
- return 0;
- }
-
- if(!skill->check_condition_castend(sd, sd->menuskill_id, lv)) { // This checks versus skill_id/skill_lv...
- skill_failed(sd);
- return 0;
- }
-
- skill->consume_requirement(sd,sd->menuskill_id,lv,2);
- sd->skillitem = sd->skillitemlv = 0; // Clear data that's skipped in 'skill_castend_pos' [Inkfish]
-
- if((group=skill->unitsetting(&sd->bl,skill_id,lv,wx,wy,0))==NULL) {
- skill_failed(sd);
- return 0;
- }
-
- group->val1 = (group->val1<<16)|(short)0;
- // record the destination coordinates
- group->val2 = (x<<16)|y;
- group->val3 = mapindex;
- }
- break;
- }
-
- sd->menuskill_id = sd->menuskill_val = 0;
- return 0;
-#undef skill_failed
-}
-
/// transforms 'target' skill unit into dissonance (if conditions are met)
int skill_dance_overlap_sub(struct block_list* bl, va_list ap) {
struct skill_unit* target = (struct skill_unit*)bl;
@@ -10713,8 +10571,13 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill
}
break;
case DC_DONTFORGETME:
+#ifdef RENEWAL
+ val1 = status->dex/10 + 3*skill_lv; // ASPD decrease
+ val2 = status->agi/10 + 2*skill_lv; // Movement speed adjustment.
+#else
val1 = status->dex/10 + 3*skill_lv + 5; // ASPD decrease
val2 = status->agi/10 + 3*skill_lv + 5; // Movement speed adjustment.
+#endif
if(sd){
val1 += pc->checkskill(sd,DC_DANCINGLESSON);
val2 += pc->checkskill(sd,DC_DANCINGLESSON);
@@ -10734,9 +10597,15 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill
}
break;
case BA_ASSASSINCROSS:
+#ifdef RENEWAL
+ val1 = 10 + skill_lv + (status->agi/10); // ASPD increase
+ if(sd)
+ val1 += 4*pc->checkskill(sd,BA_MUSICALLESSON);
+#else
val1 = 100+(10*skill_lv)+(status->agi/10); // ASPD increase
if(sd)
val1 += 5*pc->checkskill(sd,BA_MUSICALLESSON);
+#endif
break;
case DC_FORTUNEKISS:
val1 = 10+skill_lv+(status->luk/10); // Critical increase
@@ -10823,6 +10692,12 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill
case GD_HAWKEYES:
limit = 1000000;//it doesn't matter
break;
+ case WL_COMET:
+ if( sc ) {
+ sc->comet_x = x;
+ sc->comet_y = y;
+ }
+ break;
case LG_BANDING:
limit = -1;
break;
@@ -10841,7 +10716,6 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill
break;
case SO_VACUUM_EXTREME:
range++;
-
break;
case SC_BLOODYLUST:
skill->clear_group(src, 32);
@@ -10853,13 +10727,13 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, uint16 skill
break;
case KO_ZENKAI:
if( sd ){
- ARR_FIND(1, 6, i, sd->talisman[i] > 0);
+ ARR_FIND(1, 6, i, sd->charm[i] > 0);
if( i < 5 ){
- val1 = sd->talisman[i]; // no. of aura
+ val1 = sd->charm[i]; // no. of aura
val2 = i; // aura type
limit += val1 * 1000;
subunt = i - 1;
- pc->del_talisman(sd, sd->talisman[i], i);
+ pc->del_charm(sd, sd->charm[i], i);
}
}
break;
@@ -11151,7 +11025,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
case UNT_INTOABYSS:
case UNT_SIEGFRIED:
//Needed to check when a dancer/bard leaves their ensemble area.
- if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER))
+ 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);
@@ -11164,7 +11038,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
case UNT_DONTFORGETME:
case UNT_FORTUNEKISS:
case UNT_SERVICEFORYOU:
- if (sg->src_id==bl->id && !(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER))
+ if (sg->src_id==bl->id && !(sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_BARDDANCER))
return 0;
if (!sc) return 0;
@@ -11217,7 +11091,7 @@ int skill_unit_onplace (struct skill_unit *src, struct block_list *bl, unsigned
case UNT_VOLCANIC_ASH:
if (!sce)
- sc_start(bl, SC_ASH, 100, sg->skill_lv, skill->get_time(MH_VOLCANIC_ASH, sg->skill_lv));
+ sc_start(bl, SC_VOLCANIC_ASH, 100, sg->skill_lv, skill->get_time(MH_VOLCANIC_ASH, sg->skill_lv));
break;
case UNT_GD_LEADERSHIP:
@@ -11543,7 +11417,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
if( md && md->class_ == MOBID_EMPERIUM )
break;
#endif
- if( sg->src_id == bl->id && !(tsc && tsc->data[SC_SPIRIT] && tsc->data[SC_SPIRIT]->val2 == SL_BARDDANCER) )
+ if( sg->src_id == bl->id && !(tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SL_BARDDANCER) )
break; // affects self only when soullinked
heal = skill->calc_heal(ss,bl,sg->skill_id, sg->skill_lv, true);
if( tsc->data[SC_AKAITSUKI] && heal )
@@ -11574,7 +11448,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
status_heal(bl,heal,0,0);
break;
case 1: // End all negative status
- status_change_clear_buffs(bl,6);
+ status_change_clear_buffs(bl,2);
if (tsd) clif->gospel_info(tsd, 0x15);
break;
case 2: // Immunity to all status
@@ -11597,7 +11471,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
sc_start(bl,SC_BLESSING,100,10,time);
break;
case 7: // Level 10 Increase AGI
- sc_start(bl,SC_INCREASEAGI,100,10,time);
+ sc_start(bl,SC_INC_AGI,100,10,time);
break;
case 8: // Enchant weapon with Holy element
sc_start(bl,SC_ASPERSIO,100,1,time);
@@ -11678,6 +11552,8 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case UNT_FIREWALK:
case UNT_ELECTRICWALK:
case UNT_PSYCHIC_WAVE:
+ case UNT_MAGMA_ERUPTION:
+ case UNT_MAKIBISHI:
skill->attack(skill->get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
break;
@@ -11723,7 +11599,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
}
}
/* Enable this if kRO fix the current skill. Currently no damage on undead and demon monster. [Jobbie]
- else if( battle->check_target(ss, bl, BCT_ENEMY) > 0 && battle_check_undead(tstatus->race, tstatus->def_ele) )
+ else if( battle->check_target(ss, bl, BCT_ENEMY) > 0 && battle->check_undead(tstatus->race, tstatus->def_ele) )
skill->castend_damage_id(&src->bl, bl, sg->skill_id, sg->skill_lv, 0, 0);*/
break;
@@ -11775,7 +11651,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
} else
sec = 3000; // Couldn't trap it?
sg->limit = DIFF_TICK(tick, sg->tick) + sec;
- } else if( tsc->data[SC_THORNSTRAP] && bl->id == sg->val2 )
+ } else if( tsc->data[SC_THORNS_TRAP] && bl->id == sg->val2 )
skill->attack(skill->get_type(GN_THORNS_TRAP), ss, ss, bl, sg->skill_id, sg->skill_lv, tick, SD_LEVEL|SD_ANIMATION);
}
break;
@@ -11786,7 +11662,7 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case 1:
case 2:
default:
- sc_start(bl, SC_BURNING, 4 + 4 * sg->skill_lv, sg->skill_lv,
+ sc_start4(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);
@@ -11903,36 +11779,31 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
case UNT_ZENKAI_WATER:
sc_start(bl, SC_CRYSTALIZE, 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_FREEZING, 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));
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));
break;
case UNT_ZENKAI_FIRE:
- sc_start(bl, SC_BURNING, sg->val1*5, sg->skill_lv, skill->get_time2(sg->skill_id, sg->skill_lv));
+ sc_start4(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_DEEPSLEEP, 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));
break;
}
}else
sc_start2(bl,type,100,sg->val1,sg->val2,skill->get_time2(sg->skill_id, sg->skill_lv));
break;
- case UNT_MAKIBISHI:
- skill->attack(BF_MISC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
- sg->limit = DIFF_TICK(tick, sg->tick);
- sg->unit_id = UNT_USED_TRAPS;
- break;
-
case UNT_LAVA_SLIDE:
skill->attack(BF_WEAPON, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
if(++sg->val1 > 4) //after 5 stop hit and destroy me
sg->limit = DIFF_TICK(tick, sg->tick);
break;
+
case UNT_POISON_MIST:
skill->attack(BF_MAGIC, ss, &src->bl, bl, sg->skill_id, sg->skill_lv, tick, 0);
status_change_start(bl, SC_BLIND, rnd() % 100 > sg->skill_lv * 10, sg->skill_lv, sg->skill_id, 0, 0, skill->get_time2(sg->skill_id, sg->skill_lv), 2|8);
@@ -12234,7 +12105,7 @@ int skill_check_condition_char_sub (struct block_list *bl, va_list ap) {
return 1;
case WL_COMET:
// Comet does not consume Red Gemstones when there is at least 1 Warlock class next to the caster
- if( ( sd->class_&MAPID_THIRDMASK ) == MAPID_WARLOCK )
+ if( ( tsd->class_&MAPID_THIRDMASK ) == MAPID_WARLOCK )
p_sd[(*c)++] = tsd->bl.id;
return 1;
case LG_RAYOFGENESIS:
@@ -12469,11 +12340,11 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case BS_ADRENALINE: case WS_WEAPONREFINE:
case BS_WEAPONPERFECT: case WS_CARTTERMINATION:
case BS_OVERTHRUST: case WS_OVERTHRUSTMAX:
- case BS_MAXIMIZE: case NC_AXEBOOMERANG:
- case BS_ADRENALINE2: case NC_POWERSWING:
- case BS_UNFAIRLYTRICK: case NC_AXETORNADO:
+ case BS_MAXIMIZE:
+ case BS_ADRENALINE2:
+ case BS_UNFAIRLYTRICK:
case BS_GREED:
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_MADOGEAR,0);
return 0;
default: //Only Mechanic exlcusive skill can be used.
break;
@@ -12529,30 +12400,43 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
return 0;
if(sc->data[SC_BLADESTOP])
break;
- if(sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_TRIPLEATTACK)
+ if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == MO_TRIPLEATTACK )
break;
+ if( i )
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, MO_TRIPLEATTACK);
return 0;
case MO_COMBOFINISH:
- if(!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_CHAINCOMBO))
+ if(!sc)
return 0;
- break;
+ if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == MO_CHAINCOMBO )
+ break;
+ if( i )
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, MO_CHAINCOMBO);
+ return 0;
case CH_TIGERFIST:
- if(!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == MO_COMBOFINISH))
+ if(!sc)
return 0;
- break;
+ if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == MO_COMBOFINISH )
+ break;
+ if( i )
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, MO_COMBOFINISH);
+ return 0;
case CH_CHAINCRUSH:
- if(!(sc && sc->data[SC_COMBO]))
- return 0;
- if(sc->data[SC_COMBO]->val1 != MO_COMBOFINISH && sc->data[SC_COMBO]->val1 != CH_TIGERFIST)
+ if(!sc)
return 0;
- break;
+ if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == CH_TIGERFIST )
+ break;
+ if( i )
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, CH_TIGERFIST);
+ return 0;
case MO_EXTREMITYFIST:
// if(sc && sc->data[SC_EXTREMITYFIST]) //To disable Asura during the 5 min skill block uncomment this...
// return 0;
if( sc && (sc->data[SC_BLADESTOP] || sc->data[SC_CURSEDCIRCLE_ATKER]) )
break;
- if( sc && sc->data[SC_COMBO] ) {
- switch(sc->data[SC_COMBO]->val1) {
+ if( sc && sc->data[SC_COMBOATTACK] )
+ {
+ switch(sc->data[SC_COMBOATTACK]->val1) {
case MO_COMBOFINISH:
case CH_TIGERFIST:
case CH_CHAINCRUSH:
@@ -12594,17 +12478,17 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case TK_COUNTER:
if ((sd->class_&MAPID_UPPERMASK) == MAPID_SOUL_LINKER)
return 0; //Anti-Soul Linker check in case you job-changed with Stances active.
- if(!(sc && sc->data[SC_COMBO]) || sc->data[SC_COMBO]->val1 == TK_JUMPKICK)
+ if(!(sc && sc->data[SC_COMBOATTACK]) || sc->data[SC_COMBOATTACK]->val1 == TK_JUMPKICK)
return 0; //Combo needs to be ready
- if (sc->data[SC_COMBO]->val3) { //Kick chain
+ if (sc->data[SC_COMBOATTACK]->val3) { //Kick chain
//Do not repeat a kick.
- if (sc->data[SC_COMBO]->val3 != skill_id)
+ if (sc->data[SC_COMBOATTACK]->val3 != skill_id)
break;
- status_change_end(&sd->bl, SC_COMBO, INVALID_TIMER);
+ status_change_end(&sd->bl, SC_COMBOATTACK, INVALID_TIMER);
return 0;
}
- if(sc->data[SC_COMBO]->val1 != skill_id && !( sd && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON) )) { //Cancel combo wait.
+ if(sc->data[SC_COMBOATTACK]->val1 != skill_id && !( sd && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON) )) { //Cancel combo wait.
unit_cancel_combo(&sd->bl);
return 0;
}
@@ -12638,12 +12522,12 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
break;
case SL_SMA:
- if(!(sc && sc->data[SC_SMA]))
+ if(!(sc && sc->data[SC_SMA_READY]))
return 0;
break;
case HT_POWER:
- if(!(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill_id))
+ if(!(sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == skill_id))
return 0;
break;
@@ -12709,7 +12593,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
case SG_FUSION:
- if (sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_STAR)
+ if (sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_STAR)
break;
//Auron insists we should implement SP consumption when you are not Soul Linked. [Skotlex]
//Only invoke on skill begin cast (instant cast skill). [Kevin]
@@ -12751,7 +12635,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
return 0;
}
case NJ_BUNSINJYUTSU:
- if (!(sc && sc->data[SC_NEN])) {
+ if (!(sc && sc->data[SC_NJ_NEN])) {
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
@@ -12824,13 +12708,36 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case WL_SUMMONBL:
case WL_SUMMONWB:
case WL_SUMMONSTONE:
- if( sc )
+ case WL_TETRAVORTEX:
+ case WL_RELEASE:
{
- ARR_FIND(SC_SPHERE_1,SC_SPHERE_5+1,i,!sc->data[i]);
- if( i == SC_SPHERE_5+1 )
- { // No more free slots
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_SUMMON,0);
- return 0;
+ int x = SC_SUMMON1;
+ i = 0;
+ for(; x <= SC_SUMMON5; x++)
+ if( sc && sc->data[x] )
+ i++;
+
+ switch(skill_id){
+ case WL_TETRAVORTEX:
+ if( i < 4 ){
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_CONDITION,0);
+ return 0;
+ }
+ break;
+ case WL_RELEASE:
+ for(x = SC_SPELLBOOK7; x >= SC_SPELLBOOK1; x--)
+ if( sc && sc->data[x] )
+ i++;
+ if( i == 0 ){
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_SUMMON_NONE,0);
+ return 0;
+ }
+ break;
+ default:
+ if( i == 5 ){
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_SUMMON,0);
+ return 0;
+ }
}
}
break;
@@ -12845,7 +12752,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
break;
case GC_COUNTERSLASH:
case GC_WEAPONCRUSH:
- if( !(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == GC_WEAPONBLOCKING) ) {
+ if( !(sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == GC_WEAPONBLOCKING) ) {
clif->skill_fail(sd, skill_id, USESKILL_FAIL_GC_WEAPONBLOCKING, 0);
return 0;
}
@@ -12854,26 +12761,26 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
* Ranger
**/
case RA_WUGMASTERY:
- if( pc_isfalcon(sd) || pc_isridingwug(sd) || sd->sc.data[SC__GROOMY]) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ if( pc_isfalcon(sd) || pc_isridingwug(sd) || sd->sc.data[SC__GROOMY] ) {
+ clif->skill_fail(sd,skill_id,sd->sc.data[SC__GROOMY]?USESKILL_FAIL_MANUAL_NOTIFY:USESKILL_FAIL_CONDITION,0);
return 0;
}
break;
case RA_WUGSTRIKE:
if( !pc_iswug(sd) && !pc_isridingwug(sd) ) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_CONDITION,0);
return 0;
}
break;
case RA_WUGRIDER:
if( pc_isfalcon(sd) || ( !pc_isridingwug(sd) && !pc_iswug(sd) ) ) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_CONDITION,0);
return 0;
}
break;
case RA_WUGDASH:
if(!pc_isridingwug(sd)) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_CONDITION,0);
return 0;
}
break;
@@ -12915,10 +12822,13 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
}
break;
case SR_FALLENEMPIRE:
- if( !(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_DRAGONCOMBO) )
+ if( !sc )
return 0;
- break;
-
+ if( (i=(sc && sc->data[SC_COMBOATTACK])) && sc->data[SC_COMBOATTACK]->val1 == SR_DRAGONCOMBO )
+ break;
+ if( i )
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_COMBOSKILL, SR_DRAGONCOMBO);
+ return 0;
case SR_CRESCENTELBOW:
if( sc && sc->data[SC_CRESCENTELBOW] ) {
clif->skill_fail(sd, skill_id, USESKILL_FAIL_DUPLICATE, 0);
@@ -12973,7 +12883,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
break;
case SO_EL_CONTROL:
if( !sd->status.ele_id || !sd->ed ) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_EL_SUMMON,0);
return 0;
}
break;
@@ -12985,7 +12895,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
break;
case LG_REFLECTDAMAGE:
case CR_REFLECTSHIELD:
- if( sc && sc->data[SC_KYOMU] && rand()%100 < 30){
+ if( sc && sc->data[SC_KYOMU] && rand()%100 < 5 * sc->data[SC_KYOMU]->val1 ){
clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
return 0;
}
@@ -12996,18 +12906,17 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
case KO_DOHU_KOUKAI:
{
int ttype = skill->get_ele(skill_id, skill_lv);
- ARR_FIND(1, 5, i, sd->talisman[i] > 0 && i != ttype);
- if( (i < 5 && i != ttype) || sd->talisman[ttype] >= 10 ){
- clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
+ if( sd->charm[ttype] >= 10 ){
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_SUMMON, 0);
return 0;
}
}
break;
case KO_KAIHOU:
case KO_ZENKAI:
- ARR_FIND(1, 6, i, sd->talisman[i] > 0);
+ ARR_FIND(1, 6, i, sd->charm[i] > 0);
if( i > 4 ) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_SUMMON,0);
return 0;
}
break;
@@ -13051,7 +12960,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
}
case ST_CART:
if(!pc_iscarton(sd)) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_CART,0);
return 0;
}
break;
@@ -13069,7 +12978,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
break;
case ST_EXPLOSIONSPIRITS:
if(!(sc && sc->data[SC_EXPLOSIONSPIRITS])) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_EXPLOSIONSPIRITS,0);
return 0;
}
break;
@@ -13080,7 +12989,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
}
break;
case ST_MOVE_ENABLE:
- if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == skill_id)
+ if (sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == skill_id)
sd->ud.canmove_tick = iTimer->gettick(); //When using a combo, cancel the can't move delay to enable the skill. [Skotlex]
if (!unit_can_move(&sd->bl)) {
@@ -13089,7 +12998,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
}
break;
case ST_WATER:
- if (sc && (sc->data[SC_DELUGE] || sc->data[SC_SUITON]))
+ if (sc && (sc->data[SC_DELUGE] || sc->data[SC_NJ_SUITON]))
break;
if (iMap->getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKWATER))
break;
@@ -13097,7 +13006,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
return 0;
case ST_RIDINGDRAGON:
if( !pc_isridingdragon(sd) ) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_DRAGON,0);
return 0;
}
break;
@@ -13115,7 +13024,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
break;
case ST_MADO:
if( !pc_ismadogear(sd) ) {
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_MADOGEAR,0);
return 0;
}
break;
@@ -13182,7 +13091,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
return 0;
}
- if( sd->sc.data[SC_COMBO] ) {
+ if( sd->sc.data[SC_COMBOATTACK] ) {
switch( skill_id ) {
case MO_CHAINCOMBO:
case MO_COMBOFINISH:
@@ -13329,7 +13238,10 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
if( require.ammo ) { //Skill requires stuff equipped in the arrow slot.
if((i=sd->equip_index[EQI_AMMO]) < 0 || !sd->inventory_data[i] ) {
- clif->arrow_fail(sd,0);
+ if( require.ammo&1<<8 )
+ clif->skill_fail(sd,skill_id,USESKILL_FAIL_CANONBALL,0);
+ else
+ clif->arrow_fail(sd,0);
return 0;
} else if( sd->status.inventory[i].amount < require.ammo_qty ) {
char e_msg[100];
@@ -13353,12 +13265,39 @@ int skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
continue;
index[i] = pc->search_inventory(sd,require.itemid[i]);
if( index[i] < 0 || sd->status.inventory[index[i]].amount < require.amount[i] ) {
- if( require.itemid[i] == ITEMID_RED_GEMSTONE )
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_REDJAMSTONE,0);// red gemstone required
- else if( require.itemid[i] == ITEMID_BLUE_GEMSTONE )
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_BLUEJAMSTONE,0);// blue gemstone required
- else
- clif->skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+ useskill_fail_cause cause = USESKILL_FAIL_NEED_ITEM;
+ switch( skill_id ){
+ case NC_SILVERSNIPER:
+ case NC_MAGICDECOY:
+ cause = USESKILL_FAIL_STUFF_INSUFFICIENT;
+ break;
+ default:
+ switch(require.itemid[i]){
+ case ITEMID_RED_GEMSTONE:
+ cause = USESKILL_FAIL_REDJAMSTONE; break;
+ case ITEMID_BLUE_GEMSTONE:
+ cause = USESKILL_FAIL_BLUEJAMSTONE; break;
+ case ITEMID_HOLY_WATER:
+ cause = USESKILL_FAIL_HOLYWATER; break;
+ case ITEMID_ANCILLA:
+ cause = USESKILL_FAIL_ANCILLA; break;
+ case ITEMID_ACCELERATOR:
+ case ITEMID_HOVERING_BOOSTER:
+ case ITEMID_SUICIDAL_DEVICE:
+ case ITEMID_SHAPE_SHIFTER:
+ case ITEMID_COOLING_DEVICE:
+ case ITEMID_MAGNETIC_FIELD_GENERATOR:
+ case ITEMID_BARRIER_BUILDER:
+ case ITEMID_CAMOUFLAGE_GENERATOR:
+ case ITEMID_REPAIR_KIT:
+ case ITEMID_MONKEY_SPANNER:
+ cause = USESKILL_FAIL_NEED_EQUIPMENT;
+ default:
+ clif->skill_fail(sd, skill_id, cause, max(1,require.amount[i])|(require.itemid[i] << 16));
+ return 0;
+ }
+ }
+ clif->skill_fail(sd, skill_id, cause, 0);
return 0;
}
}
@@ -13417,7 +13356,7 @@ int skill_consume_requirement( struct map_session_data *sd, uint16 skill_id, uin
if( !req.itemid[i] )
continue;
- if( itemid_isgemstone(req.itemid[i]) && skill_id != HW_GANBANTEIN && sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_WIZARD )
+ if( itemid_isgemstone(req.itemid[i]) && skill_id != HW_GANBANTEIN && sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_WIZARD )
continue; //Gemstones are checked, but not substracted from inventory.
switch( skill_id ){
@@ -13521,10 +13460,12 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
if( sc ) {
if( sc->data[SC__LAZINESS] )
req.sp += req.sp + sc->data[SC__LAZINESS]->val1 * 10;
- if (sc->data[SC_UNLIMITEDHUMMINGVOICE])
- req.sp += req.sp * sc->data[SC_UNLIMITEDHUMMINGVOICE]->val2 / 100;
+ if( sc->data[SC_UNLIMITED_HUMMING_VOICE] )
+ req.sp += req.sp * sc->data[SC_UNLIMITED_HUMMING_VOICE]->val2 / 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)
+ req.sp -= req.sp * sc->data[SC_TELEKINESIS_INTENSE]->val2 / 100;
}
req.zeny = skill_db[idx].zeny[skill_lv-1];
@@ -13644,7 +13585,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
req.zeny -= req.zeny*10/100;
break;
case AL_HOLYLIGHT:
- if(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_PRIEST)
+ if(sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_PRIEST)
req.sp *= 5;
break;
case SL_SMA:
@@ -13668,7 +13609,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
case MO_COMBOFINISH:
case CH_TIGERFIST:
case CH_CHAINCRUSH:
- if(sc && sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_MONK)
+ if(sc && sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_MONK)
req.sp -= req.sp*25/100; //FIXME: Need real data. this is a custom value.
break;
case MO_BODYRELOCATION:
@@ -13680,9 +13621,9 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
{
if( sc->data[SC_BLADESTOP] )
req.spiritball--;
- else if( sc->data[SC_COMBO] )
+ else if( sc->data[SC_COMBOATTACK] )
{
- switch( sc->data[SC_COMBO]->val1 )
+ switch( sc->data[SC_COMBOATTACK]->val1 )
{
case MO_COMBOFINISH:
req.spiritball = 4;
@@ -13702,7 +13643,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
req.spiritball = sd->spiritball?sd->spiritball:15;
break;
case SR_GATEOFHELL:
- if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE )
+ if( sc && sc->data[SC_COMBOATTACK] && sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE )
req.sp -= req.sp * 10 / 100;
break;
case SO_SUMMON_AGNI:
@@ -13779,15 +13720,15 @@ int skill_castfix_sc (struct block_list *bl, int time)
if( time < 0 )
return 0;
-
+
if( bl->type == BL_MOB ) // mobs casttime is fixed nothing to alter.
return time;
if (sc && sc->count) {
if (sc->data[SC_SLOWCAST])
time += time * sc->data[SC_SLOWCAST]->val2 / 100;
- if (sc->data[SC_PARALYSIS])
- time += sc->data[SC_PARALYSIS]->val3;
+ if (sc->data[SC_NEEDLE_OF_PARALYZE])
+ time += sc->data[SC_NEEDLE_OF_PARALYZE]->val3;
if (sc->data[SC_SUFFRAGIUM]) {
time -= time * sc->data[SC_SUFFRAGIUM]->val2 / 100;
status_change_end(bl, SC_SUFFRAGIUM, INVALID_TIMER);
@@ -13859,8 +13800,12 @@ int skill_vfcastfix (struct block_list *bl, double time, uint16 skill_id, uint16
if (sc && sc->count && !(skill->get_castnodex(skill_id, skill_lv)&2) ) {
// All variable cast additive bonuses must come first
+ if (sc->data[SC_MAGICPOWER] )
+ time += 700;
if (sc->data[SC_SLOWCAST])
VARCAST_REDUCTION(-sc->data[SC_SLOWCAST]->val2);
+ if (sc->data[SC_FROSTMISTY])
+ VARCAST_REDUCTION(-15);
// Variable cast reduction bonuses
if (sc->data[SC_SUFFRAGIUM]) {
@@ -13878,17 +13823,33 @@ int skill_vfcastfix (struct block_list *bl, double time, uint16 skill_id, uint16
VARCAST_REDUCTION(50);
if (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 3 && (skill->get_ele(skill_id, skill_lv) == ELE_WATER))
VARCAST_REDUCTION(30); //Reduces 30% Variable Cast Time of Water spells.
+ if (sc->data[SC_TELEKINESIS_INTENSE])
+ VARCAST_REDUCTION(sc->data[SC_TELEKINESIS_INTENSE]->val2);
+ if (sc->data[SC_SOULLINK]){
+ if(sc->data[SC_SOULLINK]->val2 == SL_WIZARD || sc->data[SC_SOULLINK]->val2 == SL_BARDDANCER)
+ switch(skill_id){
+ case WZ_FIREPILLAR:
+ if(skill_lv < 5)
+ break;
+ case HW_GRAVITATION:
+ case MG_SAFETYWALL:
+ case MG_STONECURSE:
+ case BA_MUSICALSTRIKE:
+ case DC_THROWARROW:
+ VARCAST_REDUCTION(50);
+ }
+ }
// Fixed cast reduction bonuses
if( sc->data[SC__LAZINESS] )
fixcast_r = max(fixcast_r, sc->data[SC__LAZINESS]->val2);
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, 5 + skill_lv * 5);
+ 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;
- if (sc->data[SC_IZAYOI] && (skill_id >= NJ_TOBIDOUGU && skill_id <= NJ_ISSEN))
+ if( sc->data[SC_IZAYOI] )
fixed = 0;
if( sc->data[SC_GUST_OPTION] || sc->data[SC_BLAST_OPTION] || sc->data[SC_WILD_STORM_OPTION] )
fixed -= 1000;
@@ -13966,14 +13927,14 @@ int skill_delay_fix (struct block_list *bl, uint16 skill_id, uint16 skill_lv)
}
}
- if ( sc && sc->data[SC_SPIRIT] ) {
+ if ( sc && sc->data[SC_SOULLINK] ) {
switch (skill_id) {
case CR_SHIELDBOOMERANG:
- if (sc->data[SC_SPIRIT]->val2 == SL_CRUSADER)
+ if (sc->data[SC_SOULLINK]->val2 == SL_CRUSADER)
time /= 2;
break;
case AS_SONICBLOW:
- if (!map_flag_gvg(bl->m) && !map[bl->m].flag.battleground && sc->data[SC_SPIRIT]->val2 == SL_ASSASIN)
+ if (!map_flag_gvg(bl->m) && !map[bl->m].flag.battleground && sc->data[SC_SOULLINK]->val2 == SL_ASSASIN)
time /= 2;
break;
}
@@ -14231,7 +14192,7 @@ void skill_identify (struct map_session_data *sd, int idx)
int flag=1;
nullpo_retv(sd);
-
+ sd->state.workinprogress = 0;
if(idx >= 0 && idx < MAX_INVENTORY) {
if(sd->status.inventory[idx].nameid > 0 && sd->status.inventory[idx].identify == 0 ){
flag=0;
@@ -14258,20 +14219,29 @@ void skill_weaponrefine (struct map_session_data *sd, int idx)
if(item->nameid > 0 && ditem->type == IT_WEAPON)
{
- if( item->refine >= sd->menuskill_val
- || item->refine >= 10 // if it's no longer refineable
- || ditem->flag.no_refine // if the item isn't refinable
- || (i = pc->search_inventory(sd, material [ditem->wlv])) < 0 )
- {
+ if( ditem->flag.no_refine ){ // if the item isn't refinable
clif->skill_fail(sd,sd->menuskill_id,USESKILL_FAIL_LEVEL,0);
return;
}
+ if( item->refine >= sd->menuskill_val || item->refine >= 10 ){
+ clif->upgrademessage(sd->fd, 2, item->nameid);
+ return;
+ }
+ if( (i = pc->search_inventory(sd, material [ditem->wlv])) < 0 ){
+ clif->upgrademessage(sd->fd, 3, material [ditem->wlv]);
+ return;
+ }
- per = status_get_refine_chance(ditem->wlv, (int)item->refine);
- per += (((signed int)sd->status.job_level)-50)/2; //Updated per the new kro descriptions. [Skotlex]
-
+ per = status_get_refine_chance(ditem->wlv, (int)item->refine) * 10;
+
+ // Aegis leaked formula. [malufett]
+ if( sd->status.class_ == JOB_MECHANIC_T )
+ per += 100;
+ else
+ per += 5 * ((signed int)sd->status.job_level - 50);
+
pc->delitem(sd, i, 1, 0, 0, LOG_TYPE_OTHER);
- if (per > rnd() % 100) {
+ if (per > rnd() % 1000) {
logs->pick_pc(sd, LOG_TYPE_OTHER, -1, item, ditem);
item->refine++;
logs->pick_pc(sd, LOG_TYPE_OTHER, 1, item, ditem);
@@ -14279,9 +14249,10 @@ void skill_weaponrefine (struct map_session_data *sd, int idx)
ep = item->equip;
pc->unequipitem(sd,idx,3);
}
+ clif->delitem(sd,idx,1,0);
+ clif->upgrademessage(sd->fd, 0,item->nameid);
+ clif->inventorylist(sd);
clif->refine(sd->fd,0,idx,item->refine);
- clif->delitem(sd,idx,1,3);
- clif->additem(sd,idx,1,0);
if (ep)
pc->equipitem(sd,idx,ep);
clif->misceffect(&sd->bl,3);
@@ -14306,7 +14277,7 @@ void skill_weaponrefine (struct map_session_data *sd, int idx)
if(item->equip)
pc->unequipitem(sd,idx,3);
clif->refine(sd->fd,1,idx,item->refine);
- pc->delitem(sd,idx,1,0,2, LOG_TYPE_OTHER);
+ pc->delitem(sd,idx,1,0,0, LOG_TYPE_OTHER);
clif->misceffect(&sd->bl,2);
clif->emotion(&sd->bl, E_OMG);
}
@@ -14331,7 +14302,7 @@ int skill_autospell (struct map_session_data *sd, uint16 skill_id)
if(skill_id==MG_NAPALMBEAT) maxlv=3;
else if(skill_id==MG_COLDBOLT || skill_id==MG_FIREBOLT || skill_id==MG_LIGHTNINGBOLT){
- if (sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_SAGE)
+ if (sd->sc.data[SC_SOULLINK] && sd->sc.data[SC_SOULLINK]->val2 == SL_SAGE)
maxlv =10; //Soul Linker bonus. [Skotlex]
else if(skill_lv==2) maxlv=1;
else if(skill_lv==3) maxlv=2;
@@ -14862,7 +14833,7 @@ 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_ELEMENTALCHANGE,100,sg->skill_lv,skill->get_ele(sg->skill_id,sg->skill_lv),skill->get_time2(sg->skill_id,sg->skill_lv));
+ 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));
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
@@ -14881,7 +14852,7 @@ int skill_trap_splash (struct block_list *bl, va_list ap) {
int skill_enchant_elemental_end (struct block_list *bl, int type)
{
struct status_change *sc;
- const enum sc_type scs[] = { SC_ENCPOISON, SC_ASPERSIO, SC_FIREWEAPON, SC_WATERWEAPON, SC_WINDWEAPON, SC_EARTHWEAPON, SC_SHADOWWEAPON, SC_GHOSTWEAPON, SC_ENCHANTARMS, SC_EXEEDBREAK };
+ const enum sc_type scs[] = { SC_ENCHANTPOISON, SC_ASPERSIO, SC_PROPERTYFIRE, SC_PROPERTYWATER, SC_PROPERTYWIND, SC_PROPERTYGROUND, SC_PROPERTYDARK, SC_PROPERTYTELEKINESIS, SC_ENCHANTARMS, SC_EXEEDBREAK };
int i;
nullpo_ret(bl);
nullpo_ret(sc= status_get_sc(bl));
@@ -15036,7 +15007,7 @@ int skill_delunit (struct skill_unit* unit) {
case HT_ANKLESNARE: {
struct block_list* target = iMap->id2bl(group->val2);
if( target )
- status_change_end(target, SC_ANKLE, INVALID_TIMER);
+ status_change_end(target, SC_ANKLESNARE, INVALID_TIMER);
}
break;
case WZ_ICEWALL:
@@ -16083,40 +16054,39 @@ int skill_produce_mix (struct map_session_data *sd, uint16 skill_id, int nameid,
**/
case RK_RUNEMASTERY:
{
- int A = 100 * (51 + 2 * pc->checkskill(sd, skill_id));
- int B = 100 * status->dex / 30 + 10 * (status->luk + sd->status.job_level);
+ int A = 5100 + 200 * pc->checkskill(sd, skill_id);
+ int B = 10 * status->dex / 3 + (status->luk + sd->status.job_level);
int C = 100 * cap_value(sd->itemid,0,100); //itemid depend on makerune()
- int D = 0;
+ int D = 2500;
switch (nameid) { //rune rank it_diff 9 craftable rune
- case ITEMID_BERKANA:
- D = -2000;
- break; //Rank S
- case ITEMID_NAUTHIZ:
- case ITEMID_URUZ:
- D = -1500;
- break; //Rank A
- case ITEMID_ISA:
- case ITEMID_WYRD:
- D = -1000;
- break; //Rank B
case ITEMID_RAIDO:
case ITEMID_THURISAZ:
case ITEMID_HAGALAZ:
case ITEMID_OTHILA:
- D = -500;
- break; //Rank C
- default: D = -1500;
- break; //not specified =-15%
+ D -= 500; //Rank C
+ case ITEMID_ISA:
+ case ITEMID_WYRD:
+ D -= 500; //Rank B
+ case ITEMID_NAUTHIZ:
+ case ITEMID_URUZ:
+ D -= 500; //Rank A
+ case ITEMID_BERKANA:
+ D -= 500; //Rank S
}
- make_per = A + B + C + D;
+ make_per = A + B + C - D;
break;
}
/**
* Guilotine Cross
**/
case GC_CREATENEWPOISON:
- make_per = 3000 + 500 * pc->checkskill(sd,GC_RESEARCHNEWPOISON);
- qty = 1+rnd()%pc->checkskill(sd,GC_RESEARCHNEWPOISON);
+ {
+ const int min[] = {2, 2, 3, 3, 4, 4, 5, 5, 6, 6};
+ const int max[] = {4, 5, 5, 6, 6, 7, 7, 8, 8, 9};
+ uint16 lv = pc->checkskill(sd,GC_RESEARCHNEWPOISON);
+ make_per = 3000 + 500 * lv ;
+ qty = min[lv] + rand()%(max[lv] - min[lv]);
+ }
break;
case GN_CHANGEMATERIAL:
for(i=0; i<MAX_SKILL_PRODUCE_DB; i++)
@@ -16620,8 +16590,8 @@ int skill_spellbook (struct map_session_data *sd, int nameid) {
sc = status_get_sc(&sd->bl);
status_change_end(&sd->bl, SC_STOP, INVALID_TIMER);
- for(i=SC_SPELLBOOK1; i <= SC_MAXSPELLBOOK; i++) if( sc && !sc->data[i] ) break;
- if( i > SC_MAXSPELLBOOK )
+ for(i=SC_SPELLBOOK1; i <= SC_SPELLBOOK7; i++) if( sc && !sc->data[i] ) break;
+ if( i > SC_SPELLBOOK7 )
{
clif->skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_READING, 0);
return 0;
@@ -16637,7 +16607,7 @@ int skill_spellbook (struct map_session_data *sd, int nameid) {
return 0;
}
- max_preserve = 4 * pc->checkskill(sd, WL_FREEZE_SP) + status_get_int(&sd->bl) / 10 + sd->status.base_level / 10;
+ max_preserve = 4 * pc->checkskill(sd, WL_FREEZE_SP) + (status_get_int(&sd->bl) + sd->status.base_level) / 10;
point = skill_spellbook_db[i].point;
if( sc && sc->data[SC_READING_SB] ) {
@@ -16645,7 +16615,7 @@ int skill_spellbook (struct map_session_data *sd, int nameid) {
clif->skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK_PRESERVATION_POINT, 0);
return 0;
}
- for(i = SC_MAXSPELLBOOK; i >= SC_SPELLBOOK1; i--){ // This is how official saves spellbook. [malufett]
+ 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);
@@ -16654,7 +16624,7 @@ int skill_spellbook (struct map_session_data *sd, int nameid) {
}
}else{
sc_start2(&sd->bl, SC_READING_SB, 100, 0, point, INVALID_TIMER);
- sc_start4(&sd->bl, SC_MAXSPELLBOOK, 100, skill_id, pc->checkskill(sd,skill_id), point, 0, INVALID_TIMER);
+ sc_start4(&sd->bl, SC_SPELLBOOK7, 100, skill_id, pc->checkskill(sd,skill_id), point, 0, INVALID_TIMER);
}
return 1;
@@ -17365,7 +17335,7 @@ int skill_block_check(struct block_list *bl, sc_type type , uint16 skill_id) {
return 1; // Can't do it.
}
break;
- case SC_KAGEHUMI:
+ case SC_KG_KAGEHUMI:
switch(skill_id) {
case TF_HIDING: case AS_CLOAKING: case GC_CLOAKINGEXCEED: case SC_SHADOWFORM:
case MI_HARMONIZE: case CG_MARIONETTE: case AL_TELEPORT: case TF_BACKSLIDING:
@@ -17995,6 +17965,7 @@ void skill_defaults(void) {
skill->delay_fix = skill_delay_fix;
skill->check_condition_castbegin = skill_check_condition_castbegin;
skill->check_condition_castend = skill_check_condition_castend;
+ skill->check_condition_char_sub = skill_check_condition_char_sub;
skill->get_requirement = skill_get_requirement;
skill->check_pc_partner = skill_check_pc_partner;
skill->consume_requirement = skill_consume_requirement;
diff --git a/src/map/skill.h b/src/map/skill.h
index c585bbb3a..cc9ac4bfc 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -1281,7 +1281,26 @@ enum e_skill {
ECL_SADAGUI,
ECL_SEQUOIADUST,
ECLAGE_RECALL,
-
+
+ GC_DARKCROW = 5001,
+ RA_UNLIMIT,
+ GN_ILLUSIONDOPING,
+ RK_DRAGONBREATH_WATER,
+ RK_LUXANIMA,
+ NC_MAGMA_ERUPTION,
+ WM_FRIGG_SONG,
+ SO_ELEMENTAL_SHIELD,
+ SR_FLASHCOMBO,
+ SC_ESCAPE,
+ AB_OFFERTORIUM,
+ WL_TELEKINESIS_INTENSE,
+ LG_KINGS_GRACE,
+ ALL_FULL_THROTTLE,
+ SR_FLASHCOMBO_ATK_STEP1,
+ SR_FLASHCOMBO_ATK_STEP2,
+ SR_FLASHCOMBO_ATK_STEP3,
+ SR_FLASHCOMBO_ATK_STEP4,
+
HLIF_HEAL = 8001,
HLIF_AVOID,
HLIF_BRAIN,
@@ -1541,6 +1560,10 @@ enum {
UNT_ZENKAI_WIND,
UNT_MAKIBISHI,
UNT_VENOMFOG,
+ UNT_ICEMINE,
+ UNT_FLAMECROSS,
+ UNT_HELLBURNING,
+ UNT_MAGMA_ERUPTION,
/**
* Guild Auras
diff --git a/src/map/status.c b/src/map/status.c
index c163135d8..0e1661728 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -69,6 +69,7 @@ static struct {
static int atkmods[3][MAX_WEAPON_TYPE]; //ATK weapon modification for size (size_fix.txt)
static char job_bonus[CLASS_COUNT][MAX_LEVEL];
+static sc_conf_type sc_conf[SC_MAX];
static struct eri *sc_data_ers; //For sc_data entries
static struct status_data dummy_status;
@@ -189,7 +190,7 @@ void initChangeTables(void) {
set_sc( NPC_SILENCEATTACK , SC_SILENCE , SI_BLANK , SCB_NONE );
set_sc( NPC_WIDECONFUSE , SC_CONFUSION , SI_BLANK , SCB_NONE );
set_sc( NPC_BLINDATTACK , SC_BLIND , SI_BLANK , SCB_HIT|SCB_FLEE );
- set_sc( NPC_BLEEDING , SC_BLEEDING , SI_BLEEDING , SCB_REGEN );
+ set_sc( NPC_BLEEDING , SC_BLOODING , SI_BLOODING , SCB_REGEN );
set_sc( NPC_POISON , SC_DPOISON , SI_BLANK , SCB_DEF2|SCB_REGEN );
//The main status definitions
@@ -203,12 +204,12 @@ void initChangeTables(void) {
add_sc( MG_STONECURSE , SC_STONE );
add_sc( AL_RUWACH , SC_RUWACH );
add_sc( AL_PNEUMA , SC_PNEUMA );
- set_sc( AL_INCAGI , SC_INCREASEAGI , SI_INCREASEAGI , SCB_AGI|SCB_SPEED );
- set_sc( AL_DECAGI , SC_DECREASEAGI , SI_DECREASEAGI , SCB_AGI|SCB_SPEED );
- set_sc( AL_CRUCIS , SC_SIGNUMCRUCIS , SI_SIGNUMCRUCIS , SCB_DEF );
+ set_sc( AL_INCAGI , SC_INC_AGI , SI_INC_AGI , SCB_AGI|SCB_SPEED );
+ set_sc( AL_DECAGI , SC_DEC_AGI , SI_DEC_AGI , SCB_AGI|SCB_SPEED );
+ set_sc( AL_CRUCIS , SC_CRUCIS , SI_CRUCIS , SCB_DEF );
set_sc( AL_ANGELUS , SC_ANGELUS , SI_ANGELUS , SCB_DEF2 );
set_sc( AL_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
- set_sc( AC_CONCENTRATION , SC_CONCENTRATE , SI_CONCENTRATE , SCB_AGI|SCB_DEX );
+ set_sc( AC_CONCENTRATION , SC_CONCENTRATION , SI_CONCENTRATION , SCB_AGI|SCB_DEX );
set_sc( TF_HIDING , SC_HIDING , SI_HIDING , SCB_SPEED );
add_sc( TF_POISON , SC_POISON );
set_sc( KN_TWOHANDQUICKEN , SC_TWOHANDQUICKEN , SI_TWOHANDQUICKEN , SCB_ASPD );
@@ -222,44 +223,44 @@ void initChangeTables(void) {
set_sc( PR_MAGNIFICAT , SC_MAGNIFICAT , SI_MAGNIFICAT , SCB_REGEN );
set_sc( PR_GLORIA , SC_GLORIA , SI_GLORIA , SCB_LUK );
add_sc( PR_LEXDIVINA , SC_SILENCE );
- set_sc( PR_LEXAETERNA , SC_AETERNA , SI_AETERNA , SCB_NONE );
+ set_sc( PR_LEXAETERNA , SC_LEXAETERNA , SI_LEXAETERNA , SCB_NONE );
add_sc( WZ_METEOR , SC_STUN );
add_sc( WZ_VERMILION , SC_BLIND );
add_sc( WZ_FROSTNOVA , SC_FREEZE );
add_sc( WZ_STORMGUST , SC_FREEZE );
- set_sc( WZ_QUAGMIRE , SC_QUAGMIRE , SI_QUAGMIRE , SCB_AGI|SCB_DEX|SCB_ASPD|SCB_SPEED );
- set_sc( BS_ADRENALINE , SC_ADRENALINE , SI_ADRENALINE , SCB_ASPD );
- set_sc( BS_WEAPONPERFECT , SC_WEAPONPERFECTION, SI_WEAPONPERFECTION, SCB_NONE );
- set_sc( BS_OVERTHRUST , SC_OVERTHRUST , SI_OVERTHRUST , SCB_NONE );
- set_sc( BS_MAXIMIZE , SC_MAXIMIZEPOWER , SI_MAXIMIZEPOWER , SCB_REGEN );
- add_sc( HT_LANDMINE , SC_STUN );
- add_sc( HT_ANKLESNARE , SC_ANKLE );
+ set_sc( WZ_QUAGMIRE , SC_QUAGMIRE , SI_QUAGMIRE , SCB_AGI|SCB_DEX|SCB_ASPD|SCB_SPEED );
+ set_sc( BS_ADRENALINE , SC_ADRENALINE , SI_ADRENALINE , SCB_ASPD );
+ set_sc( BS_WEAPONPERFECT , SC_WEAPONPERFECT , SI_WEAPONPERFECT, SCB_NONE );
+ set_sc( BS_OVERTHRUST , SC_OVERTHRUST , SI_OVERTHRUST , SCB_NONE );
+ set_sc( BS_MAXIMIZE , SC_MAXIMIZEPOWER , SI_MAXIMIZE , SCB_REGEN );
+ add_sc( HT_LANDMINE , SC_STUN );
+ set_sc( HT_ANKLESNARE , SC_ANKLESNARE , SI_ANKLESNARE , SCB_NONE );
add_sc( HT_SANDMAN , SC_SLEEP );
add_sc( HT_FLASHER , SC_BLIND );
add_sc( HT_FREEZINGTRAP , SC_FREEZE );
- set_sc( AS_CLOAKING , SC_CLOAKING , SI_CLOAKING , SCB_CRI|SCB_SPEED );
+ set_sc( AS_CLOAKING , SC_CLOAKING , SI_CLOAKING , SCB_CRI|SCB_SPEED );
add_sc( AS_SONICBLOW , SC_STUN );
- set_sc( AS_ENCHANTPOISON , SC_ENCPOISON , SI_ENCPOISON , SCB_ATK_ELE );
- set_sc( AS_POISONREACT , SC_POISONREACT , SI_POISONREACT , SCB_NONE );
+ set_sc( AS_ENCHANTPOISON , SC_ENCHANTPOISON , SI_ENCHANTPOISON, SCB_ATK_ELE );
+ set_sc( AS_POISONREACT , SC_POISONREACT , SI_POISONREACT , SCB_NONE );
add_sc( AS_VENOMDUST , SC_POISON );
add_sc( AS_SPLASHER , SC_SPLASHER );
- set_sc( NV_TRICKDEAD , SC_TRICKDEAD , SI_TRICKDEAD , SCB_REGEN );
- set_sc( SM_AUTOBERSERK , SC_AUTOBERSERK , SI_AUTOBERSERK , SCB_NONE );
+ set_sc( NV_TRICKDEAD , SC_TRICKDEAD , SI_TRICKDEAD , SCB_REGEN );
+ set_sc( SM_AUTOBERSERK , SC_AUTOBERSERK , SI_AUTOBERSERK , SCB_NONE );
add_sc( TF_SPRINKLESAND , SC_BLIND );
add_sc( TF_THROWSTONE , SC_STUN );
- set_sc( MC_LOUD , SC_LOUD , SI_LOUD , SCB_STR );
- set_sc( MG_ENERGYCOAT , SC_ENERGYCOAT , SI_ENERGYCOAT , SCB_NONE );
- set_sc( NPC_EMOTION , SC_MODECHANGE , SI_BLANK , SCB_MODE );
- add_sc( NPC_EMOTION_ON , SC_MODECHANGE );
- set_sc( NPC_ATTRICHANGE , SC_ELEMENTALCHANGE , SI_ARMOR_PROPERTY , SCB_DEF_ELE );
- add_sc( NPC_CHANGEWATER , SC_ELEMENTALCHANGE );
- add_sc( NPC_CHANGEGROUND , SC_ELEMENTALCHANGE );
- add_sc( NPC_CHANGEFIRE , SC_ELEMENTALCHANGE );
- add_sc( NPC_CHANGEWIND , SC_ELEMENTALCHANGE );
- add_sc( NPC_CHANGEPOISON , SC_ELEMENTALCHANGE );
- add_sc( NPC_CHANGEHOLY , SC_ELEMENTALCHANGE );
- add_sc( NPC_CHANGEDARKNESS , SC_ELEMENTALCHANGE );
- add_sc( NPC_CHANGETELEKINESIS, SC_ELEMENTALCHANGE );
+ set_sc( MC_LOUD , SC_SHOUT , SI_SHOUT , SCB_STR );
+ set_sc( MG_ENERGYCOAT , SC_ENERGYCOAT , SI_ENERGYCOAT , SCB_NONE );
+ set_sc( NPC_EMOTION , SC_MODECHANGE , SI_BLANK , SCB_MODE );
+ add_sc( NPC_EMOTION_ON , SC_MODECHANGE );
+ set_sc( NPC_ATTRICHANGE , SC_ARMOR_PROPERTY , SI_ARMOR_PROPERTY , SCB_DEF_ELE );
+ add_sc( NPC_CHANGEWATER , SC_ARMOR_PROPERTY );
+ add_sc( NPC_CHANGEGROUND , SC_ARMOR_PROPERTY );
+ add_sc( NPC_CHANGEFIRE , SC_ARMOR_PROPERTY );
+ add_sc( NPC_CHANGEWIND , SC_ARMOR_PROPERTY );
+ add_sc( NPC_CHANGEPOISON , SC_ARMOR_PROPERTY );
+ add_sc( NPC_CHANGEHOLY , SC_ARMOR_PROPERTY );
+ add_sc( NPC_CHANGEDARKNESS , SC_ARMOR_PROPERTY );
+ add_sc( NPC_CHANGETELEKINESIS, SC_ARMOR_PROPERTY );
add_sc( NPC_POISON , SC_POISON );
add_sc( NPC_BLINDATTACK , SC_BLIND );
add_sc( NPC_SILENCEATTACK , SC_SILENCE );
@@ -273,25 +274,25 @@ void initChangeTables(void) {
set_sc( NPC_BARRIER , SC_BARRIER , SI_BLANK , SCB_MDEF|SCB_DEF );
add_sc( NPC_DEFENDER , SC_ARMOR );
add_sc( NPC_LICK , SC_STUN );
- set_sc( NPC_HALLUCINATION , SC_HALLUCINATION , SI_HALLUCINATION , SCB_NONE );
+ set_sc( NPC_HALLUCINATION , SC_ILLUSION , SI_ILLUSION , SCB_NONE );
add_sc( NPC_REBIRTH , SC_REBIRTH );
add_sc( RG_RAID , SC_STUN );
#ifdef RENEWAL
add_sc( RG_RAID , SC_RAID );
add_sc( RG_BACKSTAP , SC_STUN );
#endif
- set_sc( RG_STRIPWEAPON , SC_STRIPWEAPON , SI_STRIPWEAPON , SCB_WATK );
- set_sc( RG_STRIPSHIELD , SC_STRIPSHIELD , SI_STRIPSHIELD , SCB_DEF );
- set_sc( RG_STRIPARMOR , SC_STRIPARMOR , SI_STRIPARMOR , SCB_VIT );
- set_sc( RG_STRIPHELM , SC_STRIPHELM , SI_STRIPHELM , SCB_INT );
- add_sc( AM_ACIDTERROR , SC_BLEEDING );
- set_sc( AM_CP_WEAPON , SC_CP_WEAPON , SI_CP_WEAPON , SCB_NONE );
- set_sc( AM_CP_SHIELD , SC_CP_SHIELD , SI_CP_SHIELD , SCB_NONE );
- set_sc( AM_CP_ARMOR , SC_CP_ARMOR , SI_CP_ARMOR , SCB_NONE );
- set_sc( AM_CP_HELM , SC_CP_HELM , SI_CP_HELM , SCB_NONE );
- set_sc( CR_AUTOGUARD , SC_AUTOGUARD , SI_AUTOGUARD , SCB_NONE );
+ set_sc( RG_STRIPWEAPON , SC_NOEQUIPWEAPON , SI_NOEQUIPWEAPON , SCB_WATK );
+ set_sc( RG_STRIPSHIELD , SC_NOEQUIPSHIELD , SI_NOEQUIPSHIELD , SCB_DEF );
+ set_sc( RG_STRIPARMOR , SC_NOEQUIPARMOR , SI_NOEQUIPARMOR , SCB_VIT );
+ set_sc( RG_STRIPHELM , SC_NOEQUIPHELM , SI_NOEQUIPHELM , SCB_INT );
+ add_sc( AM_ACIDTERROR , SC_BLOODING );
+ set_sc( AM_CP_WEAPON , SC_PROTECTWEAPON , SI_PROTECTWEAPON , SCB_NONE );
+ set_sc( AM_CP_SHIELD , SC_PROTECTSHIELD , SI_PROTECTSHIELD , SCB_NONE );
+ set_sc( AM_CP_ARMOR , SC_PROTECTARMOR , SI_PROTECTARMOR , SCB_NONE );
+ set_sc( AM_CP_HELM , SC_PROTECTHELM , SI_PROTECTHELM , SCB_NONE );
+ set_sc( CR_AUTOGUARD , SC_AUTOGUARD , SI_AUTOGUARD , SCB_NONE );
add_sc( CR_SHIELDCHARGE , SC_STUN );
- set_sc( CR_REFLECTSHIELD , SC_REFLECTSHIELD , SI_REFLECTSHIELD , SCB_NONE );
+ set_sc( CR_REFLECTSHIELD , SC_REFLECTSHIELD , SI_REFLECTSHIELD , SCB_NONE );
add_sc( CR_HOLYCROSS , SC_BLIND );
add_sc( CR_GRANDCROSS , SC_BLIND );
add_sc( CR_DEVOTION , SC_DEVOTION );
@@ -304,17 +305,17 @@ void initChangeTables(void) {
set_sc( MO_EXPLOSIONSPIRITS , SC_EXPLOSIONSPIRITS, SI_EXPLOSIONSPIRITS, SCB_CRI|SCB_REGEN );
set_sc( MO_EXTREMITYFIST , SC_EXTREMITYFIST , SI_BLANK , SCB_REGEN );
#ifdef RENEWAL
- set_sc( MO_EXTREMITYFIST , SC_EXTREMITYFIST2 , SI_EXTREMITYFIST , SCB_NONE );
+ set_sc( MO_EXTREMITYFIST , SC_EXTREMITYFIST2 , SI_EXTREMITYFIST , SCB_NONE );
#endif
add_sc( SA_MAGICROD , SC_MAGICROD );
set_sc( SA_AUTOSPELL , SC_AUTOSPELL , SI_AUTOSPELL , SCB_NONE );
- set_sc( SA_FLAMELAUNCHER , SC_FIREWEAPON , SI_FIREWEAPON , SCB_ATK_ELE );
- set_sc( SA_FROSTWEAPON , SC_WATERWEAPON , SI_WATERWEAPON , SCB_ATK_ELE );
- set_sc( SA_LIGHTNINGLOADER , SC_WINDWEAPON , SI_WINDWEAPON , SCB_ATK_ELE );
- set_sc( SA_SEISMICWEAPON , SC_EARTHWEAPON , SI_EARTHWEAPON , SCB_ATK_ELE );
- set_sc( SA_VOLCANO , SC_VOLCANO , SI_LANDENDOW , SCB_WATK );
- set_sc( SA_DELUGE , SC_DELUGE , SI_LANDENDOW , SCB_MAXHP );
- set_sc( SA_VIOLENTGALE , SC_VIOLENTGALE , SI_LANDENDOW , SCB_FLEE );
+ set_sc( SA_FLAMELAUNCHER , SC_PROPERTYFIRE , SI_PROPERTYFIRE , SCB_ATK_ELE );
+ set_sc( SA_FROSTWEAPON , SC_PROPERTYWATER , SI_PROPERTYWATER , SCB_ATK_ELE );
+ set_sc( SA_LIGHTNINGLOADER , SC_PROPERTYWIND , SI_PROPERTYWIND , SCB_ATK_ELE );
+ set_sc( SA_SEISMICWEAPON , SC_PROPERTYGROUND , SI_PROPERTYGROUND , SCB_ATK_ELE );
+ set_sc( SA_VOLCANO , SC_VOLCANO , SI_GROUNDMAGIC , SCB_WATK );
+ set_sc( SA_DELUGE , SC_DELUGE , SI_GROUNDMAGIC , SCB_MAXHP );
+ set_sc( SA_VIOLENTGALE , SC_VIOLENTGALE , SI_GROUNDMAGIC , SCB_FLEE );
add_sc( SA_REVERSEORCISH , SC_ORCISH );
add_sc( SA_COMA , SC_COMA );
set_sc( BD_ENCORE , SC_DANCING , SI_BLANK , SCB_SPEED|SCB_REGEN );
@@ -334,19 +335,23 @@ void initChangeTables(void) {
set_sc( DC_HUMMING , SC_HUMMING , SI_BLANK , SCB_HIT );
set_sc( DC_DONTFORGETME , SC_DONTFORGETME , SI_BLANK , SCB_SPEED|SCB_ASPD );
set_sc( DC_FORTUNEKISS , SC_FORTUNE , SI_BLANK , SCB_CRI );
- set_sc( DC_SERVICEFORYOU , SC_SERVICE4U , SI_BLANK , SCB_ALL );
+ set_sc( DC_SERVICEFORYOU , SC_SERVICEFORYOU , SI_BLANK , SCB_ALL );
add_sc( NPC_DARKCROSS , SC_BLIND );
add_sc( NPC_GRANDDARKNESS , SC_BLIND );
set_sc( NPC_STOP , SC_STOP , SI_STOP , SCB_NONE );
set_sc( NPC_WEAPONBRAKER , SC_BROKENWEAPON , SI_BROKENWEAPON , SCB_NONE );
set_sc( NPC_ARMORBRAKE , SC_BROKENARMOR , SI_BROKENARMOR , SCB_NONE );
- set_sc( NPC_CHANGEUNDEAD , SC_CHANGEUNDEAD , SI_UNDEAD , SCB_DEF_ELE );
+ set_sc( NPC_CHANGEUNDEAD , SC_PROPERTYUNDEAD , SI_PROPERTYUNDEAD , SCB_DEF_ELE );
set_sc( NPC_POWERUP , SC_INCHITRATE , SI_BLANK , SCB_HIT );
set_sc( NPC_AGIUP , SC_INCFLEERATE , SI_BLANK , SCB_FLEE );
add_sc( NPC_INVISIBLE , SC_CLOAKING );
set_sc( LK_AURABLADE , SC_AURABLADE , SI_AURABLADE , SCB_NONE );
set_sc( LK_PARRYING , SC_PARRYING , SI_PARRYING , SCB_NONE );
- set_sc( LK_CONCENTRATION , SC_CONCENTRATION , SI_CONCENTRATION , SCB_BATK|SCB_WATK|SCB_HIT|SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_DSPD );
+#ifndef RENEWAL
+ set_sc( LK_CONCENTRATION , SC_LKCONCENTRATION , SI_CONCENTRATION , SCB_BATK|SCB_WATK|SCB_HIT|SCB_DEF|SCB_DEF2);
+#else
+ set_sc( LK_CONCENTRATION , SC_LKCONCENTRATION , SI_CONCENTRATION , SCB_HIT|SCB_DEF);
+#endif
set_sc( LK_TENSIONRELAX , SC_TENSIONRELAX , SI_TENSIONRELAX , SCB_REGEN );
set_sc( LK_BERSERK , SC_BERSERK , SI_BERSERK , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN );
set_sc( HP_ASSUMPTIO , SC_ASSUMPTIO , SI_ASSUMPTIO , SCB_NONE );
@@ -362,32 +367,32 @@ void initChangeTables(void) {
set_sc( WS_MELTDOWN , SC_MELTDOWN , SI_MELTDOWN , SCB_NONE );
set_sc( WS_CARTBOOST , SC_CARTBOOST , SI_CARTBOOST , SCB_SPEED );
set_sc( ST_CHASEWALK , SC_CHASEWALK , SI_BLANK , SCB_SPEED );
- set_sc( ST_REJECTSWORD , SC_REJECTSWORD , SI_REJECTSWORD , SCB_NONE );
+ set_sc( ST_REJECTSWORD , SC_SWORDREJECT , SI_SWORDREJECT , SCB_NONE );
add_sc( ST_REJECTSWORD , SC_AUTOCOUNTER );
- set_sc( CG_MARIONETTE , SC_MARIONETTE , SI_MARIONETTE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
- set_sc( CG_MARIONETTE , SC_MARIONETTE2 , SI_MARIONETTE2 , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+ set_sc( CG_MARIONETTE , SC_MARIONETTE_MASTER , SI_MARIONETTE_MASTER , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+ set_sc( CG_MARIONETTE , SC_MARIONETTE , SI_MARIONETTE , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
add_sc( LK_SPIRALPIERCE , SC_STOP );
- add_sc( LK_HEADCRUSH , SC_BLEEDING );
+ add_sc( LK_HEADCRUSH , SC_BLOODING );
set_sc( LK_JOINTBEAT , SC_JOINTBEAT , SI_JOINTBEAT , SCB_BATK|SCB_DEF2|SCB_SPEED|SCB_ASPD );
add_sc( HW_NAPALMVULCAN , SC_CURSE );
set_sc( PF_MINDBREAKER , SC_MINDBREAKER , SI_BLANK , SCB_MATK|SCB_MDEF2 );
add_sc( PF_MEMORIZE , SC_MEMORIZE );
add_sc( PF_FOGWALL , SC_FOGWALL );
set_sc( PF_SPIDERWEB , SC_SPIDERWEB , SI_BLANK , SCB_FLEE );
- set_sc( WE_BABY , SC_BABY , SI_BABY , SCB_NONE );
+ set_sc( WE_BABY , SC_BABY , SI_PROTECTEXP , SCB_NONE );
set_sc( TK_RUN , SC_RUN , SI_RUN , SCB_SPEED|SCB_DSPD );
- set_sc( TK_RUN , SC_SPURT , SI_SPURT , SCB_STR );
- set_sc( TK_READYSTORM , SC_READYSTORM , SI_READYSTORM , SCB_NONE );
- set_sc( TK_READYDOWN , SC_READYDOWN , SI_READYDOWN , SCB_NONE );
+ set_sc( TK_RUN , SC_STRUP , SI_STRUP , SCB_STR );
+ set_sc( TK_READYSTORM , SC_STORMKICK_READY , SI_STORMKICK_ON , SCB_NONE );
+ set_sc( TK_READYDOWN , SC_DOWNKICK_READY , SI_DOWNKICK_ON , SCB_NONE );
add_sc( TK_DOWNKICK , SC_STUN );
- set_sc( TK_READYTURN , SC_READYTURN , SI_READYTURN , SCB_NONE );
- set_sc( TK_READYCOUNTER , SC_READYCOUNTER , SI_READYCOUNTER , SCB_NONE );
- set_sc( TK_DODGE , SC_DODGE , SI_DODGE , SCB_NONE );
+ set_sc( TK_READYTURN , SC_TURNKICK_READY , SI_TURNKICK_ON , SCB_NONE );
+ set_sc( TK_READYCOUNTER , SC_COUNTERKICK_READY , SI_COUNTER_ON , SCB_NONE );
+ set_sc( TK_DODGE , SC_DODGE_READY , SI_DODGE_ON , SCB_NONE );
set_sc( TK_SPTIME , SC_EARTHSCROLL , SI_EARTHSCROLL , SCB_NONE );
- add_sc( TK_SEVENWIND , SC_SEVENWIND );
- set_sc( TK_SEVENWIND , SC_GHOSTWEAPON , SI_GHOSTWEAPON , SCB_ATK_ELE );
- set_sc( TK_SEVENWIND , SC_SHADOWWEAPON , SI_SHADOWWEAPON , SCB_ATK_ELE );
- set_sc( SG_SUN_WARM , SC_WARM , SI_WARM , SCB_NONE );
+ add_sc( TK_SEVENWIND , SC_TK_SEVENWIND );
+ set_sc( TK_SEVENWIND , SC_PROPERTYTELEKINESIS , SI_PROPERTYTELEKINESIS , SCB_ATK_ELE );
+ set_sc( TK_SEVENWIND , SC_PROPERTYDARK , SI_PROPERTYDARK , SCB_ATK_ELE );
+ set_sc( SG_SUN_WARM , SC_WARM , SI_SG_SUN_WARM , SCB_NONE );
add_sc( SG_MOON_WARM , SC_WARM );
add_sc( SG_STAR_WARM , SC_WARM );
set_sc( SG_SUN_COMFORT , SC_SUN_COMFORT , SI_SUN_COMFORT , SCB_DEF2 );
@@ -405,39 +410,40 @@ void initChangeTables(void) {
set_sc( SL_SWOO , SC_SWOO , SI_BLANK , SCB_SPEED );
set_sc( SL_SKE , SC_SKE , SI_BLANK , SCB_BATK|SCB_WATK|SCB_DEF|SCB_DEF2 );
set_sc( SL_SKA , SC_SKA , SI_BLANK , SCB_DEF|SCB_MDEF|SCB_ASPD );
- set_sc( SL_SMA , SC_SMA , SI_SMA , SCB_NONE );
+ set_sc( SL_SMA , SC_SMA_READY , SI_SMA_READY , SCB_NONE );
set_sc( SM_SELFPROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
set_sc( ST_PRESERVE , SC_PRESERVE , SI_PRESERVE , SCB_NONE );
- set_sc( PF_DOUBLECASTING , SC_DOUBLECAST , SI_DOUBLECAST , SCB_NONE );
+ set_sc( PF_DOUBLECASTING , SC_DOUBLECASTING , SI_DOUBLECASTING , SCB_NONE );
set_sc( HW_GRAVITATION , SC_GRAVITATION , SI_BLANK , SCB_ASPD );
add_sc( WS_CARTTERMINATION , SC_STUN );
- set_sc( WS_OVERTHRUSTMAX , SC_MAXOVERTHRUST , SI_MAXOVERTHRUST , SCB_NONE );
+ set_sc( WS_OVERTHRUSTMAX , SC_OVERTHRUSTMAX , SI_OVERTHRUSTMAX , SCB_NONE );
set_sc( CG_LONGINGFREEDOM , SC_LONGING , SI_BLANK , SCB_SPEED|SCB_ASPD );
add_sc( CG_HERMODE , SC_HERMODE );
+ set_sc( CG_TAROTCARD , SC_TAROTCARD , SI_TAROTCARD , SCB_NONE );
set_sc( ITEM_ENCHANTARMS , SC_ENCHANTARMS , SI_BLANK , SCB_ATK_ELE );
- set_sc( SL_HIGH , SC_SPIRIT , SI_SPIRIT , SCB_ALL );
- set_sc( KN_ONEHAND , SC_ONEHAND , SI_ONEHAND , SCB_ASPD );
+ set_sc( SL_HIGH , SC_SOULLINK , SI_SOULLINK , SCB_ALL );
+ set_sc( KN_ONEHAND , SC_ONEHANDQUICKEN , SI_ONEHANDQUICKEN , SCB_ASPD );
set_sc( GS_FLING , SC_FLING , SI_BLANK , SCB_DEF|SCB_DEF2 );
add_sc( GS_CRACKER , SC_STUN );
- add_sc( GS_DISARM , SC_STRIPWEAPON );
- add_sc( GS_PIERCINGSHOT , SC_BLEEDING );
- set_sc( GS_MADNESSCANCEL , SC_MADNESSCANCEL , SI_MADNESSCANCEL , SCB_BATK|SCB_ASPD );
- set_sc( GS_ADJUSTMENT , SC_ADJUSTMENT , SI_ADJUSTMENT , SCB_HIT|SCB_FLEE );
- set_sc( GS_INCREASING , SC_INCREASING , SI_ACCURACY , SCB_AGI|SCB_DEX|SCB_HIT );
- set_sc( GS_GATLINGFEVER , SC_GATLINGFEVER , SI_GATLINGFEVER , SCB_BATK|SCB_FLEE|SCB_SPEED|SCB_ASPD );
- set_sc( NJ_TATAMIGAESHI , SC_TATAMIGAESHI , SI_BLANK , SCB_NONE );
- set_sc( NJ_SUITON , SC_SUITON , SI_BLANK , SCB_AGI|SCB_SPEED );
+ add_sc( GS_DISARM , SC_NOEQUIPWEAPON );
+ add_sc( GS_PIERCINGSHOT , SC_BLOODING );
+ set_sc( GS_MADNESSCANCEL , SC_GS_MADNESSCANCEL , SI_GS_MADNESSCANCEL , SCB_BATK|SCB_ASPD );
+ set_sc( GS_ADJUSTMENT , SC_GS_ADJUSTMENT , SI_GS_ADJUSTMENT , SCB_HIT|SCB_FLEE );
+ set_sc( GS_INCREASING , SC_GS_ACCURACY , SI_GS_ACCURACY , SCB_AGI|SCB_DEX|SCB_HIT );
+ set_sc( GS_GATLINGFEVER , SC_GS_GATLINGFEVER , SI_GS_GATLINGFEVER , SCB_BATK|SCB_FLEE|SCB_SPEED|SCB_ASPD );
+ set_sc( NJ_TATAMIGAESHI , SC_NJ_TATAMIGAESHI , SI_BLANK , SCB_NONE );
+ set_sc( NJ_SUITON , SC_NJ_SUITON , SI_NJ_SUITON , SCB_AGI|SCB_SPEED );
add_sc( NJ_HYOUSYOURAKU , SC_FREEZE );
- set_sc( NJ_NEN , SC_NEN , SI_NEN , SCB_STR|SCB_INT );
- set_sc( NJ_UTSUSEMI , SC_UTSUSEMI , SI_UTSUSEMI , SCB_NONE );
- set_sc( NJ_BUNSINJYUTSU , SC_BUNSINJYUTSU , SI_BUNSINJYUTSU , SCB_DYE );
+ set_sc( NJ_NEN , SC_NJ_NEN , SI_NJ_NEN , SCB_STR|SCB_INT );
+ set_sc( NJ_UTSUSEMI , SC_NJ_UTSUSEMI , SI_NJ_UTSUSEMI , SCB_NONE );
+ set_sc( NJ_BUNSINJYUTSU , SC_NJ_BUNSINJYUTSU , SI_NJ_BUNSINJYUTSU , SCB_DYE );
add_sc( NPC_ICEBREATH , SC_FREEZE );
add_sc( NPC_ACIDBREATH , SC_POISON );
add_sc( NPC_HELLJUDGEMENT , SC_CURSE );
add_sc( NPC_WIDESILENCE , SC_SILENCE );
add_sc( NPC_WIDEFREEZE , SC_FREEZE );
- add_sc( NPC_WIDEBLEEDING , SC_BLEEDING );
+ add_sc( NPC_WIDEBLEEDING , SC_BLOODING );
add_sc( NPC_WIDESTONE , SC_STONE );
add_sc( NPC_WIDECONFUSE , SC_CONFUSION );
add_sc( NPC_WIDESLEEP , SC_SLEEP );
@@ -446,8 +452,8 @@ void initChangeTables(void) {
add_sc( NPC_MAGICMIRROR , SC_MAGICMIRROR );
set_sc( NPC_SLOWCAST , SC_SLOWCAST , SI_SLOWCAST , SCB_NONE );
set_sc( NPC_CRITICALWOUND , SC_CRITICALWOUND , SI_CRITICALWOUND , SCB_NONE );
- set_sc( NPC_STONESKIN , SC_ARMORCHANGE , SI_BLANK , SCB_DEF|SCB_MDEF );
- add_sc( NPC_ANTIMAGIC , SC_ARMORCHANGE );
+ set_sc( NPC_STONESKIN , SC_STONESKIN , SI_BLANK , SCB_DEF|SCB_MDEF );
+ add_sc( NPC_ANTIMAGIC , SC_STONESKIN );
add_sc( NPC_WIDECURSE , SC_CURSE );
add_sc( NPC_WIDESTUN , SC_STUN );
@@ -457,29 +463,29 @@ void initChangeTables(void) {
set_sc( NPC_INVINCIBLEOFF , SC_INVINCIBLEOFF , SI_BLANK , SCB_SPEED );
set_sc( CASH_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
- set_sc( CASH_INCAGI , SC_INCREASEAGI , SI_INCREASEAGI , SCB_AGI|SCB_SPEED );
+ set_sc( CASH_INCAGI , SC_INC_AGI , SI_INC_AGI , SCB_AGI|SCB_SPEED );
set_sc( CASH_ASSUMPTIO , SC_ASSUMPTIO , SI_ASSUMPTIO , SCB_NONE );
set_sc( ALL_PARTYFLEE , SC_PARTYFLEE , SI_PARTYFLEE , SCB_NONE );
set_sc( ALL_ODINS_POWER , SC_ODINS_POWER , SI_ODINS_POWER , SCB_MATK|SCB_BATK|SCB_MDEF|SCB_DEF );
- set_sc( CR_SHRINK , SC_SHRINK , SI_SHRINK , SCB_NONE );
- set_sc( RG_CLOSECONFINE , SC_CLOSECONFINE2 , SI_CLOSECONFINE2 , SCB_NONE );
- set_sc( RG_CLOSECONFINE , SC_CLOSECONFINE , SI_CLOSECONFINE , SCB_FLEE );
- set_sc( WZ_SIGHTBLASTER , SC_SIGHTBLASTER , SI_SIGHTBLASTER , SCB_NONE );
- set_sc( DC_WINKCHARM , SC_WINKCHARM , SI_WINKCHARM , SCB_NONE );
+ set_sc( CR_SHRINK , SC_CR_SHRINK , SI_CR_SHRINK , SCB_NONE );
+ set_sc( RG_CLOSECONFINE , SC_RG_CCONFINE_S , SI_RG_CCONFINE_S , SCB_NONE );
+ set_sc( RG_CLOSECONFINE , SC_RG_CCONFINE_M , SI_RG_CCONFINE_M , SCB_FLEE );
+ set_sc( WZ_SIGHTBLASTER , SC_WZ_SIGHTBLASTER , SI_WZ_SIGHTBLASTER , SCB_NONE );
+ set_sc( DC_WINKCHARM , SC_DC_WINKCHARM , SI_DC_WINKCHARM , SCB_NONE );
add_sc( MO_BALKYOUNG , SC_STUN );
- add_sc( SA_ELEMENTWATER , SC_ELEMENTALCHANGE );
- add_sc( SA_ELEMENTFIRE , SC_ELEMENTALCHANGE );
- add_sc( SA_ELEMENTGROUND , SC_ELEMENTALCHANGE );
- add_sc( SA_ELEMENTWIND , SC_ELEMENTALCHANGE );
-
- set_sc( HLIF_AVOID , SC_AVOID , SI_BLANK , SCB_SPEED );
- set_sc( HLIF_CHANGE , SC_CHANGE , SI_BLANK , SCB_VIT|SCB_INT );
- set_sc( HFLI_FLEET , SC_FLEET , SI_BLANK , SCB_ASPD|SCB_BATK|SCB_WATK );
- set_sc( HFLI_SPEED , SC_SPEED , SI_BLANK , SCB_FLEE );
- set_sc( HAMI_DEFENCE , SC_DEFENCE , SI_BLANK , SCB_DEF );
- set_sc( HAMI_BLOODLUST , SC_BLOODLUST , SI_BLANK , SCB_BATK|SCB_WATK );
+ add_sc( SA_ELEMENTWATER , SC_ARMOR_PROPERTY );
+ add_sc( SA_ELEMENTFIRE , SC_ARMOR_PROPERTY );
+ add_sc( SA_ELEMENTGROUND , SC_ARMOR_PROPERTY );
+ add_sc( SA_ELEMENTWIND , SC_ARMOR_PROPERTY );
+
+ set_sc( HLIF_AVOID , SC_HLIF_AVOID , SI_BLANK , SCB_SPEED );
+ set_sc( HLIF_CHANGE , SC_HLIF_CHANGE , SI_BLANK , SCB_VIT|SCB_INT );
+ set_sc( HFLI_FLEET , SC_HLIF_FLEET , SI_BLANK , SCB_ASPD|SCB_BATK|SCB_WATK );
+ set_sc( HFLI_SPEED , SC_HLIF_SPEED , SI_BLANK , SCB_FLEE );
+ set_sc( HAMI_DEFENCE , SC_HAMI_DEFENCE , SI_BLANK , SCB_DEF );
+ set_sc( HAMI_BLOODLUST , SC_HAMI_BLOODLUST , SI_BLANK , SCB_BATK|SCB_WATK );
// Homunculus S
add_sc(MH_STAHL_HORN, SC_STUN);
@@ -489,25 +495,25 @@ void initChangeTables(void) {
add_sc(MH_ERASER_CUTTER, SC_ERASER_CUTTER);
set_sc(MH_OVERED_BOOST, SC_OVERED_BOOST, SI_BLANK, SCB_FLEE|SCB_ASPD);
add_sc(MH_LIGHT_OF_REGENE, SC_LIGHT_OF_REGENE);
- set_sc(MH_VOLCANIC_ASH, SC_ASH, SI_VOLCANIC_ASH, SCB_DEF|SCB_DEF2|SCB_HIT|SCB_BATK|SCB_FLEE);
+ set_sc(MH_VOLCANIC_ASH, SC_VOLCANIC_ASH, SI_VOLCANIC_ASH, SCB_DEF|SCB_DEF2|SCB_HIT|SCB_BATK|SCB_FLEE);
set_sc(MH_GRANITIC_ARMOR, SC_GRANITIC_ARMOR, SI_GRANITIC_ARMOR, SCB_NONE);
set_sc(MH_MAGMA_FLOW, SC_MAGMA_FLOW, SI_MAGMA_FLOW, SCB_NONE);
set_sc(MH_PYROCLASTIC, SC_PYROCLASTIC, SI_PYROCLASTIC, SCB_BATK|SCB_ATK_ELE);
add_sc(MH_LAVA_SLIDE, SC_BURNING);
- set_sc(MH_NEEDLE_OF_PARALYZE, SC_PARALYSIS, SI_NEEDLE_OF_PARALYZE, SCB_DEF2);
+ set_sc(MH_NEEDLE_OF_PARALYZE, SC_NEEDLE_OF_PARALYZE, SI_NEEDLE_OF_PARALYZE, SCB_DEF2);
add_sc(MH_POISON_MIST, SC_BLIND);
set_sc(MH_PAIN_KILLER, SC_PAIN_KILLER, SI_PAIN_KILLER, SCB_ASPD);
add_sc(MH_STYLE_CHANGE, SC_STYLE_CHANGE);
- set_sc( MH_TINDER_BREAKER , SC_CLOSECONFINE2 , SI_CLOSECONFINE2 , SCB_NONE );
- set_sc( MH_TINDER_BREAKER , SC_CLOSECONFINE , SI_CLOSECONFINE , SCB_FLEE );
+ set_sc( MH_TINDER_BREAKER , SC_RG_CCONFINE_S , SI_RG_CCONFINE_S , SCB_NONE );
+ set_sc( MH_TINDER_BREAKER , SC_RG_CCONFINE_M , SI_RG_CCONFINE_M , SCB_FLEE );
add_sc( MER_CRASH , SC_STUN );
set_sc( MER_PROVOKE , SC_PROVOKE , SI_PROVOKE , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
add_sc( MS_MAGNUM , SC_WATK_ELEMENT );
add_sc( MER_SIGHT , SC_SIGHT );
- set_sc( MER_DECAGI , SC_DECREASEAGI , SI_DECREASEAGI , SCB_AGI|SCB_SPEED );
+ set_sc( MER_DECAGI , SC_DEC_AGI , SI_DEC_AGI , SCB_AGI|SCB_SPEED );
set_sc( MER_MAGNIFICAT , SC_MAGNIFICAT , SI_MAGNIFICAT , SCB_REGEN );
add_sc( MER_LEXDIVINA , SC_SILENCE );
add_sc( MA_LANDMINE , SC_STUN );
@@ -520,19 +526,19 @@ void initChangeTables(void) {
set_sc( MS_PARRYING , SC_PARRYING , SI_PARRYING , SCB_NONE );
set_sc( MS_BERSERK , SC_BERSERK , SI_BERSERK , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2|SCB_FLEE|SCB_SPEED|SCB_ASPD|SCB_MAXHP|SCB_REGEN );
add_sc( ML_SPIRALPIERCE , SC_STOP );
- set_sc( MER_QUICKEN , SC_MERC_QUICKEN , SI_BLANK , SCB_ASPD );
+ set_sc( MER_QUICKEN , SC_MER_QUICKEN , SI_BLANK , SCB_ASPD );
add_sc( ML_DEVOTION , SC_DEVOTION );
set_sc( MER_KYRIE , SC_KYRIE , SI_KYRIE , SCB_NONE );
set_sc( MER_BLESSING , SC_BLESSING , SI_BLESSING , SCB_STR|SCB_INT|SCB_DEX );
- set_sc( MER_INCAGI , SC_INCREASEAGI , SI_INCREASEAGI , SCB_AGI|SCB_SPEED );
+ set_sc( MER_INCAGI , SC_INC_AGI , SI_INC_AGI , SCB_AGI|SCB_SPEED );
set_sc( GD_LEADERSHIP , SC_LEADERSHIP , SI_BLANK , SCB_STR );
set_sc( GD_GLORYWOUNDS , SC_GLORYWOUNDS , SI_BLANK , SCB_VIT );
set_sc( GD_SOULCOLD , SC_SOULCOLD , SI_BLANK , SCB_AGI );
set_sc( GD_HAWKEYES , SC_HAWKEYES , SI_BLANK , SCB_DEX );
- set_sc( GD_BATTLEORDER , SC_BATTLEORDERS , SI_BLANK , SCB_STR|SCB_INT|SCB_DEX );
- set_sc( GD_REGENERATION , SC_REGENERATION , SI_BLANK , SCB_REGEN );
+ set_sc( GD_BATTLEORDER , SC_GDSKILL_BATTLEORDER , SI_BLANK , SCB_STR|SCB_INT|SCB_DEX );
+ set_sc( GD_REGENERATION , SC_GDSKILL_REGENERATION , SI_BLANK , SCB_REGEN );
/**
* Rune Knight
@@ -541,15 +547,16 @@ void initChangeTables(void) {
set_sc( RK_DRAGONHOWLING , SC_FEAR , SI_BLANK , SCB_FLEE|SCB_HIT );
set_sc( RK_DEATHBOUND , SC_DEATHBOUND , SI_DEATHBOUND , SCB_NONE );
set_sc( RK_WINDCUTTER , SC_FEAR , SI_BLANK , SCB_FLEE|SCB_HIT );
- add_sc( RK_DRAGONBREATH , SC_BURNING );
- set_sc( RK_MILLENNIUMSHIELD , SC_MILLENNIUMSHIELD , SI_REUSE_MILLENNIUMSHIELD , SCB_NONE );
+ set_sc( RK_DRAGONBREATH , SC_BURNING , SI_BLANK , SCB_MDEF );
+ set_sc( RK_MILLENNIUMSHIELD , SC_MILLENNIUMSHIELD , SI_BLANK , SCB_NONE );
set_sc( RK_REFRESH , SC_REFRESH , SI_REFRESH , SCB_NONE );
set_sc( RK_GIANTGROWTH , SC_GIANTGROWTH , SI_GIANTGROWTH , SCB_STR );
- set_sc( RK_STONEHARDSKIN , SC_STONEHARDSKIN , SI_STONEHARDSKIN , SCB_DEF|SCB_MDEF );
+ set_sc( RK_STONEHARDSKIN , SC_STONEHARDSKIN , SI_STONEHARDSKIN , SCB_NONE );
set_sc( RK_VITALITYACTIVATION, SC_VITALITYACTIVATION, SI_VITALITYACTIVATION, SCB_REGEN );
set_sc( RK_FIGHTINGSPIRIT , SC_FIGHTINGSPIRIT , SI_FIGHTINGSPIRIT , SCB_WATK|SCB_ASPD );
set_sc( RK_ABUNDANCE , SC_ABUNDANCE , SI_ABUNDANCE , SCB_NONE );
set_sc( RK_CRUSHSTRIKE , SC_CRUSHSTRIKE , SI_CRUSHSTRIKE , SCB_NONE );
+ add_sc( RK_DRAGONBREATH_WATER, SC_FROSTMISTY );
/**
* GC Guillotine Cross
**/
@@ -559,12 +566,13 @@ void initChangeTables(void) {
set_sc( GC_CLOAKINGEXCEED , SC_CLOAKINGEXCEED , SI_CLOAKINGEXCEED , SCB_SPEED );
set_sc( GC_HALLUCINATIONWALK , SC_HALLUCINATIONWALK, SI_HALLUCINATIONWALK, SCB_FLEE );
set_sc( GC_ROLLINGCUTTER , SC_ROLLINGCUTTER , SI_ROLLINGCUTTER , SCB_NONE );
+ set_sc_with_vfx( GC_DARKCROW , SC_DARKCROW , SI_DARKCROW , SCB_NONE );
/**
* Arch Bishop
**/
set_sc( AB_ADORAMUS , SC_ADORAMUS , SI_ADORAMUS , SCB_AGI|SCB_SPEED );
add_sc( AB_CLEMENTIA , SC_BLESSING );
- add_sc( AB_CANTO , SC_INCREASEAGI );
+ add_sc( AB_CANTO , SC_INC_AGI );
set_sc( AB_EPICLESIS , SC_EPICLESIS , SI_EPICLESIS , SCB_MAXHP );
add_sc( AB_PRAEFATIO , SC_KYRIE );
set_sc_with_vfx( AB_ORATIO , SC_ORATIO , SI_ORATIO , SCB_NONE );
@@ -574,14 +582,16 @@ void initChangeTables(void) {
set_sc( AB_EXPIATIO , SC_EXPIATIO , SI_EXPIATIO , SCB_ATK_ELE );
set_sc( AB_DUPLELIGHT , SC_DUPLELIGHT , SI_DUPLELIGHT , SCB_NONE );
set_sc( AB_SECRAMENT , SC_SECRAMENT , SI_SECRAMENT , SCB_NONE );
+ set_sc( AB_OFFERTORIUM , SC_OFFERTORIUM , SI_OFFERTORIUM , SCB_NONE );
/**
* Warlock
**/
add_sc( WL_WHITEIMPRISON , SC_WHITEIMPRISON );
- set_sc_with_vfx( WL_FROSTMISTY , SC_FREEZING , SI_FROSTMISTY , SCB_ASPD|SCB_SPEED|SCB_DEF|SCB_DEF2 );
- set_sc( WL_MARSHOFABYSS , SC_MARSHOFABYSS , SI_MARSHOFABYSS , SCB_SPEED|SCB_FLEE|SCB_DEF|SCB_MDEF );
+ set_sc_with_vfx( WL_FROSTMISTY , SC_FROSTMISTY , SI_FROSTMISTY , SCB_ASPD|SCB_SPEED|SCB_DEF );
+ set_sc( WL_MARSHOFABYSS , SC_MARSHOFABYSS , SI_MARSHOFABYSS , SCB_SPEED|SCB_FLEE|SCB_AGI|SCB_DEX );
set_sc(WL_RECOGNIZEDSPELL , SC_RECOGNIZEDSPELL , SI_RECOGNIZEDSPELL , SCB_MATK);
set_sc( WL_STASIS , SC_STASIS , SI_STASIS , SCB_NONE );
+ set_sc( WL_TELEKINESIS_INTENSE, SC_TELEKINESIS_INTENSE , SI_TELEKINESIS_INTENSE , SCB_MATK );
/**
* Ranger
**/
@@ -589,12 +599,13 @@ void initChangeTables(void) {
set_sc( RA_ELECTRICSHOCKER , SC_ELECTRICSHOCKER , SI_ELECTRICSHOCKER , SCB_NONE );
set_sc( RA_WUGDASH , SC_WUGDASH , SI_WUGDASH , SCB_SPEED );
set_sc( RA_CAMOUFLAGE , SC_CAMOUFLAGE , SI_CAMOUFLAGE , SCB_SPEED );
- add_sc( RA_MAGENTATRAP , SC_ELEMENTALCHANGE );
- add_sc( RA_COBALTTRAP , SC_ELEMENTALCHANGE );
- add_sc( RA_MAIZETRAP , SC_ELEMENTALCHANGE );
- add_sc( RA_VERDURETRAP , SC_ELEMENTALCHANGE );
- add_sc( RA_FIRINGTRAP , SC_BURNING );
- set_sc_with_vfx( RA_ICEBOUNDTRAP , SC_FREEZING , SI_FROSTMISTY , SCB_NONE );
+ add_sc( RA_MAGENTATRAP , SC_ARMOR_PROPERTY );
+ add_sc( RA_COBALTTRAP , SC_ARMOR_PROPERTY );
+ add_sc( RA_MAIZETRAP , SC_ARMOR_PROPERTY );
+ add_sc( RA_VERDURETRAP , SC_ARMOR_PROPERTY );
+ add_sc( RA_FIRINGTRAP , SC_BURNING );
+ add_sc( RA_ICEBOUNDTRAP , SC_FROSTMISTY );
+ set_sc( RA_UNLIMIT , SC_UNLIMIT , SI_UNLIMIT , SCB_NONE );
/**
* Mechanic
**/
@@ -609,7 +620,7 @@ void initChangeTables(void) {
/**
* Royal Guard
**/
- set_sc( LG_REFLECTDAMAGE , SC_REFLECTDAMAGE , SI_LG_REFLECTDAMAGE, SCB_NONE );
+ 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_EXEEDBREAK , SC_EXEEDBREAK , SI_EXEEDBREAK , SCB_NONE );
set_sc( LG_PRESTIGE , SC_PRESTIGE , SI_PRESTIGE , SCB_DEF );
@@ -619,6 +630,7 @@ void initChangeTables(void) {
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
**/
@@ -634,7 +646,7 @@ void initChangeTables(void) {
set_sc( SC_LAZINESS , SC__LAZINESS , SI_LAZINESS , SCB_FLEE );
set_sc( SC_UNLUCKY , SC__UNLUCKY , SI_UNLUCKY , SCB_CRI|SCB_FLEE2 );
set_sc( SC_WEAKNESS , SC__WEAKNESS , SI_WEAKNESS , SCB_FLEE2|SCB_MAXHP );
- set_sc( SC_STRIPACCESSARY , SC__STRIPACCESSORY , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK );
+ 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 );
set_sc_with_vfx( SC_BLOODYLUST , SC__BLOODYLUST , SI_BLOODYLUST , SCB_DEF | SCB_DEF2 | SCB_MDEF | SCB_MDEF2 | SCB_FLEE | SCB_SPEED | SCB_ASPD | SCB_MAXHP | SCB_REGEN );
@@ -647,30 +659,32 @@ void initChangeTables(void) {
set_sc_with_vfx( SR_CURSEDCIRCLE , SC_CURSEDCIRCLE_TARGET, SI_CURSEDCIRCLE_TARGET , SCB_NONE );
set_sc( SR_LIGHTNINGWALK , SC_LIGHTNINGWALK , SI_LIGHTNINGWALK , SCB_NONE );
set_sc( SR_RAISINGDRAGON , SC_RAISINGDRAGON , SI_RAISINGDRAGON , SCB_REGEN|SCB_MAXHP|SCB_MAXSP );
- set_sc( SR_GENTLETOUCH_ENERGYGAIN, SC_GT_ENERGYGAIN , SI_GENTLETOUCH_ENERGYGAIN, SCB_NONE );
- set_sc( SR_GENTLETOUCH_CHANGE , SC_GT_CHANGE , SI_GENTLETOUCH_CHANGE , SCB_ASPD|SCB_MDEF|SCB_MAXHP );
- set_sc( SR_GENTLETOUCH_REVITALIZE, SC_GT_REVITALIZE , SI_GENTLETOUCH_REVITALIZE, SCB_MAXHP|SCB_REGEN );
+ set_sc( SR_GENTLETOUCH_ENERGYGAIN, SC_GENTLETOUCH_ENERGYGAIN , SI_GENTLETOUCH_ENERGYGAIN, SCB_NONE );
+ set_sc( SR_GENTLETOUCH_CHANGE , SC_GENTLETOUCH_CHANGE , SI_GENTLETOUCH_CHANGE , SCB_ASPD|SCB_MDEF|SCB_MAXHP );
+ set_sc( SR_GENTLETOUCH_REVITALIZE, SC_GENTLETOUCH_REVITALIZE , SI_GENTLETOUCH_REVITALIZE, SCB_MAXHP|SCB_REGEN );
/**
* Wanderer / Minstrel
**/
- set_sc( WA_SWING_DANCE , SC_SWINGDANCE , SI_SWINGDANCE , SCB_SPEED|SCB_ASPD );
- set_sc( WA_SYMPHONY_OF_LOVER , SC_SYMPHONYOFLOVER , SI_SYMPHONYOFLOVERS , SCB_MDEF );
- set_sc( WA_MOONLIT_SERENADE , SC_MOONLITSERENADE , SI_MOONLITSERENADE , SCB_MATK );
- set_sc( MI_RUSH_WINDMILL , SC_RUSHWINDMILL , SI_RUSHWINDMILL , SCB_BATK );
- 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_with_vfx( WM_VOICEOFSIREN , SC_VOICEOFSIREN , SI_VOICEOFSIREN , SCB_NONE );
- set_sc_with_vfx( WM_LULLABY_DEEPSLEEP , SC_DEEPSLEEP , SI_DEEPSLEEP , SCB_NONE );
- set_sc( WM_SIRCLEOFNATURE , SC_SIRCLEOFNATURE , SI_SIRCLEOFNATURE , SCB_NONE );
- set_sc( WM_GLOOMYDAY , SC_GLOOMYDAY , SI_GLOOMYDAY , SCB_FLEE|SCB_ASPD );
- set_sc( WM_SONG_OF_MANA , SC_SONGOFMANA , SI_SONGOFMANA , SCB_NONE );
- set_sc( WM_DANCE_WITH_WUG , SC_DANCEWITHWUG , SI_DANCEWITHWUG , SCB_ASPD );
- set_sc( WM_SATURDAY_NIGHT_FEVER , SC_SATURDAYNIGHTFEVER , SI_SATURDAYNIGHTFEVER , SCB_BATK|SCB_DEF|SCB_FLEE|SCB_REGEN );
- set_sc( WM_LERADS_DEW , SC_LERADSDEW , SI_LERADSDEW , SCB_MAXHP );
- set_sc( WM_MELODYOFSINK , SC_MELODYOFSINK , SI_MELODYOFSINK , SCB_BATK|SCB_MATK );
- set_sc( WM_BEYOND_OF_WARCRY , SC_BEYONDOFWARCRY , SI_WARCRYOFBEYOND , SCB_BATK|SCB_MATK );
- set_sc( WM_UNLIMITED_HUMMING_VOICE, SC_UNLIMITEDHUMMINGVOICE, SI_UNLIMITEDHUMMINGVOICE, SCB_NONE );
+ 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_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_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 );
+ set_sc( WM_GLOOMYDAY , SC_GLOOMYDAY , SI_GLOOMYDAY , SCB_FLEE|SCB_ASPD );
+ set_sc( WM_SONG_OF_MANA , SC_SONG_OF_MANA , SI_SONG_OF_MANA , SCB_NONE );
+ 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_UNLIMITED_HUMMING_VOICE, SC_UNLIMITED_HUMMING_VOICE, SI_UNLIMITEDHUMMINGVOICE, SCB_NONE );
+ set_sc( WM_FRIGG_SONG , SC_FRIGG_SONG , SI_FRIGG_SONG , SCB_MAXHP );
+
/**
* Sorcerer
**/
@@ -682,7 +696,7 @@ void initChangeTables(void) {
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 );
- set_sc( SO_ARRULLO , SC_DEEPSLEEP , SI_DEEPSLEEP , SCB_NONE );
+ set_sc( SO_ARRULLO , SC_DEEP_SLEEP , SI_DEEPSLEEP , SCB_NONE );
set_sc( SO_FIRE_INSIGNIA , SC_FIRE_INSIGNIA , SI_FIRE_INSIGNIA , SCB_MATK | SCB_BATK | SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
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 );
@@ -691,11 +705,11 @@ void initChangeTables(void) {
* Genetic
**/
set_sc( GN_CARTBOOST , SC_GN_CARTBOOST, SI_CARTSBOOST , SCB_SPEED );
- set_sc( GN_THORNS_TRAP , SC_THORNSTRAP , SI_THORNTRAP , SCB_NONE );
- set_sc_with_vfx( GN_BLOOD_SUCKER , SC_BLOODSUCKER , SI_BLOODSUCKER , SCB_NONE );
+ set_sc( GN_THORNS_TRAP , SC_THORNS_TRAP , SI_THORNTRAP , SCB_NONE );
+ set_sc_with_vfx( GN_BLOOD_SUCKER , SC_BLOOD_SUCKER , SI_BLOODSUCKER , SCB_NONE );
set_sc( GN_WALLOFTHORN , SC_STOP , SI_BLANK , SCB_NONE );
- set_sc( GN_FIRE_EXPANSION_SMOKE_POWDER, SC_SMOKEPOWDER , SI_FIRE_EXPANSION_SMOKE_POWDER, SCB_NONE );
- set_sc( GN_FIRE_EXPANSION_TEAR_GAS , SC_TEARGAS , SI_FIRE_EXPANSION_TEAR_GAS , SCB_NONE );
+ set_sc( GN_FIRE_EXPANSION_SMOKE_POWDER, SC_FIRE_EXPANSION_SMOKE_POWDER , SI_FIRE_EXPANSION_SMOKE_POWDER, SCB_NONE );
+ set_sc( GN_FIRE_EXPANSION_TEAR_GAS , SC_FIRE_EXPANSION_TEAR_GAS , SI_FIRE_EXPANSION_TEAR_GAS , SCB_NONE );
set_sc( GN_MANDRAGORA , SC_MANDRAGORA , SI_MANDRAGORA , SCB_INT );
// Elemental Spirit summoner's 'side' status changes.
@@ -727,7 +741,7 @@ void initChangeTables(void) {
set_sc( EL_ROCK_CRUSHER_ATK, SC_ROCK_CRUSHER_ATK , SI_ROCK_CRUSHER_ATK , SCB_SPEED );
add_sc( KO_YAMIKUMO , SC_HIDING );
- set_sc_with_vfx( KO_JYUMONJIKIRI , SC_JYUMONJIKIRI , SI_KO_JYUMONJIKIRI , SCB_NONE );
+ set_sc_with_vfx( KO_JYUMONJIKIRI , SC_KO_JYUMONJIKIRI , SI_KO_JYUMONJIKIRI , SCB_NONE );
add_sc( KO_MAKIBISHI , SC_STUN );
set_sc( KO_MEIKYOUSISUI , SC_MEIKYOUSISUI , SI_MEIKYOUSISUI , SCB_NONE );
set_sc( KO_KYOUGAKU , SC_KYOUGAKU , SI_KYOUGAKU , SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
@@ -736,12 +750,14 @@ void initChangeTables(void) {
set_sc( KO_IZAYOI , SC_IZAYOI , SI_IZAYOI , SCB_MATK );
set_sc( KG_KYOMU , SC_KYOMU , SI_KYOMU , SCB_NONE );
set_sc( KG_KAGEMUSYA , SC_KAGEMUSYA , SI_KAGEMUSYA , SCB_NONE );
- set_sc( KG_KAGEHUMI , SC_KAGEHUMI , SI_KG_KAGEHUMI , SCB_NONE );
+ set_sc( KG_KAGEHUMI , SC_KG_KAGEHUMI , SI_KG_KAGEHUMI , SCB_NONE );
set_sc( OB_ZANGETSU , SC_ZANGETSU , SI_ZANGETSU , SCB_MATK|SCB_BATK );
set_sc_with_vfx( OB_AKAITSUKI , SC_AKAITSUKI , SI_AKAITSUKI , SCB_NONE );
set_sc( OB_OBOROGENSOU , SC_GENSOU , SI_GENSOU , SCB_NONE );
- // Storing the target job rather than simply SC_SPIRIT simplifies code later on.
+ set_sc( ALL_FULL_THROTTLE , SC_FULL_THROTTLE , SI_FULL_THROTTLE , SCB_SPEED|SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+
+ // Storing the target job rather than simply SC_SOULLINK simplifies code later on.
SkillStatusChangeTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
SkillStatusChangeTable[SL_MONK] = (sc_type)MAPID_MONK,
SkillStatusChangeTable[SL_STAR] = (sc_type)MAPID_STAR_GLADIATOR,
@@ -759,33 +775,33 @@ void initChangeTables(void) {
SkillStatusChangeTable[SL_SOULLINKER] = (sc_type)MAPID_SOUL_LINKER,
//Status that don't have a skill associated.
- StatusIconChangeTable[SC_WEIGHT50] = SI_WEIGHT50;
- StatusIconChangeTable[SC_WEIGHT90] = SI_WEIGHT90;
- StatusIconChangeTable[SC_ASPDPOTION0] = SI_ASPDPOTION0;
- StatusIconChangeTable[SC_ASPDPOTION1] = SI_ASPDPOTION1;
- StatusIconChangeTable[SC_ASPDPOTION2] = SI_ASPDPOTION2;
- StatusIconChangeTable[SC_ASPDPOTION3] = SI_ASPDPOTIONINFINITY;
- StatusIconChangeTable[SC_SPEEDUP0] = SI_MOVHASTE_HORSE;
- StatusIconChangeTable[SC_SPEEDUP1] = SI_SPEEDPOTION1;
- StatusIconChangeTable[SC_INCSTR] = SI_INCSTR;
- StatusIconChangeTable[SC_MIRACLE] = SI_SPIRIT;
- StatusIconChangeTable[SC_INTRAVISION] = SI_INTRAVISION;
- StatusIconChangeTable[SC_STRFOOD] = SI_FOODSTR;
- StatusIconChangeTable[SC_AGIFOOD] = SI_FOODAGI;
- StatusIconChangeTable[SC_VITFOOD] = SI_FOODVIT;
- StatusIconChangeTable[SC_INTFOOD] = SI_FOODINT;
- StatusIconChangeTable[SC_DEXFOOD] = SI_FOODDEX;
- StatusIconChangeTable[SC_LUKFOOD] = SI_FOODLUK;
- StatusIconChangeTable[SC_FLEEFOOD]= SI_FOODFLEE;
- StatusIconChangeTable[SC_HITFOOD] = SI_FOODHIT;
+ StatusIconChangeTable[SC_WEIGHTOVER50] = SI_WEIGHTOVER50;
+ StatusIconChangeTable[SC_WEIGHTOVER90] = SI_WEIGHTOVER90;
+ StatusIconChangeTable[SC_ATTHASTE_POTION1] = SI_ATTHASTE_POTION1;
+ StatusIconChangeTable[SC_ATTHASTE_POTION2] = SI_ATTHASTE_POTION2;
+ StatusIconChangeTable[SC_ATTHASTE_POTION3] = SI_ATTHASTE_POTION3;
+ StatusIconChangeTable[SC_ATTHASTE_INFINITY] = SI_ATTHASTE_INFINITY;
+ StatusIconChangeTable[SC_MOVHASTE_HORSE] = SI_MOVHASTE_HORSE;
+ StatusIconChangeTable[SC_MOVHASTE_INFINITY] = SI_MOVHASTE_INFINITY;
+ StatusIconChangeTable[SC_CHASEWALK2] = SI_INCSTR;
+ StatusIconChangeTable[SC_MIRACLE] = SI_SOULLINK;
+ StatusIconChangeTable[SC_CLAIRVOYANCE] = SI_CLAIRVOYANCE;
+ StatusIconChangeTable[SC_FOOD_STR] = SI_FOOD_STR;
+ StatusIconChangeTable[SC_FOOD_AGI] = SI_FOOD_AGI;
+ StatusIconChangeTable[SC_FOOD_VIT] = SI_FOOD_VIT;
+ StatusIconChangeTable[SC_FOOD_INT] = SI_FOOD_INT;
+ StatusIconChangeTable[SC_FOOD_DEX] = SI_FOOD_DEX;
+ StatusIconChangeTable[SC_FOOD_LUK] = SI_FOOD_LUK;
+ StatusIconChangeTable[SC_FOOD_BASICAVOIDANCE]= SI_FOOD_BASICAVOIDANCE;
+ StatusIconChangeTable[SC_FOOD_BASICHIT] = SI_FOOD_BASICHIT;
StatusIconChangeTable[SC_MANU_ATK] = SI_MANU_ATK;
StatusIconChangeTable[SC_MANU_DEF] = SI_MANU_DEF;
StatusIconChangeTable[SC_SPL_ATK] = SI_SPL_ATK;
StatusIconChangeTable[SC_SPL_DEF] = SI_SPL_DEF;
StatusIconChangeTable[SC_MANU_MATK] = SI_MANU_MATK;
StatusIconChangeTable[SC_SPL_MATK] = SI_SPL_MATK;
- StatusIconChangeTable[SC_ATKPOTION] = SI_PLUSATTACKPOWER;
- StatusIconChangeTable[SC_MATKPOTION] = SI_PLUSMAGICPOWER;
+ StatusIconChangeTable[SC_PLUSATTACKPOWER] = SI_PLUSATTACKPOWER;
+ StatusIconChangeTable[SC_PLUSMAGICPOWER] = SI_PLUSMAGICPOWER;
//Cash Items
StatusIconChangeTable[SC_FOOD_STR_CASH] = SI_FOOD_STR_CASH;
StatusIconChangeTable[SC_FOOD_AGI_CASH] = SI_FOOD_AGI_CASH;
@@ -793,32 +809,32 @@ void initChangeTables(void) {
StatusIconChangeTable[SC_FOOD_DEX_CASH] = SI_FOOD_DEX_CASH;
StatusIconChangeTable[SC_FOOD_INT_CASH] = SI_FOOD_INT_CASH;
StatusIconChangeTable[SC_FOOD_LUK_CASH] = SI_FOOD_LUK_CASH;
- StatusIconChangeTable[SC_EXPBOOST] = SI_EXPBOOST;
- StatusIconChangeTable[SC_ITEMBOOST] = SI_ITEMBOOST;
- StatusIconChangeTable[SC_JEXPBOOST] = SI_CASH_PLUSONLYJOBEXP;
- StatusIconChangeTable[SC_LIFEINSURANCE] = SI_LIFEINSURANCE;
- StatusIconChangeTable[SC_BOSSMAPINFO] = SI_BOSSMAPINFO;
- StatusIconChangeTable[SC_DEF_RATE] = SI_DEF_RATE;
- StatusIconChangeTable[SC_MDEF_RATE] = SI_MDEF_RATE;
- StatusIconChangeTable[SC_INCCRI] = SI_INCCRI;
- StatusIconChangeTable[SC_INCFLEE2] = SI_PLUSAVOIDVALUE;
- StatusIconChangeTable[SC_INCHEALRATE] = SI_INCHEALRATE;
+ StatusIconChangeTable[SC_CASH_PLUSEXP] = SI_CASH_PLUSEXP;
+ StatusIconChangeTable[SC_CASH_RECEIVEITEM] = SI_CASH_RECEIVEITEM;
+ StatusIconChangeTable[SC_CASH_PLUSONLYJOBEXP] = SI_CASH_PLUSONLYJOBEXP;
+ StatusIconChangeTable[SC_CASH_DEATHPENALTY] = SI_CASH_DEATHPENALTY;
+ StatusIconChangeTable[SC_CASH_BOSS_ALARM] = SI_CASH_BOSS_ALARM;
+ StatusIconChangeTable[SC_PROTECT_DEF] = SI_PROTECT_DEF;
+ StatusIconChangeTable[SC_PROTECT_MDEF] = SI_PROTECT_MDEF;
+ StatusIconChangeTable[SC_CRITICALPERCENT] = SI_CRITICALPERCENT;
+ StatusIconChangeTable[SC_PLUSAVOIDVALUE] = SI_PLUSAVOIDVALUE;
+ StatusIconChangeTable[SC_HEALPLUS] = SI_HEALPLUS;
StatusIconChangeTable[SC_S_LIFEPOTION] = SI_S_LIFEPOTION;
StatusIconChangeTable[SC_L_LIFEPOTION] = SI_L_LIFEPOTION;
- StatusIconChangeTable[SC_SPCOST_RATE] = SI_ATKER_BLOOD;
- StatusIconChangeTable[SC_COMMONSC_RESIST] = SI_TARGET_BLOOD;
+ StatusIconChangeTable[SC_ATKER_BLOOD] = SI_ATKER_BLOOD;
+ StatusIconChangeTable[SC_TARGET_BLOOD] = SI_TARGET_BLOOD;
// Mercenary Bonus Effects
- StatusIconChangeTable[SC_MERC_FLEEUP] = SI_MERC_FLEEUP;
- StatusIconChangeTable[SC_MERC_ATKUP] = SI_MERC_ATKUP;
- StatusIconChangeTable[SC_MERC_HPUP] = SI_MERC_HPUP;
- StatusIconChangeTable[SC_MERC_SPUP] = SI_MERC_SPUP;
- StatusIconChangeTable[SC_MERC_HITUP] = SI_MERC_HITUP;
+ StatusIconChangeTable[SC_MER_FLEE] = SI_MER_FLEE;
+ StatusIconChangeTable[SC_MER_ATK] = SI_MER_ATK;
+ StatusIconChangeTable[SC_MER_HP] = SI_MER_HP;
+ StatusIconChangeTable[SC_MER_SP] = SI_MER_SP;
+ StatusIconChangeTable[SC_MER_HIT] = SI_MER_HIT;
// Warlock Spheres
- StatusIconChangeTable[SC_SPHERE_1] = SI_SPHERE_1;
- StatusIconChangeTable[SC_SPHERE_2] = SI_SPHERE_2;
- StatusIconChangeTable[SC_SPHERE_3] = SI_SPHERE_3;
- StatusIconChangeTable[SC_SPHERE_4] = SI_SPHERE_4;
- StatusIconChangeTable[SC_SPHERE_5] = SI_SPHERE_5;
+ StatusIconChangeTable[SC_SUMMON1] = SI_SPHERE_1;
+ StatusIconChangeTable[SC_SUMMON2] = SI_SPHERE_2;
+ StatusIconChangeTable[SC_SUMMON3] = SI_SPHERE_3;
+ StatusIconChangeTable[SC_SUMMON4] = SI_SPHERE_4;
+ StatusIconChangeTable[SC_SUMMON5] = SI_SPHERE_5;
// Warlock Preserved spells
StatusIconChangeTable[SC_SPELLBOOK1] = SI_SPELLBOOK1;
StatusIconChangeTable[SC_SPELLBOOK2] = SI_SPELLBOOK2;
@@ -826,7 +842,7 @@ void initChangeTables(void) {
StatusIconChangeTable[SC_SPELLBOOK4] = SI_SPELLBOOK4;
StatusIconChangeTable[SC_SPELLBOOK5] = SI_SPELLBOOK5;
StatusIconChangeTable[SC_SPELLBOOK6] = SI_SPELLBOOK6;
- StatusIconChangeTable[SC_MAXSPELLBOOK] = SI_SPELLBOOK7;
+ StatusIconChangeTable[SC_SPELLBOOK7] = SI_SPELLBOOK7;
StatusIconChangeTable[SC_NEUTRALBARRIER_MASTER] = SI_NEUTRALBARRIER_MASTER;
StatusIconChangeTable[SC_STEALTHFIELD_MASTER] = SI_STEALTHFIELD_MASTER;
@@ -856,7 +872,7 @@ void initChangeTables(void) {
StatusIconChangeTable[SC_MYSTERIOUS_POWDER] = SI_MYSTERIOUS_POWDER;
StatusIconChangeTable[SC_MELON_BOMB] = SI_MELON_BOMB;
StatusIconChangeTable[SC_BANANA_BOMB] = SI_BANANA_BOMB;
- StatusIconChangeTable[SC_BANANA_BOMB_SITDOWN] = SI_BANANA_BOMB_SITDOWN_POSTDELAY;
+ StatusIconChangeTable[SC_BANANA_BOMB_SITDOWN_POSTDELAY] = SI_BANANA_BOMB_SITDOWN_POSTDELAY;
//Genetics New Food Items Status Icons
StatusIconChangeTable[SC_SAVAGE_STEAK] = SI_SAVAGE_STEAK;
@@ -897,19 +913,20 @@ void initChangeTables(void) {
StatusIconChangeTable[SC_CURSED_SOIL] = SI_CURSED_SOIL;
StatusIconChangeTable[SC_UPHEAVAL] = SI_UPHEAVAL;
StatusIconChangeTable[SC_PUSH_CART] = SI_ON_PUSH_CART;
+ StatusIconChangeTable[SC_REBOUND] = SI_REBOUND;
StatusIconChangeTable[SC_ALL_RIDING] = SI_ALL_RIDING;
//Other SC which are not necessarily associated to skills.
- StatusChangeFlagTable[SC_ASPDPOTION0] = SCB_ASPD;
- StatusChangeFlagTable[SC_ASPDPOTION1] = SCB_ASPD;
- StatusChangeFlagTable[SC_ASPDPOTION2] = SCB_ASPD;
- StatusChangeFlagTable[SC_ASPDPOTION3] = SCB_ASPD;
- StatusChangeFlagTable[SC_SPEEDUP0] = SCB_SPEED;
- StatusChangeFlagTable[SC_SPEEDUP1] = SCB_SPEED;
- StatusChangeFlagTable[SC_ATKPOTION] = SCB_BATK;
- StatusChangeFlagTable[SC_MATKPOTION] = SCB_MATK;
+ StatusChangeFlagTable[SC_ATTHASTE_POTION1] = SCB_ASPD;
+ StatusChangeFlagTable[SC_ATTHASTE_POTION2] = SCB_ASPD;
+ StatusChangeFlagTable[SC_ATTHASTE_POTION3] = SCB_ASPD;
+ StatusChangeFlagTable[SC_ATTHASTE_INFINITY] = SCB_ASPD;
+ StatusChangeFlagTable[SC_MOVHASTE_HORSE] = SCB_SPEED;
+ StatusChangeFlagTable[SC_MOVHASTE_INFINITY] = SCB_SPEED;
+ StatusChangeFlagTable[SC_PLUSATTACKPOWER] = SCB_BATK;
+ StatusChangeFlagTable[SC_PLUSMAGICPOWER] = SCB_MATK;
StatusChangeFlagTable[SC_INCALLSTATUS] |= SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK;
- StatusChangeFlagTable[SC_INCSTR] |= SCB_STR;
+ StatusChangeFlagTable[SC_CHASEWALK2] |= SCB_STR;
StatusChangeFlagTable[SC_INCAGI] |= SCB_AGI;
StatusChangeFlagTable[SC_INCVIT] |= SCB_VIT;
StatusChangeFlagTable[SC_INCINT] |= SCB_INT;
@@ -919,9 +936,9 @@ void initChangeTables(void) {
StatusChangeFlagTable[SC_INCHITRATE] |= SCB_HIT;
StatusChangeFlagTable[SC_INCFLEE] |= SCB_FLEE;
StatusChangeFlagTable[SC_INCFLEERATE] |= SCB_FLEE;
- StatusChangeFlagTable[SC_INCCRI] |= SCB_CRI;
+ StatusChangeFlagTable[SC_CRITICALPERCENT] |= SCB_CRI;
StatusChangeFlagTable[SC_INCASPDRATE] |= SCB_ASPD;
- StatusChangeFlagTable[SC_INCFLEE2] |= SCB_FLEE2;
+ StatusChangeFlagTable[SC_PLUSAVOIDVALUE] |= SCB_FLEE2;
StatusChangeFlagTable[SC_INCMHPRATE] |= SCB_MAXHP;
StatusChangeFlagTable[SC_INCMSPRATE] |= SCB_MAXSP;
StatusChangeFlagTable[SC_INCMHP] |= SCB_MAXHP;
@@ -929,20 +946,20 @@ void initChangeTables(void) {
StatusChangeFlagTable[SC_INCATKRATE] |= SCB_BATK|SCB_WATK;
StatusChangeFlagTable[SC_INCMATKRATE] |= SCB_MATK;
StatusChangeFlagTable[SC_INCDEFRATE] |= SCB_DEF;
- StatusChangeFlagTable[SC_STRFOOD] |= SCB_STR;
- StatusChangeFlagTable[SC_AGIFOOD] |= SCB_AGI;
- StatusChangeFlagTable[SC_VITFOOD] |= SCB_VIT;
- StatusChangeFlagTable[SC_INTFOOD] |= SCB_INT;
- StatusChangeFlagTable[SC_DEXFOOD] |= SCB_DEX;
- StatusChangeFlagTable[SC_LUKFOOD] |= SCB_LUK;
- StatusChangeFlagTable[SC_HITFOOD] |= SCB_HIT;
- StatusChangeFlagTable[SC_FLEEFOOD] |= SCB_FLEE;
+ StatusChangeFlagTable[SC_FOOD_STR] |= SCB_STR;
+ StatusChangeFlagTable[SC_FOOD_AGI] |= SCB_AGI;
+ StatusChangeFlagTable[SC_FOOD_VIT] |= SCB_VIT;
+ StatusChangeFlagTable[SC_FOOD_INT] |= SCB_INT;
+ StatusChangeFlagTable[SC_FOOD_DEX] |= SCB_DEX;
+ StatusChangeFlagTable[SC_FOOD_LUK] |= SCB_LUK;
+ StatusChangeFlagTable[SC_FOOD_BASICHIT] |= SCB_HIT;
+ StatusChangeFlagTable[SC_FOOD_BASICAVOIDANCE] |= SCB_FLEE;
StatusChangeFlagTable[SC_BATKFOOD] |= SCB_BATK;
StatusChangeFlagTable[SC_WATKFOOD] |= SCB_WATK;
StatusChangeFlagTable[SC_MATKFOOD] |= SCB_MATK;
- StatusChangeFlagTable[SC_ARMOR_ELEMENT] |= SCB_ALL;
+ StatusChangeFlagTable[SC_ARMORPROPERTY] |= SCB_ALL;
StatusChangeFlagTable[SC_ARMOR_RESIST] |= SCB_ALL;
- StatusChangeFlagTable[SC_SPCOST_RATE] |= SCB_ALL;
+ StatusChangeFlagTable[SC_ATKER_BLOOD] |= SCB_ALL;
StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
StatusChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL;
// Cash Items
@@ -953,11 +970,11 @@ void initChangeTables(void) {
StatusChangeFlagTable[SC_FOOD_INT_CASH] = SCB_INT;
StatusChangeFlagTable[SC_FOOD_LUK_CASH] = SCB_LUK;
// Mercenary Bonus Effects
- StatusChangeFlagTable[SC_MERC_FLEEUP] |= SCB_FLEE;
- StatusChangeFlagTable[SC_MERC_ATKUP] |= SCB_WATK;
- StatusChangeFlagTable[SC_MERC_HPUP] |= SCB_MAXHP;
- StatusChangeFlagTable[SC_MERC_SPUP] |= SCB_MAXSP;
- StatusChangeFlagTable[SC_MERC_HITUP] |= SCB_HIT;
+ StatusChangeFlagTable[SC_MER_FLEE] |= SCB_FLEE;
+ StatusChangeFlagTable[SC_MER_ATK] |= SCB_WATK;
+ StatusChangeFlagTable[SC_MER_HP] |= SCB_MAXHP;
+ StatusChangeFlagTable[SC_MER_SP] |= SCB_MAXSP;
+ StatusChangeFlagTable[SC_MER_HIT] |= SCB_HIT;
// Guillotine Cross Poison Effects
StatusChangeFlagTable[SC_PARALYSE] |= SCB_ASPD|SCB_FLEE|SCB_SPEED;
StatusChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN;
@@ -978,30 +995,31 @@ void initChangeTables(void) {
StatusChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN;
StatusChangeFlagTable[SC_VITATA_500] |= SCB_REGEN;
StatusChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD;
+ StatusChangeFlagTable[SC_REBOUND] |= SCB_SPEED|SCB_REGEN;
StatusChangeFlagTable[SC_ALL_RIDING] = SCB_SPEED;
/* StatusDisplayType Table [Ind/Hercules] */
StatusDisplayType[SC_ALL_RIDING] = true;
StatusDisplayType[SC_PUSH_CART] = true;
- StatusDisplayType[SC_SPHERE_1] = true;
- StatusDisplayType[SC_SPHERE_2] = true;
- StatusDisplayType[SC_SPHERE_3] = true;
- StatusDisplayType[SC_SPHERE_4] = true;
- StatusDisplayType[SC_SPHERE_5] = true;
+ StatusDisplayType[SC_SUMMON1] = true;
+ StatusDisplayType[SC_SUMMON2] = true;
+ StatusDisplayType[SC_SUMMON3] = true;
+ StatusDisplayType[SC_SUMMON4] = true;
+ StatusDisplayType[SC_SUMMON5] = true;
StatusDisplayType[SC_CAMOUFLAGE] = true;
StatusDisplayType[SC_DUPLELIGHT] = true;
StatusDisplayType[SC_ORATIO] = true;
- StatusDisplayType[SC_FREEZING] = true;
+ StatusDisplayType[SC_FROSTMISTY] = true;
StatusDisplayType[SC_VENOMIMPRESS] = true;
StatusDisplayType[SC_HALLUCINATIONWALK] = true;
StatusDisplayType[SC_ROLLINGCUTTER] = true;
StatusDisplayType[SC_BANDING] = true;
StatusDisplayType[SC_CRYSTALIZE] = true;
- StatusDisplayType[SC_DEEPSLEEP] = true;
+ StatusDisplayType[SC_DEEP_SLEEP] = true;
StatusDisplayType[SC_CURSEDCIRCLE_ATKER]= true;
StatusDisplayType[SC_CURSEDCIRCLE_TARGET]= true;
- StatusDisplayType[SC_BLOODSUCKER] = true;
+ StatusDisplayType[SC_BLOOD_SUCKER] = true;
StatusDisplayType[SC__SHADOWFORM] = true;
StatusDisplayType[SC__MANHOLE] = true;
@@ -1011,7 +1029,7 @@ void initChangeTables(void) {
#endif
if( !battle_config.display_hallucination ) //Disable Hallucination.
- StatusIconChangeTable[SC_HALLUCINATION] = SI_BLANK;
+ StatusIconChangeTable[SC_ILLUSION] = SI_BLANK;
}
static void initDummyData(void)
@@ -1147,7 +1165,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
status_change_end(target, SC_STONE, INVALID_TIMER);
status_change_end(target, SC_FREEZE, INVALID_TIMER);
status_change_end(target, SC_SLEEP, INVALID_TIMER);
- status_change_end(target, SC_WINKCHARM, INVALID_TIMER);
+ status_change_end(target, SC_DC_WINKCHARM, INVALID_TIMER);
status_change_end(target, SC_CONFUSION, INVALID_TIMER);
status_change_end(target, SC_TRICKDEAD, INVALID_TIMER);
status_change_end(target, SC_HIDING, INVALID_TIMER);
@@ -1155,8 +1173,8 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
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_DEEPSLEEP, INVALID_TIMER);
- if ((sce=sc->data[SC_ENDURE]) && !sce->val4) {
+ 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]
if (src && src->type != BL_PC && !map_flag_gvg(target->m) && !map[target->m].flag.battleground && --(sce->val2) < 0)
@@ -1192,8 +1210,8 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
status_change_end(target, SC_BERSERK, INVALID_TIMER);
if( sc->data[SC_RAISINGDRAGON] && status->hp <= 1000 )
status_change_end(target, SC_RAISINGDRAGON, INVALID_TIMER);
- if (sc->data[SC_SATURDAYNIGHTFEVER] && status->hp <= 100)
- status_change_end(target, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
+ if (sc->data[SC_SATURDAY_NIGHT_FEVER] && status->hp <= 100)
+ status_change_end(target, SC_SATURDAY_NIGHT_FEVER, INVALID_TIMER);
if (sc->data[SC__BLOODYLUST] && status->hp <= 100)
status_change_end(target, SC__BLOODYLUST, INVALID_TIMER);
}
@@ -1576,9 +1594,9 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
)
return 0;
- if (sc->data[SC_WINKCHARM] && target && !flag) { //Prevents skill usage
+ if (sc->data[SC_DC_WINKCHARM] && target && !flag) { //Prevents skill usage
if( unit_bl2ud(src) && (unit_bl2ud(src))->walktimer == INVALID_TIMER )
- unit_walktobl(src, iMap->id2bl(sc->data[SC_WINKCHARM]->val2), 3, 1);
+ unit_walktobl(src, iMap->id2bl(sc->data[SC_DC_WINKCHARM]->val2), 3, 1);
clif->emotion(src, E_LV);
return 0;
}
@@ -1632,13 +1650,13 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
sc->data[SC__INVISIBILITY] ||
(sc->data[SC_CRYSTALIZE] && src->type != BL_MOB) ||
sc->data[SC__IGNORANCE] ||
- sc->data[SC_DEEPSLEEP] ||
- sc->data[SC_SATURDAYNIGHTFEVER] ||
+ sc->data[SC_DEEP_SLEEP] ||
+ sc->data[SC_SATURDAY_NIGHT_FEVER] ||
sc->data[SC_CURSEDCIRCLE_TARGET] ||
- (sc->data[SC_MARIONETTE] && skill_id != CG_MARIONETTE) || //Only skill you can use is marionette again to cancel it
- (sc->data[SC_MARIONETTE2] && skill_id == CG_MARIONETTE) || //Cannot use marionette if you are being buffed by another
+ (sc->data[SC_MARIONETTE_MASTER] && skill_id != CG_MARIONETTE) || //Only skill you can use is marionette again to cancel it
+ (sc->data[SC_MARIONETTE] && skill_id == CG_MARIONETTE) || //Cannot use marionette if you are being buffed by another
(sc->data[SC_STASIS] && skill->block_check(src, SC_STASIS, skill_id)) ||
- (sc->data[SC_KAGEHUMI] && skill->block_check(src, SC_KAGEHUMI, skill_id))
+ (sc->data[SC_KG_KAGEHUMI] && skill->block_check(src, SC_KG_KAGEHUMI, skill_id))
))
return 0;
@@ -1882,17 +1900,18 @@ static unsigned short status_base_atk(const struct block_list *bl, const struct
str += dstr*dstr;
if (bl->type == BL_PC)
#ifdef RENEWAL
- str = (rstr*10 + dex*10/5 + status->luk*10/3 + ((TBL_PC*)bl)->status.base_level*10/4)/10;
+ str = (int)(rstr + (float)dex/5 + (float)status->luk/3 + (float)((TBL_PC*)bl)->status.base_level/4);
+ else if(bl->type == BL_MOB)
+ str = rstr + ((TBL_MOB*)bl)->level;
#else
str+= dex/5 + status->luk/5;
#endif
return cap_value(str, 0, USHRT_MAX);
}
-#ifndef RENEWAL
static inline unsigned short status_base_matk_min(const struct status_data* status){ return status->int_+(status->int_/7)*(status->int_/7); }
static inline unsigned short status_base_matk_max(const struct status_data* status){ return status->int_+(status->int_/5)*(status->int_/5); }
-#else
+#ifdef RENEWAL
unsigned short status_base_matk(const struct status_data* status, int level){ return status->int_+(status->int_/2)+(status->dex/5)+(status->luk/3)+(level/4); }
#endif
@@ -1907,11 +1926,11 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev
status->cri = status->flee2 = 0;
#ifdef RENEWAL // renewal formulas
- status->matk_min = status->matk_max = status_base_matk(status, level);
- status->hit += level + status->dex + status->luk/3 + 175; //base level + ( every 1 dex = +1 hit ) + (every 3 luk = +1 hit) + 175
- status->flee += level + status->agi + status->luk/5 + 100; //base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100
- status->def2 += (int)(((float)level + status->vit)/2 + ((float)status->agi/5)); //base level + (every 2 vit = +1 def) + (every 5 agi = +1 def)
- status->mdef2 += (int)(status->int_ + ((float)level/4) + ((float)status->dex/5) + ((float)status->vit/5)); //(every 4 base level = +1 mdef) + (every 1 int = +1 mdef) + (every 5 dex = +1 mdef) + (every 5 vit = +1 mdef)
+ status->matk_min = status->matk_max = bl->type == BL_PC ? status_base_matk(status, level) : level + status->int_;
+ status->hit += level + status->dex + (bl->type == BL_PC ? status->luk/3 + 175 : 150); //base level + ( every 1 dex = +1 hit ) + (every 3 luk = +1 hit) + 175
+ status->flee += level + status->agi + (bl->type == BL_PC ? status->luk/5 : 0) + 100; //base level + ( every 1 agi = +1 flee ) + (every 5 luk = +1 flee) + 100
+ status->def2 += (int)(((float)level + status->vit)/2 + ( bl->type == BL_PC ? ((float)status->agi/5) : 0 )); //base level + (every 2 vit = +1 def) + (every 5 agi = +1 def)
+ status->mdef2 += (int)( bl->type == BL_PC ?(status->int_ + ((float)level/4) + ((float)(status->dex+status->vit)/5)):((float)(status->int_ + level)/4)); //(every 4 base level = +1 mdef) + (every 1 int = +1 mdef) + (every 5 dex = +1 mdef) + (every 5 vit = +1 mdef)
#else
status->matk_min = status_base_matk_min(status);
status->matk_max = status_base_matk_max(status);
@@ -1947,6 +1966,13 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev
case BL_PC:
//Players don't have a critical adjustment setting as of yet.
break;
+ case BL_MER:
+#ifdef RENEWAL
+ status->matk_min = status->matk_max = status_base_matk_max(status);
+ status->def2 = status->vit + level / 10 + status->vit / 5;
+ status->mdef2 = level / 10 + status->int_ / 5;
+#endif
+ break;
default:
if(battle_config.critical_rate != 100)
status->cri = status->cri*battle_config.critical_rate/100;
@@ -2030,7 +2056,7 @@ int status_calc_mob_(struct mob_data* md, bool first)
if (ud->skill_id == AM_SPHEREMINE) {
status->max_hp = 2000 + 400*ud->skill_lv;
} else if(ud->skill_id == KO_ZANZOU){
- status->max_hp = 3000 + 3000 * ud->skill_lv;
+ status->max_hp = 3000 + 3000 * ud->skill_lv + status_get_max_sp(battle->get_master(mbl));
} else { //AM_CANNIBALIZE
status->max_hp = 1500 + 200*ud->skill_lv + 10*status_get_lv(mbl);
status->mode|= MD_CANATTACK|MD_AGGRESSIVE;
@@ -2352,8 +2378,8 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
memset (&sd->right_weapon.overrefine, 0, sizeof(sd->right_weapon) - sizeof(sd->right_weapon.atkmods));
memset (&sd->left_weapon.overrefine, 0, sizeof(sd->left_weapon) - sizeof(sd->left_weapon.atkmods));
- if (sd->special_state.intravision && !sd->sc.data[SC_INTRAVISION]) //Clear intravision as long as nothing else is using it
- clif->sc_end(&sd->bl,sd->bl.id,SELF,SI_INTRAVISION);
+ if (sd->special_state.intravision && !sd->sc.data[SC_CLAIRVOYANCE]) //Clear intravision as long as nothing else is using it
+ clif->sc_end(&sd->bl,sd->bl.id,SELF,SI_CLAIRVOYANCE);
memset(&sd->special_state,0,sizeof(sd->special_state));
memset(&status->max_hp, 0, sizeof(struct status_data)-(sizeof(status->hp)+sizeof(status->sp)));
@@ -2365,7 +2391,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
status->mode = MD_MASK&~(MD_BOSS|MD_PLANT|MD_DETECTOR|MD_ANGRY|MD_TARGETWEAK);
status->size = (sd->class_&JOBL_BABY)?SZ_SMALL:SZ_MEDIUM;
- if (battle_config.character_size && pc_isriding(sd)) { //[Lupus]
+ if (battle_config.character_size && (pc_isriding(sd) || pc_isridingdragon(sd)) ) { //[Lupus]
if (sd->class_&JOBL_BABY) {
if (battle_config.character_size&SZ_BIG)
status->size++;
@@ -2638,7 +2664,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
sd->left_weapon.atkmods[1] = atkmods[1][sd->weapontype2];
sd->left_weapon.atkmods[2] = atkmods[2][sd->weapontype2];
- if(pc_isriding(sd) &&
+ if( (pc_isriding(sd) || pc_isridingdragon(sd)) &&
(sd->status.weapon==W_1HSPEAR || sd->status.weapon==W_2HSPEAR))
{ //When Riding with spear, damage modifier to mid-class becomes
//same as versus large size.
@@ -2704,8 +2730,10 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
if (sd->status.weapon < MAX_WEAPON_TYPE && sd->weapon_atk[sd->status.weapon])
status->batk += sd->weapon_atk[sd->status.weapon];
// Absolute modifiers from passive skills
- if((skill=pc->checkskill(sd,BS_HILTBINDING))>0)
+#ifndef RENEWAL
+ if((skill=pc->checkskill(sd,BS_HILTBINDING))>0) // it doesn't work in RE.
status->batk += 4;
+#endif
// ----- HP MAX CALCULATION -----
@@ -2964,11 +2992,11 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
if((skill=pc->checkskill(sd,HP_MANARECHARGE))>0 )
sd->dsprate -= 4*skill;
- if(sc->data[SC_SERVICE4U])
- sd->dsprate -= sc->data[SC_SERVICE4U]->val3;
+ if(sc->data[SC_SERVICEFORYOU])
+ sd->dsprate -= sc->data[SC_SERVICEFORYOU]->val3;
- if(sc->data[SC_SPCOST_RATE])
- sd->dsprate -= sc->data[SC_SPCOST_RATE]->val1;
+ if(sc->data[SC_ATKER_BLOOD])
+ sd->dsprate -= sc->data[SC_ATKER_BLOOD]->val1;
//Underflow protections.
if(sd->dsprate < 0)
@@ -3002,9 +3030,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
}
if(sc->count){
- if(sc->data[SC_CONCENTRATE]) { //Update the card-bonus data
- sc->data[SC_CONCENTRATE]->val3 = sd->param_bonus[1]; //Agi
- sc->data[SC_CONCENTRATE]->val4 = sd->param_bonus[4]; //Dex
+ if(sc->data[SC_CONCENTRATION]) { //Update the card-bonus data
+ sc->data[SC_CONCENTRATION]->val3 = sd->param_bonus[1]; //Agi
+ sc->data[SC_CONCENTRATION]->val4 = sd->param_bonus[4]; //Dex
}
if(sc->data[SC_SIEGFRIED]){
i = sc->data[SC_SIEGFRIED]->val2;
@@ -3022,11 +3050,11 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
sd->subele[ELE_HOLY] += sc->data[SC_PROVIDENCE]->val2;
sd->subrace[RC_DEMON] += sc->data[SC_PROVIDENCE]->val2;
}
- if(sc->data[SC_ARMOR_ELEMENT]) { //This status change should grant card-type elemental resist.
- sd->subele[ELE_WATER] += sc->data[SC_ARMOR_ELEMENT]->val1;
- sd->subele[ELE_EARTH] += sc->data[SC_ARMOR_ELEMENT]->val2;
- sd->subele[ELE_FIRE] += sc->data[SC_ARMOR_ELEMENT]->val3;
- sd->subele[ELE_WIND] += sc->data[SC_ARMOR_ELEMENT]->val4;
+ if(sc->data[SC_ARMORPROPERTY]) { //This status change should grant card-type elemental resist.
+ sd->subele[ELE_WATER] += sc->data[SC_ARMORPROPERTY]->val1;
+ sd->subele[ELE_EARTH] += sc->data[SC_ARMORPROPERTY]->val2;
+ sd->subele[ELE_FIRE] += sc->data[SC_ARMORPROPERTY]->val3;
+ sd->subele[ELE_WIND] += sc->data[SC_ARMORPROPERTY]->val4;
}
if(sc->data[SC_ARMOR_RESIST]) { // Undead Scroll
sd->subele[ELE_WATER] += sc->data[SC_ARMOR_RESIST]->val1;
@@ -3266,17 +3294,13 @@ static unsigned short status_calc_vit(struct block_list *,struct status_change *
static unsigned short status_calc_int(struct block_list *,struct status_change *,int);
static unsigned short status_calc_dex(struct block_list *,struct status_change *,int);
static unsigned short status_calc_luk(struct block_list *,struct status_change *,int);
-static unsigned short status_calc_batk(struct block_list *,struct status_change *,int);
-static unsigned short status_calc_watk(struct block_list *,struct status_change *,int);
-static unsigned short status_calc_matk(struct block_list *,struct status_change *,int);
-static signed short status_calc_hit(struct block_list *,struct status_change *,int);
-static signed short status_calc_critical(struct block_list *,struct status_change *,int);
-static signed short status_calc_flee(struct block_list *,struct status_change *,int);
-static signed short status_calc_flee2(struct block_list *,struct status_change *,int);
-static defType status_calc_def(struct block_list *bl, struct status_change *sc, int);
-static signed short status_calc_def2(struct block_list *,struct status_change *,int);
-static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int);
-static signed short status_calc_mdef2(struct block_list *,struct status_change *,int);
+static unsigned short status_calc_batk(struct block_list *,struct status_change *,int,bool);
+static unsigned short status_calc_watk(struct block_list *,struct status_change *,int,bool);
+static unsigned short status_calc_matk(struct block_list *,struct status_change *,int,bool);
+static signed short status_calc_hit(struct block_list *,struct status_change *,int,bool);
+static signed short status_calc_critical(struct block_list *,struct status_change *,int,bool);
+static signed short status_calc_flee(struct block_list *,struct status_change *,int,bool);
+static signed short status_calc_flee2(struct block_list *,struct status_change *,int,bool);
static unsigned short status_calc_speed(struct block_list *,struct status_change *,int);
static short status_calc_aspd_rate(struct block_list *,struct status_change *,int);
static unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion);
@@ -3430,18 +3454,18 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
|| (sc->data[SC_DPOISON] && !sc->data[SC_SLOWPOISON])
|| sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]
|| sc->data[SC_TRICKDEAD]
- || sc->data[SC_BLEEDING]
+ || sc->data[SC_BLOODING]
|| sc->data[SC_MAGICMUSHROOM]
|| sc->data[SC_RAISINGDRAGON]
- || sc->data[SC_SATURDAYNIGHTFEVER]
+ || sc->data[SC_SATURDAY_NIGHT_FEVER]
) //No regen
regen->flag = 0;
if (
- sc->data[SC_DANCING] || sc->data[SC_OBLIVIONCURSE] || sc->data[SC_MAXIMIZEPOWER]
+ sc->data[SC_DANCING] || sc->data[SC_OBLIVIONCURSE] || sc->data[SC_MAXIMIZEPOWER] || sc->data[SC_REBOUND]
|| (
(bl->type == BL_PC && ((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK &&
- (sc->data[SC_EXTREMITYFIST] || (sc->data[SC_EXPLOSIONSPIRITS] && (!sc->data[SC_SPIRIT] || sc->data[SC_SPIRIT]->val2 != SL_MONK)))
+ (sc->data[SC_EXTREMITYFIST] || (sc->data[SC_EXPLOSIONSPIRITS] && (!sc->data[SC_SOULLINK] || sc->data[SC_SOULLINK]->val2 != SL_MONK)))
)
) //No natural SP regen
regen->flag &=~RGN_SP;
@@ -3458,9 +3482,9 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
regen->rate.hp += 1;
regen->rate.sp += 1;
}
- if (sc->data[SC_REGENERATION])
+ if (sc->data[SC_GDSKILL_REGENERATION])
{
- const struct status_change_entry *sce = sc->data[SC_REGENERATION];
+ const struct status_change_entry *sce = sc->data[SC_GDSKILL_REGENERATION];
if (!sce->val4)
{
regen->rate.hp += sce->val2;
@@ -3468,8 +3492,8 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
} else
regen->flag&=~sce->val4; //Remove regen as specified by val4
}
- if(sc->data[SC_GT_REVITALIZE]){
- regen->hp = cap_value(regen->hp*sc->data[SC_GT_REVITALIZE]->val3/100, 1, SHRT_MAX);
+ if(sc->data[SC_GENTLETOUCH_REVITALIZE]){
+ regen->hp = cap_value(regen->hp*sc->data[SC_GENTLETOUCH_REVITALIZE]->val3/100, 1, SHRT_MAX);
regen->state.walk= 1;
}
if ((sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 1) //if insignia lvl 1
@@ -3563,23 +3587,22 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
temp += status->batk;
status->batk = cap_value(temp, 0, USHRT_MAX);
}
- status->batk = status_calc_batk(bl, sc, status->batk);
+ status->batk = status_calc_batk(bl, sc, status->batk, true);
}
- if(flag&SCB_WATK) {
-
- status->rhw.atk = status_calc_watk(bl, sc, b_status->rhw.atk);
+ if(flag&SCB_WATK) {
+ status->rhw.atk = status_calc_watk(bl, sc, b_status->rhw.atk, true);
if (!sd) //Should not affect weapon refine bonus
- status->rhw.atk2 = status_calc_watk(bl, sc, b_status->rhw.atk2);
+ status->rhw.atk2 = status_calc_watk(bl, sc, b_status->rhw.atk2, true);
if(b_status->lhw.atk) {
if (sd) {
sd->state.lr_flag = 1;
- status->lhw.atk = status_calc_watk(bl, sc, b_status->lhw.atk);
+ status->lhw.atk = status_calc_watk(bl, sc, b_status->lhw.atk, true);
sd->state.lr_flag = 0;
} else {
- status->lhw.atk = status_calc_watk(bl, sc, b_status->lhw.atk);
- status->lhw.atk2= status_calc_watk(bl, sc, b_status->lhw.atk2);
+ status->lhw.atk = status_calc_watk(bl, sc, b_status->lhw.atk, true);
+ status->lhw.atk2 = status_calc_watk(bl, sc, b_status->lhw.atk2, true);
}
}
@@ -3598,13 +3621,13 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
&& status->luk == b_status->luk
#endif
)
- status->hit = status_calc_hit(bl, sc, b_status->hit);
+ status->hit = status_calc_hit(bl, sc, b_status->hit, true);
else
status->hit = status_calc_hit(bl, sc, b_status->hit + (status->dex - b_status->dex)
#ifdef RENEWAL
+ (status->luk/3 - b_status->luk/3)
#endif
- );
+ , true);
}
if(flag&SCB_FLEE) {
@@ -3613,18 +3636,18 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
&& status->luk == b_status->luk
#endif
)
- status->flee = status_calc_flee(bl, sc, b_status->flee);
+ status->flee = status_calc_flee(bl, sc, b_status->flee, true);
else
status->flee = status_calc_flee(bl, sc, b_status->flee +(status->agi - b_status->agi)
#ifdef RENEWAL
+ (status->luk/5 - b_status->luk/5)
#endif
- );
+ , true);
}
if(flag&SCB_DEF)
{
- status->def = status_calc_def(bl, sc, b_status->def);
+ status->def = status_calc_def(bl, sc, b_status->def, true);
if( bl->type&BL_HOM )
status->def += (status->vit/5 - b_status->vit/5);
@@ -3636,7 +3659,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
&& status->agi == b_status->agi
#endif
)
- status->def2 = status_calc_def2(bl, sc, b_status->def2);
+ status->def2 = status_calc_def2(bl, sc, b_status->def2, true);
else
status->def2 = status_calc_def2(bl, sc, b_status->def2
#ifdef RENEWAL
@@ -3644,12 +3667,12 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
#else
+ (status->vit - b_status->vit)
#endif
- );
+ , true);
}
if(flag&SCB_MDEF)
{
- status->mdef = status_calc_mdef(bl, sc, b_status->mdef);
+ status->mdef = status_calc_mdef(bl, sc, b_status->mdef, true);
if( bl->type&BL_HOM )
status->mdef += (status->int_/5 - b_status->int_/5);
@@ -3661,7 +3684,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
&& status->dex == b_status->dex
#endif
)
- status->mdef2 = status_calc_mdef2(bl, sc, b_status->mdef2);
+ status->mdef2 = status_calc_mdef2(bl, sc, b_status->mdef2, true);
else
status->mdef2 = status_calc_mdef2(bl, sc, b_status->mdef2 +(status->int_ - b_status->int_)
#ifdef RENEWAL
@@ -3669,7 +3692,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
#else
+ ((status->vit - b_status->vit)>>1)
#endif
- );
+ , true);
}
if(flag&SCB_SPEED) {
@@ -3693,9 +3716,9 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
if(flag&SCB_CRI && b_status->cri) {
if (status->luk == b_status->luk)
- status->cri = status_calc_critical(bl, sc, b_status->cri);
+ status->cri = status_calc_critical(bl, sc, b_status->cri, true);
else
- status->cri = status_calc_critical(bl, sc, b_status->cri + 3*(status->luk - b_status->luk));
+ status->cri = status_calc_critical(bl, sc, b_status->cri + 3*(status->luk - b_status->luk), true);
/**
* after status_calc_critical so the bonus is applied despite if you have or not a sc bugreport:5240
**/
@@ -3706,9 +3729,9 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
if(flag&SCB_FLEE2 && b_status->flee2) {
if (status->luk == b_status->luk)
- status->flee2 = status_calc_flee2(bl, sc, b_status->flee2);
+ status->flee2 = status_calc_flee2(bl, sc, b_status->flee2, true);
else
- status->flee2 = status_calc_flee2(bl, sc, b_status->flee2 +(status->luk - b_status->luk));
+ status->flee2 = status_calc_flee2(bl, sc, b_status->flee2 +(status->luk - b_status->luk), true);
}
if(flag&SCB_ATK_ELE) {
@@ -3784,52 +3807,8 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
}
}
- if(flag&SCB_MATK) {
-#ifndef RENEWAL
- status->matk_min = status_base_matk_min(status) + (sd?sd->bonus.ematk:0);
- status->matk_max = status_base_matk_max(status) + (sd?sd->bonus.ematk:0);
-#else
- /**
- * RE MATK Formula (from irowiki:http://irowiki.org/wiki/MATK)
- * MATK = (sMATK + wMATK + eMATK) * Multiplicative Modifiers
- **/
- status->matk_min = status->matk_max = status_base_matk(status, status_get_lv(bl));
- if( bl->type&BL_PC ){
- // Any +MATK you get from skills and cards, including cards in weapon, is added here.
- if( sd->bonus.ematk > 0 ){
- status->matk_max += sd->bonus.ematk;
- status->matk_min += sd->bonus.ematk;
- }
- status->matk_min = status_calc_ematk(bl, sc, status->matk_min);
- status->matk_max = status_calc_ematk(bl, sc, status->matk_max);
- //This is the only portion in MATK that varies depending on the weapon level and refinement rate.
- if( status->rhw.matk > 0 ){
- int wMatk = status->rhw.matk;
- int variance = wMatk * status->rhw.wlv / 10;
- status->matk_min += wMatk - variance;
- status->matk_max += wMatk + variance;
- }
- }
-#endif
- if (bl->type&BL_PC && sd->matk_rate != 100) {
- status->matk_max = status->matk_max * sd->matk_rate/100;
- status->matk_min = status->matk_min * sd->matk_rate/100;
- }
-
- status->matk_min = status_calc_matk(bl, sc, status->matk_min);
- status->matk_max = status_calc_matk(bl, sc, status->matk_max);
-
- if ((bl->type&BL_HOM && battle_config.hom_setting&0x20) //Hom Min Matk is always the same as Max Matk
- || sc->data[SC_RECOGNIZEDSPELL])
- status->matk_min = status->matk_max;
-
-#ifdef RENEWAL
- if( sd && sd->right_weapon.overrefine > 0){
- status->matk_min++;
- status->matk_max += sd->right_weapon.overrefine - 1;
- }
-#endif
-
+ if(flag&SCB_MATK) {
+ status_get_matk(bl, 0);
}
if(flag&SCB_ASPD) {
@@ -3844,11 +3823,11 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
amotion = amotion*status->aspd_rate/1000;
#else
// aspd = baseaspd + floor(sqrt((agi^2/2) + (dex^2/5))/4 + (potskillbonus*agi/200))
- amotion -= (int)(sqrt( (pow(status->agi, 2) / 2) + (pow(status->dex, 2) / 5) ) / 4 + (status_calc_aspd(bl, sc, 1) * status->agi / 200)) * 10;
+ amotion -= (int)(sqrt( (pow(status->agi, 2) / 2) + (pow(status->dex, 2) / 5) ) / 4 + ((float)status_calc_aspd(bl, sc, 1) * status->agi / 200)) * 10;
if( (status_calc_aspd(bl, sc, 2) + status->aspd_rate2) != 0 ) // RE ASPD percertage modifier
- amotion -= ( amotion - ((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd) )
- * (status_calc_aspd(bl, sc, 2) + status->aspd_rate2) / 100;
+ amotion -= (( amotion - ((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd) )
+ * (status_calc_aspd(bl, sc, 2) + status->aspd_rate2) / 10 + 5) / 10;
if(status->aspd_rate != 1000) // absolute percentage modifier
amotion = ( 200 - (200-amotion/10) * status->aspd_rate / 1000 ) * 10;
@@ -4102,38 +4081,38 @@ static unsigned short status_calc_str(struct block_list *bl, struct status_chang
str -= sc->data[SC_HARMONIZE]->val2;
return (unsigned short)cap_value(str,0,USHRT_MAX);
}
- if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && str < 50)
+ if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && str < 50)
return 50;
if(sc->data[SC_INCALLSTATUS])
str += sc->data[SC_INCALLSTATUS]->val1;
- if(sc->data[SC_INCSTR])
- str += sc->data[SC_INCSTR]->val1;
- if(sc->data[SC_STRFOOD])
- str += sc->data[SC_STRFOOD]->val1;
+ if(sc->data[SC_CHASEWALK2])
+ str += sc->data[SC_CHASEWALK2]->val1;
+ if(sc->data[SC_FOOD_STR])
+ str += sc->data[SC_FOOD_STR]->val1;
if(sc->data[SC_FOOD_STR_CASH])
str += sc->data[SC_FOOD_STR_CASH]->val1;
- if(sc->data[SC_BATTLEORDERS])
+ if(sc->data[SC_GDSKILL_BATTLEORDER])
str += 5;
if(sc->data[SC_LEADERSHIP])
str += sc->data[SC_LEADERSHIP]->val1;
- if(sc->data[SC_LOUD])
+ if(sc->data[SC_SHOUT])
str += 4;
if(sc->data[SC_TRUESIGHT])
str += 5;
- if(sc->data[SC_SPURT])
+ if(sc->data[SC_STRUP])
str += 10;
- if(sc->data[SC_NEN])
- str += sc->data[SC_NEN]->val1;
+ if(sc->data[SC_NJ_NEN])
+ str += sc->data[SC_NJ_NEN]->val1;
if(sc->data[SC_BLESSING]){
if(sc->data[SC_BLESSING]->val2)
str += sc->data[SC_BLESSING]->val2;
else
str >>= 1;
}
+ if(sc->data[SC_MARIONETTE_MASTER])
+ str -= ((sc->data[SC_MARIONETTE_MASTER]->val3)>>16)&0xFF;
if(sc->data[SC_MARIONETTE])
- str -= ((sc->data[SC_MARIONETTE]->val3)>>16)&0xFF;
- if(sc->data[SC_MARIONETTE2])
- str += ((sc->data[SC_MARIONETTE2]->val3)>>16)&0xFF;
+ str += ((sc->data[SC_MARIONETTE]->val3)>>16)&0xFF;
if(sc->data[SC_GIANTGROWTH])
str += 30;
if(sc->data[SC_SAVAGE_STEAK])
@@ -4144,6 +4123,8 @@ static unsigned short status_calc_str(struct block_list *bl, struct status_chang
str -= sc->data[SC_STOMACHACHE]->val1;
if(sc->data[SC_KYOUGAKU])
str -= sc->data[SC_KYOUGAKU]->val2;
+ if(sc->data[SC_FULL_THROTTLE])
+ str += str * 20 / 100;
return (unsigned short)cap_value(str,0,USHRT_MAX);
}
@@ -4157,36 +4138,36 @@ static unsigned short status_calc_agi(struct block_list *bl, struct status_chang
agi -= sc->data[SC_HARMONIZE]->val2;
return (unsigned short)cap_value(agi,0,USHRT_MAX);
}
- if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && agi < 50)
+ if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && agi < 50)
return 50;
- if(sc->data[SC_CONCENTRATE] && !sc->data[SC_QUAGMIRE])
- agi += (agi-sc->data[SC_CONCENTRATE]->val3)*sc->data[SC_CONCENTRATE]->val2/100;
+ if(sc->data[SC_CONCENTRATION] && !sc->data[SC_QUAGMIRE])
+ agi += (agi-sc->data[SC_CONCENTRATION]->val3)*sc->data[SC_CONCENTRATION]->val2/100;
if(sc->data[SC_INCALLSTATUS])
agi += sc->data[SC_INCALLSTATUS]->val1;
if(sc->data[SC_INCAGI])
agi += sc->data[SC_INCAGI]->val1;
- if(sc->data[SC_AGIFOOD])
- agi += sc->data[SC_AGIFOOD]->val1;
+ if(sc->data[SC_FOOD_AGI])
+ agi += sc->data[SC_FOOD_AGI]->val1;
if(sc->data[SC_FOOD_AGI_CASH])
agi += sc->data[SC_FOOD_AGI_CASH]->val1;
if(sc->data[SC_SOULCOLD])
agi += sc->data[SC_SOULCOLD]->val1;
if(sc->data[SC_TRUESIGHT])
agi += 5;
- if(sc->data[SC_INCREASEAGI])
- agi += sc->data[SC_INCREASEAGI]->val2;
- if(sc->data[SC_INCREASING])
+ if(sc->data[SC_INC_AGI])
+ agi += sc->data[SC_INC_AGI]->val2;
+ if(sc->data[SC_GS_ACCURACY])
agi += 4; // added based on skill updates [Reddozen]
- if(sc->data[SC_DECREASEAGI])
- agi -= sc->data[SC_DECREASEAGI]->val2;
+ if(sc->data[SC_DEC_AGI])
+ agi -= sc->data[SC_DEC_AGI]->val2;
if(sc->data[SC_QUAGMIRE])
agi -= sc->data[SC_QUAGMIRE]->val2;
- if(sc->data[SC_SUITON] && sc->data[SC_SUITON]->val3)
- agi -= sc->data[SC_SUITON]->val2;
+ if(sc->data[SC_NJ_SUITON] && sc->data[SC_NJ_SUITON]->val3)
+ agi -= sc->data[SC_NJ_SUITON]->val2;
+ if(sc->data[SC_MARIONETTE_MASTER])
+ agi -= ((sc->data[SC_MARIONETTE_MASTER]->val3)>>8)&0xFF;
if(sc->data[SC_MARIONETTE])
- agi -= ((sc->data[SC_MARIONETTE]->val3)>>8)&0xFF;
- if(sc->data[SC_MARIONETTE2])
- agi += ((sc->data[SC_MARIONETTE2]->val3)>>8)&0xFF;
+ agi += ((sc->data[SC_MARIONETTE]->val3)>>8)&0xFF;
if(sc->data[SC_ADORAMUS])
agi -= sc->data[SC_ADORAMUS]->val2;
if(sc->data[SC_DROCERA_HERB_STEAMED])
@@ -4198,6 +4179,11 @@ static unsigned short status_calc_agi(struct block_list *bl, struct status_chang
if(sc->data[SC_KYOUGAKU])
agi -= sc->data[SC_KYOUGAKU]->val2;
+ if(sc->data[SC_MARSHOFABYSS])
+ agi -= agi * sc->data[SC_MARSHOFABYSS]->val2 / 100;
+ if(sc->data[SC_FULL_THROTTLE])
+ agi += agi * 20 / 100;
+
return (unsigned short)cap_value(agi,0,USHRT_MAX);
}
@@ -4210,26 +4196,26 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang
vit -= sc->data[SC_HARMONIZE]->val2;
return (unsigned short)cap_value(vit,0,USHRT_MAX);
}
- if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && vit < 50)
+ if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && vit < 50)
return 50;
if(sc->data[SC_INCALLSTATUS])
vit += sc->data[SC_INCALLSTATUS]->val1;
if(sc->data[SC_INCVIT])
vit += sc->data[SC_INCVIT]->val1;
- if(sc->data[SC_VITFOOD])
- vit += sc->data[SC_VITFOOD]->val1;
+ if(sc->data[SC_FOOD_VIT])
+ vit += sc->data[SC_FOOD_VIT]->val1;
if(sc->data[SC_FOOD_VIT_CASH])
vit += sc->data[SC_FOOD_VIT_CASH]->val1;
- if(sc->data[SC_CHANGE])
- vit += sc->data[SC_CHANGE]->val2;
+ if(sc->data[SC_HLIF_CHANGE])
+ vit += sc->data[SC_HLIF_CHANGE]->val2;
if(sc->data[SC_GLORYWOUNDS])
vit += sc->data[SC_GLORYWOUNDS]->val1;
if(sc->data[SC_TRUESIGHT])
vit += 5;
+ if(sc->data[SC_MARIONETTE_MASTER])
+ vit -= sc->data[SC_MARIONETTE_MASTER]->val3&0xFF;
if(sc->data[SC_MARIONETTE])
- vit -= sc->data[SC_MARIONETTE]->val3&0xFF;
- if(sc->data[SC_MARIONETTE2])
- vit += sc->data[SC_MARIONETTE2]->val3&0xFF;
+ vit += sc->data[SC_MARIONETTE]->val3&0xFF;
if(sc->data[SC_LAUDAAGNUS])
vit += 4 + sc->data[SC_LAUDAAGNUS]->val1;
if(sc->data[SC_MINOR_BBQ])
@@ -4241,8 +4227,10 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang
if(sc->data[SC_KYOUGAKU])
vit -= sc->data[SC_KYOUGAKU]->val2;
- if(sc->data[SC_STRIPARMOR])
- vit -= vit * sc->data[SC_STRIPARMOR]->val2/100;
+ if(sc->data[SC_NOEQUIPARMOR])
+ vit -= vit * sc->data[SC_NOEQUIPARMOR]->val2/100;
+ if(sc->data[SC_FULL_THROTTLE])
+ vit += vit * 20 / 100;
return (unsigned short)cap_value(vit,0,USHRT_MAX);
}
@@ -4256,19 +4244,19 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
int_ -= sc->data[SC_HARMONIZE]->val2;
return (unsigned short)cap_value(int_,0,USHRT_MAX);
}
- if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && int_ < 50)
+ if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && int_ < 50)
return 50;
if(sc->data[SC_INCALLSTATUS])
int_ += sc->data[SC_INCALLSTATUS]->val1;
if(sc->data[SC_INCINT])
int_ += sc->data[SC_INCINT]->val1;
- if(sc->data[SC_INTFOOD])
- int_ += sc->data[SC_INTFOOD]->val1;
+ if(sc->data[SC_FOOD_INT])
+ int_ += sc->data[SC_FOOD_INT]->val1;
if(sc->data[SC_FOOD_INT_CASH])
int_ += sc->data[SC_FOOD_INT_CASH]->val1;
- if(sc->data[SC_CHANGE])
- int_ += sc->data[SC_CHANGE]->val3;
- if(sc->data[SC_BATTLEORDERS])
+ if(sc->data[SC_HLIF_CHANGE])
+ int_ += sc->data[SC_HLIF_CHANGE]->val3;
+ if(sc->data[SC_GDSKILL_BATTLEORDER])
int_ += 5;
if(sc->data[SC_TRUESIGHT])
int_ += 5;
@@ -4278,12 +4266,12 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
else
int_ >>= 1;
}
- if(sc->data[SC_NEN])
- int_ += sc->data[SC_NEN]->val1;
+ if(sc->data[SC_NJ_NEN])
+ int_ += sc->data[SC_NJ_NEN]->val1;
+ if(sc->data[SC_MARIONETTE_MASTER])
+ int_ -= ((sc->data[SC_MARIONETTE_MASTER]->val4)>>16)&0xFF;
if(sc->data[SC_MARIONETTE])
- int_ -= ((sc->data[SC_MARIONETTE]->val4)>>16)&0xFF;
- if(sc->data[SC_MARIONETTE2])
- int_ += ((sc->data[SC_MARIONETTE2]->val4)>>16)&0xFF;
+ int_ += ((sc->data[SC_MARIONETTE]->val4)>>16)&0xFF;
if(sc->data[SC_MANDRAGORA])
int_ -= 5 + 5 * sc->data[SC_MANDRAGORA]->val1;
if(sc->data[SC_COCKTAIL_WARG_BLOOD])
@@ -4295,10 +4283,12 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
if(sc->data[SC_KYOUGAKU])
int_ -= sc->data[SC_KYOUGAKU]->val2;
- if(sc->data[SC_STRIPHELM])
- int_ -= int_ * sc->data[SC_STRIPHELM]->val2/100;
- if(sc->data[SC__STRIPACCESSORY])
- int_ -= int_ * sc->data[SC__STRIPACCESSORY]->val2 / 100;
+ 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;
return (unsigned short)cap_value(int_,0,USHRT_MAX);
}
@@ -4312,19 +4302,19 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang
dex -= sc->data[SC_HARMONIZE]->val2;
return (unsigned short)cap_value(dex,0,USHRT_MAX);
}
- if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && dex < 50)
+ if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && dex < 50)
return 50;
- if(sc->data[SC_CONCENTRATE] && !sc->data[SC_QUAGMIRE])
- dex += (dex-sc->data[SC_CONCENTRATE]->val4)*sc->data[SC_CONCENTRATE]->val2/100;
+ if(sc->data[SC_CONCENTRATION] && !sc->data[SC_QUAGMIRE])
+ dex += (dex-sc->data[SC_CONCENTRATION]->val4)*sc->data[SC_CONCENTRATION]->val2/100;
if(sc->data[SC_INCALLSTATUS])
dex += sc->data[SC_INCALLSTATUS]->val1;
if(sc->data[SC_INCDEX])
dex += sc->data[SC_INCDEX]->val1;
- if(sc->data[SC_DEXFOOD])
- dex += sc->data[SC_DEXFOOD]->val1;
+ if(sc->data[SC_FOOD_DEX])
+ dex += sc->data[SC_FOOD_DEX]->val1;
if(sc->data[SC_FOOD_DEX_CASH])
dex += sc->data[SC_FOOD_DEX_CASH]->val1;
- if(sc->data[SC_BATTLEORDERS])
+ if(sc->data[SC_GDSKILL_BATTLEORDER])
dex += 5;
if(sc->data[SC_HAWKEYES])
dex += sc->data[SC_HAWKEYES]->val1;
@@ -4338,12 +4328,12 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang
else
dex >>= 1;
}
- if(sc->data[SC_INCREASING])
+ if(sc->data[SC_GS_ACCURACY])
dex += 4; // added based on skill updates [Reddozen]
+ if(sc->data[SC_MARIONETTE_MASTER])
+ dex -= ((sc->data[SC_MARIONETTE_MASTER]->val4)>>8)&0xFF;
if(sc->data[SC_MARIONETTE])
- dex -= ((sc->data[SC_MARIONETTE]->val4)>>8)&0xFF;
- if(sc->data[SC_MARIONETTE2])
- dex += ((sc->data[SC_MARIONETTE2]->val4)>>8)&0xFF;
+ dex += ((sc->data[SC_MARIONETTE]->val4)>>8)&0xFF;
if(sc->data[SC_SIROMA_ICE_TEA])
dex += sc->data[SC_SIROMA_ICE_TEA]->val1;
if(sc->data[SC_INSPIRATION])
@@ -4353,8 +4343,12 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang
if(sc->data[SC_KYOUGAKU])
dex -= sc->data[SC_KYOUGAKU]->val2;
- if(sc->data[SC__STRIPACCESSORY])
- dex -= dex * sc->data[SC__STRIPACCESSORY]->val2 / 100;
+ if(sc->data[SC_MARSHOFABYSS])
+ dex -= dex * sc->data[SC_MARSHOFABYSS]->val2 / 100;
+ if(sc->data[SC__STRIPACCESSARY])
+ dex -= dex * sc->data[SC__STRIPACCESSARY]->val2 / 100;
+ if(sc->data[SC_FULL_THROTTLE])
+ dex += dex * 20 / 100;
return (unsigned short)cap_value(dex,0,USHRT_MAX);
}
@@ -4370,24 +4364,24 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang
}
if(sc->data[SC_CURSE])
return 0;
- if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && luk < 50)
+ if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH && luk < 50)
return 50;
if(sc->data[SC_INCALLSTATUS])
luk += sc->data[SC_INCALLSTATUS]->val1;
if(sc->data[SC_INCLUK])
luk += sc->data[SC_INCLUK]->val1;
- if(sc->data[SC_LUKFOOD])
- luk += sc->data[SC_LUKFOOD]->val1;
+ if(sc->data[SC_FOOD_LUK])
+ luk += sc->data[SC_FOOD_LUK]->val1;
if(sc->data[SC_FOOD_LUK_CASH])
luk += sc->data[SC_FOOD_LUK_CASH]->val1;
if(sc->data[SC_TRUESIGHT])
luk += 5;
if(sc->data[SC_GLORIA])
luk += 30;
+ if(sc->data[SC_MARIONETTE_MASTER])
+ luk -= sc->data[SC_MARIONETTE_MASTER]->val4&0xFF;
if(sc->data[SC_MARIONETTE])
- luk -= sc->data[SC_MARIONETTE]->val4&0xFF;
- if(sc->data[SC_MARIONETTE2])
- luk += sc->data[SC_MARIONETTE2]->val4&0xFF;
+ luk += sc->data[SC_MARIONETTE]->val4&0xFF;
if(sc->data[SC_PUTTI_TAILS_NOODLES])
luk += sc->data[SC_PUTTI_TAILS_NOODLES]->val1;
if(sc->data[SC_INSPIRATION])
@@ -4399,26 +4393,33 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang
if(sc->data[SC_LAUDARAMUS])
luk += 4 + sc->data[SC_LAUDARAMUS]->val1;
- if(sc->data[SC__STRIPACCESSORY])
- luk -= luk * sc->data[SC__STRIPACCESSORY]->val2 / 100;
+ if(sc->data[SC__STRIPACCESSARY])
+ luk -= luk * sc->data[SC__STRIPACCESSARY]->val2 / 100;
if(sc->data[SC_BANANA_BOMB])
luk -= luk * sc->data[SC_BANANA_BOMB]->val1 / 100;
+ if(sc->data[SC_FULL_THROTTLE])
+ luk += luk * 20 / 100;
return (unsigned short)cap_value(luk,0,USHRT_MAX);
}
-static unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, int batk)
+static unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, int batk, bool viewable)
{
if(!sc || !sc->count)
return cap_value(batk,0,USHRT_MAX);
+
+ if( !viewable ){
+ /* some statuses that are hidden in the status window */
+ return (unsigned short)cap_value(batk,0,USHRT_MAX);
+ }
- if(sc->data[SC_ATKPOTION])
- batk += sc->data[SC_ATKPOTION]->val1;
+ if(sc->data[SC_PLUSATTACKPOWER])
+ batk += sc->data[SC_PLUSATTACKPOWER]->val1;
if(sc->data[SC_BATKFOOD])
batk += sc->data[SC_BATKFOOD]->val1;
- if(sc->data[SC_GATLINGFEVER])
- batk += sc->data[SC_GATLINGFEVER]->val3;
- if(sc->data[SC_MADNESSCANCEL])
+ if(sc->data[SC_GS_GATLINGFEVER])
+ batk += sc->data[SC_GS_GATLINGFEVER]->val3;
+ if(sc->data[SC_GS_MADNESSCANCEL])
batk += 100;
if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
batk += 50;
@@ -4433,7 +4434,7 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
batk += sc->data[SC_FULL_SWING_K]->val1;
if(sc->data[SC_ODINS_POWER])
batk += 70;
- if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
+ if(sc->data[SC_VOLCANIC_ASH] && (bl->type==BL_MOB)){
if(status_get_element(bl) == ELE_WATER) //water type
batk /= 2;
}
@@ -4446,42 +4447,53 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
batk += batk * sc->data[SC_INCATKRATE]->val1/100;
if(sc->data[SC_PROVOKE])
batk += batk * sc->data[SC_PROVOKE]->val3/100;
- if(sc->data[SC_CONCENTRATION])
- batk += batk * sc->data[SC_CONCENTRATION]->val2/100;
+#ifndef RENEWAL
+ if(sc->data[SC_LKCONCENTRATION])
+ batk += batk * sc->data[SC_LKCONCENTRATION]->val2/100;
+#endif
if(sc->data[SC_SKE])
batk += batk * 3;
- if(sc->data[SC_BLOODLUST])
- batk += batk * sc->data[SC_BLOODLUST]->val2/100;
+ if(sc->data[SC_HAMI_BLOODLUST])
+ batk += batk * sc->data[SC_HAMI_BLOODLUST]->val2/100;
if(sc->data[SC_JOINTBEAT] && sc->data[SC_JOINTBEAT]->val2&BREAK_WAIST)
batk -= batk * 25/100;
if(sc->data[SC_CURSE])
batk -= batk * 25/100;
+ if( sc->data[SC_ZANGETSU] )
+ batk += sc->data[SC_ZANGETSU]->val2;
//Curse shouldn't effect on this? <- Curse OR Bleeding??
-// if(sc->data[SC_BLEEDING])
+// if(sc->data[SC_BLOODING])
// batk -= batk * 25/100;
- if(sc->data[SC_FLEET])
- batk += batk * sc->data[SC_FLEET]->val3/100;
+ if(sc->data[SC_HLIF_FLEET])
+ 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_RUSHWINDMILL])
- batk += batk * sc->data[SC_RUSHWINDMILL]->val2/100;
- if(sc->data[SC_SATURDAYNIGHTFEVER])
- batk += 100 * sc->data[SC_SATURDAYNIGHTFEVER]->val1;
+ 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_BEYONDOFWARCRY])
- batk += batk * sc->data[SC_BEYONDOFWARCRY]->val3/100;
- if( sc->data[SC_ZANGETSU] )
- batk += batk * sc->data[SC_ZANGETSU]->val2 / 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);
}
-static unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc, int watk)
+static unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc, int watk, bool viewable)
{
if(!sc || !sc->count)
return cap_value(watk,0,USHRT_MAX);
+ if( !viewable ){
+ /* some statuses that are hidden in the status window */
+ if(sc->data[SC_STRIKING])
+ watk += sc->data[SC_STRIKING]->val2;
+ if(sc->data[SC_GENTLETOUCH_CHANGE] && sc->data[SC_GENTLETOUCH_CHANGE]->val2)
+ watk += sc->data[SC_GENTLETOUCH_CHANGE]->val2;
+ return (unsigned short)cap_value(watk,0,USHRT_MAX);
+ }
+
if(sc->data[SC_IMPOSITIO])
watk += sc->data[SC_IMPOSITIO]->val2;
if(sc->data[SC_WATKFOOD])
@@ -4490,12 +4502,10 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
watk += sc->data[SC_DRUMBATTLE]->val2;
if(sc->data[SC_VOLCANO])
watk += sc->data[SC_VOLCANO]->val2;
- if(sc->data[SC_MERC_ATKUP])
- watk += sc->data[SC_MERC_ATKUP]->val2;
+ if(sc->data[SC_MER_ATK])
+ watk += sc->data[SC_MER_ATK]->val2;
if(sc->data[SC_FIGHTINGSPIRIT])
watk += sc->data[SC_FIGHTINGSPIRIT]->val1;
- if(sc->data[SC_STRIKING])
- watk += sc->data[SC_STRIKING]->val2;
if(sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 3)
watk += sc->data[SC_SHIELDSPELL_DEF]->val2;
if(sc->data[SC_INSPIRATION])
@@ -4522,23 +4532,28 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
watk += sc->data[SC_NIBELUNGEN]->val2;
}
}
-
+#ifndef RENEWAL
+ if(sc->data[SC_STRIKING])
+ watk += sc->data[SC_STRIKING]->val2;
+ if(sc->data[SC_GENTLETOUCH_CHANGE] && sc->data[SC_GENTLETOUCH_CHANGE]->val2)
+ watk += sc->data[SC_GENTLETOUCH_CHANGE]->val2;
+ if(sc->data[SC_LKCONCENTRATION])
+ watk += watk * sc->data[SC_LKCONCENTRATION]->val2/100;
+#endif
if(sc->data[SC_INCATKRATE])
watk += watk * sc->data[SC_INCATKRATE]->val1/100;
if(sc->data[SC_PROVOKE])
watk += watk * sc->data[SC_PROVOKE]->val3/100;
- if(sc->data[SC_CONCENTRATION])
- watk += watk * sc->data[SC_CONCENTRATION]->val2/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_FLEET])
- watk += watk * sc->data[SC_FLEET]->val3/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_STRIPWEAPON])
- watk -= watk * sc->data[SC_STRIPWEAPON]->val2/100;
+ if(sc->data[SC_NOEQUIPWEAPON])
+ 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_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2)
@@ -4551,10 +4566,6 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
watk += watk * sc->data[SC_TIDAL_WEAPON]->val2 / 100;
if(sc->data[SC_ANGRIFFS_MODUS])
watk += watk * sc->data[SC_ANGRIFFS_MODUS]->val2/100;
-#ifdef RENEWAL_EDP
- if( sc->data[SC_EDP] )
- watk = watk * (100 + sc->data[SC_EDP]->val1 * 80) / 100;
-#endif
return (unsigned short)cap_value(watk,0,USHRT_MAX);
}
@@ -4564,8 +4575,8 @@ static unsigned short status_calc_ematk(struct block_list *bl, struct status_cha
if (!sc || !sc->count)
return cap_value(matk,0,USHRT_MAX);
- if (sc->data[SC_MATKPOTION])
- matk += sc->data[SC_MATKPOTION]->val1;
+ if (sc->data[SC_PLUSMAGICPOWER])
+ matk += sc->data[SC_PLUSMAGICPOWER]->val1;
if (sc->data[SC_MATKFOOD])
matk += sc->data[SC_MATKFOOD]->val1;
if(sc->data[SC_MANA_PLUS])
@@ -4581,18 +4592,24 @@ static unsigned short status_calc_ematk(struct block_list *bl, struct status_cha
if(sc->data[SC_ODINS_POWER])
matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; //70 lvl1, 100lvl2
if(sc->data[SC_IZAYOI])
- matk += 50 * sc->data[SC_IZAYOI]->val1;
+ matk += 25 * sc->data[SC_IZAYOI]->val1;
return (unsigned short)cap_value(matk,0,USHRT_MAX);
}
#endif
-static unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, int matk)
+static unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, int matk, bool viewable)
{
if(!sc || !sc->count)
return cap_value(matk,0,USHRT_MAX);
+
+ if( !viewable ){
+ /* some statuses that are hidden in the status window */
+ return (unsigned short)cap_value(matk,0,USHRT_MAX);
+ }
+
#ifndef RENEWAL
// take note fixed value first before % modifiers
- if (sc->data[SC_MATKPOTION])
- matk += sc->data[SC_MATKPOTION]->val1;
+ if (sc->data[SC_PLUSMAGICPOWER])
+ matk += sc->data[SC_PLUSMAGICPOWER]->val1;
if (sc->data[SC_MATKFOOD])
matk += sc->data[SC_MATKFOOD]->val1;
if (sc->data[SC_MANA_PLUS])
@@ -4608,33 +4625,38 @@ static unsigned short status_calc_matk(struct block_list *bl, struct status_chan
if (sc->data[SC_ODINS_POWER])
matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; //70 lvl1, 100lvl2
if (sc->data[SC_IZAYOI])
- matk += 50 * sc->data[SC_IZAYOI]->val1;
+ matk += 25 * sc->data[SC_IZAYOI]->val1;
#endif
+ if( sc->data[SC_ZANGETSU] )
+ matk += sc->data[SC_ZANGETSU]->val3;
if (sc->data[SC_MAGICPOWER] && sc->data[SC_MAGICPOWER]->val4)
matk += matk * sc->data[SC_MAGICPOWER]->val3/100;
if (sc->data[SC_MINDBREAKER])
matk += matk * sc->data[SC_MINDBREAKER]->val2/100;
if (sc->data[SC_INCMATKRATE])
matk += matk * sc->data[SC_INCMATKRATE]->val1/100;
- if (sc->data[SC_MOONLITSERENADE])
- matk += matk * sc->data[SC_MOONLITSERENADE]->val2/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_BEYONDOFWARCRY])
- matk -= matk * sc->data[SC_BEYONDOFWARCRY]->val3/100;
- if( sc->data[SC_ZANGETSU] )
- matk += matk * sc->data[SC_ZANGETSU]->val2 / 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);
}
-static signed short status_calc_critical(struct block_list *bl, struct status_change *sc, int critical) {
+static signed short status_calc_critical(struct block_list *bl, struct status_change *sc, int critical, bool viewable) {
if(!sc || !sc->count)
return cap_value(critical,10,SHRT_MAX);
- if (sc->data[SC_INCCRI])
- critical += sc->data[SC_INCCRI]->val2;
+ if( !viewable ){
+ /* some statuses that are hidden in the status window */
+ return (short)cap_value(critical,10,SHRT_MAX);
+ }
+
+ if (sc->data[SC_CRITICALPERCENT])
+ critical += sc->data[SC_CRITICALPERCENT]->val2;
if (sc->data[SC_EXPLOSIONSPIRITS])
critical += sc->data[SC_EXPLOSIONSPIRITS]->val2;
if (sc->data[SC_FORTUNE])
@@ -4658,30 +4680,35 @@ static signed short status_calc_critical(struct block_list *bl, struct status_ch
return (short)cap_value(critical,10,SHRT_MAX);
}
-static signed short status_calc_hit(struct block_list *bl, struct status_change *sc, int hit)
+static signed short status_calc_hit(struct block_list *bl, struct status_change *sc, int hit, bool viewable)
{
if(!sc || !sc->count)
return cap_value(hit,1,SHRT_MAX);
+ if( !viewable ){
+ /* some statuses that are hidden in the status window */
+ return (short)cap_value(hit,1,SHRT_MAX);
+ }
+
if(sc->data[SC_INCHIT])
hit += sc->data[SC_INCHIT]->val1;
- if(sc->data[SC_HITFOOD])
- hit += sc->data[SC_HITFOOD]->val1;
+ if(sc->data[SC_FOOD_BASICHIT])
+ hit += sc->data[SC_FOOD_BASICHIT]->val1;
if(sc->data[SC_TRUESIGHT])
hit += sc->data[SC_TRUESIGHT]->val3;
if(sc->data[SC_HUMMING])
hit += sc->data[SC_HUMMING]->val2;
- if(sc->data[SC_CONCENTRATION])
- hit += sc->data[SC_CONCENTRATION]->val3;
+ if(sc->data[SC_LKCONCENTRATION])
+ hit += sc->data[SC_LKCONCENTRATION]->val3;
if(sc->data[SC_INSPIRATION])
hit += 5 * sc->data[SC_INSPIRATION]->val1;
- if(sc->data[SC_ADJUSTMENT])
+ if(sc->data[SC_GS_ADJUSTMENT])
hit -= 30;
- if(sc->data[SC_INCREASING])
+ if(sc->data[SC_GS_ACCURACY])
hit += 20; // RockmanEXE; changed based on updated [Reddozen]
- if(sc->data[SC_MERC_HITUP])
- hit += sc->data[SC_MERC_HITUP]->val2;
+ if(sc->data[SC_MER_HIT])
+ hit += sc->data[SC_MER_HIT]->val2;
if(sc->data[SC_INCHITRATE])
hit += hit * sc->data[SC_INCHITRATE]->val1/100;
@@ -4691,13 +4718,13 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change
hit -= hit * sc->data[SC__GROOMY]->val3 / 100;
if(sc->data[SC_FEAR])
hit -= hit * 20 / 100;
- if (sc->data[SC_ASH])
+ if (sc->data[SC_VOLCANIC_ASH])
hit /= 2;
return (short)cap_value(hit,1,SHRT_MAX);
}
-static signed short status_calc_flee(struct block_list *bl, struct status_change *sc, int flee)
+static signed short status_calc_flee(struct block_list *bl, struct status_change *sc, int flee, bool viewable)
{
if( bl->type == BL_PC )
{
@@ -4710,10 +4737,15 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
if(!sc || !sc->count)
return cap_value(flee,1,SHRT_MAX);
+ if( !viewable ){
+ /* some statuses that are hidden in the status window */
+ return (short)cap_value(flee,1,SHRT_MAX);
+ }
+
if(sc->data[SC_INCFLEE])
flee += sc->data[SC_INCFLEE]->val1;
- if(sc->data[SC_FLEEFOOD])
- flee += sc->data[SC_FLEEFOOD]->val1;
+ if(sc->data[SC_FOOD_BASICAVOIDANCE])
+ flee += sc->data[SC_FOOD_BASICAVOIDANCE]->val1;
if(sc->data[SC_WHISTLE])
flee += sc->data[SC_WHISTLE]->val2;
if(sc->data[SC_WINDWALK])
@@ -4722,28 +4754,26 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
flee += sc->data[SC_VIOLENTGALE]->val2;
if(sc->data[SC_MOON_COMFORT]) //SG skill [Komurka]
flee += sc->data[SC_MOON_COMFORT]->val2;
- if(sc->data[SC_CLOSECONFINE])
+ if(sc->data[SC_RG_CCONFINE_M])
flee += 10;
if (sc->data[SC_ANGRIFFS_MODUS])
flee -= sc->data[SC_ANGRIFFS_MODUS]->val3;
if (sc->data[SC_OVERED_BOOST])
flee = max(flee,sc->data[SC_OVERED_BOOST]->val2);
- if(sc->data[SC_ADJUSTMENT])
+ if(sc->data[SC_GS_ADJUSTMENT])
flee += 30;
- if(sc->data[SC_SPEED])
- flee += 10 + sc->data[SC_SPEED]->val1 * 10;
- if(sc->data[SC_GATLINGFEVER])
- flee -= sc->data[SC_GATLINGFEVER]->val4;
+ if(sc->data[SC_HLIF_SPEED])
+ flee += 10 + sc->data[SC_HLIF_SPEED]->val1 * 10;
+ if(sc->data[SC_GS_GATLINGFEVER])
+ flee -= sc->data[SC_GS_GATLINGFEVER]->val4;
if(sc->data[SC_PARTYFLEE])
flee += sc->data[SC_PARTYFLEE]->val1 * 10;
- if(sc->data[SC_MERC_FLEEUP])
- flee += sc->data[SC_MERC_FLEEUP]->val2;
+ if(sc->data[SC_MER_FLEE])
+ flee += sc->data[SC_MER_FLEE]->val2;
if( sc->data[SC_HALLUCINATIONWALK] )
flee += sc->data[SC_HALLUCINATIONWALK]->val2;
if( sc->data[SC_WATER_BARRIER] )
flee -= sc->data[SC_WATER_BARRIER]->val3;
- if( sc->data[SC_MARSHOFABYSS] )
- flee -= (9 * sc->data[SC_MARSHOFABYSS]->val3 / 10 + sc->data[SC_MARSHOFABYSS]->val2 / 10) * (bl->type == BL_MOB ? 2 : 1);
#ifdef RENEWAL
if( sc->data[SC_SPEARQUICKEN] )
flee += 2 * sc->data[SC_SPEARQUICKEN]->val1;
@@ -4767,13 +4797,13 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
flee -= flee * sc->data[SC__LAZINESS]->val3 / 100;
if( sc->data[SC_GLOOMYDAY] )
flee -= flee * sc->data[SC_GLOOMYDAY]->val2 / 100;
- if( sc->data[SC_SATURDAYNIGHTFEVER] )
- flee -= flee * (40 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->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;
- if(sc->data[SC_ASH] && (bl->type==BL_MOB)){ //mob
+ if(sc->data[SC_VOLCANIC_ASH] && (bl->type==BL_MOB)){ //mob
if(status_get_element(bl) == ELE_WATER) //water type
flee /= 2;
}
@@ -4781,13 +4811,18 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
return (short)cap_value(flee,1,SHRT_MAX);
}
-static signed short status_calc_flee2(struct block_list *bl, struct status_change *sc, int flee2)
+static signed short status_calc_flee2(struct block_list *bl, struct status_change *sc, int flee2, bool viewable)
{
if(!sc || !sc->count)
return cap_value(flee2,10,SHRT_MAX);
- if(sc->data[SC_INCFLEE2])
- flee2 += sc->data[SC_INCFLEE2]->val2;
+ if( !viewable ){
+ /* some statuses that are hidden in the status window */
+ return (short)cap_value(flee2,10,SHRT_MAX);
+ }
+
+ if(sc->data[SC_PLUSAVOIDVALUE])
+ flee2 += sc->data[SC_PLUSAVOIDVALUE]->val2;
if(sc->data[SC_WHISTLE])
flee2 += sc->data[SC_WHISTLE]->val3*10;
if(sc->data[SC__UNLUCKY])
@@ -4795,11 +4830,20 @@ static signed short status_calc_flee2(struct block_list *bl, struct status_chang
return (short)cap_value(flee2,10,SHRT_MAX);
}
-static defType status_calc_def(struct block_list *bl, struct status_change *sc, int def) {
+defType status_calc_def(struct block_list *bl, struct status_change *sc, int def, bool viewable) {
if(!sc || !sc->count)
return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);
+ if( !viewable ){
+ /* some statuses that are hidden in the status window */
+ if( sc && sc->data[SC_CAMOUFLAGE] )
+ def -= def * 5 * (10-sc->data[SC_CAMOUFLAGE]->val4) / 100;
+ if( sc && sc->data[SC_GENTLETOUCH_REVITALIZE] && sc->data[SC_GENTLETOUCH_REVITALIZE]->val4 )
+ def += 2 * sc->data[SC_GENTLETOUCH_REVITALIZE]->val4;
+ return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);
+ }
+
if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
return 0;
if(sc->data[SC_SKA])
@@ -4813,12 +4857,12 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
return 90;
#endif
- if(sc->data[SC_ARMORCHANGE])
- def += sc->data[SC_ARMORCHANGE]->val2;
+ if(sc->data[SC_STONESKIN])
+ def += sc->data[SC_STONESKIN]->val2;
if(sc->data[SC_DRUMBATTLE])
def += sc->data[SC_DRUMBATTLE]->val3;
- if(sc->data[SC_DEFENCE]) //[orn]
- def += sc->data[SC_DEFENCE]->val2 ;
+ if(sc->data[SC_HAMI_DEFENCE]) //[orn]
+ def += sc->data[SC_HAMI_DEFENCE]->val2 ;
if(sc->data[SC_INCDEFRATE])
def += def * sc->data[SC_INCDEFRATE]->val1/100;
if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
@@ -4833,28 +4877,24 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
def >>=1;
if(sc->data[SC_FREEZE])
def >>=1;
- if(sc->data[SC_SIGNUMCRUCIS])
- def -= def * sc->data[SC_SIGNUMCRUCIS]->val2/100;
- if(sc->data[SC_CONCENTRATION])
- def -= def * sc->data[SC_CONCENTRATION]->val4/100;
+ if(sc->data[SC_CRUCIS])
+ def -= def * sc->data[SC_CRUCIS]->val2/100;
+ if(sc->data[SC_LKCONCENTRATION])
+ def -= def * sc->data[SC_LKCONCENTRATION]->val4/100;
if(sc->data[SC_SKE])
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_STRIPSHIELD])
- def -= def * sc->data[SC_STRIPSHIELD]->val2/100;
+ if(sc->data[SC_NOEQUIPSHIELD])
+ def -= def * sc->data[SC_NOEQUIPSHIELD]->val2/100;
if (sc->data[SC_FLING])
def -= def * (sc->data[SC_FLING]->val2)/100;
- if( sc->data[SC_FREEZING] )
- def -= def * 10 / 100;
- if( sc->data[SC_MARSHOFABYSS] )
- def -= def * ( 6 + 6 * sc->data[SC_MARSHOFABYSS]->val3/10 + (bl->type == BL_MOB ? 5 : 3) * sc->data[SC_MARSHOFABYSS]->val2/36 ) / 100;
if( sc->data[SC_ANALYZE] )
def -= def * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
if( sc->data[SC_FORCEOFVANGUARD] )
def += def * 2 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100;
- if(sc->data[SC_SATURDAYNIGHTFEVER])
- def -= def * (10 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100;
+ if(sc->data[SC_SATURDAY_NIGHT_FEVER])
+ 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_ROCK_CRUSHER] )
@@ -4863,15 +4903,17 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
def += def * sc->data[SC_POWER_OF_GAIA]->val2 / 100;
if( sc->data[SC_PRESTIGE] )
def += def * sc->data[SC_PRESTIGE]->val1 / 100;
- if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
+ if( sc->data[SC_FROSTMISTY] )
+ def -= def * 10 / 100;
+ if(sc->data[SC_VOLCANIC_ASH] && (bl->type==BL_MOB)){
if(status_get_race(bl)==RC_PLANT)
def /= 2;
}
- return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);;
+ return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);
}
-static signed short status_calc_def2(struct block_list *bl, struct status_change *sc, int def2)
+signed short status_calc_def2(struct block_list *bl, struct status_change *sc, int def2, bool viewable)
{
if(!sc || !sc->count)
#ifdef RENEWAL
@@ -4880,6 +4922,21 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
return (short)cap_value(def2,1,SHRT_MAX);
#endif
+ if( !viewable ){
+ /* some statuses that are hidden in the status window */
+#ifdef RENEWAL
+ if( sc && sc->data[SC_ASSUMPTIO] )
+ def2 <<= 1;
+#endif
+ if( sc && sc->data[SC_CAMOUFLAGE] )
+ def2 -= def2 * 5 * (10-sc->data[SC_CAMOUFLAGE]->val4) / 100;
+#ifdef RENEWAL
+ return (short)cap_value(def2,SHRT_MIN,SHRT_MAX);
+#else
+ return (short)cap_value(def2,1,SHRT_MAX);
+#endif
+ }
+
if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
return 0;
if(sc->data[SC_ETERNALCHAOS])
@@ -4896,9 +4953,9 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
def2 += status_get_vit(bl) / 2 * sc->data[SC_ANGELUS]->val2/100;
#else
def2 += def2 * sc->data[SC_ANGELUS]->val2/100;
+ if(sc->data[SC_LKCONCENTRATION])
+ def2 -= def2 * sc->data[SC_LKCONCENTRATION]->val4/100;
#endif
- if(sc->data[SC_CONCENTRATION])
- def2 -= def2 * sc->data[SC_CONCENTRATION]->val4/100;
if(sc->data[SC_POISON])
def2 -= def2 * 25/100;
if(sc->data[SC_DPOISON])
@@ -4912,18 +4969,16 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
+ def2 * ( sc->data[SC_JOINTBEAT]->val2&BREAK_WAIST ? 25 : 0 ) / 100;
if(sc->data[SC_FLING])
def2 -= def2 * (sc->data[SC_FLING]->val3)/100;
- if( sc->data[SC_FREEZING] )
- def2 -= def2 * 3 / 10;
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;
- if(sc->data[SC_ASH] && (bl->type==BL_MOB)){
+ if(sc->data[SC_VOLCANIC_ASH] && (bl->type==BL_MOB)){
if(status_get_race(bl)==RC_PLANT)
def2 /= 2;
}
- if (sc->data[SC_PARALYSIS])
- def2 -= def2 * sc->data[SC_PARALYSIS]->val2 / 100;
+ if (sc->data[SC_NEEDLE_OF_PARALYZE])
+ def2 -= def2 * sc->data[SC_NEEDLE_OF_PARALYZE]->val2 / 100;
#ifdef RENEWAL
return (short)cap_value(def2,SHRT_MIN,SHRT_MAX);
@@ -4933,11 +4988,16 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
}
-static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef) {
+defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef, bool viewable) {
if(!sc || !sc->count)
return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
+ if( !viewable ){
+ /* some statuses that are hidden in the status window */
+ return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
+ }
+
if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
return 0;
if(sc->data[SC_BARRIER])
@@ -4948,15 +5008,13 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc,
return 90;
#endif
- if(sc->data[SC_ARMORCHANGE])
- mdef += sc->data[SC_ARMORCHANGE]->val3;
+ if(sc->data[SC_STONESKIN])
+ mdef += sc->data[SC_STONESKIN]->val3;
if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
mdef += 50;
if(sc->data[SC_ENDURE])// It has been confirmed that eddga card grants 1 MDEF, not 0, not 10, but 1.
mdef += (sc->data[SC_ENDURE]->val4 == 0) ? sc->data[SC_ENDURE]->val1 : 1;
- if(sc->data[SC_CONCENTRATION])
- mdef += 1; //Skill info says it adds a fixed 1 Mdef point.
- if(sc->data[SC_STONEHARDSKIN])
+ if(sc->data[SC_STONEHARDSKIN])// Final MDEF increase divided by 10 since were using classic (pre-renewal) mechanics. [Rytech]
mdef += sc->data[SC_STONEHARDSKIN]->val1;
if(sc->data[SC_WATER_BARRIER])
mdef += sc->data[SC_WATER_BARRIER]->val2;
@@ -4964,21 +5022,21 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc,
mdef += 25*mdef/100;
if(sc->data[SC_FREEZE])
mdef += 25*mdef/100;
- if( sc->data[SC_MARSHOFABYSS] )
- mdef -= mdef * ( 6 + 6 * sc->data[SC_MARSHOFABYSS]->val3/10 + (bl->type == BL_MOB ? 5 : 3) * sc->data[SC_MARSHOFABYSS]->val2/36 ) / 100;
if(sc->data[SC_ANALYZE])
mdef -= mdef * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
- if(sc->data[SC_SYMPHONYOFLOVER])
- mdef += mdef * sc->data[SC_SYMPHONYOFLOVER]->val2 / 100;
- if(sc->data[SC_GT_CHANGE] && sc->data[SC_GT_CHANGE]->val4)
- mdef -= mdef * sc->data[SC_GT_CHANGE]->val4 / 100;
+ if(sc->data[SC_SYMPHONY_LOVE])
+ 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_ODINS_POWER])
mdef -= 20 * sc->data[SC_ODINS_POWER]->val1;
+ if(sc->data[SC_BURNING])
+ mdef -= mdef *25 / 100;
return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
}
-static signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, int mdef2)
+signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, int mdef2, bool viewable)
{
if(!sc || !sc->count)
#ifdef RENEWAL
@@ -4987,6 +5045,16 @@ static signed short status_calc_mdef2(struct block_list *bl, struct status_chang
return (short)cap_value(mdef2,1,SHRT_MAX);
#endif
+ if( !viewable ){
+ /* some statuses that are hidden in the status window */
+#ifdef RENEWAL
+ if(sc && sc->data[SC_ASSUMPTIO])
+ mdef2 <<= 1;
+ return (short)cap_value(mdef2,SHRT_MIN,SHRT_MAX);
+#else
+ return (short)cap_value(mdef2,1,SHRT_MAX);
+#endif
+ }
if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
return 0;
@@ -5063,9 +5131,9 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
val = max( val, 50 - 10 * sc->data[SC_LONGING]->val1 );
else
if( sd && sc->data[SC_DANCING] )
- val = max( val, 500 - (40 + 10 * (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_BARDDANCER)) * pc->checkskill(sd,(sd->status.sex?BA_MUSICALLESSON:DC_DANCINGLESSON)) );
+ val = max( val, 500 - (40 + 10 * (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_BARDDANCER)) * pc->checkskill(sd,(sd->status.sex?BA_MUSICALLESSON:DC_DANCINGLESSON)) );
- if( sc->data[SC_DECREASEAGI] )
+ 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) )
val = max( val, 50 );
@@ -5085,16 +5153,14 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
val = max( val, 75 );
if( sc->data[SC_SLOWDOWN] ) // Slow Potion
val = max( val, 100 );
- if( sc->data[SC_GATLINGFEVER] )
+ if( sc->data[SC_GS_GATLINGFEVER] )
val = max( val, 100 );
- if( sc->data[SC_SUITON] )
- val = max( val, sc->data[SC_SUITON]->val3 );
+ if( sc->data[SC_NJ_SUITON] )
+ val = max( val, sc->data[SC_NJ_SUITON]->val3 );
if( sc->data[SC_SWOO] )
val = max( val, 300 );
- if( sc->data[SC_FREEZING] )
- val = max( val, 70 );
- if( sc->data[SC_MARSHOFABYSS] )
- val = max( val, 40 + 10 * sc->data[SC_MARSHOFABYSS]->val1 );
+ if( sc->data[SC_FROSTMISTY] )
+ val = max( val, 50 );
if( sc->data[SC_CAMOUFLAGE] && (sc->data[SC_CAMOUFLAGE]->val3&1) == 0 )
val = max( val, sc->data[SC_CAMOUFLAGE]->val1 < 3 ? 0 : 25 * (5 - sc->data[SC_CAMOUFLAGE]->val1) );
if( sc->data[SC__GROOMY] )
@@ -5109,6 +5175,9 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
val = max( val, sc->data[SC_POWER_OF_GAIA]->val2 );
if( sc->data[SC_MELON_BOMB] )
val = max( val, sc->data[SC_MELON_BOMB]->val1 );
+
+ if( sc->data[SC_MARSHOFABYSS] ) // It stacks to other statuses so always put this at the end.
+ val = max( 50, val + 10 * sc->data[SC_MARSHOFABYSS]->val1 );
if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate > 0 ) // permanent item-based speedup
val = max( val, sd->bonus.speed_rate + sd->bonus.speed_add_rate );
@@ -5121,9 +5190,9 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
{
int val = 0;
- if( sc->data[SC_SPEEDUP1] ) //FIXME: used both by NPC_AGIUP and Speed Potion script
+ if( sc->data[SC_MOVHASTE_INFINITY] ) //FIXME: used both by NPC_AGIUP and Speed Potion script
val = max( val, 50 );
- if( sc->data[SC_INCREASEAGI] )
+ if( sc->data[SC_INC_AGI] )
val = max( val, 25 );
if( sc->data[SC_WINDWALK] )
val = max( val, 2 * sc->data[SC_WINDWALK]->val1 );
@@ -5137,8 +5206,8 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
val = max( val, 25 );
if( sc->data[SC_RUN] )
val = max( val, 55 );
- if( sc->data[SC_AVOID] )
- val = max( val, 10 * sc->data[SC_AVOID]->val1 );
+ if( sc->data[SC_HLIF_AVOID] )
+ val = max( val, 10 * sc->data[SC_HLIF_AVOID]->val1 );
if( sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
val = max( val, 75 );
if( sc->data[SC_CLOAKINGEXCEED] )
@@ -5147,13 +5216,14 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
val = max( val, 10 );
if( sc->data[SC_GN_CARTBOOST] )
val = max( val, sc->data[SC_GN_CARTBOOST]->val2 );
- if( sc->data[SC_SWINGDANCE] )
- val = max( val, sc->data[SC_SWINGDANCE]->val2 );
+ if( sc->data[SC_SWING] )
+ val = max( val, sc->data[SC_SWING]->val2 );
if( sc->data[SC_WIND_STEP_OPTION] )
val = max( val, sc->data[SC_WIND_STEP_OPTION]->val2 );
-
+ if( sc->data[SC_FULL_THROTTLE] )
+ val = max( val, 30);
//FIXME: official items use a single bonus for this [ultramage]
- if( sc->data[SC_SPEEDUP0] ) // temporary item-based speedup
+ if( sc->data[SC_MOVHASTE_HORSE] ) // temporary item-based speedup
val = max( val, 25 );
if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate < 0 ) // permanent item-based speedup
val = max( val, -(sd->bonus.speed_rate + sd->bonus.speed_add_rate) );
@@ -5171,6 +5241,8 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
speed += speed * (50 - 5 * pc->checkskill(sd,MC_PUSHCART)) / 100;
if( sc->data[SC_PARALYSE] )
speed += speed * 50 / 100;
+ if( sc->data[SC_REBOUND] )
+ speed += max(speed, 100);
if( speed_rate != 100 )
speed = speed * speed_rate / 100;
if( sc->data[SC_STEELBODY] )
@@ -5179,6 +5251,7 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
speed = max(speed, 200);
if( sc->data[SC_WALKSPEED] && sc->data[SC_WALKSPEED]->val1 > 0 ) // ChangeSpeed
speed = speed * 100 / sc->data[SC_WALKSPEED]->val1;
+
}
return (short)cap_value(speed,10,USHRT_MAX);
@@ -5194,22 +5267,19 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s
if(!sc || !sc->count)
return 0;
- if(sc->data[i=SC_ASPDPOTION3] ||
- sc->data[i=SC_ASPDPOTION2] ||
- sc->data[i=SC_ASPDPOTION1] ||
- sc->data[i=SC_ASPDPOTION0])
+ if(sc->data[i=SC_ATTHASTE_INFINITY] ||
+ sc->data[i=SC_ATTHASTE_POTION3] ||
+ sc->data[i=SC_ATTHASTE_POTION2] ||
+ sc->data[i=SC_ATTHASTE_POTION1])
pots += sc->data[i]->val1;
if( !sc->data[SC_QUAGMIRE] ){
- if(sc->data[SC_STAR_COMFORT])
- skills1 = 5; // needs more info
-
if(sc->data[SC_TWOHANDQUICKEN] && skills1 < 7)
skills1 = 7;
- if(sc->data[SC_ONEHAND] && skills1 < 7) skills1 = 7;
+ if(sc->data[SC_ONEHANDQUICKEN] && skills1 < 7) skills1 = 7;
- if(sc->data[SC_MERC_QUICKEN] && skills1 < 7) // needs more info
+ if(sc->data[SC_MER_QUICKEN] && skills1 < 7) // needs more info
skills1 = 7;
if(sc->data[SC_ADRENALINE2] && skills1 < 6)
@@ -5221,48 +5291,25 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s
if(sc->data[SC_SPEARQUICKEN] && skills1 < 7)
skills1 = 7;
- if(sc->data[SC_GATLINGFEVER] && skills1 < 9) // needs more info
- skills1 = 9;
-
- if(sc->data[SC_FLEET] && skills1 < 5)
+ if(sc->data[SC_HLIF_FLEET] && skills1 < 5)
skills1 = 5;
-
- if(sc->data[SC_ASSNCROS] &&
- skills1 < 5+1*sc->data[SC_ASSNCROS]->val1) // needs more info
- {
- if (bl->type!=BL_PC)
- skills1 = 4+1*sc->data[SC_ASSNCROS]->val1;
- else
- switch(((TBL_PC*)bl)->status.weapon)
- {
- case W_BOW:
- case W_REVOLVER:
- case W_RIFLE:
- case W_GATLING:
- case W_SHOTGUN:
- case W_GRENADE:
- break;
- default:
- skills1 = 5+1*sc->data[SC_ASSNCROS]->val1;
- }
- }
}
if((sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) && skills1 < 15)
skills1 = 15;
- else if(sc->data[SC_MADNESSCANCEL] && skills1 < 15) // needs more info
- skills1 = 15;
+ else if(sc->data[SC_GS_MADNESSCANCEL] && skills1 < 20)
+ skills1 = 20;
if(sc->data[SC_DONTFORGETME])
- skills2 -= sc->data[SC_DONTFORGETME]->val2; // needs more info
+ skills2 -= sc->data[SC_DONTFORGETME]->val2;
if(sc->data[SC_LONGING])
- skills2 -= sc->data[SC_LONGING]->val2; // needs more info
+ skills2 -= sc->data[SC_LONGING]->val2;
if(sc->data[SC_STEELBODY])
skills2 -= 25;
if(sc->data[SC_SKA])
skills2 -= 25;
if(sc->data[SC_DEFENDER])
- skills2 -= sc->data[SC_DEFENDER]->val4; // needs more info
+ skills2 -= sc->data[SC_DEFENDER]->val4 / 10;
if(sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_ENEMY) // needs more info
skills2 -= 25;
if(sc->data[SC_GRAVITATION])
@@ -5273,8 +5320,8 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s
if( sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE )
skills2 -= 10;
}
- if( sc->data[SC_FREEZING] )
- skills2 -= 30;
+ if( sc->data[SC_FROSTMISTY] )
+ skills2 -= 15;
if( sc->data[SC_HALLUCINATIONWALK_POSTDELAY] )
skills2 -= 50;
if( sc->data[SC_PARALYSE] )
@@ -5285,25 +5332,46 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s
skills2 -= sc->data[SC__INVISIBILITY]->val2 ;
if( sc->data[SC__GROOMY] )
skills2 -= sc->data[SC__GROOMY]->val2;
- if( sc->data[SC_SWINGDANCE] )
- skills2 += sc->data[SC_SWINGDANCE]->val2;
- if( sc->data[SC_DANCEWITHWUG] )
- skills2 += sc->data[SC_DANCEWITHWUG]->val3;
if( sc->data[SC_GLOOMYDAY] )
skills2 -= sc->data[SC_GLOOMYDAY]->val3;
if( sc->data[SC_EARTHDRIVE] )
skills2 -= 25;
- if( sc->data[SC_GT_CHANGE] )
- skills2 += sc->data[SC_GT_CHANGE]->val3;
if( sc->data[SC_MELON_BOMB] )
skills2 -= sc->data[SC_MELON_BOMB]->val1;
+
+ if( sc->data[SC_SWING] )
+ skills2 += sc->data[SC_SWING]->val2;
+ if( sc->data[SC_DANCE_WITH_WUG] )
+ skills2 += sc->data[SC_DANCE_WITH_WUG]->val3;
+ if( sc->data[SC_GENTLETOUCH_CHANGE] )
+ skills2 += sc->data[SC_GENTLETOUCH_CHANGE]->val3;
if( sc->data[SC_BOOST500] )
skills2 += sc->data[SC_BOOST500]->val1;
if( sc->data[SC_EXTRACT_SALAMINE_JUICE] )
skills2 += sc->data[SC_EXTRACT_SALAMINE_JUICE]->val1;
if( sc->data[SC_INCASPDRATE] )
skills2 += sc->data[SC_INCASPDRATE]->val1;
-
+ if( sc->data[SC_GS_GATLINGFEVER] )
+ skills2 += sc->data[SC_GS_GATLINGFEVER]->val1;
+ if( sc->data[SC_STAR_COMFORT] )
+ skills2 += 3 * sc->data[SC_STAR_COMFORT]->val1;
+ if( sc->data[SC_ASSNCROS] && !skills1){
+ if (bl->type!=BL_PC)
+ skills2 += sc->data[SC_ASSNCROS]->val2;
+ else
+ switch(((TBL_PC*)bl)->status.weapon)
+ {
+ case W_BOW:
+ case W_REVOLVER:
+ case W_RIFLE:
+ case W_GATLING:
+ case W_SHOTGUN:
+ case W_GRENADE:
+ break;
+ default:
+ skills2 += sc->data[SC_ASSNCROS]->val2;
+ }
+ }
return ( flag&1? (skills1 + pots) : skills2 );
}
#endif
@@ -5344,13 +5412,13 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
max < sc->data[SC_TWOHANDQUICKEN]->val2)
max = sc->data[SC_TWOHANDQUICKEN]->val2;
- if(sc->data[SC_ONEHAND] &&
- max < sc->data[SC_ONEHAND]->val2)
- max = sc->data[SC_ONEHAND]->val2;
+ if(sc->data[SC_ONEHANDQUICKEN] &&
+ max < sc->data[SC_ONEHANDQUICKEN]->val2)
+ max = sc->data[SC_ONEHANDQUICKEN]->val2;
- if(sc->data[SC_MERC_QUICKEN] &&
- max < sc->data[SC_MERC_QUICKEN]->val2)
- max = sc->data[SC_MERC_QUICKEN]->val2;
+ if(sc->data[SC_MER_QUICKEN] &&
+ max < sc->data[SC_MER_QUICKEN]->val2)
+ max = sc->data[SC_MER_QUICKEN]->val2;
if(sc->data[SC_ADRENALINE2] &&
max < sc->data[SC_ADRENALINE2]->val3)
@@ -5364,13 +5432,13 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
max < sc->data[SC_SPEARQUICKEN]->val2)
max = sc->data[SC_SPEARQUICKEN]->val2;
- if(sc->data[SC_GATLINGFEVER] &&
- max < sc->data[SC_GATLINGFEVER]->val2)
- max = sc->data[SC_GATLINGFEVER]->val2;
+ if(sc->data[SC_GS_GATLINGFEVER] &&
+ max < sc->data[SC_GS_GATLINGFEVER]->val2)
+ max = sc->data[SC_GS_GATLINGFEVER]->val2;
- if(sc->data[SC_FLEET] &&
- max < sc->data[SC_FLEET]->val2)
- max = sc->data[SC_FLEET]->val2;
+ if(sc->data[SC_HLIF_FLEET] &&
+ max < sc->data[SC_HLIF_FLEET]->val2)
+ max = sc->data[SC_HLIF_FLEET]->val2;
if(sc->data[SC_ASSNCROS] &&
max < sc->data[SC_ASSNCROS]->val2)
@@ -5395,14 +5463,14 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
if((sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]))
aspd_rate -= 300;
- else if(sc->data[SC_MADNESSCANCEL])
+ else if(sc->data[SC_GS_MADNESSCANCEL])
aspd_rate -= 200;
}
- if( sc->data[i=SC_ASPDPOTION3] ||
- sc->data[i=SC_ASPDPOTION2] ||
- sc->data[i=SC_ASPDPOTION1] ||
- sc->data[i=SC_ASPDPOTION0] )
+ if( sc->data[i=SC_ATTHASTE_INFINITY] ||
+ sc->data[i=SC_ATTHASTE_POTION3] ||
+ sc->data[i=SC_ATTHASTE_POTION2] ||
+ sc->data[i=SC_ATTHASTE_POTION1] )
aspd_rate -= sc->data[i]->val2;
if(sc->data[SC_DONTFORGETME])
@@ -5425,8 +5493,8 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
if( sc->data[SC_JOINTBEAT]->val2&BREAK_KNEE )
aspd_rate += 100;
}
- if( sc->data[SC_FREEZING] )
- aspd_rate += 300;
+ if( sc->data[SC_FROSTMISTY] )
+ aspd_rate += 150;
if( sc->data[SC_HALLUCINATIONWALK_POSTDELAY] )
aspd_rate += 500;
if( sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
@@ -5439,16 +5507,16 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
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_SWINGDANCE] )
- aspd_rate -= sc->data[SC_SWINGDANCE]->val2 * 10;
- if( sc->data[SC_DANCEWITHWUG] )
- aspd_rate -= sc->data[SC_DANCEWITHWUG]->val3 * 10;
+ if( sc->data[SC_SWING] )
+ aspd_rate -= sc->data[SC_SWING]->val2 * 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;
if( sc->data[SC_EARTHDRIVE] )
aspd_rate += 250;
- if( sc->data[SC_GT_CHANGE] )
- aspd_rate -= sc->data[SC_GT_CHANGE]->val3 * 10;
+ if( sc->data[SC_GENTLETOUCH_CHANGE] )
+ aspd_rate -= sc->data[SC_GENTLETOUCH_CHANGE]->val3 * 10;
if( sc->data[SC_MELON_BOMB] )
aspd_rate += sc->data[SC_MELON_BOMB]->val1 * 10;
if( sc->data[SC_BOOST500] )
@@ -5474,8 +5542,6 @@ static unsigned short status_calc_dmotion(struct block_list *bl, struct status_c
**/
if( sc->data[SC_ENDURE] || ( bl->type == BL_MOB && (((TBL_MOB*)bl)->status.mode&MD_BOSS) ) )
return 0;
- if( sc->data[SC_CONCENTRATION] )
- return 0;
if( sc->data[SC_RUN] || sc->data[SC_WUGDASH] )
return 0;
@@ -5497,7 +5563,7 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
maxhp += maxhp * sc->data[SC_DELUGE]->val2/100;
if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
maxhp += maxhp * 2;
- if(sc->data[SC_MARIONETTE])
+ if(sc->data[SC_MARIONETTE_MASTER])
maxhp -= 1000;
if(sc->data[SC_SOLID_SKIN_OPTION])
maxhp += 2000;// Fix amount.
@@ -5506,8 +5572,8 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
maxhp += 500;
- if(sc->data[SC_MERC_HPUP])
- maxhp += maxhp * sc->data[SC_MERC_HPUP]->val2/100;
+ if(sc->data[SC_MER_HP])
+ maxhp += maxhp * sc->data[SC_MER_HP]->val2/100;
if(sc->data[SC_EPICLESIS])
maxhp += maxhp * 5 * sc->data[SC_EPICLESIS]->val1 / 100;
@@ -5515,18 +5581,18 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
maxhp -= maxhp * 15 / 100;
if(sc->data[SC__WEAKNESS])
maxhp -= maxhp * sc->data[SC__WEAKNESS]->val2 / 100;
- if(sc->data[SC_LERADSDEW])
- maxhp += maxhp * sc->data[SC_LERADSDEW]->val3 / 100;
+ if(sc->data[SC_LERADS_DEW])
+ maxhp += maxhp * sc->data[SC_LERADS_DEW]->val3 / 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_RAISINGDRAGON])
maxhp += maxhp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100;
- if(sc->data[SC_GT_CHANGE]) // Max HP decrease: [Skill Level x 4] %
- maxhp -= maxhp * (4 * sc->data[SC_GT_CHANGE]->val1) / 100;
- if(sc->data[SC_GT_REVITALIZE])// Max HP increase: [Skill Level x 2] %
- maxhp += maxhp * (2 * sc->data[SC_GT_REVITALIZE]->val1) / 100;
+ if(sc->data[SC_GENTLETOUCH_CHANGE]) // Max HP decrease: [Skill Level x 4] %
+ maxhp -= maxhp * (4 * sc->data[SC_GENTLETOUCH_CHANGE]->val1) / 100;
+ if(sc->data[SC_GENTLETOUCH_REVITALIZE])// Max HP increase: [Skill Level x 2] %
+ maxhp += maxhp * (2 * sc->data[SC_GENTLETOUCH_REVITALIZE]->val1) / 100;
if(sc->data[SC_MUSTLE_M])
maxhp += maxhp * sc->data[SC_MUSTLE_M]->val1/100;
if(sc->data[SC_MYSTERIOUS_POWDER])
@@ -5537,6 +5603,8 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
maxhp += maxhp * 5 * sc->data[SC_ANGRIFFS_MODUS]->val1 /100;
if (sc->data[SC_GOLDENE_FERSE])
maxhp += maxhp * sc->data[SC_GOLDENE_FERSE]->val2 / 100;
+ if(sc->data[SC_FRIGG_SONG])
+ maxhp += maxhp * sc->data[SC_FRIGG_SONG]->val2 / 100;
return (unsigned int)cap_value(maxhp,1,UINT_MAX);
}
@@ -5550,10 +5618,10 @@ static unsigned int status_calc_maxsp(struct block_list *bl, struct status_chang
maxsp += maxsp * sc->data[SC_INCMSPRATE]->val1/100;
if(sc->data[SC_INCMSP])
maxsp += (sc->data[SC_INCMSP]->val1);
- if(sc->data[SC_SERVICE4U])
- maxsp += maxsp * sc->data[SC_SERVICE4U]->val2/100;
- if(sc->data[SC_MERC_SPUP])
- maxsp += maxsp * sc->data[SC_MERC_SPUP]->val2/100;
+ if(sc->data[SC_SERVICEFORYOU])
+ maxsp += maxsp * sc->data[SC_SERVICEFORYOU]->val2/100;
+ if(sc->data[SC_MER_SP])
+ maxsp += maxsp * sc->data[SC_MER_SP]->val2/100;
if(sc->data[SC_RAISINGDRAGON])
maxsp += maxsp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100;
if(sc->data[SC_LIFE_FORCE_F])
@@ -5575,10 +5643,10 @@ static unsigned char status_calc_element(struct block_list *bl, struct status_ch
return ELE_EARTH;
if(sc->data[SC_BENEDICTIO])
return ELE_HOLY;
- if(sc->data[SC_CHANGEUNDEAD])
+ if(sc->data[SC_PROPERTYUNDEAD])
return ELE_UNDEAD;
- if(sc->data[SC_ELEMENTALCHANGE])
- return sc->data[SC_ELEMENTALCHANGE]->val2;
+ if(sc->data[SC_ARMOR_PROPERTY])
+ return sc->data[SC_ARMOR_PROPERTY]->val2;
if(sc->data[SC_SHAPESHIFT])
return sc->data[SC_SHAPESHIFT]->val2;
@@ -5596,10 +5664,10 @@ static unsigned char status_calc_element_lv(struct block_list *bl, struct status
return 1;
if(sc->data[SC_BENEDICTIO])
return 1;
- if(sc->data[SC_CHANGEUNDEAD])
+ if(sc->data[SC_PROPERTYUNDEAD])
return 1;
- if(sc->data[SC_ELEMENTALCHANGE])
- return sc->data[SC_ELEMENTALCHANGE]->val1;
+ if(sc->data[SC_ARMOR_PROPERTY])
+ return sc->data[SC_ARMOR_PROPERTY]->val1;
if(sc->data[SC_SHAPESHIFT])
return 1;
if(sc->data[SC__INVISIBILITY])
@@ -5615,25 +5683,25 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch
return element;
if(sc->data[SC_ENCHANTARMS])
return sc->data[SC_ENCHANTARMS]->val2;
- if(sc->data[SC_WATERWEAPON]
+ if(sc->data[SC_PROPERTYWATER]
|| (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2) )
return ELE_WATER;
- if(sc->data[SC_EARTHWEAPON]
+ if(sc->data[SC_PROPERTYGROUND]
|| (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2) )
return ELE_EARTH;
- if(sc->data[SC_FIREWEAPON]
+ if(sc->data[SC_PROPERTYFIRE]
|| (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2) )
return ELE_FIRE;
- if(sc->data[SC_WINDWEAPON]
+ if(sc->data[SC_PROPERTYWIND]
|| (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2) )
return ELE_WIND;
- if(sc->data[SC_ENCPOISON])
+ if(sc->data[SC_ENCHANTPOISON])
return ELE_POISON;
if(sc->data[SC_ASPERSIO])
return ELE_HOLY;
- if(sc->data[SC_SHADOWWEAPON])
+ if(sc->data[SC_PROPERTYDARK])
return ELE_DARK;
- if(sc->data[SC_GHOSTWEAPON] || sc->data[SC__INVISIBILITY])
+ if(sc->data[SC_PROPERTYTELEKINESIS] || sc->data[SC__INVISIBILITY])
return ELE_GHOST;
if(sc->data[SC_TIDAL_WEAPON_OPTION] || sc->data[SC_TIDAL_WEAPON] )
return ELE_WATER;
@@ -6119,14 +6187,14 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
//Status that are blocked by Golden Thief Bug card or Wand of Hermod
if (status_isimmune(bl))
switch (type) {
- case SC_DECREASEAGI:
+ case SC_DEC_AGI:
case SC_SILENCE:
case SC_COMA:
- case SC_INCREASEAGI:
+ case SC_INC_AGI:
case SC_BLESSING:
case SC_SLOWPOISON:
case SC_IMPOSITIO:
- case SC_AETERNA:
+ case SC_LEXAETERNA:
case SC_SUFFRAGIUM:
case SC_BENEDICTIO:
case SC_PROVIDENCE:
@@ -6137,11 +6205,11 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
case SC_GLORIA:
case SC_WINDWALK:
case SC_MAGICROD:
- case SC_HALLUCINATION:
+ case SC_ILLUSION:
case SC_STONE:
case SC_QUAGMIRE:
- case SC_SUITON:
- case SC_SWINGDANCE:
+ case SC_NJ_SUITON:
+ case SC_SWING:
case SC__ENERVATION:
case SC__GROOMY:
case SC__IGNORANCE:
@@ -6164,7 +6232,7 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
return tick;
case SC_DPOISON:
case SC_SILENCE:
- case SC_BLEEDING:
+ case SC_BLOODING:
sc_def = status->vit*100;
sc_def2 = status->luk*10;
break;
@@ -6172,11 +6240,11 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
sc_def = status->int_*100;
sc_def2 = status->luk*10;
break;
- case SC_DEEPSLEEP:
+ case SC_DEEP_SLEEP:
sc_def = status->int_*50;
tick_def = status->int_*10 + status_get_lv(bl) * 65 / 10; //Seems to be -1 sec every 10 int and -5% chance every 10 int.
break;
- case SC_DECREASEAGI:
+ case SC_DEC_AGI:
case SC_ADORAMUS: //Arch Bishop
if (sd) tick>>=1; //Half duration for players.
case SC_STONE:
@@ -6205,13 +6273,13 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
sc_def = (status->str + status->int_)*50;
sc_def2 = status->luk*10;
break;
- case SC_ANKLE:
+ case SC_ANKLESNARE:
if(status->mode&MD_BOSS) // Lasts 5 times less on bosses
tick /= 5;
sc_def = status->agi*50;
break;
case SC_MAGICMIRROR:
- case SC_ARMORCHANGE:
+ case SC_STONESKIN:
if (sd) //Duration greatly reduced for players.
tick /= 15;
sc_def2 = status_get_lv(bl)*20 + status->vit*25 + status->agi*10; // Lineal Reduction of Rate
@@ -6231,21 +6299,20 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
tick -= (status->vit + status->luk) / 20 * 1000;
break;
case SC_BURNING:
- // From iROwiki : http://forums.irowiki.org/showpost.php?p=577240&postcount=583
- tick -= 50*status->luk + 60*status->int_ + 170*status->vit;
- tick = max(tick,10000); // Minimum Duration 10s.
+ tick -= 75 * status->luk + 125 * status->agi;
+ tick = max(tick,5000); // Minimum Duration 5s.
break;
- case SC_FREEZING:
+ case SC_FROSTMISTY:
tick -= 1000 * ((status->vit + status->dex) / 20);
- tick = max(tick,10000); // Minimum Duration 10s.
+ tick = max(tick,6000); // Minimum Duration 10s.
break;
case SC_OBLIVIONCURSE: // 100% - (100 - 0.8 x INT)
sc_def = 100 - ( 100 - status->int_* 8 / 10 );
sc_def = max(sc_def, 5); // minimum of 5%
break;
- case SC_BITE: // {(Base Success chance) - (Target's AGI / 4)}
- rate -= status->agi*1000/4;
- rate = max(rate,50000); // minimum of 50%
+ case SC_WUGBITE: // {(Base Success chance) - (Target's AGI / 4)}
+ rate -= status->agi*100/4;
+ rate = max(rate,5000); // minimum of 50%
break;
case SC_ELECTRICSHOCKER:
if( bl->type == BL_MOB )
@@ -6258,11 +6325,11 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
sc_def = (status->vit+status->luk)/5;
break;
case SC_KYOUGAKU:
- tick -= 30*status->int_;
+ tick -= 1000 * status_get_int(bl) / 20;
break;
- case SC_PARALYSIS:
- tick -= 50 * (status->vit + status->luk); //(1000/20);
- break;
+ case SC_NEEDLE_OF_PARALYZE:
+ tick -= 50 * (status->vit + status->luk); //(1000/20);
+ break;
default:
//Effect that cannot be reduced? Likely a buff.
if (!(rnd()%10000 < rate))
@@ -6320,7 +6387,7 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
//Minimum chances
switch (type) {
- case SC_BITE:
+ case SC_WUGBITE:
rate = max(rate, 5000); //Minimum of 50%
break;
}
@@ -6330,8 +6397,8 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
{
if( sd->reseff[type-SC_COMMON_MIN] > 0 )
rate -= rate*sd->reseff[type-SC_COMMON_MIN]/10000;
- if( sd->sc.data[SC_COMMONSC_RESIST] )
- rate -= rate*sd->sc.data[SC_COMMONSC_RESIST]->val1/100;
+ if( sd->sc.data[SC_TARGET_BLOOD] )
+ rate -= rate*sd->sc.data[SC_TARGET_BLOOD]->val1/100;
}
}
@@ -6350,13 +6417,13 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
//Minimum durations
switch (type) {
- case SC_ANKLE:
+ case SC_ANKLESNARE:
case SC_MARSHOFABYSS:
case SC_STASIS:
tick = max(tick, 5000); //Minimum duration 5s
break;
case SC_BURNING:
- case SC_FREEZING:
+ case SC_FROSTMISTY:
tick = max(tick, 10000); //Minimum duration 10s
break;
default:
@@ -6460,9 +6527,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
return 0; // Immune to status ailements
switch( type ) {
case SC_QUAGMIRE://Tester said it protects against this and decrease agi.
- case SC_DECREASEAGI:
+ case SC_DEC_AGI:
case SC_BURNING:
- case SC_FREEZING:
+ case SC_FROSTMISTY:
//case SC_WHITEIMPRISON://Need confirm. Protected against this in the past. [Rytech]
case SC_MARSHOFABYSS:
case SC_TOXIN:
@@ -6474,7 +6541,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_OBLIVIONCURSE:
case SC_LEECHESEND:
case SC_CRYSTALIZE: ////08/31/2011 - Class Balance Changes
- case SC_DEEPSLEEP:
+ case SC_DEEP_SLEEP:
case SC_MANDRAGORA:
return 0;
}
@@ -6483,8 +6550,8 @@ 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_DEEPSLEEP:
- case SC_SATURDAYNIGHTFEVER:
+ case SC_DEEP_SLEEP:
+ case SC_SATURDAY_NIGHT_FEVER:
case SC_PYREXIA:
case SC_DEATHHURT:
case SC_MAGICMUSHROOM:
@@ -6528,14 +6595,14 @@ 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_DEEPSLEEP:
+ case SC_DEEP_SLEEP:
case SC_SLEEP:
case SC_STUN:
- case SC_FREEZING:
+ case SC_FROSTMISTY:
case SC_CRYSTALIZE:
if (sc->opt1)
return 0; //Cannot override other opt1 status changes. [Skotlex]
- if((type == SC_FREEZE || type == SC_FREEZING || type == SC_CRYSTALIZE) && sc->data[SC_WARMER])
+ if((type == SC_FREEZE || type == SC_FROSTMISTY || type == SC_CRYSTALIZE) && sc->data[SC_WARMER])
return 0; //Immune to Frozen and Freezing status if under Warmer status. [Jobbie]
break;
@@ -6543,23 +6610,23 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC__BLOODYLUST:
if(!sd) return 0; //should only affect player
case SC_BERSERK:
- if (((type == SC_BERSERK) && (sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC__BLOODYLUST]))
- || ((type == SC__BLOODYLUST) && (sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC_BERSERK]))
+ if (((type == SC_BERSERK) && (sc->data[SC_SATURDAY_NIGHT_FEVER] || sc->data[SC__BLOODYLUST]))
+ || ((type == SC__BLOODYLUST) && (sc->data[SC_SATURDAY_NIGHT_FEVER] || sc->data[SC_BERSERK]))
)
return 0;
break;
case SC_BURNING:
- if(sc->opt1 || sc->data[SC_FREEZING])
+ if(sc->opt1 || sc->data[SC_FROSTMISTY])
return 0;
break;
- case SC_SIGNUMCRUCIS:
+ case SC_CRUCIS:
//Only affects demons and undead element (but not players)
if((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
return 0;
break;
- case SC_AETERNA:
+ case SC_LEXAETERNA:
if( (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE) || sc->data[SC_FREEZE] )
return 0;
break;
@@ -6568,9 +6635,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
return 0;
break;
case SC_OVERTHRUST:
- if (sc->data[SC_MAXOVERTHRUST])
+ if (sc->data[SC_OVERTHRUSTMAX])
return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex]
- case SC_MAXOVERTHRUST:
+ case SC_OVERTHRUSTMAX:
if( sc->option&OPTION_MADOGEAR )
return 0;//Overthrust and Overthrust Max cannot be used on Mado Gear [Ind]
break;
@@ -6578,7 +6645,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE)))
return 0;
if (sc->data[SC_QUAGMIRE] ||
- sc->data[SC_DECREASEAGI] ||
+ sc->data[SC_DEC_AGI] ||
sc->option&OPTION_MADOGEAR //Adrenaline doesn't affect Mado Gear [Ind]
)
return 0;
@@ -6587,27 +6654,27 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if(sd && !pc_check_weapontype(sd,skill->get_weapontype(BS_ADRENALINE2)))
return 0;
if (sc->data[SC_QUAGMIRE] ||
- sc->data[SC_DECREASEAGI]
+ sc->data[SC_DEC_AGI]
)
return 0;
break;
case SC_MAGNIFICAT:
- if( sc->option&OPTION_MADOGEAR ) //Mado is immune to magnificat
+ if( sc->data[SC_OFFERTORIUM] || sc->option&OPTION_MADOGEAR ) //Mado is immune to magnificat
return 0;
break;
- case SC_ONEHAND:
- case SC_MERC_QUICKEN:
+ case SC_ONEHANDQUICKEN:
+ case SC_MER_QUICKEN:
case SC_TWOHANDQUICKEN:
- if(sc->data[SC_DECREASEAGI])
+ if(sc->data[SC_DEC_AGI])
return 0;
- case SC_INCREASEAGI:
+ case SC_INC_AGI:
if(sd && pc_issit(sd)){
pc->setstand(sd);
clif->standing(&sd->bl);
}
- case SC_CONCENTRATE:
+ case SC_CONCENTRATION:
case SC_SPEARQUICKEN:
case SC_TRUESIGHT:
case SC_WINDWALK:
@@ -6648,7 +6715,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
break;
//Strip skills, need to divest something or it fails.
- case SC_STRIPWEAPON:
+ case SC_NOEQUIPWEAPON:
if (sd && !(flag&4)) { //apply sc anyway if loading saved sc_data
int i;
opt_flag = 0; //Reuse to check success condition.
@@ -6664,7 +6731,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
- case SC_STRIPSHIELD:
+ case SC_NOEQUIPSHIELD:
if( val2 == 1 ) val2 = 0; //GX effect. Do not take shield off..
else
if (sd && !(flag&4)) {
@@ -6678,7 +6745,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
- case SC_STRIPARMOR:
+ case SC_NOEQUIPARMOR:
if (sd && !(flag&4)) {
int i;
if(sd->bonus.unstripable_equip&EQP_ARMOR)
@@ -6690,7 +6757,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
- case SC_STRIPHELM:
+ case SC_NOEQUIPHELM:
if (sd && !(flag&4)) {
int i;
if(sd->bonus.unstripable_equip&EQP_HELM)
@@ -6702,67 +6769,67 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC
break;
- case SC_MERC_FLEEUP:
- case SC_MERC_ATKUP:
- case SC_MERC_HPUP:
- case SC_MERC_SPUP:
- case SC_MERC_HITUP:
+ case SC_MER_FLEE:
+ case SC_MER_ATK:
+ case SC_MER_HP:
+ case SC_MER_SP:
+ case SC_MER_HIT:
if( bl->type != BL_MER )
return 0; // Stats only for Mercenaries
break;
- case SC_STRFOOD:
+ case SC_FOOD_STR:
if (sc->data[SC_FOOD_STR_CASH] && sc->data[SC_FOOD_STR_CASH]->val1 > val1)
return 0;
break;
- case SC_AGIFOOD:
+ case SC_FOOD_AGI:
if (sc->data[SC_FOOD_AGI_CASH] && sc->data[SC_FOOD_AGI_CASH]->val1 > val1)
return 0;
break;
- case SC_VITFOOD:
+ case SC_FOOD_VIT:
if (sc->data[SC_FOOD_VIT_CASH] && sc->data[SC_FOOD_VIT_CASH]->val1 > val1)
return 0;
break;
- case SC_INTFOOD:
+ case SC_FOOD_INT:
if (sc->data[SC_FOOD_INT_CASH] && sc->data[SC_FOOD_INT_CASH]->val1 > val1)
return 0;
break;
- case SC_DEXFOOD:
+ case SC_FOOD_DEX:
if (sc->data[SC_FOOD_DEX_CASH] && sc->data[SC_FOOD_DEX_CASH]->val1 > val1)
return 0;
break;
- case SC_LUKFOOD:
+ case SC_FOOD_LUK:
if (sc->data[SC_FOOD_LUK_CASH] && sc->data[SC_FOOD_LUK_CASH]->val1 > val1)
return 0;
break;
case SC_FOOD_STR_CASH:
- if (sc->data[SC_STRFOOD] && sc->data[SC_STRFOOD]->val1 > val1)
+ if (sc->data[SC_FOOD_STR] && sc->data[SC_FOOD_STR]->val1 > val1)
return 0;
break;
case SC_FOOD_AGI_CASH:
- if (sc->data[SC_AGIFOOD] && sc->data[SC_AGIFOOD]->val1 > val1)
+ if (sc->data[SC_FOOD_AGI] && sc->data[SC_FOOD_AGI]->val1 > val1)
return 0;
break;
case SC_FOOD_VIT_CASH:
- if (sc->data[SC_VITFOOD] && sc->data[SC_VITFOOD]->val1 > val1)
+ if (sc->data[SC_FOOD_VIT] && sc->data[SC_FOOD_VIT]->val1 > val1)
return 0;
break;
case SC_FOOD_INT_CASH:
- if (sc->data[SC_INTFOOD] && sc->data[SC_INTFOOD]->val1 > val1)
+ if (sc->data[SC_FOOD_INT] && sc->data[SC_FOOD_INT]->val1 > val1)
return 0;
break;
case SC_FOOD_DEX_CASH:
- if (sc->data[SC_DEXFOOD] && sc->data[SC_DEXFOOD]->val1 > val1)
+ if (sc->data[SC_FOOD_DEX] && sc->data[SC_FOOD_DEX]->val1 > val1)
return 0;
break;
case SC_FOOD_LUK_CASH:
- if (sc->data[SC_LUKFOOD] && sc->data[SC_LUKFOOD]->val1 > val1)
+ if (sc->data[SC_FOOD_LUK] && sc->data[SC_FOOD_LUK]->val1 > val1)
return 0;
break;
case SC_CAMOUFLAGE:
if( sd && pc->checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill->check_camouflage(bl,NULL) )
return 0;
break;
- case SC__STRIPACCESSORY:
+ case SC__STRIPACCESSARY:
if( sd ) {
int i = -1;
if( !(sd->bonus.unstripable_equip&EQI_ACC_L) ) {
@@ -6793,10 +6860,14 @@ 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_SATURDAYNIGHTFEVER:
+ case SC_SATURDAY_NIGHT_FEVER:
if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION] || sc->data[SC__BLOODYLUST])
return 0;
break;
+ case SC_OFFERTORIUM:
+ if (sc->data[SC_MAGNIFICAT])
+ return 0;
+ break;
}
//Check for BOSS resistances
@@ -6805,20 +6876,20 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
return 0;
switch (type) {
case SC_BLESSING:
- case SC_DECREASEAGI:
+ case SC_DEC_AGI:
case SC_PROVOKE:
case SC_COMA:
case SC_GRAVITATION:
- case SC_SUITON:
+ case SC_NJ_SUITON:
case SC_RICHMANKIM:
case SC_ROKISWEIL:
case SC_FOGWALL:
- case SC_FREEZING:
+ case SC_FROSTMISTY:
case SC_BURNING:
case SC_MARSHOFABYSS:
case SC_ADORAMUS:
- case SC_PARALYSIS:
- case SC_DEEPSLEEP:
+ case SC_NEEDLE_OF_PARALYZE:
+ case SC_DEEP_SLEEP:
case SC_CRYSTALIZE:
// Exploit prevention - kRO Fix
@@ -6832,7 +6903,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_LEECHESEND:
// Ranger Effects
- case SC_BITE:
+ case SC_WUGBITE:
case SC_ELECTRICSHOCKER:
case SC_MAGNETICFIELD:
@@ -6851,35 +6922,35 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
status_change_end(bl, SC_STONE, INVALID_TIMER);
}
break;
- case SC_INCREASEAGI:
- status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER);
+ case SC_INC_AGI:
+ status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
break;
case SC_QUAGMIRE:
- status_change_end(bl, SC_CONCENTRATE, INVALID_TIMER);
+ status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER);
status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
//Also blocks the ones below...
- case SC_DECREASEAGI:
+ case SC_DEC_AGI:
status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
//Also blocks the ones below...
case SC_DONTFORGETME:
- status_change_end(bl, SC_INCREASEAGI, INVALID_TIMER);
+ status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
status_change_end(bl, SC_ADRENALINE, INVALID_TIMER);
status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER);
status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
- status_change_end(bl, SC_MERC_QUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
status_change_end(bl, SC_ACCELERATION, INVALID_TIMER);
break;
- case SC_ONEHAND:
+ case SC_ONEHANDQUICKEN:
//Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
- status_change_end(bl, SC_ASPDPOTION0, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION1, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION3, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
break;
- case SC_MAXOVERTHRUST:
+ case SC_OVERTHRUSTMAX:
//Cancels Normal Overthrust. [Skotlex]
status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
break;
@@ -6896,18 +6967,18 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
break;
case SC_HIDING:
- status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
- status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
+ status_change_end(bl, SC_RG_CCONFINE_M, INVALID_TIMER);
+ status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER);
break;
case SC__BLOODYLUST:
case SC_BERSERK:
if(battle_config.berserk_cancels_buffs) {
- status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
+ status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
+ status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
status_change_end(bl, SC_PARRYING, INVALID_TIMER);
status_change_end(bl, SC_AURABLADE, INVALID_TIMER);
- status_change_end(bl, SC_MERC_QUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
}
#ifdef RENEWAL
else {
@@ -6923,61 +6994,65 @@ 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_DECREASEAGI])
+ if(sc->data[SC_DEC_AGI])
{ //Cancel Decrease Agi, but take no further effect [Skotlex]
- status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER);
+ status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
return 0;
}
break;
case SC_FUSION:
- status_change_end(bl, SC_SPIRIT, INVALID_TIMER);
+ status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
break;
- case SC_ADJUSTMENT:
- status_change_end(bl, SC_MADNESSCANCEL, INVALID_TIMER);
+ case SC_GS_ADJUSTMENT:
+ status_change_end(bl, SC_GS_MADNESSCANCEL, INVALID_TIMER);
break;
- case SC_MADNESSCANCEL:
- status_change_end(bl, SC_ADJUSTMENT, INVALID_TIMER);
+ case SC_GS_MADNESSCANCEL:
+ status_change_end(bl, SC_GS_ADJUSTMENT, INVALID_TIMER);
break;
//NPC_CHANGEUNDEAD will debuff Blessing and Agi Up
- case SC_CHANGEUNDEAD:
+ case SC_PROPERTYUNDEAD:
status_change_end(bl, SC_BLESSING, INVALID_TIMER);
- status_change_end(bl, SC_INCREASEAGI, INVALID_TIMER);
+ status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
break;
- case SC_STRFOOD:
+ case SC_FOOD_STR:
status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER);
break;
- case SC_AGIFOOD:
+ case SC_FOOD_AGI:
status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER);
break;
- case SC_VITFOOD:
+ case SC_FOOD_VIT:
status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER);
break;
- case SC_INTFOOD:
+ case SC_FOOD_INT:
status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER);
break;
- case SC_DEXFOOD:
+ case SC_FOOD_DEX:
status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER);
break;
- case SC_LUKFOOD:
+ case SC_FOOD_LUK:
status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER);
break;
case SC_FOOD_STR_CASH:
- status_change_end(bl, SC_STRFOOD, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_STR, INVALID_TIMER);
break;
case SC_FOOD_AGI_CASH:
- status_change_end(bl, SC_AGIFOOD, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_AGI, INVALID_TIMER);
break;
case SC_FOOD_VIT_CASH:
- status_change_end(bl, SC_VITFOOD, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_VIT, INVALID_TIMER);
break;
case SC_FOOD_INT_CASH:
- status_change_end(bl, SC_INTFOOD, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_INT, INVALID_TIMER);
break;
case SC_FOOD_DEX_CASH:
- status_change_end(bl, SC_DEXFOOD, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_DEX, INVALID_TIMER);
break;
case SC_FOOD_LUK_CASH:
- status_change_end(bl, SC_LUKFOOD, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER);
+ break;
+ case SC_ENDURE:
+ if( val4 )
+ status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
break;
case SC_FIGHTINGSPIRIT:
status_change_end(bl, type, INVALID_TIMER); // Remove previous one.
@@ -6985,57 +7060,57 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_MARSHOFABYSS:
status_change_end(bl, SC_INCAGI, INVALID_TIMER);
status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION0, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION1, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION2, INVALID_TIMER);
- status_change_end(bl, SC_ASPDPOTION3, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
break;
- case SC_SWINGDANCE:
- case SC_SYMPHONYOFLOVER:
- case SC_MOONLITSERENADE:
- case SC_RUSHWINDMILL:
+ 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
- if (type != SC_SWINGDANCE) status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
- if (type != SC_SYMPHONYOFLOVER) status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
- if (type != SC_MOONLITSERENADE) status_change_end(bl, SC_MOONLITSERENADE, INVALID_TIMER);
- if (type != SC_RUSHWINDMILL) status_change_end(bl, SC_RUSHWINDMILL, INVALID_TIMER);
+ 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);
break;
- case SC_VOICEOFSIREN:
- case SC_DEEPSLEEP:
+ case SC_SIREN:
+ case SC_DEEP_SLEEP:
case SC_GLOOMYDAY:
- case SC_SONGOFMANA:
- case SC_DANCEWITHWUG:
- case SC_SATURDAYNIGHTFEVER:
- case SC_LERADSDEW:
+ case SC_SONG_OF_MANA:
+ case SC_DANCE_WITH_WUG:
+ case SC_SATURDAY_NIGHT_FEVER:
+ case SC_LERADS_DEW:
case SC_MELODYOFSINK:
- case SC_BEYONDOFWARCRY:
- case SC_UNLIMITEDHUMMINGVOICE: //group B
- if (type != SC_VOICEOFSIREN) status_change_end(bl, SC_VOICEOFSIREN, INVALID_TIMER);
- if (type != SC_DEEPSLEEP) status_change_end(bl, SC_DEEPSLEEP, INVALID_TIMER);
- if (type != SC_LERADSDEW) status_change_end(bl, SC_LERADSDEW, INVALID_TIMER);
+ case SC_BEYOND_OF_WARCRY:
+ case SC_UNLIMITED_HUMMING_VOICE: //group B
+ 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_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_BEYONDOFWARCRY) status_change_end(bl, SC_BEYONDOFWARCRY, INVALID_TIMER);
- if (type != SC_UNLIMITEDHUMMINGVOICE) status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, 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_SONGOFMANA) status_change_end(bl, SC_SONGOFMANA, INVALID_TIMER);
- if (type != SC_DANCEWITHWUG) status_change_end(bl, SC_DANCEWITHWUG, INVALID_TIMER);
- if (type != SC_SATURDAYNIGHTFEVER) {
- if (sc->data[SC_SATURDAYNIGHTFEVER]) {
- sc->data[SC_SATURDAYNIGHTFEVER]->val2 = 0; //mark to not lose hp
- status_change_end(bl, SC_SATURDAYNIGHTFEVER, 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_REFLECTDAMAGE, INVALID_TIMER);
+ status_change_end(bl, SC_LG_REFLECTDAMAGE, INVALID_TIMER);
break;
- case SC_REFLECTDAMAGE:
+ case SC_LG_REFLECTDAMAGE:
status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
break;
case SC_SHIELDSPELL_DEF:
@@ -7049,15 +7124,15 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if( type != SC_SHIELDSPELL_REF )
status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
break;
- case SC_GT_ENERGYGAIN:
- case SC_GT_CHANGE:
- case SC_GT_REVITALIZE:
- if( type != SC_GT_REVITALIZE )
- status_change_end(bl, SC_GT_REVITALIZE, INVALID_TIMER);
- if( type != SC_GT_ENERGYGAIN )
- status_change_end(bl, SC_GT_ENERGYGAIN, INVALID_TIMER);
- if( type != SC_GT_CHANGE )
- status_change_end(bl, SC_GT_CHANGE, INVALID_TIMER);
+ case SC_GENTLETOUCH_ENERGYGAIN:
+ case SC_GENTLETOUCH_CHANGE:
+ case SC_GENTLETOUCH_REVITALIZE:
+ if( type != SC_GENTLETOUCH_REVITALIZE )
+ status_change_end(bl, SC_GENTLETOUCH_REVITALIZE, INVALID_TIMER);
+ if( type != SC_GENTLETOUCH_ENERGYGAIN )
+ status_change_end(bl, SC_GENTLETOUCH_ENERGYGAIN, INVALID_TIMER);
+ if( type != SC_GENTLETOUCH_CHANGE )
+ status_change_end(bl, SC_GENTLETOUCH_CHANGE, INVALID_TIMER);
break;
case SC_INVINCIBLE:
status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER);
@@ -7073,24 +7148,24 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
//Check for overlapping fails
if( (sce = sc->data[type]) ) {
switch( type ) {
- case SC_MERC_FLEEUP:
- case SC_MERC_ATKUP:
- case SC_MERC_HPUP:
- case SC_MERC_SPUP:
- case SC_MERC_HITUP:
+ case SC_MER_FLEE:
+ case SC_MER_ATK:
+ case SC_MER_HP:
+ case SC_MER_SP:
+ case SC_MER_HIT:
if( sce->val1 > val1 )
val1 = sce->val1;
break;
case SC_ADRENALINE:
case SC_ADRENALINE2:
- case SC_WEAPONPERFECTION:
+ case SC_WEAPONPERFECT:
case SC_OVERTHRUST:
if (sce->val2 > val2)
return 0;
break;
case SC_S_LIFEPOTION:
case SC_L_LIFEPOTION:
- case SC_BOSSMAPINFO:
+ case SC_CASH_BOSS_ALARM:
case SC_STUN:
case SC_SLEEP:
case SC_POISON:
@@ -7098,13 +7173,13 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_SILENCE:
case SC_CONFUSION:
case SC_BLIND:
- case SC_BLEEDING:
+ case SC_BLOODING:
case SC_DPOISON:
- case SC_CLOSECONFINE2: //Can't be re-closed in.
+ case SC_RG_CCONFINE_S: //Can't be re-closed in.
+ case SC_MARIONETTE_MASTER:
case SC_MARIONETTE:
- case SC_MARIONETTE2:
case SC_NOCHAT:
- case SC_CHANGE: //Otherwise your Hp/Sp would get refilled while still within effect of the last invocation.
+ case SC_HLIF_CHANGE: //Otherwise your Hp/Sp would get refilled while still within effect of the last invocation.
case SC__INVISIBILITY:
case SC__ENERVATION:
case SC__GROOMY:
@@ -7113,17 +7188,17 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC__WEAKNESS:
case SC__UNLUCKY:
return 0;
- case SC_COMBO:
+ case SC_COMBOATTACK:
case SC_DANCING:
case SC_DEVOTION:
- case SC_ASPDPOTION0:
- case SC_ASPDPOTION1:
- case SC_ASPDPOTION2:
- case SC_ASPDPOTION3:
- case SC_ATKPOTION:
- case SC_MATKPOTION:
+ case SC_ATTHASTE_POTION1:
+ case SC_ATTHASTE_POTION2:
+ case SC_ATTHASTE_POTION3:
+ case SC_ATTHASTE_INFINITY:
+ case SC_PLUSATTACKPOWER:
+ case SC_PLUSMAGICPOWER:
case SC_ENCHANTARMS:
- case SC_ARMOR_ELEMENT:
+ case SC_ARMORPROPERTY:
case SC_ARMOR_RESIST:
break;
case SC_GOSPEL:
@@ -7153,7 +7228,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val3 = sce->val3;
val4 = sce->val4;
break;
- case SC_LERADSDEW:
+ case SC_LERADS_DEW:
if (sc && (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]))
return 0;
case SC_SHAPESHIFT:
@@ -7178,8 +7253,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
calc_flag = StatusChangeFlagTable[type];
if(!(flag&4)) { //&4 - Do not parse val settings when loading SCs
switch(type) {
- case SC_DECREASEAGI:
- case SC_INCREASEAGI:
+ case SC_DEC_AGI:
+ case SC_INC_AGI:
val2 = 2 + val1; //Agi change
break;
case SC_ENDURE:
@@ -7209,7 +7284,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
sc_start4(bl,SC_PROVOKE,100,10,1,0,0,60000);
tick = -1;
break;
- case SC_SIGNUMCRUCIS:
+ case SC_CRUCIS:
val2 = 10 + 4*val1; //Def reduction
tick = -1;
clif->emotion(bl,E_SWT);
@@ -7220,7 +7295,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_EDP: // [Celest]
val2 = val1 + 2; //Chance to Poison enemies.
- #ifndef RENEWAL_EDP
+ #ifdef RENEWAL_EDP
+ val3 = 50*(val1+3);
+ val4 = 100 * ((val1 + 1)/2 + 2);
+ #else
val3 = 50*(val1+1); //Damage increase (+50 +50*lv%)
#endif
if( sd )//[Ind] - iROwiki says each level increases its duration by 3 seconds
@@ -7247,18 +7325,18 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 5; //Lasts 5 hits
tick = -1;
break;
- case SC_ENCPOISON:
+ case SC_ENCHANTPOISON:
val2= 250+50*val1; //Poisoning Chance (2.5+0.5%) in 1/10000 rate
case SC_ASPERSIO:
- case SC_FIREWEAPON:
- case SC_WATERWEAPON:
- case SC_WINDWEAPON:
- case SC_EARTHWEAPON:
- case SC_SHADOWWEAPON:
- case SC_GHOSTWEAPON:
+ case SC_PROPERTYFIRE:
+ case SC_PROPERTYWATER:
+ case SC_PROPERTYWIND:
+ case SC_PROPERTYGROUND:
+ case SC_PROPERTYDARK:
+ case SC_PROPERTYTELEKINESIS:
skill->enchant_elemental_end(bl,type);
break;
- case SC_ELEMENTALCHANGE:
+ case SC_ARMOR_PROPERTY:
// val1 : Element Lvl (if called by skill lvl 1, takes random value between 1 and 4)
// val2 : Element (When no element, random one is picked)
// val3 : 0 = called by skill 1 = called by script (fixed level)
@@ -7291,19 +7369,19 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
status_change_start(&tsd->bl, type, 10000, val1, val2, 0, 0, tick, 1);
}
break;
- case SC_STRIPWEAPON:
+ case SC_NOEQUIPWEAPON:
if (!sd) //Watk reduction
val2 = 25;
break;
- case SC_STRIPSHIELD:
+ case SC_NOEQUIPSHIELD:
if (!sd) //Def reduction
val2 = 15;
break;
- case SC_STRIPARMOR:
+ case SC_NOEQUIPARMOR:
if (!sd) //Vit reduction
val2 = 40;
break;
- case SC_STRIPHELM:
+ case SC_NOEQUIPHELM:
if (!sd) //Int reduction
val2 = 40;
break;
@@ -7334,7 +7412,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 0;
#endif
break;
- case SC_SUITON:
+ case SC_NJ_SUITON:
if (!val2 || (sd && (sd->class_&MAPID_BASEMASK) == MAPID_NINJA)) {
//No penalties.
val2 = 0; //Agi penalty
@@ -7345,13 +7423,13 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 3*((val1+1)/3);
if (val1 > 4) val2--;
break;
- case SC_ONEHAND:
+ case SC_ONEHANDQUICKEN:
case SC_TWOHANDQUICKEN:
val2 = 300;
if (val1 > 10) //For boss casted skills [Skotlex]
val2 += 20*(val1-10);
break;
- case SC_MERC_QUICKEN:
+ case SC_MER_QUICKEN:
val2 = 300;
break;
#ifndef RENEWAL_ASPD
@@ -7365,24 +7443,28 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
//val3 : Brings the skill_lv (merged into val1 here)
//val4 : Partner
if (val1 == CG_MOONLIT)
- clif->status_change(bl,SI_MOONLIT,1,tick,0, 0, 0);
+ clif->status_change(bl,SI_MOON,1,tick,0, 0, 0);
val1|= (val3<<16);
val3 = tick/1000; //Tick duration
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_LONGING:
+ #ifdef RENEWAL
+ val2 = 50 + 10 * val1;
+ #else
val2 = 500-100*val1; //Aspd penalty.
+ #endif
break;
case SC_EXPLOSIONSPIRITS:
val2 = 75 + 25*val1; //Cri bonus
break;
- case SC_ASPDPOTION0:
- case SC_ASPDPOTION1:
- case SC_ASPDPOTION2:
- case SC_ASPDPOTION3:
- val2 = 50*(2+type-SC_ASPDPOTION0);
- break;
+ case SC_ATTHASTE_POTION1:
+ case SC_ATTHASTE_POTION2:
+ case SC_ATTHASTE_POTION3:
+ case SC_ATTHASTE_INFINITY:
+ val2 = 50*(2+type-SC_ATTHASTE_POTION1);
+ break;
case SC_WEDDING:
case SC_XMAS:
@@ -7407,7 +7489,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val3 = tick/1000; //Petrified HP-damage iterations.
if(val3 < 1) val3 = 1;
tick = val4; //Petrifying time.
- tick = max(tick, 1000); //Min time
+ if(val4 > 500) // not with WL_SIENNAEXECRATE
+ tick = max(tick, 1000); //Min time
calc_flag = 0; //Actual status changes take effect on petrified state.
break;
@@ -7439,7 +7522,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_CONFUSION:
clif->emotion(bl,E_WHAT);
break;
- case SC_BLEEDING:
+ case SC_BLOODING:
val4 = tick/10000;
if (!val4) val4 = 1;
tick_time = 10000; // [GodLesZ] tick time
@@ -7455,7 +7538,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val4 = 1;
tick_time = val2 * 1000; // [GodLesZ] tick time
break;
- case SC_BOSSMAPINFO:
+ case SC_CASH_BOSS_ALARM:
if( sd != NULL )
{
struct mob_data *boss_md = iMap->getmob_boss(bl->m); // Search for Boss on this Map
@@ -7479,7 +7562,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_CHASEWALK:
val2 = tick>0?tick:10000; //Interval at which SP is drained.
val3 = 35 - 5 * val1; //Speed adjustment.
- if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE)
+ if (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_ROGUE)
val3 -= 40;
val4 = 10+val1*2; //SP cost.
if (map_flag_gvg(bl->m) || map[bl->m].flag.battleground) val4 *= 5;
@@ -7500,24 +7583,24 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_SIGHT: /* splash status */
case SC_RUWACH:
- case SC_SIGHTBLASTER:
+ case SC_WZ_SIGHTBLASTER:
val3 = skill->get_splash(val2, val1); //Val2 should bring the skill-id.
val2 = tick/250;
tick_time = 10; // [GodLesZ] tick time
break;
//Permanent effects.
- case SC_AETERNA:
+ case SC_LEXAETERNA:
case SC_MODECHANGE:
- case SC_WEIGHT50:
- case SC_WEIGHT90:
+ case SC_WEIGHTOVER50:
+ case SC_WEIGHTOVER90:
case SC_BROKENWEAPON:
case SC_BROKENARMOR:
- case SC_READYSTORM:
- case SC_READYDOWN:
- case SC_READYCOUNTER:
- case SC_READYTURN:
- case SC_DODGE:
+ case SC_STORMKICK_READY:
+ case SC_DOWNKICK_READY:
+ case SC_COUNTERKICK_READY:
+ case SC_TURNKICK_READY:
+ case SC_DODGE_READY:
case SC_PUSH_CART:
case SC_ALL_RIDING:
tick = -1;
@@ -7591,7 +7674,7 @@ 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_BLEEDING,100,val1,val3,skill->get_time2(status_sc2skill(type),val1));
+ sc_start2(bl,SC_BLOODING,100,val1,val3,skill->get_time2(status_sc2skill(type),val1));
break;
case SC_BERSERK:
@@ -7614,7 +7697,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
break;
- case SC_MARIONETTE:
+ case SC_MARIONETTE_MASTER:
{
int stat;
@@ -7628,13 +7711,13 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
stat = ( sd ? sd->status.luk : status_get_base_status(bl)->luk ) / 2; val4 |= cap_value(stat,0,0xFF);
break;
}
- case SC_MARIONETTE2:
+ case SC_MARIONETTE:
{
int stat,max_stat;
// fetch caster information
struct block_list *pbl = iMap->id2bl(val1);
struct status_change *psc = pbl?status_get_sc(pbl):NULL;
- struct status_change_entry *psce = psc?psc->data[SC_MARIONETTE]:NULL;
+ struct status_change_entry *psce = psc?psc->data[SC_MARIONETTE_MASTER]:NULL;
// fetch target's stats
struct status_data* status = status_get_status_data(bl); // battle status
@@ -7652,7 +7735,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
stat = (psce->val4 >> 0)&0xFF; stat = min(stat, max_stat - status->luk ); val4 |= cap_value(stat,0,0xFF);
break;
}
- case SC_REJECTSWORD:
+ case SC_SWORDREJECT:
val2 = 15*val1; //Reflect chance
val3 = 3; //Reflections
tick = -1;
@@ -7667,7 +7750,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 50*val1; //aspd reduction
break;
- case SC_REGENERATION:
+ case SC_GDSKILL_REGENERATION:
if (val1 == 1)
val2 = 2;
else
@@ -7706,18 +7789,18 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
status_zap(bl, status->hp-1, val2?0:status->sp);
return 1;
break;
- case SC_CLOSECONFINE2:
+ case SC_RG_CCONFINE_S:
{
struct block_list *src = val2?iMap->id2bl(val2):NULL;
struct status_change *sc2 = src?status_get_sc(src):NULL;
- struct status_change_entry *sce2 = sc2?sc2->data[SC_CLOSECONFINE]:NULL;
+ struct status_change_entry *sce2 = sc2?sc2->data[SC_RG_CCONFINE_M]:NULL;
if (src && sc2) {
if (!sce2) //Start lock on caster.
- sc_start4(src,SC_CLOSECONFINE,100,val1,1,0,0,tick+1000);
+ sc_start4(src,SC_RG_CCONFINE_M,100,val1,1,0,0,tick+1000);
else { //Increase count of locked enemies and refresh time.
(sce2->val2)++;
iTimer->delete_timer(sce2->timer, status_change_timer);
- sce2->timer = iTimer->add_timer(iTimer->gettick()+tick+1000, status_change_timer, src->id, SC_CLOSECONFINE);
+ sce2->timer = iTimer->add_timer(iTimer->gettick()+tick+1000, status_change_timer, src->id, SC_RG_CCONFINE_M);
}
} else //Status failed.
return 0;
@@ -7742,7 +7825,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
break;
- case SC_COMBO: {
+ case SC_COMBOATTACK: {
//val1: Skill ID
//val2: When given, target (for autotargetting skills)
//val3: When set, this combo time should NOT delay attack/movement
@@ -7780,7 +7863,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (vd) vd->dead_sit = 1;
tick = -1;
break;
- case SC_CONCENTRATE:
+ case SC_CONCENTRATION:
val2 = 2 + val1;
if (sd) { //Store the card-bonus data that should not count in the %
val3 = sd->param_bonus[1]; //Agi
@@ -7789,7 +7872,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val3 = val4 = 0;
}
break;
- case SC_MAXOVERTHRUST:
+ case SC_OVERTHRUSTMAX:
val2 = 20*val1; //Power increase
break;
case SC_OVERTHRUST:
@@ -7801,14 +7884,15 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_ADRENALINE2:
case SC_ADRENALINE:
val3 = (val2) ? 300 : 200; // aspd increase
- case SC_WEAPONPERFECTION:
+ case SC_WEAPONPERFECT:
if(sd && pc->checkskill(sd,BS_HILTBINDING)>0)
tick += tick / 10;
break;
- case SC_CONCENTRATION:
+ case SC_LKCONCENTRATION:
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
break;
case SC_ANGELUS:
val2 = 5*val1; //def increase
@@ -7838,7 +7922,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
// gs_something1 [Vicious]
- case SC_GATLINGFEVER:
+ case SC_GS_GATLINGFEVER:
val2 = 20*val1; //Aspd increase
val3 = 20+10*val1; //Batk increase
val4 = 5*val1; //Flee decrease
@@ -7856,18 +7940,18 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val3 = 2+3*val1; //Atk increase
val4 = 5+5*val1; //Def reduction.
break;
- case SC_AVOID:
+ case SC_HLIF_AVOID:
//val2 = 10*val1; //Speed change rate.
break;
- case SC_DEFENCE:
+ case SC_HAMI_DEFENCE:
val2 = 2*val1; //Def bonus
break;
- case SC_BLOODLUST:
+ case SC_HAMI_BLOODLUST:
val2 = 20+10*val1; //Atk rate change.
val3 = 3*val1; //Leech chance
val4 = 20; //Leech percent
break;
- case SC_FLEET:
+ case SC_HLIF_FLEET:
val2 = 30*val1; //Aspd change
val3 = 5+5*val1; //bAtk/wAtk rate change
break;
@@ -7901,14 +7985,14 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
}
break;
- case SC_UTSUSEMI:
+ case SC_NJ_UTSUSEMI:
val2=(val1+1)/2; // number of hits blocked
val3=skill->get_blewcount(NJ_UTSUSEMI, val1); //knockback value.
break;
- case SC_BUNSINJYUTSU:
+ case SC_NJ_BUNSINJYUTSU:
val2=(val1+1)/2; // number of hits blocked
break;
- case SC_CHANGE:
+ case SC_HLIF_CHANGE:
val2= 30*val1; //Vit increase
val3= 20*val1; //Int increase
break;
@@ -7944,7 +8028,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 20*val1; //Magic reflection/cast rate
break;
- case SC_ARMORCHANGE:
+ case SC_STONESKIN:
if (val2 == NPC_ANTIMAGIC)
{ //Boost mdef
val2 =-20;
@@ -7956,32 +8040,32 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2*=val1; //20% per level
val3*=val1;
break;
- case SC_EXPBOOST:
- case SC_JEXPBOOST:
+ case SC_CASH_PLUSEXP:
+ case SC_CASH_PLUSONLYJOBEXP:
if (val1 < 0)
val1 = 0;
break;
- case SC_INCFLEE2:
- case SC_INCCRI:
+ case SC_PLUSAVOIDVALUE:
+ case SC_CRITICALPERCENT:
val2 = val1*10; //Actual boost (since 100% = 1000)
break;
case SC_SUFFRAGIUM:
val2 = 15 * val1; //Speed cast decrease
break;
- case SC_INCHEALRATE:
+ case SC_HEALPLUS:
if (val1 < 1)
val1 = 1;
break;
- case SC_HALLUCINATION:
+ case SC_ILLUSION:
val2 = 5+val1; //Factor by which displayed damage is increased by
break;
- case SC_DOUBLECAST:
+ case SC_DOUBLECASTING:
val2 = 30+10*val1; //Trigger rate
break;
case SC_KAIZEL:
val2 = 10*val1; //% of life to be revived with
break;
- // case SC_ARMOR_ELEMENT:
+ // case SC_ARMORPROPERTY:
// case SC_ARMOR_RESIST:
// Mod your resistance against elements:
// val1 = water | val2 = earth | val3 = fire | val4 = wind
@@ -7991,13 +8075,13 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
//associated, and yet are not wrong/unknown. [Skotlex]
//break;
- case SC_MERC_FLEEUP:
- case SC_MERC_ATKUP:
- case SC_MERC_HITUP:
+ case SC_MER_FLEE:
+ case SC_MER_ATK:
+ case SC_MER_HIT:
val2 = 15 * val1;
break;
- case SC_MERC_HPUP:
- case SC_MERC_SPUP:
+ case SC_MER_HP:
+ case SC_MER_SP:
val2 = 5 * val1;
break;
case SC_REBIRTH:
@@ -8023,8 +8107,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
tick_time = 1000; // [GodLesZ] tick time
break;
case SC_BURNING:
- val4 = tick / 2000; // Total Ticks to Burn!!
- tick_time = 2000; // [GodLesZ] tick time
+ val4 = tick / 3000; // Total Ticks to Burn!!
+ tick_time = 3000; // [GodLesZ] tick time
break;
/**
* Rune Knight
@@ -8110,24 +8194,27 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_WHITEIMPRISON:
status_change_end(bl, SC_BURNING, INVALID_TIMER);
- status_change_end(bl, SC_FREEZING, INVALID_TIMER);
+ status_change_end(bl, SC_FROSTMISTY, INVALID_TIMER);
status_change_end(bl, SC_FREEZE, INVALID_TIMER);
status_change_end(bl, SC_STONE, INVALID_TIMER);
break;
- case SC_FREEZING:
+ case SC_MARSHOFABYSS:
+ val2 = 6 * val1;
+ if( sd ) // half on players
+ val2 >>= 1;
+ break;
+ case SC_FROSTMISTY:
status_change_end(bl, SC_BURNING, INVALID_TIMER);
break;
case SC_READING_SB:
// val2 = sp reduction per second
tick_time = 5000; // [GodLesZ] tick time
break;
- case SC_SPHERE_1:
- case SC_SPHERE_2:
- case SC_SPHERE_3:
- case SC_SPHERE_4:
- case SC_SPHERE_5:
- if( !sd )
- return 0; // Should only work on players.
+ case SC_SUMMON1:
+ case SC_SUMMON2:
+ case SC_SUMMON3:
+ case SC_SUMMON4:
+ case SC_SUMMON5:
val4 = tick / 1000;
if( val4 < 1 )
val4 = 1;
@@ -8168,7 +8255,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
tick_time = 1000; // [GodLesZ] tick time
}
break;
- case SC__STRIPACCESSORY:
+ case SC__STRIPACCESSARY:
if (!sd)
val2 = 20;
break;
@@ -8212,8 +8299,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 10 * val1;
val_flag |= 1|2;
// bypasses coating protection and MADO
- sc_start(bl,SC_STRIPWEAPON,100,val1,tick);
- sc_start(bl,SC_STRIPSHIELD,100,val1,tick);
+ sc_start(bl,SC_NOEQUIPWEAPON,100,val1,tick);
+ sc_start(bl,SC_NOEQUIPSHIELD,100,val1,tick);
break;
break;
case SC_GN_CARTBOOST:
@@ -8230,7 +8317,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_WARMER:
status_change_end(bl, SC_FREEZE, INVALID_TIMER);
- status_change_end(bl, SC_FREEZING, INVALID_TIMER);
+ status_change_end(bl, SC_FROSTMISTY, INVALID_TIMER);
status_change_end(bl, SC_CRYSTALIZE, INVALID_TIMER);
break;
case SC_STRIKING:
@@ -8238,36 +8325,42 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val4 = tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
- case SC_BLOODSUCKER:
- val4 = tick / 1000;
- tick_time = 1000; // [GodLesZ] tick time
+ case SC_BLOOD_SUCKER:
+ {
+ struct block_list *src = iMap->id2bl(sce->val2);
+ val3 = 1;
+ if(src)
+ val3 = 200 + 100 * sce->val1 + status_get_int(src);
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ }
break;
case SC_VACUUM_EXTREME:
tick -= (status->str / 20) * 1000;
val4 = val3 = tick / 100;
tick_time = 100; // [GodLesZ] tick time
break;
- case SC_SWINGDANCE:
+ case SC_SWING:
val2 = 4 * val1; // Walk speed and aspd reduction.
break;
- case SC_SYMPHONYOFLOVER:
- case SC_RUSHWINDMILL:
+ case SC_SYMPHONY_LOVE:
+ 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
break;
- case SC_MOONLITSERENADE:
+ case SC_MOONLIT_SERENADE:
val2 = 10 * val1;
break;
case SC_HARMONIZE:
val2 = 5 + 5 * val1;
break;
- case SC_VOICEOFSIREN:
+ case SC_SIREN:
val4 = tick / 2000;
tick_time = 2000; // [GodLesZ] tick time
break;
- case SC_DEEPSLEEP:
+ case SC_DEEP_SLEEP:
val4 = tick / 2000;
tick_time = 2000; // [GodLesZ] tick time
break;
@@ -8277,12 +8370,12 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val4 = tick / 1000;
tick_time = 1000; // [GodLesZ] tick time
break;
- case SC_SONGOFMANA:
+ case SC_SONG_OF_MANA:
val3 = 10 + (2 * val2);
val4 = tick/3000;
tick_time = 3000; // [GodLesZ] tick time
break;
- case SC_SATURDAYNIGHTFEVER:
+ case SC_SATURDAY_NIGHT_FEVER:
if (!val4) val4 = skill->get_time2(status_sc2skill(type),val1);
if (!val4) val4 = 3000;
val3 = tick/val4;
@@ -8302,7 +8395,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 15 + rand()%( (sd?pc->checkskill(sd, WM_LESSON)*5:0) + val1*10 );
break;
case SC_SITDOWN_FORCE:
- case SC_BANANA_BOMB_SITDOWN:
+ case SC_BANANA_BOMB_SITDOWN_POSTDELAY:
if( sd && !pc_issit(sd) )
{
pc_setsit(sd);
@@ -8310,19 +8403,19 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
clif->sitting(bl);
}
break;
- case SC_DANCEWITHWUG:
+ case SC_DANCE_WITH_WUG:
val3 = (5 * val1) + (1 * val2); //Still need official value.
break;
- case SC_LERADSDEW:
+ case SC_LERADS_DEW:
val3 = (5 * val1) + (1 * val2);
break;
case SC_MELODYOFSINK:
val3 = (5 * val1) + (1 * val2);
break;
- case SC_BEYONDOFWARCRY:
+ case SC_BEYOND_OF_WARCRY:
val3 = (5 * val1) + (1 * val2);
break;
- case SC_UNLIMITEDHUMMINGVOICE:
+ case SC_UNLIMITED_HUMMING_VOICE:
{
struct unit_data *ud = unit_bl2ud(bl);
if( ud == NULL ) return 0;
@@ -8330,7 +8423,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val3 = 15 - (2 * val2);
}
break;
- case SC_REFLECTDAMAGE:
+ case SC_LG_REFLECTDAMAGE:
val2 = 15 + 5 * val1;
val3 = (val1==5)?20:(val1+4)*2; // SP consumption
val4 = tick/10000;
@@ -8398,15 +8491,17 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val3 = tick / 5000;
tick_time = 5000; // [GodLesZ] tick time
break;
- case SC_GT_CHANGE:
+ case SC_GENTLETOUCH_CHANGE:
{// take note there is no def increase as skill desc says. [malufett]
struct block_list * src;
val3 = status->agi * val1 / 60; // ASPD increase: [(Target AGI x Skill Level) / 60] %
- if( (src = iMap->id2bl(val2)) )
+ if( (src = iMap->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]
+ }
}
break;
- case SC_GT_REVITALIZE:
+ case SC_GENTLETOUCH_REVITALIZE:
{// take note there is no vit,aspd,speed increase as skill desc says. [malufett]
struct block_list * src;
val3 = val1 * 30 + 150; // Natural HP recovery increase: [(Skill Level x 30) + 50] %
@@ -8519,8 +8614,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
tick_time = 10000; // [GodLesZ] tick time
break;
case SC_KYOUGAKU:
- val2 = 2*val1 + rand()%val1;
- clif->status_change(bl,SI_ACTIVE_MONSTER_TRANSFORM,1,0,1002,0,0);
+ val2 = 2*val1 + rand()%(3 * val1);
+ clif->status_change(bl, SI_ACTIVE_MONSTER_TRANSFORM, 1, 0, 1002, 0, 0); // Poring in disguise
break;
case SC_KAGEMUSYA:
val3 = val1 * 2;
@@ -8529,80 +8624,100 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
tick_time = 1000;
break;
case SC_ZANGETSU:
- if( (status_get_hp(bl)+status_get_sp(bl)) % 2 == 0)
- val2 = status_get_lv(bl) / 2 + 50;
- else
- val2 -= 50;
+ val2 = status_get_lv(bl) / 3 + 20 * val1;
+ val3 = status_get_lv(bl) / 2 + 30 * val1;
+ val2 = (!(status_get_hp(bl)%2) ? val2 : -val3);
+ val3 = (!(status_get_sp(bl)%2) ? val2 : -val3);
break;
case SC_GENSOU:
{
- int hp = status_get_hp(bl), lv = 5;
- short per = 100 / (status_get_max_hp(bl) / hp);
-
- if( per <= 15 )
- lv = 1;
- else if( per <= 30 )
- lv = 2;
- else if( per <= 50 )
- lv = 3;
- else if( per <= 75 )
- lv = 4;
- if( hp % 2 == 0)
- status_heal(bl, hp * (6-lv) * 4 / 100, status_get_sp(bl) * (6-lv) * 3 / 100, 1);
- else
- status_zap(bl, hp * (lv*4) / 100, status_get_sp(bl) * (lv*3) / 100);
+ int hp = status_get_hp(bl), sp = status_get_sp(bl), lv = 5;
+ #define PER( a ) { if( a <= 15 )lv = 1;else if( a <= 30 )lv = 2;else if( a <= 50 )lv = 3;else if( a <= 75 )lv = 4;}
+
+ if( rand()%100 > (25 + 10 * val1) - status_get_int(bl) / 2)
+ return 0;
+
+ PER( 100 / (status_get_max_hp(bl) / hp) );
+ status_heal(bl, (!(hp%2) ? (6-lv) *4 / 100 : -(lv*4) / 100), 0, 1);
+
+ PER( 100 / (status_get_max_sp(bl) / sp) );
+ status_heal(bl, 0,(!(sp%2) ? (6-lv) *3 / 100 : -(lv*3) / 100), 1);
}
break;
- case SC_ANGRIFFS_MODUS:
- val2 = 50 + 20 * val1; //atk bonus
- val3 = 40 + 20 * val1; // Flee reduction.
- val4 = tick/1000; // hp/sp reduction timer
- tick_time = 1000;
- break;
- case SC_NEUTRALBARRIER:
- tick_time = tick;
- tick = -1;
- break;
- case SC_GOLDENE_FERSE:
- val2 = 10 + 10*val1; //max hp bonus
- val3 = 6 + 4 * val1; // Aspd Bonus
- val4 = 2 + 2 * val1; // Chance of holy attack
- break;
- case SC_OVERED_BOOST:
- val2 = 300 + 40*val1; //flee bonus
- val3 = 179 + 2*val1; //aspd bonus
- break;
- case SC_GRANITIC_ARMOR:
- val2 = 2*val1; //dmg reduction
- val3 = 6*val1; //dmg on status end
- break;
- case SC_MAGMA_FLOW:
- val2 = 3*val1; //activation chance
- break;
- case SC_PYROCLASTIC:
- val2 += 10*val1; //atk bonus
- break;
- case SC_PARALYSIS: //[Lighta] need real info
- val2 = 2*val1; //def reduction
- val3 = 500*val1; //varcast augmentation
- break;
- case SC_PAIN_KILLER: //[Lighta] need real info
- val2 = 2*val1; //aspd reduction %
- val3 = 2*val1; //dmg reduction %
- if(sc->data[SC_PARALYSIS])
- sc_start(bl, SC_ENDURE, 100, val1, tick); //start endure for same duration
- break;
- case SC_STYLE_CHANGE: //[Lighta] need real info
- tick = -1;
- if(val2 == MH_MD_FIGHTING) val2 = MH_MD_GRAPPLING;
- else val2 = MH_MD_FIGHTING;
- break;
- default:
- if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 )
- { //Status change with no calc, no icon, and no skill associated...?
- ShowError("UnknownStatusChange [%d]\n", type);
- return 0;
- }
+ case SC_ANGRIFFS_MODUS:
+ val2 = 50 + 20 * val1; //atk bonus
+ val3 = 40 + 20 * val1; // Flee reduction.
+ val4 = tick/1000; // hp/sp reduction timer
+ tick_time = 1000;
+ break;
+ case SC_NEUTRALBARRIER:
+ tick_time = tick;
+ tick = -1;
+ break;
+ case SC_GOLDENE_FERSE:
+ val2 = 10 + 10*val1; //max hp bonus
+ val3 = 6 + 4 * val1; // Aspd Bonus
+ val4 = 2 + 2 * val1; // Chance of holy attack
+ break;
+ case SC_OVERED_BOOST:
+ val2 = 300 + 40*val1; //flee bonus
+ val3 = 179 + 2*val1; //aspd bonus
+ break;
+ case SC_GRANITIC_ARMOR:
+ val2 = 2*val1; //dmg reduction
+ val3 = 6*val1; //dmg on status end
+ break;
+ case SC_MAGMA_FLOW:
+ val2 = 3*val1; //activation chance
+ break;
+ case SC_PYROCLASTIC:
+ val2 += 10*val1; //atk bonus
+ break;
+ case SC_NEEDLE_OF_PARALYZE: //[Lighta] need real info
+ val2 = 2*val1; //def reduction
+ val3 = 500*val1; //varcast augmentation
+ break;
+ case SC_PAIN_KILLER: //[Lighta] need real info
+ 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
+ break;
+ case SC_STYLE_CHANGE: //[Lighta] need real info
+ tick = -1;
+ if(val2 == MH_MD_FIGHTING) val2 = MH_MD_GRAPPLING;
+ else val2 = MH_MD_FIGHTING;
+ break;
+ case SC_FULL_THROTTLE:
+ status_percent_heal(bl,100,0);
+ val2 = 7 - val1;
+ tick_time = 1000;
+ val4 = tick / tick_time;
+ break;
+ case SC_KINGS_GRACE:
+ val2 = 3 + val1;
+ tick_time = 1000;
+ val4 = tick / tick_time;
+ break;
+ case SC_TELEKINESIS_INTENSE:
+ val2 = 10 * val1;
+ val3 = 40 * val1;
+ break;
+ case SC_OFFERTORIUM:
+ val2 = 30 * val1;
+ break;
+ case SC_FRIGG_SONG:
+ val2 = 5 * val1;
+ val3 = 1000 + 100 * val1;
+ tick_time = 10000;
+ val4 = tick / tick_time;
+ break;
+ default:
+ if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 )
+ { //Status change with no calc, no icon, and no skill associated...?
+ ShowError("UnknownStatusChange [%d]\n", type);
+ return 0;
+ }
}
} else { //Special considerations when loading SC data.
switch( type ) {
@@ -8619,6 +8734,13 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_KAAHI:
val4 = INVALID_TIMER;
break;
+ case SC_SUMMON1:
+ case SC_SUMMON2:
+ case SC_SUMMON3:
+ case SC_SUMMON4:
+ case SC_SUMMON5:
+ val_flag |= 1;
+ break;
}
}
@@ -8642,7 +8764,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_STUN:
case SC_SLEEP:
case SC_STONE:
- case SC_DEEPSLEEP:
+ case SC_DEEP_SLEEP:
if (sd && pc_issit(sd)) //Avoid sprite sync problems.
pc->setstand(sd);
case SC_TRICKDEAD:
@@ -8654,12 +8776,12 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
unit_stop_attack(bl);
case SC_STOP:
case SC_CONFUSION:
- case SC_CLOSECONFINE:
- case SC_CLOSECONFINE2:
+ case SC_RG_CCONFINE_M:
+ case SC_RG_CCONFINE_S:
case SC_SPIDERWEB:
case SC_ELECTRICSHOCKER:
- case SC_BITE:
- case SC_THORNSTRAP:
+ case SC_WUGBITE:
+ case SC_THORNS_TRAP:
case SC__MANHOLE:
case SC_CRYSTALIZE:
case SC_CURSEDCIRCLE_ATKER:
@@ -8668,10 +8790,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_NETHERWORLD:
case SC_MEIKYOUSISUI:
case SC_KYOUGAKU:
- case SC_PARALYSIS:
+ case SC_NEEDLE_OF_PARALYZE:
+ case SC_DEATHBOUND:
unit_stop_walking(bl,1);
break;
- case SC_ANKLE:
+ case SC_ANKLESNARE:
if( battle_config.skill_trap_type || !map_flag_gvg(bl->m) )
unit_stop_walking(bl,1);
break;
@@ -8679,9 +8802,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_CLOAKING:
case SC_CLOAKINGEXCEED:
case SC_CHASEWALK:
- case SC_WEIGHT90:
+ case SC_WEIGHTOVER90:
case SC_CAMOUFLAGE:
- case SC_VOICEOFSIREN:
+ case SC_SIREN:
unit_stop_attack(bl);
break;
case SC_SILENCE:
@@ -8697,7 +8820,7 @@ 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_DEEPSLEEP: opt_flag = 0;
+ 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;
@@ -8707,24 +8830,24 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_CURSE: sc->opt2 |= OPT2_CURSE; break;
case SC_SILENCE: sc->opt2 |= OPT2_SILENCE; break;
- case SC_SIGNUMCRUCIS:
+ case SC_CRUCIS:
sc->opt2 |= OPT2_SIGNUMCRUCIS;
break;
case SC_BLIND: sc->opt2 |= OPT2_BLIND; break;
case SC_ANGELUS: sc->opt2 |= OPT2_ANGELUS; break;
- case SC_BLEEDING: sc->opt2 |= OPT2_BLEEDING; break;
+ case SC_BLOODING: sc->opt2 |= OPT2_BLEEDING; break;
case SC_DPOISON: sc->opt2 |= OPT2_DPOISON; break;
//OPT3
case SC_TWOHANDQUICKEN:
- case SC_ONEHAND:
+ case SC_ONEHANDQUICKEN:
case SC_SPEARQUICKEN:
- case SC_CONCENTRATION:
- case SC_MERC_QUICKEN:
+ case SC_LKCONCENTRATION:
+ case SC_MER_QUICKEN:
sc->opt3 |= OPT3_QUICKEN;
opt_flag = 0;
break;
- case SC_MAXOVERTHRUST:
+ case SC_OVERTHRUSTMAX:
case SC_OVERTHRUST:
case SC_SWOO: //Why does it shares the same opt as Overthrust? Perhaps we'll never know...
sc->opt3 |= OPT3_OVERTHRUST;
@@ -8772,8 +8895,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
sc->opt3 |= OPT3_MOONLIT;
opt_flag = 0;
break;
+ case SC_MARIONETTE_MASTER:
case SC_MARIONETTE:
- case SC_MARIONETTE2:
sc->opt3 |= OPT3_MARIONETTE;
opt_flag = 0;
break;
@@ -8789,15 +8912,15 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
sc->opt3 |= OPT3_KAITE;
opt_flag = 0;
break;
- case SC_BUNSINJYUTSU:
+ case SC_NJ_BUNSINJYUTSU:
sc->opt3 |= OPT3_BUNSIN;
opt_flag = 0;
break;
- case SC_SPIRIT:
+ case SC_SOULLINK:
sc->opt3 |= OPT3_SOULLINK;
opt_flag = 0;
break;
- case SC_CHANGEUNDEAD:
+ case SC_PROPERTYUNDEAD:
sc->opt3 |= OPT3_UNDEAD;
opt_flag = 0;
break;
@@ -8911,7 +9034,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
}
sce->val2 = 5 * status->max_hp / 100;
break;
- case SC_CHANGE:
+ case SC_HLIF_CHANGE:
status_percent_heal(bl, 100, 100);
break;
case SC_RUN:
@@ -8921,13 +9044,13 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
ud->state.running = unit_run(bl);
}
break;
- case SC_BOSSMAPINFO:
+ case SC_CASH_BOSS_ALARM:
clif->bossmapinfo(sd->fd, iMap->id2boss(sce->val1), 0); // First Message
break;
- case SC_MERC_HPUP:
+ case SC_MER_HP:
status_percent_heal(bl, 100, 0); // Recover Full HP
break;
- case SC_MERC_SPUP:
+ case SC_MER_SP:
status_percent_heal(bl, 0, 100); // Recover Full SP
break;
/**
@@ -8940,7 +9063,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
ud->state.running = unit_wugdash(bl, sd);
}
break;
- case SC_COMBO:
+ case SC_COMBOATTACK:
switch (sce->val1) {
case TK_STORMKICK:
clif->skill_nodamage(bl,bl,TK_READYSTORM,1,1);
@@ -9008,68 +9131,25 @@ int status_change_clear(struct block_list* bl, int type) {
for(i = 0; i < SC_MAX; i++) {
if(!sc->data[i])
continue;
-
- if(type == 0) {
- switch (i) { //Type 0: PC killed -> Place here statuses that do not dispel on death.
- case SC_ELEMENTALCHANGE://Only when its Holy or Dark that it doesn't dispell on death
- if( sc->data[i]->val2 != ELE_HOLY && sc->data[i]->val2 != ELE_DARK )
- break;
- case SC_WEIGHT50:
- case SC_WEIGHT90:
- case SC_EDP:
- case SC_MELTDOWN:
- case SC_XMAS:
- case SC_SUMMER:
- case SC_HANBOK:
- case SC_NOCHAT:
- case SC_FUSION:
- case SC_EARTHSCROLL:
- case SC_READYSTORM:
- case SC_READYDOWN:
- case SC_READYCOUNTER:
- case SC_READYTURN:
- case SC_DODGE:
- case SC_JAILED:
- case SC_EXPBOOST:
- case SC_ITEMBOOST:
- case SC_HELLPOWER:
- case SC_JEXPBOOST:
- case SC_AUTOTRADE:
- case SC_WHISTLE:
- case SC_ASSNCROS:
- case SC_POEMBRAGI:
- case SC_APPLEIDUN:
- case SC_HUMMING:
- case SC_DONTFORGETME:
- case SC_FORTUNE:
- case SC_SERVICE4U:
- case SC_FOOD_STR_CASH:
- case SC_FOOD_AGI_CASH:
- case SC_FOOD_VIT_CASH:
- case SC_FOOD_DEX_CASH:
- case SC_FOOD_INT_CASH:
- case SC_FOOD_LUK_CASH:
- case SC_DEF_RATE:
- case SC_MDEF_RATE:
- case SC_INCHEALRATE:
- case SC_INCFLEE2:
- case SC_INCHIT:
- case SC_ATKPOTION:
- case SC_MATKPOTION:
- case SC_S_LIFEPOTION:
- case SC_L_LIFEPOTION:
- case SC_PUSH_CART:
- case SC_ALL_RIDING:
- continue;
+
+ if(type == 0){
+ if( status_get_sc_type(i)&SC_NO_REM_DEATH ){
+ switch (i) {
+ case SC_ARMOR_PROPERTY://Only when its Holy or Dark that it doesn't dispell on death
+ if( sc->data[i]->val2 != ELE_HOLY && sc->data[i]->val2 != ELE_DARK )
+ break;
+ default:
+ continue;
+ }
}
}
-
if( type == 3 ) {
switch (i) {// TODO: This list may be incomplete
- case SC_WEIGHT50:
- case SC_WEIGHT90:
+ case SC_WEIGHTOVER50:
+ case SC_WEIGHTOVER90:
case SC_NOCHAT:
case SC_PUSH_CART:
+ case SC_JAILED:
case SC_ALL_RIDING:
continue;
}
@@ -9094,6 +9174,7 @@ int status_change_clear(struct block_list* bl, int type) {
#ifndef RENEWAL
sc->sg_counter = 0;
#endif
+
if( type == 0 || type == 2 )
clif->changeoption(bl);
@@ -9188,7 +9269,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
DIFF_TICK(iTimer->gettick(), sce->val4) <= 1000 &&
(!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0))
)
- sc_start(bl,SC_SPURT,100,sce->val1,skill->get_time2(status_sc2skill(type), sce->val1));
+ sc_start(bl,SC_STRUP,100,sce->val1,skill->get_time2(status_sc2skill(type), sce->val1));
}
break;
case SC_AUTOBERSERK:
@@ -9307,7 +9388,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
if((sce->val1&0xFFFF) == CG_MOONLIT)
- clif->sc_end(bl,bl->id,AREA,SI_MOONLIT);
+ clif->sc_end(bl,bl->id,AREA,SI_MOON);
status_change_end(bl, SC_LONGING, INVALID_TIMER);
}
@@ -9328,18 +9409,18 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
skill->castend_damage_id(src, bl, sce->val2, sce->val1, iTimer->gettick(), SD_LEVEL );
}
break;
- case SC_CLOSECONFINE2:
+ case SC_RG_CCONFINE_S:
{
struct block_list *src = sce->val2?iMap->id2bl(sce->val2):NULL;
struct status_change *sc2 = src?status_get_sc(src):NULL;
- if (src && sc2 && sc2->data[SC_CLOSECONFINE]) {
+ if (src && sc2 && sc2->data[SC_RG_CCONFINE_M]) {
//If status was already ended, do nothing.
//Decrease count
- if (--(sc2->data[SC_CLOSECONFINE]->val1) <= 0) //No more holds, free him up.
- status_change_end(src, SC_CLOSECONFINE, INVALID_TIMER);
+ if (--(sc2->data[SC_RG_CCONFINE_M]->val1) <= 0) //No more holds, free him up.
+ status_change_end(src, SC_RG_CCONFINE_M, INVALID_TIMER);
}
}
- case SC_CLOSECONFINE:
+ case SC_RG_CCONFINE_M:
if (sce->val2 > 0) {
//Caster has been unlocked... nearby chars need to be unlocked.
int range = 1
@@ -9349,7 +9430,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,iTimer->gettick());
}
break;
- case SC_COMBO:
+ case SC_COMBOATTACK:
if( sd )
switch (sce->val1) {
case MO_COMBOFINISH:
@@ -9371,11 +9452,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
break;
- case SC_MARIONETTE:
- case SC_MARIONETTE2: /// Marionette target
+ case SC_MARIONETTE_MASTER:
+ case SC_MARIONETTE: /// Marionette target
if (sce->val1)
{ // check for partner and end their marionette status as well
- enum sc_type type2 = (type == SC_MARIONETTE) ? SC_MARIONETTE2 : SC_MARIONETTE;
+ enum sc_type type2 = (type == SC_MARIONETTE_MASTER) ? SC_MARIONETTE : SC_MARIONETTE_MASTER;
struct block_list *pbl = iMap->id2bl(sce->val1);
struct status_change* sc2 = pbl?status_get_sc(pbl):NULL;
@@ -9388,7 +9469,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
break;
case SC_BERSERK:
- case SC_SATURDAYNIGHTFEVER:
+ case SC_SATURDAY_NIGHT_FEVER:
//If val2 is removed, no HP penalty (dispelled?) [Skotlex]
if (status->hp > 100 && sce->val2)
status_set_hp(bl, 100, 0);
@@ -9398,8 +9479,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
status_change_end(bl, SC_ENDURE, INVALID_TIMER);
}
case SC__BLOODYLUST:
- sc_start4(bl, SC_REGENERATION, 100, 10,0,0,(RGN_HP|RGN_SP), skill->get_time(LK_BERSERK, sce->val1));
- if( type == SC_SATURDAYNIGHTFEVER ) //Sit down force of Saturday Night Fever has the duration of only 3 seconds.
+ sc_start4(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));
break;
case SC_GOSPEL:
@@ -9440,7 +9521,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
if(sd && sd->mapindex == sce->val2)
pc->setpos(sd,(unsigned short)sce->val3,sce->val4&0xFFFF, sce->val4>>16, CLR_TELEPORT);
break; //guess hes not in jail :P
- case SC_CHANGE:
+ case SC_HLIF_CHANGE:
if (tid == INVALID_TIMER)
break;
// "lose almost all their HP and SP" on natural expiration.
@@ -9466,6 +9547,9 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
status_change_end(tbl, SC_STOP, INVALID_TIMER);
}
break;
+ case SC_LKCONCENTRATION:
+ status_change_end(bl, SC_ENDURE, INVALID_TIMER);
+ break;
/**
* 3rd Stuff
**/
@@ -9552,7 +9636,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
}
break;
- case SC_BLOODSUCKER:
+ case SC_BLOOD_SUCKER:
if( sce->val2 ){
struct block_list *src = iMap->id2bl(sce->val2);
if(src){
@@ -9565,10 +9649,13 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
clif->sc_end(&sd->bl,sd->bl.id,AREA,SI_KYOUGAKU);
clif->sc_end(&sd->bl,sd->bl.id,AREA,SI_ACTIVE_MONSTER_TRANSFORM);
break;
- case SC_INTRAVISION:
+ case SC_CLAIRVOYANCE:
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));
+ break;
+ }
opt_flag = 1;
switch(type){
@@ -9576,7 +9663,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
case SC_FREEZE:
case SC_STUN:
case SC_SLEEP:
- case SC_DEEPSLEEP:
+ case SC_DEEP_SLEEP:
case SC_BURNING:
case SC_WHITEIMPRISON:
case SC_CRYSTALIZE:
@@ -9592,7 +9679,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
case SC_DPOISON:
sc->opt2 &= ~OPT2_DPOISON;
break;
- case SC_SIGNUMCRUCIS:
+ case SC_CRUCIS:
sc->opt2 &= ~OPT2_SIGNUMCRUCIS;
break;
@@ -9641,15 +9728,15 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
break;
//opt3
case SC_TWOHANDQUICKEN:
- case SC_ONEHAND:
+ case SC_ONEHANDQUICKEN:
case SC_SPEARQUICKEN:
case SC_CONCENTRATION:
- case SC_MERC_QUICKEN:
+ case SC_MER_QUICKEN:
sc->opt3 &= ~OPT3_QUICKEN;
opt_flag = 0;
break;
case SC_OVERTHRUST:
- case SC_MAXOVERTHRUST:
+ case SC_OVERTHRUSTMAX:
case SC_SWOO:
sc->opt3 &= ~OPT3_OVERTHRUST;
if( type == SC_SWOO )
@@ -9700,7 +9787,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
opt_flag = 0;
break;
case SC_MARIONETTE:
- case SC_MARIONETTE2:
+ case SC_MARIONETTE_MASTER:
sc->opt3 &= ~OPT3_MARIONETTE;
opt_flag = 0;
break;
@@ -9716,15 +9803,15 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
sc->opt3 &= ~OPT3_KAITE;
opt_flag = 0;
break;
- case SC_BUNSINJYUTSU:
+ case SC_NJ_BUNSINJYUTSU:
sc->opt3 &= ~OPT3_BUNSIN;
opt_flag = 0;
break;
- case SC_SPIRIT:
+ case SC_SOULLINK:
sc->opt3 &= ~OPT3_SOULLINK;
opt_flag = 0;
break;
- case SC_CHANGEUNDEAD:
+ case SC_PROPERTYUNDEAD:
sc->opt3 &= ~OPT3_UNDEAD;
opt_flag = 0;
break;
@@ -9861,9 +9948,9 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
if(!status_charge(bl, 0, sce->val4))
break; //Not enough SP to continue.
- if (!sc->data[SC_INCSTR]) {
- sc_start(bl, SC_INCSTR,100,1<<(sce->val1-1),
- (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE?10:1) //SL bonus -> x10 duration
+ if (!sc->data[SC_CHASEWALK2]) {
+ sc_start(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));
}
sc_timer_next(sce->val2+tick, status_change_timer, bl->id, data);
@@ -9891,8 +9978,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
case SC_SIGHT:
case SC_RUWACH:
- case SC_SIGHTBLASTER:
- if(type == SC_SIGHTBLASTER)
+ case SC_WZ_SIGHTBLASTER:
+ if(type == SC_WZ_SIGHTBLASTER)
iMap->foreachinrange( status_change_timer_sub, bl, sce->val3, BL_CHAR|BL_SKILL, bl, sce, type, tick);
else
iMap->foreachinrange( status_change_timer_sub, bl, sce->val3, BL_CHAR, bl, sce, type, tick);
@@ -9970,7 +10057,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
- case SC_BLEEDING:
+ case SC_BLOODING:
if (--(sce->val4) >= 0) {
int hp = rnd()%600 + 200;
struct block_list* src = iMap->id2bl(sce->val2);
@@ -10005,7 +10092,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
- case SC_BOSSMAPINFO:
+ case SC_CASH_BOSS_ALARM:
if( sd && --(sce->val4) >= 0 )
{
struct mob_data *boss_md = iMap->id2boss(sce->val1);
@@ -10112,8 +10199,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
+ case SC_MARIONETTE_MASTER:
case SC_MARIONETTE:
- case SC_MARIONETTE2:
{
struct block_list *pbl = iMap->id2bl(sce->val1);
if( pbl && check_distance_bl(bl, pbl, 7) )
@@ -10160,7 +10247,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_PYREXIA:
- if( --(sce->val4) >= 0 ) {
+ if( --(sce->val4) > 0 ) {
iMap->freeblock_lock();
clif->damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,0,0);
status_fix_damage(NULL,bl,100,0);
@@ -10173,7 +10260,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_LEECHESEND:
- if( --(sce->val4) >= 0 ) {
+ if( --(sce->val4) > 0 ) {
int damage = status->max_hp/100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100)
damage += status->vit * (sce->val1 - 3);
unit_skillcastcancel(bl,2);
@@ -10188,7 +10275,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_MAGICMUSHROOM:
- if( --(sce->val4) >= 0 ) {
+ if( --(sce->val4) > 0 ) {
bool flag = 0;
int damage = status->max_hp * 3 / 100;
if( status->hp <= damage )
@@ -10233,7 +10320,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_TOXIN:
- if( --(sce->val4) >= 0 )
+ if( --(sce->val4) > 0 )
{ //Damage is every 10 seconds including 3%sp drain.
iMap->freeblock_lock();
clif->damage(bl,bl,tick,status_get_amotion(bl),1,1,0,0,0);
@@ -10247,7 +10334,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_OBLIVIONCURSE:
- if( --(sce->val4) >= 0 )
+ if( --(sce->val4) > 0 )
{
clif->emotion(bl,E_WHAT);
sc_timer_next(3000 + tick, status_change_timer, bl->id, data );
@@ -10256,7 +10343,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_WEAPONBLOCKING:
- if( --(sce->val4) >= 0 )
+ if( --(sce->val4) > 0 )
{
if( !status_charge(bl,0,3) )
break;
@@ -10272,7 +10359,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
return 0;
case SC_RENOVATIO:
- if( --(sce->val4) >= 0 )
+ if( --(sce->val4) > 0 )
{
int heal = status->max_hp * 3 / 100;
if( sc && sc->data[SC_AKAITSUKI] && heal )
@@ -10284,7 +10371,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_BURNING:
- if( --(sce->val4) >= 0 )
+ if( --(sce->val4) > 0 )
{
struct block_list *src = iMap->id2bl(sce->val3);
int damage = 1000 + 3 * status_get_max_hp(bl) / 100; // Deals fixed (1000 + 3%*MaxHP)
@@ -10294,7 +10381,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
status_damage(src, bl, damage, 0, 0, 1);
if( sc->data[type]){ // Target still lives. [LimitLine]
- sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
+ sc_timer_next(3000 + tick, status_change_timer, bl->id, data);
}
iMap->freeblock_unlock();
return 0;
@@ -10302,7 +10389,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_FEAR:
- if( --(sce->val4) >= 0 )
+ if( --(sce->val4) > 0 )
{
if( sce->val2 > 0 )
sce->val2--;
@@ -10311,12 +10398,12 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
- case SC_SPHERE_1:
- case SC_SPHERE_2:
- case SC_SPHERE_3:
- case SC_SPHERE_4:
- case SC_SPHERE_5:
- if( --(sce->val4) >= 0 )
+ case SC_SUMMON1:
+ case SC_SUMMON2:
+ case SC_SUMMON3:
+ case SC_SUMMON4:
+ case SC_SUMMON5:
+ if( --(sce->val4) > 0 )
{
if( !status_charge(bl, 0, 1) )
break;
@@ -10328,7 +10415,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
case SC_READING_SB:
if( !status_charge(bl, 0, sce->val2) ){
int i;
- for(i = SC_SPELLBOOK1; i <= SC_MAXSPELLBOOK; i++) // Also remove stored spell as well.
+ for(i = SC_SPELLBOOK1; i <= SC_SPELLBOOK7; i++) // Also remove stored spell as well.
status_change_end(bl, (sc_type)i, INVALID_TIMER);
break;
}
@@ -10336,7 +10423,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
return 0;
case SC_ELECTRICSHOCKER:
- if( --(sce->val4) >= 0 )
+ if( --(sce->val4) > 0 )
{
status_charge(bl, 0, status->max_sp / 100 * sce->val1 );
sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
@@ -10359,7 +10446,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
return 0;
case SC__SHADOWFORM:
- if( --(sce->val4) >= 0 )
+ if( --(sce->val4) > 0 )
{
if( !status_charge(bl, 0, sce->val1 - (sce->val1 - 1)) )
break;
@@ -10369,7 +10456,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC__INVISIBILITY:
- if( --(sce->val4) >= 0 )
+ if( --(sce->val4) > 0 )
{
if( !status_charge(bl, 0, (status->sp * 6 - sce->val1) / 100) )// 6% - skill_lv.
break;
@@ -10379,7 +10466,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_STRIKING:
- if( --(sce->val4) >= 0 )
+ if( --(sce->val4) > 0 )
{
if( !status_charge(bl,0, sce->val1 ) )
break;
@@ -10388,19 +10475,19 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
case SC_VACUUM_EXTREME:
- if( --(sce->val4) >= 0 ){
+ if( --(sce->val4) > 0 ){
sc_timer_next(100 + tick, status_change_timer, bl->id, data);
return 0;
}
break;
- case SC_BLOODSUCKER:
- if( --(sce->val4) >= 0 ) {
+ case SC_BLOOD_SUCKER:
+ if( --(sce->val4) > 0 ) {
struct block_list *src = iMap->id2bl(sce->val2);
int damage;
if( !src || (src && (status_isdead(src) || src->m != bl->m || distance_bl(src, bl) >= 12)) )
break;
iMap->freeblock_lock();
- damage = 200 + 100 * sce->val1 + status_get_int(src);
+ damage = sce->val3;
status_damage(src, bl, damage, 0, clif->damage(bl,bl,tick,status->amotion,status->dmotion+200,damage,1,0,0), 1);
unit_skillcastcancel(bl,1);
if ( sc->data[type] ) {
@@ -10412,8 +10499,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
- case SC_VOICEOFSIREN:
- if( --(sce->val4) >= 0 )
+ case SC_SIREN:
+ if( --(sce->val4) > 0 )
{
clif->emotion(bl,E_LV);
sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
@@ -10421,8 +10508,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
- case SC_DEEPSLEEP:
- if( --(sce->val4) >= 0 )
+ case SC_DEEP_SLEEP:
+ if( --(sce->val4) > 0 )
{ // Recovers 1% HP/SP every 2 seconds.
status_heal(bl, status->max_hp / 100, status->max_sp / 100, 2);
sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
@@ -10431,7 +10518,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_SIRCLEOFNATURE:
- if( --(sce->val4) >= 0 )
+ if( --(sce->val4) > 0 )
{
if( !status_charge(bl,0,sce->val2) )
break;
@@ -10441,8 +10528,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
- case SC_SONGOFMANA:
- if( --(sce->val4) >= 0 )
+ case SC_SONG_OF_MANA:
+ if( --(sce->val4) > 0 )
{
status_heal(bl,0,sce->val3,3);
sc_timer_next(3000 + tick, status_change_timer, bl->id, data);
@@ -10451,9 +10538,9 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
- case SC_SATURDAYNIGHTFEVER:
+ case SC_SATURDAY_NIGHT_FEVER:
// 1% HP/SP drain every val4 seconds [Jobbie]
- if( --(sce->val3) >= 0 )
+ if( --(sce->val3) > 0 )
{
int hp = status->hp / 100;
int sp = status->sp / 100;
@@ -10465,7 +10552,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_CRYSTALIZE:
- if( --(sce->val4) >= 0 )
+ if( --(sce->val4) > 0 )
{ // Drains 2% of HP and 1% of SP every seconds.
if( bl->type != BL_MOB) // doesn't work on mobs
status_charge(bl, status->max_hp * 2 / 100, status->max_sp / 100);
@@ -10489,8 +10576,8 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
- case SC_REFLECTDAMAGE:
- if( --(sce->val4) >= 0 ) {
+ case SC_LG_REFLECTDAMAGE:
+ if( --(sce->val4) > 0 ) {
if( !status_charge(bl,0,sce->val3) )
break;
sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
@@ -10538,7 +10625,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_INSPIRATION:
- if(--(sce->val4) >= 0)
+ if(--(sce->val4) > 0)
{
int hp = status->max_hp * (7-sce->val1) / 100;
int sp = status->max_sp * (9-sce->val1) / 100;
@@ -10615,12 +10702,36 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
case SC_ANGRIFFS_MODUS:
- if(--(sce->val4) >= 0) { //drain hp/sp
+ if(--(sce->val4) > 0) { //drain hp/sp
if( !status_charge(bl,100,20) ) break;
sc_timer_next(1000+tick,status_change_timer,bl->id, data);
return 0;
}
break;
+ case SC_FULL_THROTTLE:
+ if( --(sce->val4) > 0 )
+ {
+ status_percent_damage(bl, bl, sce->val2, 0, false);
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+ case SC_KINGS_GRACE:
+ if( --(sce->val4) > 0 )
+ {
+ status_percent_heal(bl, sce->val2, 0);
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+ 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);
+ return 0;
+ }
+ break;
}
// default for all non-handled control paths is to end the status
@@ -10650,7 +10761,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
if( tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 >0 && sce->val4%2000 == 0) && // for every 2 seconds do the checking
rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10 ) // [100 - (Skill Level x 10)] %
status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
- case SC_CONCENTRATE:
+ case SC_CONCENTRATION:
status_change_end(bl, SC_HIDING, INVALID_TIMER);
status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
@@ -10673,7 +10784,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10 ) // [100 - (Skill Level x 10)] %
status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
break;
- case SC_SIGHTBLASTER:
+ case SC_WZ_SIGHTBLASTER:
if (battle->check_target( src, bl, BCT_ENEMY ) > 0 &&
status_check_skilluse(src, bl, WZ_SIGHTBLASTER, 2))
{
@@ -10683,11 +10794,11 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
}
}
break;
- case SC_CLOSECONFINE:
+ case SC_RG_CCONFINE_M:
//Lock char has released the hold on everyone...
- if (tsc && tsc->data[SC_CLOSECONFINE2] && tsc->data[SC_CLOSECONFINE2]->val2 == src->id) {
- tsc->data[SC_CLOSECONFINE2]->val2 = 0;
- status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
+ if (tsc && tsc->data[SC_RG_CCONFINE_S] && tsc->data[SC_RG_CCONFINE_S]->val2 == src->id) {
+ tsc->data[SC_RG_CCONFINE_S]->val2 = 0;
+ status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER);
}
break;
case SC_CURSEDCIRCLE_TARGET:
@@ -10700,6 +10811,131 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
return 0;
}
+#ifdef RENEWAL
+int status_get_total_def(struct block_list *src){ return status_get_status_data(src)->def2 + (short)status_get_def(src); }
+int status_get_total_mdef(struct block_list *src){ return status_get_status_data(src)->mdef2 + (short)status_get_mdef(src); }
+int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int flag){
+ int min = 0, max = 0, dstr;
+ float strdex_bonus, variance;
+ struct status_change *sc = status_get_sc(bl);
+ struct status_data *status = status_get_status_data(bl);
+
+ if ( bl->type == BL_PC && watk->atk ){
+ if ( flag&16 )
+ dstr = status_get_dex(bl);
+ else
+ dstr = status_get_str(bl);
+
+ variance = 5.0f * watk->atk * watk->wlv / 100.0f;
+ strdex_bonus = watk->atk * dstr / 200.0f;
+
+ min = (watk->atk - (int)(variance + strdex_bonus)) + watk->atk2;
+ max = (watk->atk + (int)(variance + strdex_bonus)) + watk->atk2;
+ }else if( watk->atk ){
+ min = watk->atk * 80 / 100;
+ max = watk->atk * 120 / 100;
+ }
+
+ if( !(flag&1) ){
+ if( max > min )
+ max = min + rnd()%(max - min);
+ else
+ max = min;
+ }
+
+ if( bl->type == BL_PC && ((TBL_PC*)bl)->right_weapon.overrefine > 0)
+ max += rnd()%((TBL_PC*)bl)->right_weapon.overrefine + 1;
+
+ max = status_calc_watk(bl, sc, max, false);
+
+ return max;
+}
+#endif
+
+#define GETRANDMATK(){\
+ if( status->matk_max > status->matk_min )\
+ return status->matk_min + rnd()%(status->matk_max - status->matk_min);\
+ else\
+ return status->matk_min;\
+}
+
+/*==========================================
+ * flag [malufett]
+ * 0 - update matk values
+ * 1 - get matk w/o SC bonuses
+ * 2 - get modified matk
+ * 3 - get matk w/o eatk & SC bonuses
+ *------------------------------------------*/
+int status_get_matk(struct block_list *bl, int flag){
+ struct status_data *status;
+ struct status_change *sc;
+ struct map_session_data *sd;
+
+ if( bl == NULL )
+ return 1;
+
+ status = status_get_status_data(bl);
+ sc = status_get_sc(bl);
+ sd = BL_CAST(BL_PC, bl);
+
+ if( flag == 2 ) // just get matk
+ GETRANDMATK();
+
+#ifndef RENEWAL
+ status->matk_min = status_base_matk_min(status) + (sd?sd->bonus.ematk:0);
+ status->matk_max = status_base_matk_max(status) + (sd?sd->bonus.ematk:0);
+#else
+ /**
+ * RE MATK Formula (from irowiki:http://irowiki.org/wiki/MATK)
+ * MATK = (sMATK + wMATK + eMATK) * Multiplicative Modifiers
+ **/
+ status->matk_min = status_base_matk(status, status_get_lv(bl));
+
+ // Any +MATK you get from skills and cards, including cards in weapon, is added here.
+ if( sd && sd->bonus.ematk > 0 && flag != 3 )
+ status->matk_min += sd->bonus.ematk;
+ if( flag != 3 )
+ status->matk_min = status_calc_ematk(bl, sc, status->matk_min);
+
+ status->matk_max = status->matk_min;
+
+ //This is the only portion in MATK that varies depending on the weapon level and refinement rate.
+ if( bl->type&BL_PC && (status->rhw.matk + status->lhw.matk) > 0 ){
+ int wMatk = status->rhw.matk + status->lhw.matk; // Left and right matk stacks
+ int variance = wMatk * status->rhw.wlv / 10; // Only use right hand weapon level
+ status->matk_min += wMatk - variance;
+ status->matk_max += wMatk + variance;
+ }else if( bl->type&BL_MOB ){
+ status->matk_min = status->matk_max = status_get_int(bl) + status_get_lv(bl);
+ status->matk_min += 70 * ((TBL_MOB*)bl)->status.rhw.atk2 / 100;
+ status->matk_max += 130 * ((TBL_MOB*)bl)->status.rhw.atk2 / 100;
+ }
+#endif
+ if (bl->type&BL_PC && sd->matk_rate != 100) {
+ status->matk_max = status->matk_max * sd->matk_rate/100;
+ status->matk_min = status->matk_min * sd->matk_rate/100;
+ }
+
+ if ((bl->type&BL_HOM && battle_config.hom_setting&0x20) //Hom Min Matk is always the same as Max Matk
+ || sc->data[SC_RECOGNIZEDSPELL])
+ status->matk_min = status->matk_max;
+
+#ifdef RENEWAL
+ if( sd && sd->right_weapon.overrefine > 0){
+ status->matk_min++;
+ status->matk_max += sd->right_weapon.overrefine - 1;
+ }
+#endif
+
+ if( flag ) // get unmodified from sc matk
+ GETRANDMATK();
+
+ status->matk_min = status_calc_matk(bl, sc, status->matk_min, true);
+ status->matk_max = status_calc_matk(bl, sc, status->matk_max, true);
+
+ return 0;
+}
+
/*==========================================
* Clears buffs/debuffs of a character.
* type&1 -> buffs, type&2 -> debuffs
@@ -10719,70 +10955,18 @@ int status_change_clear_buffs (struct block_list* bl, int type)
for( i = SC_COMMON_MAX+1; i < SC_MAX; i++ )
{
- if(!sc->data[i])
+ if( !sc->data[i] || !status_get_sc_type(i) )
continue;
- switch (i) {
- //Stuff that cannot be removed
- case SC_WEIGHT50:
- case SC_WEIGHT90:
- case SC_COMBO:
- case SC_SMA:
- case SC_DANCING:
- case SC_LEADERSHIP:
- case SC_GLORYWOUNDS:
- case SC_SOULCOLD:
- case SC_HAWKEYES:
- case SC_GUILDAURA:
- case SC_SAFETYWALL:
- case SC_PNEUMA:
- case SC_NOCHAT:
- case SC_JAILED:
- case SC_ANKLE:
- case SC_BLADESTOP:
- case SC_CP_WEAPON:
- case SC_CP_SHIELD:
- case SC_CP_ARMOR:
- case SC_CP_HELM:
- case SC_STRFOOD:
- case SC_AGIFOOD:
- case SC_VITFOOD:
- case SC_INTFOOD:
- case SC_DEXFOOD:
- case SC_LUKFOOD:
- case SC_HITFOOD:
- case SC_FLEEFOOD:
- case SC_BATKFOOD:
- case SC_WATKFOOD:
- case SC_MATKFOOD:
- case SC_FOOD_STR_CASH:
- case SC_FOOD_AGI_CASH:
- case SC_FOOD_VIT_CASH:
- case SC_FOOD_DEX_CASH:
- case SC_FOOD_INT_CASH:
- case SC_FOOD_LUK_CASH:
- case SC_EXPBOOST:
- case SC_JEXPBOOST:
- case SC_ITEMBOOST:
- case SC_ELECTRICSHOCKER:
- case SC__MANHOLE:
- case SC_GIANTGROWTH:
- case SC_MILLENNIUMSHIELD:
- case SC_REFRESH:
- case SC_STONEHARDSKIN:
- case SC_VITALITYACTIVATION:
- case SC_FIGHTINGSPIRIT:
- case SC_ABUNDANCE:
- case SC_CURSEDCIRCLE_ATKER:
- case SC_CURSEDCIRCLE_TARGET:
- case SC_PUSH_CART:
- case SC_ALL_RIDING:
- continue;
+ if( type&1 && !(status_get_sc_type(i)&SC_BUFF) )
+ continue;
- //Debuffs that can be removed.
- case SC_DEEPSLEEP:
- case SC_BURNING:
- case SC_FREEZING:
+ if( type&2 && !(status_get_sc_type(i)&SC_DEBUFF) )
+ continue;
+
+ switch (i) {
+ case SC_DEEP_SLEEP:
+ case SC_FROSTMISTY:
case SC_CRYSTALIZE:
case SC_TOXIN:
case SC_PARALYSE:
@@ -10797,40 +10981,13 @@ int status_change_clear_buffs (struct block_list* bl, int type)
if(!(type&4))
continue;
break;
- case SC_HALLUCINATION:
- case SC_QUAGMIRE:
- case SC_SIGNUMCRUCIS:
- case SC_DECREASEAGI:
- case SC_SLOWDOWN:
- case SC_MINDBREAKER:
- case SC_WINKCHARM:
- case SC_STOP:
- case SC_ORCISH:
- case SC_STRIPWEAPON:
- case SC_STRIPSHIELD:
- case SC_STRIPARMOR:
- case SC_STRIPHELM:
- case SC_BITE:
- case SC_ADORAMUS:
- case SC_VACUUM_EXTREME:
- case SC_FEAR:
- case SC_MAGNETICFIELD:
- case SC_NETHERWORLD:
- if (!(type&2))
- continue;
- break;
- //The rest are buffs that can be removed.
case SC__BLOODYLUST:
case SC_BERSERK:
- case SC_SATURDAYNIGHTFEVER:
- if (!(type&1))
+ case SC_SATURDAY_NIGHT_FEVER:
+ if(type&4)
continue;
sc->data[i]->val2 = 0;
break;
- default:
- if (!(type&1))
- continue;
- break;
}
status_change_end(bl, (sc_type)i, INVALID_TIMER);
}
@@ -10861,21 +11018,21 @@ int status_change_spread( struct block_list *src, struct block_list *bl ) {
case SC_CONFUSION:
case SC_BLIND:
case SC_NOCHAT:
- case SC_HALLUCINATION:
- case SC_SIGNUMCRUCIS:
- case SC_DECREASEAGI:
+ case SC_ILLUSION:
+ case SC_CRUCIS:
+ case SC_DEC_AGI:
case SC_SLOWDOWN:
case SC_MINDBREAKER:
- case SC_WINKCHARM:
+ case SC_DC_WINKCHARM:
case SC_STOP:
case SC_ORCISH:
- //case SC_STRIPWEAPON://Omg I got infected and had the urge to strip myself physically.
- //case SC_STRIPSHIELD://No this is stupid and shouldnt be spreadable at all.
- //case SC_STRIPARMOR:// Disabled until I can confirm if it does or not. [Rytech]
- //case SC_STRIPHELM:
- //case SC__STRIPACCESSORY:
- case SC_BITE:
- case SC_FREEZING:
+ //case SC_NOEQUIPWEAPON://Omg I got infected and had the urge to strip myself physically.
+ //case SC_NOEQUIPSHIELD://No this is stupid and shouldnt be spreadable at all.
+ //case SC_NOEQUIPARMOR:// Disabled until I can confirm if it does or not. [Rytech]
+ //case SC_NOEQUIPHELM:
+ //case SC__STRIPACCESSARY:
+ case SC_WUGBITE:
+ case SC_FROSTMISTY:
case SC_VENOMBLEED:
case SC_DEATHHURT:
case SC_PARALYSE:
@@ -10907,7 +11064,7 @@ int status_change_spread( struct block_list *src, struct block_list *bl ) {
data.tick = sc->data[i]->val4 * 4000;
break;
case SC_TOXIN:
- case SC_BLEEDING:
+ case SC_BLOODING:
data.tick = sc->data[i]->val4 * 10000;
break;
default:
@@ -11142,6 +11299,13 @@ int status_get_refine_chance(enum refine_type wlv, int refine) {
return refine_info[wlv].chance[refine];
}
+int status_get_sc_type(sc_type type) {
+
+ if( type <= SC_NONE || type >= SC_MAX )
+ return 0;
+
+ return sc_conf[type];
+}
/*------------------------------------------
* DB reading.
@@ -11244,6 +11408,20 @@ static bool status_readdb_refine(char* fields[], int columns, int current)
return true;
}
+static bool status_readdb_scconfig(char* fields[], int columns, int current)
+{
+ int val = 0;
+ char* type = fields[0];
+
+ if( !script_get_constant(type, &val) ){
+ ShowWarning("status_readdb_sc_conf: Invalid status type %s specified.\n", type);
+ return false;
+ }
+
+ sc_conf[val] = (int)strtol(fields[1], NULL, 0);
+
+ return true;
+}
/*
* Read status db
* job1.txt
@@ -11295,6 +11473,7 @@ int status_readdb(void)
sv->readdb(iMap->db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, &status_readdb_job2);
sv->readdb(iMap->db_path, "size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(atkmods), &status_readdb_sizefix);
sv->readdb(iMap->db_path, DBPATH"refine_db.txt", ',', 4+MAX_REFINE, 4+MAX_REFINE, ARRAYLENGTH(refine_info), &status_readdb_refine);
+ sv->readdb(iMap->db_path, "sc_config.txt", ',', 2, 2, SC_MAX, &status_readdb_scconfig);
return 0;
}
diff --git a/src/map/status.h b/src/map/status.h
index 4a7af884e..617cd9572 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -31,6 +31,16 @@ enum refine_type {
REFINE_TYPE_MAX = 5
};
+typedef enum sc_conf_type {
+ SC_NO_REM_DEATH = 0x1,
+ SC_NO_SAVE = 0x2,
+ SC_NO_DISPELL = 0x4,
+ SC_NO_CLEARANCE = 0x8,
+ SC_BUFF = 0x10,
+ SC_DEBUFF = 0x20,
+ SC_MADO_NO_RESET = 0x40
+} sc_conf_type;
+
int status_get_refine_chance(enum refine_type wlv, int refine);
// Status changes listing. These code are for use by the server.
@@ -48,25 +58,26 @@ typedef enum sc_type {
SC_SILENCE,
SC_CONFUSION,
SC_BLIND,
- SC_BLEEDING,
- SC_DPOISON, //10
- SC_COMMON_MAX = 10, // end
+ SC_BLOODING,
+ SC_DPOISON,
+ SC_BURNING, //11
+ SC_COMMON_MAX = 11, // end
//Next up, we continue on 20, to leave enough room for additional "common" ailments in the future.
SC_PROVOKE = 20,
SC_ENDURE,
SC_TWOHANDQUICKEN,
- SC_CONCENTRATE,
+ SC_CONCENTRATION,
SC_HIDING,
SC_CLOAKING,
- SC_ENCPOISON,
+ SC_ENCHANTPOISON,
SC_POISONREACT,
SC_QUAGMIRE,
SC_ANGELUS,
SC_BLESSING, //30
- SC_SIGNUMCRUCIS,
- SC_INCREASEAGI,
- SC_DECREASEAGI,
+ SC_CRUCIS,
+ SC_INC_AGI,
+ SC_DEC_AGI,
SC_SLOWPOISON,
SC_IMPOSITIO ,
SC_SUFFRAGIUM,
@@ -75,40 +86,40 @@ typedef enum sc_type {
SC_KYRIE,
SC_MAGNIFICAT, //40
SC_GLORIA,
- SC_AETERNA,
+ SC_LEXAETERNA,
SC_ADRENALINE,
- SC_WEAPONPERFECTION,
+ SC_WEAPONPERFECT,
SC_OVERTHRUST,
SC_MAXIMIZEPOWER,
SC_TRICKDEAD,
- SC_LOUD,
+ SC_SHOUT,
SC_ENERGYCOAT,
SC_BROKENARMOR, //50 - NOTE: These two aren't used anywhere, and they have an icon...
SC_BROKENWEAPON,
- SC_HALLUCINATION,
- SC_WEIGHT50,
- SC_WEIGHT90,
- SC_ASPDPOTION0,
- SC_ASPDPOTION1,
- SC_ASPDPOTION2,
- SC_ASPDPOTION3,
- SC_SPEEDUP0,
- SC_SPEEDUP1, //60
- SC_ATKPOTION,
- SC_MATKPOTION,
+ SC_ILLUSION,
+ SC_WEIGHTOVER50,
+ SC_WEIGHTOVER90,
+ SC_ATTHASTE_POTION1,
+ SC_ATTHASTE_POTION2,
+ SC_ATTHASTE_POTION3,
+ SC_ATTHASTE_INFINITY,
+ SC_MOVHASTE_HORSE,
+ SC_MOVHASTE_INFINITY, //60
+ SC_PLUSATTACKPOWER,
+ SC_PLUSMAGICPOWER,
SC_WEDDING,
SC_SLOWDOWN,
- SC_ANKLE,
+ SC_ANKLESNARE,
SC_KEEPING,
SC_BARRIER,
- SC_STRIPWEAPON,
- SC_STRIPSHIELD,
- SC_STRIPARMOR, //70
- SC_STRIPHELM,
- SC_CP_WEAPON,
- SC_CP_SHIELD,
- SC_CP_ARMOR,
- SC_CP_HELM,
+ SC_NOEQUIPWEAPON,
+ SC_NOEQUIPSHIELD,
+ SC_NOEQUIPARMOR, //70
+ SC_NOEQUIPHELM,
+ SC_PROTECTWEAPON,
+ SC_PROTECTSHIELD,
+ SC_PROTECTARMOR,
+ SC_PROTECTHELM,
SC_AUTOGUARD,
SC_REFLECTSHIELD,
SC_SPLASHER,
@@ -126,24 +137,24 @@ typedef enum sc_type {
SC_RUWACH, //90
SC_EXTREMITYFIST,
SC_EXPLOSIONSPIRITS,
- SC_COMBO,
+ SC_COMBOATTACK,
SC_BLADESTOP_WAIT,
SC_BLADESTOP,
- SC_FIREWEAPON,
- SC_WATERWEAPON,
- SC_WINDWEAPON,
- SC_EARTHWEAPON,
+ SC_PROPERTYFIRE,
+ SC_PROPERTYWATER,
+ SC_PROPERTYWIND,
+ SC_PROPERTYGROUND,
SC_VOLCANO, //100,
SC_DELUGE,
SC_VIOLENTGALE,
SC_WATK_ELEMENT,
SC_ARMOR,
- SC_ARMOR_ELEMENT,
+ SC_ARMORPROPERTY,
SC_NOCHAT,
SC_BABY,
SC_AURABLADE,
SC_PARRYING,
- SC_CONCENTRATION, //110
+ SC_LKCONCENTRATION, //110
SC_TENSIONRELAX,
SC_BERSERK,
SC_FURY,
@@ -158,10 +169,10 @@ typedef enum sc_type {
SC_MELTDOWN,
SC_CARTBOOST,
SC_CHASEWALK,
- SC_REJECTSWORD,
+ SC_SWORDREJECT,
+ SC_MARIONETTE_MASTER,
SC_MARIONETTE,
- SC_MARIONETTE2,
- SC_CHANGEUNDEAD,
+ SC_PROPERTYUNDEAD,
SC_JOINTBEAT,
SC_MINDBREAKER, //130
SC_MEMORIZE,
@@ -171,39 +182,40 @@ typedef enum sc_type {
SC_SACRIFICE,
SC_STEELBODY,
SC_ORCISH,
- SC_READYSTORM,
- SC_READYDOWN,
- SC_READYTURN, //140
- SC_READYCOUNTER,
- SC_DODGE,
+ SC_STORMKICK_READY,
+ SC_DOWNKICK_READY,
+ SC_TURNKICK_READY, //140
+ SC_COUNTERKICK_READY,
+ SC_DODGE_READY,
SC_RUN,
- SC_SHADOWWEAPON,
+ SC_PROPERTYDARK,
SC_ADRENALINE2,
- SC_GHOSTWEAPON,
+ SC_PROPERTYTELEKINESIS,
SC_KAIZEL,
SC_KAAHI,
SC_KAUPE,
- SC_ONEHAND, //150
+ SC_ONEHANDQUICKEN, //150
SC_PRESERVE,
- SC_BATTLEORDERS,
- SC_REGENERATION,
- SC_DOUBLECAST,
+ SC_GDSKILL_BATTLEORDER,
+ SC_GDSKILL_REGENERATION,
+ SC_DOUBLECASTING,
SC_GRAVITATION,
- SC_MAXOVERTHRUST,
+ SC_OVERTHRUSTMAX,
SC_LONGING,
SC_HERMODE,
- SC_SHRINK,
- SC_SIGHTBLASTER, //160
- SC_WINKCHARM,
- SC_CLOSECONFINE,
- SC_CLOSECONFINE2,
+ SC_TAROTCARD,
+ SC_CR_SHRINK, //160
+ SC_WZ_SIGHTBLASTER,
+ SC_DC_WINKCHARM,
+ SC_RG_CCONFINE_M,
+ SC_RG_CCONFINE_S,
SC_DANCING,
- SC_ELEMENTALCHANGE,
+ SC_ARMOR_PROPERTY,
SC_RICHMANKIM,
SC_ETERNALCHAOS,
SC_DRUMBATTLE,
- SC_NIBELUNGEN,
- SC_ROKISWEIL, //170
+ SC_NIBELUNGEN, //170
+ SC_ROKISWEIL,
SC_INTOABYSS,
SC_SIEGFRIED,
SC_WHISTLE,
@@ -212,18 +224,18 @@ typedef enum sc_type {
SC_APPLEIDUN,
SC_MODECHANGE,
SC_HUMMING,
- SC_DONTFORGETME,
- SC_FORTUNE, //180
- SC_SERVICE4U,
+ SC_DONTFORGETME, //180
+ SC_FORTUNE,
+ SC_SERVICEFORYOU,
SC_STOP, //Prevents inflicted chars from walking. [Skotlex]
- SC_SPURT,
- SC_SPIRIT,
+ SC_STRUP,
+ SC_SOULLINK,
SC_COMA, //Not a real SC_, it makes a char's HP/SP hit 1.
- SC_INTRAVISION,
+ SC_CLAIRVOYANCE,
SC_INCALLSTATUS,
- SC_INCSTR,
- SC_INCAGI,
- SC_INCVIT, //190
+ SC_CHASEWALK2,
+ SC_INCAGI, //190
+ SC_INCVIT,
SC_INCINT,
SC_INCDEX,
SC_INCLUK,
@@ -232,18 +244,18 @@ typedef enum sc_type {
SC_INCFLEE,
SC_INCFLEERATE,
SC_INCMHPRATE,
- SC_INCMSPRATE,
- SC_INCATKRATE, //200
+ SC_INCMSPRATE, //200
+ SC_INCATKRATE,
SC_INCMATKRATE,
SC_INCDEFRATE,
- SC_STRFOOD,
- SC_AGIFOOD,
- SC_VITFOOD,
- SC_INTFOOD,
- SC_DEXFOOD,
- SC_LUKFOOD,
- SC_HITFOOD,
- SC_FLEEFOOD, //210
+ SC_FOOD_STR,
+ SC_FOOD_AGI,
+ SC_FOOD_VIT,
+ SC_FOOD_INT,
+ SC_FOOD_DEX,
+ SC_FOOD_LUK,
+ SC_FOOD_BASICHIT, //210
+ SC_FOOD_BASICAVOIDANCE,
SC_BATKFOOD,
SC_WATKFOOD,
SC_MATKFOOD,
@@ -252,8 +264,8 @@ typedef enum sc_type {
SC_WARM, //SG skills [Komurka]
SC_SUN_COMFORT,
SC_MOON_COMFORT,
- SC_STAR_COMFORT,
- SC_FUSION, //220
+ SC_STAR_COMFORT, //220
+ SC_FUSION,
SC_SKILLRATE_UP,
SC_SKE,
SC_KAITE,
@@ -261,82 +273,82 @@ typedef enum sc_type {
SC_SKA, // [marquis007]
SC_EARTHSCROLL,
SC_MIRACLE, //SG 'hidden' skill [Komurka]
- SC_MADNESSCANCEL,
- SC_ADJUSTMENT,
- SC_INCREASING, //230
- SC_GATLINGFEVER,
- SC_TATAMIGAESHI,
- SC_UTSUSEMI,
- SC_BUNSINJYUTSU,
- SC_KAENSIN,
- SC_SUITON,
- SC_NEN,
+ SC_GS_MADNESSCANCEL,
+ SC_GS_ADJUSTMENT, //230
+ SC_GS_ACCURACY,
+ SC_GS_GATLINGFEVER,
+ SC_NJ_TATAMIGAESHI,
+ SC_NJ_UTSUSEMI,
+ SC_NJ_BUNSINJYUTSU,
+ SC_NJ_KAENSIN,
+ SC_NJ_SUITON,
+ SC_NJ_NEN,
SC_KNOWLEDGE,
- SC_SMA,
- SC_FLING, //240
- SC_AVOID,
- SC_CHANGE,
- SC_BLOODLUST,
- SC_FLEET,
- SC_SPEED,
- SC_DEFENCE,
+ SC_SMA_READY, //240
+ SC_FLING,
+ SC_HLIF_AVOID,
+ SC_HLIF_CHANGE,
+ SC_HAMI_BLOODLUST,
+ SC_HLIF_FLEET,
+ SC_HLIF_SPEED,
+ SC_HAMI_DEFENCE,
SC_INCASPDRATE,
- SC_INCFLEE2 = 248,
- SC_JAILED,
- SC_ENCHANTARMS, //250
+ SC_PLUSAVOIDVALUE,
+ SC_JAILED, //250
+ SC_ENCHANTARMS,
SC_MAGICALATTACK,
- SC_ARMORCHANGE,
+ SC_STONESKIN,
SC_CRITICALWOUND,
SC_MAGICMIRROR,
SC_SLOWCAST,
SC_SUMMER,
- SC_EXPBOOST,
- SC_ITEMBOOST,
- SC_BOSSMAPINFO,
- SC_LIFEINSURANCE, //260
- SC_INCCRI,
+ SC_CASH_PLUSEXP,
+ SC_CASH_RECEIVEITEM,
+ SC_CASH_BOSS_ALARM, //260
+ SC_CASH_DEATHPENALTY,
+ SC_CRITICALPERCENT,
//SC_INCDEF,
- //SC_INCBASEATK = 263,
+ //SC_INCBASEATK = 264,
//SC_FASTCAST,
- SC_MDEF_RATE = 265,
+ SC_PROTECT_MDEF = 266,
//SC_HPREGEN,
- SC_INCHEALRATE = 267,
+ SC_HEALPLUS = 268,
SC_PNEUMA,
- SC_AUTOTRADE,
- SC_KSPROTECTED, //270
- SC_ARMOR_RESIST = 271,
- SC_SPCOST_RATE,
- SC_COMMONSC_RESIST,
- SC_SEVENWIND,
- SC_DEF_RATE,
+ SC_AUTOTRADE, //270
+ SC_KSPROTECTED,
+ SC_ARMOR_RESIST,
+ SC_ATKER_BLOOD,
+ SC_TARGET_BLOOD,
+ SC_TK_SEVENWIND,
+ SC_PROTECT_DEF,
//SC_SPREGEN,
- SC_WALKSPEED = 277,
+ SC_WALKSPEED = 278,
// Mercenary Only Bonus Effects
- SC_MERC_FLEEUP,
- SC_MERC_ATKUP,
- SC_MERC_HPUP, //280
- SC_MERC_SPUP,
- SC_MERC_HITUP,
- SC_MERC_QUICKEN,
+ SC_MER_FLEE,
+ SC_MER_ATK, //280
+ SC_MER_HP,
+ SC_MER_SP,
+ SC_MER_HIT,
+ SC_MER_QUICKEN,
SC_REBIRTH,
- //SC_SKILLCASTRATE, //285
+ //SC_SKILLCASTRATE, //286
//SC_DEFRATIOATK,
//SC_HPDRAIN,
//SC_SKILLATKBONUS,
- SC_ITEMSCRIPT = 289,
- SC_S_LIFEPOTION, //290
+ SC_ITEMSCRIPT = 290,
+ SC_S_LIFEPOTION,
SC_L_LIFEPOTION,
- SC_JEXPBOOST,
+ SC_CASH_PLUSONLYJOBEXP,
//SC_IGNOREDEF,
- SC_HELLPOWER = 294,
- SC_INVINCIBLE, //295
+ SC_HELLPOWER = 295,
+ SC_INVINCIBLE,
SC_INVINCIBLEOFF,
SC_MANU_ATK,
SC_MANU_DEF,
- SC_SPL_ATK,
- SC_SPL_DEF, //300
+ SC_SPL_ATK, //300
+ SC_SPL_DEF,
SC_MANU_MATK,
SC_SPL_MATK,
SC_FOOD_STR_CASH,
@@ -344,25 +356,24 @@ typedef enum sc_type {
SC_FOOD_VIT_CASH,
SC_FOOD_DEX_CASH,
SC_FOOD_INT_CASH,
- SC_FOOD_LUK_CASH,//308
+ SC_FOOD_LUK_CASH,
/**
* 3rd
**/
- SC_FEAR,//309
- SC_BURNING,//310
- SC_FREEZING,//311
+ SC_FEAR,
+ SC_FROSTMISTY,
/**
* Rune Knight
**/
- SC_ENCHANTBLADE,//312
- SC_DEATHBOUND,//313
+ SC_ENCHANTBLADE,
+ SC_DEATHBOUND,
SC_MILLENNIUMSHIELD,
- SC_CRUSHSTRIKE,//315
+ SC_CRUSHSTRIKE,
SC_REFRESH,
SC_REUSE_REFRESH,
SC_GIANTGROWTH,
SC_STONEHARDSKIN,
- SC_VITALITYACTIVATION,//320
+ SC_VITALITYACTIVATION,
SC_STORMBLAST,
SC_FIGHTINGSPIRIT,
SC_ABUNDANCE,
@@ -370,12 +381,12 @@ typedef enum sc_type {
* Arch Bishop
**/
SC_ADORAMUS,
- SC_EPICLESIS,//325
+ SC_EPICLESIS,
SC_ORATIO,
SC_LAUDAAGNUS,
SC_LAUDARAMUS,
SC_RENOVATIO,
- SC_EXPIATIO,//330
+ SC_EXPIATIO,
SC_DUPLELIGHT,
SC_SECRAMENT,
/**
@@ -383,38 +394,38 @@ typedef enum sc_type {
**/
SC_WHITEIMPRISON,
SC_MARSHOFABYSS,
- SC_RECOGNIZEDSPELL,//335
+ SC_RECOGNIZEDSPELL,
SC_STASIS,
- SC_SPHERE_1,
- SC_SPHERE_2,
- SC_SPHERE_3,
- SC_SPHERE_4,//340
- SC_SPHERE_5,
+ SC_SUMMON1,
+ SC_SUMMON2,
+ SC_SUMMON3,
+ SC_SUMMON4,
+ SC_SUMMON5,
SC_READING_SB,
- SC_FREEZINGSPELL,
+ SC_FREEZINGSP,
/**
* Ranger
**/
SC_FEARBREEZE,
- SC_ELECTRICSHOCKER,//345
+ SC_ELECTRICSHOCKER,
SC_WUGDASH,
- SC_BITE,
+ SC_WUGBITE,
SC_CAMOUFLAGE,
/**
* Mechanic
**/
SC_ACCELERATION,
- SC_HOVERING,//350
+ SC_HOVERING,
SC_SHAPESHIFT,
SC_INFRAREDSCAN,
SC_ANALYZE,
SC_MAGNETICFIELD,
- SC_NEUTRALBARRIER,//355
+ SC_NEUTRALBARRIER,
SC_NEUTRALBARRIER_MASTER,
SC_STEALTHFIELD,
SC_STEALTHFIELD_MASTER,
SC_OVERHEAT,
- SC_OVERHEAT_LIMITPOINT,//360
+ SC_OVERHEAT_LIMITPOINT,
/**
* Guillotine Cross
**/
@@ -422,30 +433,30 @@ typedef enum sc_type {
SC_POISONINGWEAPON,
SC_WEAPONBLOCKING,
SC_CLOAKINGEXCEED,
- SC_HALLUCINATIONWALK,//365
+ SC_HALLUCINATIONWALK,
SC_HALLUCINATIONWALK_POSTDELAY,
SC_ROLLINGCUTTER,
SC_TOXIN,
SC_PARALYSE,
- SC_VENOMBLEED,//370
+ SC_VENOMBLEED,
SC_MAGICMUSHROOM,
SC_DEATHHURT,
SC_PYREXIA,
SC_OBLIVIONCURSE,
- SC_LEECHESEND,//375
+ SC_LEECHESEND,
/**
* Royal Guard
**/
- SC_REFLECTDAMAGE,
+ SC_LG_REFLECTDAMAGE,
SC_FORCEOFVANGUARD,
SC_SHIELDSPELL_DEF,
SC_SHIELDSPELL_MDEF,
- SC_SHIELDSPELL_REF,//380
+ SC_SHIELDSPELL_REF,
SC_EXEEDBREAK,
SC_PRESTIGE,
SC_BANDING,
SC_BANDING_DEFENCE,
- SC_EARTHDRIVE,//385
+ SC_EARTHDRIVE,
SC_INSPIRATION,
/**
* Sorcerer
@@ -453,30 +464,30 @@ typedef enum sc_type {
SC_SPELLFIST,
SC_CRYSTALIZE,
SC_STRIKING,
- SC_WARMER,//390
+ SC_WARMER,
SC_VACUUM_EXTREME,
SC_PROPERTYWALK,
/**
* Minstrel / Wanderer
**/
- SC_SWINGDANCE,
- SC_SYMPHONYOFLOVER,
- SC_MOONLITSERENADE,//395
- SC_RUSHWINDMILL,
+ SC_SWING,
+ SC_SYMPHONY_LOVE,
+ SC_MOONLIT_SERENADE,
+ SC_RUSH_WINDMILL,
SC_ECHOSONG,
SC_HARMONIZE,
- SC_VOICEOFSIREN,
- SC_DEEPSLEEP,//400
+ SC_SIREN,
+ SC_DEEP_SLEEP,
SC_SIRCLEOFNATURE,
SC_GLOOMYDAY,
SC_GLOOMYDAY_SK,
- SC_SONGOFMANA,
- SC_DANCEWITHWUG,//405
- SC_SATURDAYNIGHTFEVER,
- SC_LERADSDEW,
+ SC_SONG_OF_MANA,
+ SC_DANCE_WITH_WUG,
+ SC_SATURDAY_NIGHT_FEVER,
+ SC_LERADS_DEW,
SC_MELODYOFSINK,
- SC_BEYONDOFWARCRY,
- SC_UNLIMITEDHUMMINGVOICE,//410
+ SC_BEYOND_OF_WARCRY,
+ SC_UNLIMITED_HUMMING_VOICE,
SC_SITDOWN_FORCE,
SC_NETHERWORLD,
/**
@@ -485,35 +496,35 @@ typedef enum sc_type {
SC_CRESCENTELBOW,
SC_CURSEDCIRCLE_ATKER,
SC_CURSEDCIRCLE_TARGET,
- SC_LIGHTNINGWALK,//416
+ SC_LIGHTNINGWALK,
SC_RAISINGDRAGON,
- SC_GT_ENERGYGAIN,
- SC_GT_CHANGE,
- SC_GT_REVITALIZE,
+ SC_GENTLETOUCH_ENERGYGAIN,
+ SC_GENTLETOUCH_CHANGE,
+ SC_GENTLETOUCH_REVITALIZE,
/**
* Genetic
**/
- SC_GN_CARTBOOST,//427
- SC_THORNSTRAP,
- SC_BLOODSUCKER,
- SC_SMOKEPOWDER,
- SC_TEARGAS,
- SC_MANDRAGORA,//426
+ SC_GN_CARTBOOST,
+ SC_THORNS_TRAP,
+ SC_BLOOD_SUCKER,
+ SC_FIRE_EXPANSION_SMOKE_POWDER,
+ SC_FIRE_EXPANSION_TEAR_GAS,
+ SC_MANDRAGORA,
SC_STOMACHACHE,
SC_MYSTERIOUS_POWDER,
SC_MELON_BOMB,
SC_BANANA_BOMB,
- SC_BANANA_BOMB_SITDOWN,//431
+ SC_BANANA_BOMB_SITDOWN_POSTDELAY,
SC_SAVAGE_STEAK,
SC_COCKTAIL_WARG_BLOOD,
SC_MINOR_BBQ,
SC_SIROMA_ICE_TEA,
- SC_DROCERA_HERB_STEAMED,//436
+ SC_DROCERA_HERB_STEAMED,
SC_PUTTI_TAILS_NOODLES,
SC_BOOST500,
SC_FULL_SWING_K,
SC_MANA_PLUS,
- SC_MUSTLE_M,//441
+ SC_MUSTLE_M,
SC_LIFE_FORCE_F,
SC_EXTRACT_WHITE_POTION_Z,
SC_VITATA_500,
@@ -521,21 +532,21 @@ typedef enum sc_type {
/**
* Shadow Chaser
**/
- SC__REPRODUCE,//446
+ SC__REPRODUCE,
SC__AUTOSHADOWSPELL,
SC__SHADOWFORM,
SC__BODYPAINT,
SC__INVISIBILITY,
- SC__DEADLYINFECT,//451
+ SC__DEADLYINFECT,
SC__ENERVATION,
SC__GROOMY,
SC__IGNORANCE,
SC__LAZINESS,
- SC__UNLUCKY,//456
+ SC__UNLUCKY,
SC__WEAKNESS,
- SC__STRIPACCESSORY,
+ SC__STRIPACCESSARY,
SC__MANHOLE,
- SC__BLOODYLUST,//460
+ SC__BLOODYLUST,
/**
* Elemental Spirits
**/
@@ -543,61 +554,60 @@ typedef enum sc_type {
SC_CIRCLE_OF_FIRE_OPTION,
SC_FIRE_CLOAK,
SC_FIRE_CLOAK_OPTION,
- SC_WATER_SCREEN,//465
+ SC_WATER_SCREEN,
SC_WATER_SCREEN_OPTION,
SC_WATER_DROP,
SC_WATER_DROP_OPTION,
SC_WATER_BARRIER,
- SC_WIND_STEP,//470
+ SC_WIND_STEP,
SC_WIND_STEP_OPTION,
SC_WIND_CURTAIN,
SC_WIND_CURTAIN_OPTION,
SC_ZEPHYR,
- SC_SOLID_SKIN,//475
+ SC_SOLID_SKIN,
SC_SOLID_SKIN_OPTION,
SC_STONE_SHIELD,
SC_STONE_SHIELD_OPTION,
SC_POWER_OF_GAIA,
- SC_PYROTECHNIC,//480
+ SC_PYROTECHNIC,
SC_PYROTECHNIC_OPTION,
SC_HEATER,
SC_HEATER_OPTION,
SC_TROPIC,
- SC_TROPIC_OPTION,//485
+ SC_TROPIC_OPTION,
SC_AQUAPLAY,
SC_AQUAPLAY_OPTION,
SC_COOLER,
SC_COOLER_OPTION,
- SC_CHILLY_AIR,//490
+ SC_CHILLY_AIR,
SC_CHILLY_AIR_OPTION,
SC_GUST,
SC_GUST_OPTION,
SC_BLAST,
- SC_BLAST_OPTION,//495
+ SC_BLAST_OPTION,
SC_WILD_STORM,
SC_WILD_STORM_OPTION,
SC_PETROLOGY,
SC_PETROLOGY_OPTION,
- SC_CURSED_SOIL,//500
+ SC_CURSED_SOIL,
SC_CURSED_SOIL_OPTION,
SC_UPHEAVAL,
SC_UPHEAVAL_OPTION,
SC_TIDAL_WEAPON,
- SC_TIDAL_WEAPON_OPTION,//505
+ SC_TIDAL_WEAPON_OPTION,
SC_ROCK_CRUSHER,
SC_ROCK_CRUSHER_ATK,
/* Guild Aura */
SC_LEADERSHIP,
SC_GLORYWOUNDS,
- SC_SOULCOLD, //508
+ SC_SOULCOLD,
SC_HAWKEYES,
/* ... */
SC_ODINS_POWER,
- SC_RAID,
/* Sorcerer .extra */
SC_FIRE_INSIGNIA,
SC_WATER_INSIGNIA,
- SC_WIND_INSIGNIA, //516
+ SC_WIND_INSIGNIA,
SC_EARTH_INSIGNIA,
/* new pushcart */
SC_PUSH_CART,
@@ -610,22 +620,22 @@ typedef enum sc_type {
SC_SPELLBOOK6,
/**
* In official server there are only 7 maximum number of spell books that can be memorized
- * To increase the maximum value just add another status type before SC_MAXSPELLBOOK (ex. SC_SPELLBOOK7, SC_SPELLBOOK8 and so on)
+ * To increase the maximum value just add another status type before SC_SPELLBOOK7 (ex. SC_SPELLBOOK8, SC_SPELLBOOK9 and so on)
**/
- SC_MAXSPELLBOOK,
+ SC_SPELLBOOK7,
/* Max HP & SP */
SC_INCMHP,
SC_INCMSP,
- SC_PARTYFLEE, // 531
+ SC_PARTYFLEE,
/**
* Kagerou & Oboro [malufett]
**/
SC_MEIKYOUSISUI,
- SC_JYUMONJIKIRI,
+ SC_KO_JYUMONJIKIRI,
SC_KYOUGAKU,
SC_IZAYOI,
SC_ZENKAI,
- SC_KAGEHUMI,
+ SC_KG_KAGEHUMI,
SC_KYOMU,
SC_KAGEMUSYA,
SC_ZANGETSU,
@@ -639,17 +649,24 @@ typedef enum sc_type {
SC_ERASER_CUTTER,
SC_OVERED_BOOST,
SC_LIGHT_OF_REGENE,
- SC_ASH,
+ SC_VOLCANIC_ASH,
SC_GRANITIC_ARMOR,
SC_MAGMA_FLOW,
SC_PYROCLASTIC,
- SC_PARALYSIS,
+ SC_NEEDLE_OF_PARALYZE,
SC_PAIN_KILLER,
-
-
#ifdef RENEWAL
SC_EXTREMITYFIST2,
+ SC_RAID,
#endif
+ SC_DARKCROW = 553,
+ SC_FULL_THROTTLE,
+ SC_REBOUND,
+ SC_UNLIMIT,
+ SC_KINGS_GRACE,
+ SC_TELEKINESIS_INTENSE,
+ SC_OFFERTORIUM,
+ SC_FRIGG_SONG,
SC_ALL_RIDING,
SC_HANBOK,
@@ -660,66 +677,66 @@ typedef enum sc_type {
// Official status change ids, used to display status icons on the client.
enum si_type {
SI_BLANK = -1,
- SI_PROVOKE = 0,
- SI_ENDURE = 1,
- SI_TWOHANDQUICKEN = 2,
- SI_CONCENTRATE = 3,
- SI_HIDING = 4,
- SI_CLOAKING = 5,
- SI_ENCPOISON = 6,
- SI_POISONREACT = 7,
- SI_QUAGMIRE = 8,
- SI_ANGELUS = 9,
- SI_BLESSING = 10,
- SI_SIGNUMCRUCIS = 11,
- SI_INCREASEAGI = 12,
- SI_DECREASEAGI = 13,
- SI_SLOWPOISON = 14,
- SI_IMPOSITIO = 15,
- SI_SUFFRAGIUM = 16,
- SI_ASPERSIO = 17,
- SI_BENEDICTIO = 18,
- SI_KYRIE = 19,
- SI_MAGNIFICAT = 20,
- SI_GLORIA = 21,
- SI_AETERNA = 22,
- SI_ADRENALINE = 23,
- SI_WEAPONPERFECTION = 24,
- SI_OVERTHRUST = 25,
- SI_MAXIMIZEPOWER = 26,
- SI_RIDING = 27,
- SI_FALCON = 28,
- SI_TRICKDEAD = 29,
- SI_LOUD = 30,
- SI_ENERGYCOAT = 31,
- SI_BROKENARMOR = 32,
- SI_BROKENWEAPON = 33,
- SI_HALLUCINATION = 34,
- SI_WEIGHT50 = 35,
- SI_WEIGHT90 = 36,
- SI_ASPDPOTION0 = 37,
- SI_ASPDPOTION1 = 38,
- SI_ASPDPOTION2 = 39,
- SI_ASPDPOTIONINFINITY = 40,
- SI_SPEEDPOTION1 = 41,
-// SI_MOVHASTE_INFINITY = 42,
+ SI_PROVOKE = 0,
+ SI_ENDURE = 1,
+ SI_TWOHANDQUICKEN = 2,
+ SI_CONCENTRATION = 3,
+ SI_HIDING = 4,
+ SI_CLOAKING = 5,
+ SI_ENCHANTPOISON = 6,
+ SI_POISONREACT = 7,
+ SI_QUAGMIRE = 8,
+ SI_ANGELUS = 9,
+ SI_BLESSING = 10,
+ SI_CRUCIS = 11,
+ SI_INC_AGI = 12,
+ SI_DEC_AGI = 13,
+ SI_SLOWPOISON = 14,
+ SI_IMPOSITIO = 15,
+ SI_SUFFRAGIUM = 16,
+ SI_ASPERSIO = 17,
+ SI_BENEDICTIO = 18,
+ SI_KYRIE = 19,
+ SI_MAGNIFICAT = 20,
+ SI_GLORIA = 21,
+ SI_LEXAETERNA = 22,
+ SI_ADRENALINE = 23,
+ SI_WEAPONPERFECT = 24,
+ SI_OVERTHRUST = 25,
+ SI_MAXIMIZE = 26,
+ SI_RIDING = 27,
+ SI_FALCON = 28,
+ SI_TRICKDEAD = 29,
+ SI_SHOUT = 30,
+ SI_ENERGYCOAT = 31,
+ SI_BROKENARMOR = 32,
+ SI_BROKENWEAPON = 33,
+ SI_ILLUSION = 34,
+ SI_WEIGHTOVER50 = 35,
+ SI_WEIGHTOVER90 = 36,
+ SI_ATTHASTE_POTION1 = 37,
+ SI_ATTHASTE_POTION2 = 38,
+ SI_ATTHASTE_POTION3 = 39,
+ SI_ATTHASTE_INFINITY = 40,
+ SI_MOVHASTE_POTION = 41,
+ SI_MOVHASTE_INFINITY = 42,
// SI_AUTOCOUNTER = 43,
// SI_SPLASHER = 44,
-// SI_ANKLESNARE = 45,
- SI_ACTIONDELAY = 46,
+ SI_ANKLESNARE = 45,
+ SI_POSTDELAY = 46,
// SI_NOACTION = 47,
// SI_IMPOSSIBLEPICKUP = 48,
// SI_BARRIER = 49,
- SI_STRIPWEAPON = 50,
- SI_STRIPSHIELD = 51,
- SI_STRIPARMOR = 52,
- SI_STRIPHELM = 53,
- SI_CP_WEAPON = 54,
- SI_CP_SHIELD = 55,
- SI_CP_ARMOR = 56,
- SI_CP_HELM = 57,
- SI_AUTOGUARD = 58,
- SI_REFLECTSHIELD = 59,
+ SI_NOEQUIPWEAPON = 50,
+ SI_NOEQUIPSHIELD = 51,
+ SI_NOEQUIPARMOR = 52,
+ SI_NOEQUIPHELM = 53,
+ SI_PROTECTWEAPON = 54,
+ SI_PROTECTSHIELD = 55,
+ SI_PROTECTARMOR = 56,
+ SI_PROTECTHELM = 57,
+ SI_AUTOGUARD = 58,
+ SI_REFLECTSHIELD = 59,
// SI_DEVOTION = 60,
SI_PROVIDENCE = 61,
SI_DEFENDER = 62,
@@ -750,29 +767,29 @@ enum si_type {
SI_STEELBODY = 87,
SI_EXTREMITYFIST = 88,
// SI_COMBOATTACK = 89,
- SI_FIREWEAPON = 90,
- SI_WATERWEAPON = 91,
- SI_WINDWEAPON = 92,
- SI_EARTHWEAPON = 93,
+ SI_PROPERTYFIRE = 90,
+ SI_PROPERTYWATER = 91,
+ SI_PROPERTYWIND = 92,
+ SI_PROPERTYGROUND = 93,
// SI_MAGICATTACK = 94,
SI_STOP = 95,
// SI_WEAPONBRAKER = 96,
- SI_UNDEAD = 97,
+ SI_PROPERTYUNDEAD = 97,
// SI_POWERUP = 98,
// SI_AGIUP = 99,
// SI_SIEGEMODE = 100,
// SI_INVISIBLE = 101,
// SI_STATUSONE = 102,
- SI_AURABLADE = 103,
- SI_PARRYING = 104,
- SI_CONCENTRATION = 105,
- SI_TENSIONRELAX = 106,
+ SI_AURABLADE = 103,
+ SI_PARRYING = 104,
+ SI_LKCONCENTRATION = 105,
+ SI_TENSIONRELAX = 106,
SI_BERSERK = 107,
// SI_SACRIFICE = 108,
// SI_GOSPEL = 109,
SI_ASSUMPTIO = 110,
// SI_BASILICA = 111,
- SI_LANDENDOW = 112,
+ SI_GROUNDMAGIC = 112,
SI_MAGICPOWER = 113,
SI_EDP = 114,
SI_TRUESIGHT = 115,
@@ -780,52 +797,52 @@ enum si_type {
SI_MELTDOWN = 117,
SI_CARTBOOST = 118,
// SI_CHASEWALK = 119,
- SI_REJECTSWORD = 120,
- SI_MARIONETTE = 121,
- SI_MARIONETTE2 = 122,
- SI_MOONLIT = 123,
- SI_BLEEDING = 124,
+ SI_SWORDREJECT = 120,
+ SI_MARIONETTE_MASTER = 121,
+ SI_MARIONETTE = 122,
+ SI_MOON = 123,
+ SI_BLOODING = 124,
SI_JOINTBEAT = 125,
// SI_MINDBREAKER = 126,
// SI_MEMORIZE = 127,
// SI_FOGWALL = 128,
// SI_SPIDERWEB = 129,
- SI_BABY = 130,
+ SI_PROTECTEXP = 130,
// SI_SUB_WEAPONPROPERTY = 131,
SI_AUTOBERSERK = 132,
SI_RUN = 133,
- SI_BUMP = 134,
- SI_READYSTORM = 135,
-// SI_STORMKICK_READY = 136,
- SI_READYDOWN = 137,
-// SI_DOWNKICK_READY = 138,
- SI_READYTURN = 139,
-// SI_TURNKICK_READY = 140,
- SI_READYCOUNTER = 141,
-// SI_COUNTER_READY = 142,
- SI_DODGE = 143,
-// SI_DODGE_READY = 144,
- SI_SPURT = 145,
- SI_SHADOWWEAPON = 146,
- SI_ADRENALINE2 = 147,
- SI_GHOSTWEAPON = 148,
- SI_SPIRIT = 149,
- SI_PLUSATTACKPOWER = 150,
- SI_PLUSMAGICPOWER = 151,
- SI_DEVIL = 152,
+ SI_TING = 134,
+ SI_STORMKICK_ON = 135,
+ SI_STORMKICK_READY = 136,
+ SI_DOWNKICK_ON = 137,
+ SI_DOWNKICK_READY = 138,
+ SI_TURNKICK_ON = 139,
+ SI_TURNKICK_READY = 140,
+ SI_COUNTER_ON = 141,
+ SI_COUNTER_READY = 142,
+ SI_DODGE_ON = 143,
+ SI_DODGE_READY = 144,
+ SI_STRUP = 145,
+ SI_PROPERTYDARK = 146,
+ SI_ADRENALINE2 = 147,
+ SI_PROPERTYTELEKINESIS = 148,
+ SI_SOULLINK = 149,
+ SI_PLUSATTACKPOWER = 150,
+ SI_PLUSMAGICPOWER = 151,
+ SI_DEVIL1 = 152,
SI_KAITE = 153,
// SI_SWOO = 154,
// SI_STAR2 = 155,
SI_KAIZEL = 156,
SI_KAAHI = 157,
SI_KAUPE = 158,
- SI_SMA = 159,
- SI_NIGHT = 160,
- SI_ONEHAND = 161,
+ SI_SMA_READY = 159,
+ SI_SKE = 160,
+ SI_ONEHANDQUICKEN = 161,
// SI_FRIEND = 162,
// SI_FRIENDUP = 163,
// SI_SG_WARM = 164,
- SI_WARM = 165,
+ SI_SG_SUN_WARM = 165,
// 166 | The three show the exact same display: ultra red character (165, 166, 167)
// 167 | Their names would be SI_SG_SUN_WARM, SI_SG_MOON_WARM, SI_SG_STAR_WARM
// SI_EMOTION = 168,
@@ -844,34 +861,34 @@ enum si_type {
SI_PRESERVE = 181,
SI_INCSTR = 182,
// SI_NOT_EXTREMITYFIST = 183,
- SI_INTRAVISION = 184,
+ SI_CLAIRVOYANCE = 184,
// SI_MOVESLOW_POTION = 185,
- SI_DOUBLECAST = 186,
+ SI_DOUBLECASTING = 186,
// SI_GRAVITATION = 187,
- SI_MAXOVERTHRUST = 188,
+ SI_OVERTHRUSTMAX = 188,
// SI_LONGING = 189,
// SI_HERMODE = 190,
- SI_TAROT = 191, // the icon allows no doubt... but what is it really used for ?? [DracoRPG]
+ SI_TAROTCARD = 191, // the icon allows no doubt... but what is it really used for ?? [DracoRPG]
// SI_HLIF_AVOID = 192,
// SI_HFLI_FLEET = 193,
// SI_HFLI_SPEED = 194,
// SI_HLIF_CHANGE = 195,
// SI_HAMI_BLOODLUST = 196,
- SI_SHRINK = 197,
- SI_SIGHTBLASTER = 198,
- SI_WINKCHARM = 199,
- SI_CLOSECONFINE = 200,
- SI_CLOSECONFINE2 = 201,
+ SI_CR_SHRINK = 197,
+ SI_WZ_SIGHTBLASTER = 198,
+ SI_DC_WINKCHARM = 199,
+ SI_RG_CCONFINE_M = 200,
+ SI_RG_CCONFINE_S = 201,
// SI_DISABLEMOVE = 202,
- SI_MADNESSCANCEL = 203, //[blackhole89]
- SI_GATLINGFEVER = 204,
- SI_EARTHSCROLL = 205,
- SI_UTSUSEMI = 206,
- SI_BUNSINJYUTSU = 207,
- SI_NEN = 208,
- SI_ADJUSTMENT = 209,
- SI_ACCURACY = 210,
-// SI_NJ_SUITON = 211,
+ SI_GS_MADNESSCANCEL = 203, //[blackhole89]
+ SI_GS_GATLINGFEVER = 204,
+ SI_EARTHSCROLL = 205,
+ SI_NJ_UTSUSEMI = 206,
+ SI_NJ_BUNSINJYUTSU = 207,
+ SI_NJ_NEN = 208,
+ SI_GS_ADJUSTMENT = 209,
+ SI_GS_ACCURACY = 210,
+ SI_NJ_SUITON = 211,
// SI_PET = 212,
// SI_MENTAL = 213,
// SI_EXPMEMORY = 214,
@@ -901,19 +918,19 @@ enum si_type {
// SI_DGAUGE = 238,
// SI_DACCEL = 239,
// SI_DBLOCK = 240,
- SI_FOODSTR = 241,
- SI_FOODAGI = 242,
- SI_FOODVIT = 243,
- SI_FOODDEX = 244,
- SI_FOODINT = 245,
- SI_FOODLUK = 246,
- SI_FOODFLEE = 247,
- SI_FOODHIT = 248,
- SI_FOODCRI = 249,
- SI_EXPBOOST = 250,
- SI_LIFEINSURANCE = 251,
- SI_ITEMBOOST = 252,
- SI_BOSSMAPINFO = 253,
+ SI_FOOD_STR = 241,
+ SI_FOOD_AGI = 242,
+ SI_FOOD_VIT = 243,
+ SI_FOOD_DEX = 244,
+ SI_FOOD_INT = 245,
+ SI_FOOD_LUK = 246,
+ SI_FOOD_BASICAVOIDANCE = 247,
+ SI_FOOD_BASICHIT = 248,
+ SI_FOOD_CRITICALSUCCESSVALUE = 249,
+ SI_CASH_PLUSEXP = 250,
+ SI_CASH_DEATHPENALTY = 251,
+ SI_CASH_RECEIVEITEM = 252,
+ SI_CASH_BOSS_ALARM = 253,
// SI_DA_ENERGY = 254,
// SI_DA_FIRSTSLOT = 255,
// SI_DA_HEADDEF = 256,
@@ -937,11 +954,11 @@ enum si_type {
SI_FOOD_DEX_CASH = 274,
SI_FOOD_INT_CASH = 275,
SI_FOOD_LUK_CASH = 276,
- SI_MERC_FLEEUP = 277,
- SI_MERC_ATKUP = 278,
- SI_MERC_HPUP = 279,
- SI_MERC_SPUP = 280,
- SI_MERC_HITUP = 281,
+ SI_MER_FLEE = 277,
+ SI_MER_ATK = 278,
+ SI_MER_HP = 279,
+ SI_MER_SP = 280,
+ SI_MER_HIT = 281,
SI_SLOWCAST = 282,
// SI_MAGICMIRROR = 283,
// SI_STONESKIN = 284,
@@ -949,14 +966,14 @@ enum si_type {
SI_CRITICALWOUND = 286,
// SI_NPC_DEFENDER = 287,
// SI_NOACTION_WAIT = 288,
- SI_MOVHASTE_HORSE = 289,
- SI_DEF_RATE = 290,
- SI_MDEF_RATE = 291,
- SI_INCHEALRATE = 292,
- SI_S_LIFEPOTION = 293,
- SI_L_LIFEPOTION = 294,
- SI_INCCRI = 295,
- SI_PLUSAVOIDVALUE = 296,
+ SI_MOVHASTE_HORSE = 289,
+ SI_PROTECT_DEF = 290,
+ SI_PROTECT_MDEF = 291,
+ SI_HEALPLUS = 292,
+ SI_S_LIFEPOTION = 293,
+ SI_L_LIFEPOTION = 294,
+ SI_CRITICALPERCENT = 295,
+ SI_PLUSAVOIDVALUE = 296,
// SI_ATKER_ASPD = 297,
// SI_TARGET_ASPD = 298,
// SI_ATKER_MOVESPEED = 299,
@@ -975,7 +992,7 @@ enum si_type {
SI_CASH_PLUSONLYJOBEXP = 312,
SI_PARTYFLEE = 313,
// SI_ANGEL_PROTECT = 314,
- SI_ENDURE_MDEF = 315,
+// SI_ENDURE_MDEF = 315,
SI_ENCHANTBLADE = 316,
SI_DEATHBOUND = 317,
SI_REFRESH = 318,
@@ -1094,12 +1111,12 @@ enum si_type {
SI_PROPERTYWALK = 431,
SI_SPELLFIST = 432,
SI_NETHERWORLD = 433,
- SI_VOICEOFSIREN = 434,
+ SI_SIREN = 434,
SI_DEEPSLEEP = 435,
SI_SIRCLEOFNATURE = 436,
SI_COLD = 437,
SI_GLOOMYDAY = 438,
- SI_SONGOFMANA = 439,
+ SI_SONG_OF_MANA = 439,
SI_CLOUDKILL = 440,
SI_DANCEWITHWUG = 441,
SI_RUSHWINDMILL = 442,
@@ -1361,6 +1378,34 @@ enum si_type {
SI_QUEST_BUFF3 = 707,
SI_REUSE_LIMIT_RECALL = 708,
SI_SAVEPOSITION = 709,
+ SI_HANDICAPSTATE_ICEEXPLO = 710,
+ SI_FENRIR_CARD = 711,
+ SI_REUSE_LIMIT_ASPD_POTION = 712,
+ SI_MAXPAIN = 713,
+ SI_PC_STOP = 714,
+ SI_FRIGG_SONG = 715,
+ SI_OFFERTORIUM = 716,
+ SI_TELEKINESIS_INTENSE = 717,
+ SI_MOONSTAR = 718,
+ SI_STRANGELIGHTS = 719,
+ SI_FULL_THROTTLE = 720,
+ SI_REBOUND = 721,
+ SI_UNLIMIT = 722,
+ SI_KINGS_GRACE = 723,
+ SI_ITEM_ATKMAX = 724,
+ SI_ITEM_ATKMIN = 725,
+ SI_ITEM_MATKMAX = 726,
+ SI_ITEM_MATKMIN = 727,
+ SI_SUPER_STAR = 728,
+ SI_HIGH_RANKER = 729,
+ SI_DARKCROW = 730,
+ SI_2013_VALENTINE1 = 731,
+ SI_2013_VALENTINE2 = 732,
+ SI_2013_VALENTINE3 = 733,
+ //SI_ = 734,
+ //SI_ = 735,
+ SI_CHILL = 736,
+ SI_BURNT = 737,
SI_MAX,
};
@@ -1553,7 +1598,7 @@ enum scb_flag
//Basic damage info of a weapon
//Required because players have two of these, one in status_data
//and another for their left hand weapon.
-struct weapon_atk {
+typedef struct weapon_atk {
unsigned short atk, atk2;
unsigned short range;
unsigned char ele;
@@ -1561,7 +1606,7 @@ struct weapon_atk {
unsigned short matk;
unsigned char wlv;
#endif
-};
+}weapon_atk;
sc_type SkillStatusChangeTable[MAX_SKILL]; // skill -> status
int StatusIconChangeTable[SC_MAX]; // status -> "icon" (icon is a bit of a misnomer, since there exist values with no icon associated)
@@ -1681,6 +1726,7 @@ sc_type status_skill2sc(int skill);
int status_sc2skill(sc_type sc);
unsigned int status_sc2scb_flag(sc_type sc);
int status_type2relevant_bl_types(int type);
+int status_get_sc_type(sc_type idx);
int status_damage(struct block_list *src,struct block_list *target,int hp,int sp, int walkdelay, int flag);
//Define for standard HP damage attacks.
@@ -1801,10 +1847,20 @@ int status_check_visibility(struct block_list *src, struct block_list *target);
int status_change_spread( struct block_list *src, struct block_list *bl );
+defType status_calc_def(struct block_list *bl, struct status_change *sc, int, bool);
+signed short status_calc_def2(struct block_list *,struct status_change *, int, bool);
+defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int, bool);
+signed short status_calc_mdef2(struct block_list *,struct status_change *, int, bool);
+
#ifdef RENEWAL
unsigned short status_base_matk(const struct status_data* status, int level);
+int status_get_weapon_atk(struct block_list *src, struct weapon_atk *watk, int flag);
+int status_get_total_mdef(struct block_list *src);
+int status_get_total_def(struct block_list *src);
#endif
+int status_get_matk(struct block_list *src, int flag);
+
int status_readdb(void);
int do_init_status(void);
void do_final_status(void);
diff --git a/src/map/unit.c b/src/map/unit.c
index 153ef5eda..371a75ac7 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -491,7 +491,7 @@ int unit_run(struct block_list *bl)
if( (to_x == bl->x && to_y == bl->y ) || (to_x == (bl->x+1) || to_y == (bl->y+1)) || (to_x == (bl->x-1) || to_y == (bl->y-1))) {
//If you can't run forward, you must be next to a wall, so bounce back. [Skotlex]
- clif->sc_load(bl,bl->id,AREA,SI_BUMP,0,0,0);
+ clif->sc_load(bl,bl->id,AREA,SI_TING,0,0,0);
//Set running to 0 beforehand so status_change_end knows not to enable spurt [Kevin]
unit_bl2ud(bl)->state.running = 0;
@@ -499,7 +499,7 @@ int unit_run(struct block_list *bl)
skill->blown(bl,bl,skill->get_blewcount(TK_RUN,lv),unit_getdir(bl),0);
clif->fixpos(bl); //Why is a clif->slide (skill->blown) AND a fixpos needed? Ask Aegis.
- clif->sc_end(bl,bl->id,AREA,SI_BUMP);
+ clif->sc_end(bl,bl->id,AREA,SI_TING);
return 0;
}
if (unit_walktoxy(bl, to_x, to_y, 1))
@@ -511,7 +511,7 @@ int unit_run(struct block_list *bl)
} while (--i > 0 && !unit_walktoxy(bl, to_x, to_y, 1));
if ( i == 0 ) {
// copy-paste from above
- clif->sc_load(bl,bl->id,AREA,SI_BUMP,0,0,0);
+ clif->sc_load(bl,bl->id,AREA,SI_TING,0,0,0);
//Set running to 0 beforehand so status_change_end knows not to enable spurt [Kevin]
unit_bl2ud(bl)->state.running = 0;
@@ -519,7 +519,7 @@ int unit_run(struct block_list *bl)
skill->blown(bl,bl,skill->get_blewcount(TK_RUN,lv),unit_getdir(bl),0);
clif->fixpos(bl);
- clif->sc_end(bl,bl->id,AREA,SI_BUMP);
+ clif->sc_end(bl,bl->id,AREA,SI_TING);
return 0;
}
return 1;
@@ -924,7 +924,7 @@ int unit_can_move(struct block_list *bl) {
if (sc) {
if( sc->count && (
- sc->data[SC_ANKLE]
+ sc->data[SC_ANKLESNARE]
|| sc->data[SC_AUTOCOUNTER]
|| sc->data[SC_TRICKDEAD]
|| sc->data[SC_BLADESTOP]
@@ -932,14 +932,14 @@ int unit_can_move(struct block_list *bl) {
|| (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF) // cannot move while gospel is in effect
|| (sc->data[SC_BASILICA] && sc->data[SC_BASILICA]->val4 == bl->id) // Basilica caster cannot move
|| sc->data[SC_STOP]
- || sc->data[SC_CLOSECONFINE]
- || sc->data[SC_CLOSECONFINE2]
- || sc->data[SC_MADNESSCANCEL]
+ || sc->data[SC_RG_CCONFINE_M]
+ || sc->data[SC_RG_CCONFINE_S]
+ || sc->data[SC_GS_MADNESSCANCEL]
|| (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF)
|| sc->data[SC_WHITEIMPRISON]
|| sc->data[SC_ELECTRICSHOCKER]
- || sc->data[SC_BITE]
- || sc->data[SC_THORNSTRAP]
+ || sc->data[SC_WUGBITE]
+ || sc->data[SC_THORNS_TRAP]
|| sc->data[SC_MAGNETICFIELD]
|| sc->data[SC__MANHOLE]
|| sc->data[SC_CURSEDCIRCLE_ATKER]
@@ -948,9 +948,9 @@ int unit_can_move(struct block_list *bl) {
|| sc->data[SC_NETHERWORLD]
|| (sc->data[SC_CAMOUFLAGE] && sc->data[SC_CAMOUFLAGE]->val1 < 3 && !(sc->data[SC_CAMOUFLAGE]->val3&1))
|| sc->data[SC_MEIKYOUSISUI]
- || sc->data[SC_KAGEHUMI]
+ || sc->data[SC_KG_KAGEHUMI]
|| sc->data[SC_KYOUGAKU]
- || sc->data[SC_PARALYSIS]
+ || sc->data[SC_NEEDLE_OF_PARALYZE]
|| sc->data[SC_VACUUM_EXTREME]
|| (sc->data[SC_FEAR] && sc->data[SC_FEAR]->val2 > 0)
|| (sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
@@ -1069,10 +1069,10 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
sc = NULL; //Unneeded
//temp: used to signal combo-skills right now.
- if (sc && sc->data[SC_COMBO] && (sc->data[SC_COMBO]->val1 == skill_id ||
+ if (sc && sc->data[SC_COMBOATTACK] && (sc->data[SC_COMBOATTACK]->val1 == skill_id ||
(sd?skill->check_condition_castbegin(sd,skill_id,skill_lv):0) )) {
- if (sc->data[SC_COMBO]->val2)
- target_id = sc->data[SC_COMBO]->val2;
+ if (sc->data[SC_COMBOATTACK]->val2)
+ target_id = sc->data[SC_COMBOATTACK]->val2;
else
target_id = ud->target;
@@ -1240,17 +1240,17 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
casttime += casttime * min(skill_lv, sd->spiritball);
break;
case MO_EXTREMITYFIST:
- if (sc && sc->data[SC_COMBO] &&
- (sc->data[SC_COMBO]->val1 == MO_COMBOFINISH ||
- sc->data[SC_COMBO]->val1 == CH_TIGERFIST ||
- sc->data[SC_COMBO]->val1 == CH_CHAINCRUSH))
+ if (sc && sc->data[SC_COMBOATTACK] &&
+ (sc->data[SC_COMBOATTACK]->val1 == MO_COMBOFINISH ||
+ sc->data[SC_COMBOATTACK]->val1 == CH_TIGERFIST ||
+ sc->data[SC_COMBOATTACK]->val1 == CH_CHAINCRUSH))
casttime = -1;
temp = 1;
break;
case SR_GATEOFHELL:
case SR_TIGERCANNON:
- if (sc && sc->data[SC_COMBO] &&
- sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE)
+ if (sc && sc->data[SC_COMBOATTACK] &&
+ sc->data[SC_COMBOATTACK]->val1 == SR_FALLENEMPIRE)
casttime = -1;
temp = 1;
break;
@@ -1317,10 +1317,11 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
if(!ud->state.running) //need TK_RUN or WUGDASH handler to be done before that, see bugreport:6026
unit_stop_walking(src,1);// eventhough this is not how official works but this will do the trick. bugreport:6829
+
// in official this is triggered even if no cast time.
clif->skillcasting(src, src->id, target_id, 0,0, skill_id, skill->get_ele(skill_id, skill_lv), casttime);
if( casttime > 0 || temp )
- {
+ {
if (sd && target->type == BL_MOB)
{
TBL_MOB *md = (TBL_MOB*)target;
@@ -1518,7 +1519,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
if( casttime > 0 ) {
ud->skilltimer = iTimer->add_timer( tick+casttime, skill->castend_pos, src->id, 0 );
if( (sd && pc->checkskill(sd,SA_FREECAST) > 0) || skill_id == LG_EXEEDBREAK)
- status_calc_bl(&sd->bl, SCB_SPEED);
+ status_calc_bl(&sd->bl, SCB_SPEED);
} else {
ud->skilltimer = INVALID_TIMER;
skill->castend_pos(ud->skilltimer,tick,src->id,0);
@@ -1638,7 +1639,7 @@ int unit_cancel_combo(struct block_list *bl)
{
struct unit_data *ud;
- if (!status_change_end(bl, SC_COMBO, INVALID_TIMER))
+ if (!status_change_end(bl, SC_COMBOATTACK, INVALID_TIMER))
return 0; //Combo wasn't active.
ud = unit_bl2ud(bl);
@@ -1925,7 +1926,7 @@ int unit_skillcastcancel(struct block_list *bl,int type)
return 0;
if (sd && (sd->special_state.no_castcancel2 ||
- ((sd->sc.data[SC_UNLIMITEDHUMMINGVOICE] || sd->special_state.no_castcancel) && !map_flag_gvg(bl->m) && !map[bl->m].flag.battleground))) //fixed flags being read the wrong way around [blackhole89]
+ ((sd->sc.data[SC_UNLIMITED_HUMMING_VOICE] || sd->special_state.no_castcancel) && !map_flag_gvg(bl->m) && !map[bl->m].flag.battleground))) //fixed flags being read the wrong way around [blackhole89]
return 0;
}
@@ -2053,17 +2054,17 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
if(sc && sc->count ) { //map-change/warp dispells.
status_change_end(bl, SC_BLADESTOP, INVALID_TIMER);
status_change_end(bl, SC_BASILICA, INVALID_TIMER);
- status_change_end(bl, SC_ANKLE, INVALID_TIMER);
+ status_change_end(bl, SC_ANKLESNARE, INVALID_TIMER);
status_change_end(bl, SC_TRICKDEAD, INVALID_TIMER);
status_change_end(bl, SC_BLADESTOP_WAIT, INVALID_TIMER);
status_change_end(bl, SC_RUN, INVALID_TIMER);
status_change_end(bl, SC_DANCING, INVALID_TIMER);
status_change_end(bl, SC_WARM, INVALID_TIMER);
status_change_end(bl, SC_DEVOTION, INVALID_TIMER);
+ status_change_end(bl, SC_MARIONETTE_MASTER, INVALID_TIMER);
status_change_end(bl, SC_MARIONETTE, INVALID_TIMER);
- status_change_end(bl, SC_MARIONETTE2, INVALID_TIMER);
- status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
- status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
+ status_change_end(bl, SC_RG_CCONFINE_M, INVALID_TIMER);
+ status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER);
status_change_end(bl, SC_HIDING, INVALID_TIMER);
// Ensure the bl is a PC; if so, we'll handle the removal of cloaking and cloaking exceed later
if ( bl->type != BL_PC )
@@ -2074,7 +2075,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
status_change_end(bl, SC_CHASEWALK, INVALID_TIMER);
if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
- status_change_end(bl, SC_CHANGE, INVALID_TIMER);
+ status_change_end(bl, SC_HLIF_CHANGE, INVALID_TIMER);
status_change_end(bl, SC_STOP, INVALID_TIMER);
status_change_end(bl, SC_WUGDASH, INVALID_TIMER);
status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
@@ -2322,7 +2323,7 @@ int unit_free(struct block_list *bl, clr_type clrtype)
pc->inventory_rental_clear(sd);
pc->delspiritball(sd,sd->spiritball,1);
for(i = 1; i < 5; i++)
- pc->del_talisman(sd, sd->talisman[i], i);
+ pc->del_charm(sd, sd->charm[i], i);
if( sd->reg ) { //Double logout already freed pointer fix... [Skotlex]
aFree(sd->reg);
diff --git a/src/map/vending.c b/src/map/vending.c
index e0dd844e1..b9575c8dd 100644
--- a/src/map/vending.c
+++ b/src/map/vending.c
@@ -272,7 +272,7 @@ void vending_openvending(struct map_session_data* sd, const char* message, const
clif->skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet
return;
}
- sd->state.prevend = 0;
+ sd->state.prevend = sd->state.workinprogress = 0;
sd->state.vending = true;
sd->vender_id = getid();
sd->vend_num = i;