summaryrefslogtreecommitdiff
path: root/src/map/status.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/status.c')
-rw-r--r--src/map/status.c1764
1 files changed, 1712 insertions, 52 deletions
diff --git a/src/map/status.c b/src/map/status.c
index 4df2c80d6..28506a4f6 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -56,7 +56,13 @@ static int refinebonus[MAX_REFINE_BONUS][3]; // Έ˜Bƒ{[ƒiƒXƒe[ƒuƒ‹(refine_db.t
int percentrefinery[5][MAX_REFINE+1]; // Έ˜B¬Œχ—¦(refine_db.txt)
static int atkmods[3][MAX_WEAPON_TYPE]; // •ŠνATKƒTƒCƒYC³(size_fix.txt)
static char job_bonus[CLASS_COUNT][MAX_LEVEL];
-
+#if RRMODE
+enum {
+ SHIELD_ASPD,
+ RE_JOB_DB_MAX,
+} RE_JOB_DB;
+static int re_job_db[CLASS_COUNT][RE_JOB_DB_MAX];//[RRInd]
+#endif
static struct eri *sc_data_ers; //For sc_data entries
static struct status_data dummy_status;
@@ -445,6 +451,162 @@ void initChangeTables(void)
set_sc( GD_LEADERSHIP , SC_GUILDAURA , SI_BLANK , SCB_STR|SCB_AGI|SCB_VIT|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 );
+
+ /**
+ * Rune Knight
+ **/
+ set_sc( RK_ENCHANTBLADE , SC_ENCHANTBLADE , SI_ENCHANTBLADE , SCB_NONE );
+ 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_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_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 );
+ /**
+ * GC Guillotine Cross
+ **/
+ set_sc( GC_VENOMIMPRESS , SC_VENOMIMPRESS , SI_VENOMIMPRESS , SCB_NONE );
+ set_sc( GC_POISONINGWEAPON , SC_POISONINGWEAPON , SI_POISONINGWEAPON , SCB_NONE );
+ set_sc( GC_WEAPONBLOCKING , SC_WEAPONBLOCKING , SI_WEAPONBLOCKING , SCB_NONE );
+ 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 );
+ /**
+ * 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 );
+ set_sc( AB_EPICLESIS , SC_EPICLESIS , SI_EPICLESIS , SCB_MAXHP );
+ add_sc( AB_PRAEFATIO , SC_KYRIE );
+ set_sc( AB_ORATIO , SC_ORATIO , SI_ORATIO , SCB_NONE );
+ set_sc( AB_LAUDAAGNUS , SC_LAUDAAGNUS , SI_LAUDAAGNUS , SCB_VIT );
+ set_sc( AB_LAUDARAMUS , SC_LAUDARAMUS , SI_LAUDARAMUS , SCB_LUK );
+ set_sc( AB_RENOVATIO , SC_RENOVATIO , SI_RENOVATIO , SCB_REGEN );
+ 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 );
+ /**
+ * Warlock
+ **/
+ add_sc( WL_WHITEIMPRISON , SC_WHITEIMPRISON );
+ set_sc( 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( WL_RECOGNIZEDSPELL , SC_RECOGNIZEDSPELL , SI_RECOGNIZEDSPELL , SCB_NONE );
+ set_sc( WL_STASIS , SC_STASIS , SI_STASIS , SCB_NONE );
+ /**
+ * Ranger
+ **/
+ set_sc( RA_FEARBREEZE , SC_FEARBREEZE , SI_FEARBREEZE , SCB_NONE );
+ 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_CRI|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( RA_ICEBOUNDTRAP , SC_FREEZING , SI_FROSTMISTY , SCB_NONE );
+ /**
+ * Mechanic
+ **/
+ set_sc( NC_ACCELERATION , SC_ACCELERATION , SI_ACCELERATION , SCB_SPEED );
+ set_sc( NC_HOVERING , SC_HOVERING , SI_HOVERING , SCB_SPEED );
+ set_sc( NC_SHAPESHIFT , SC_SHAPESHIFT , SI_SHAPESHIFT , SCB_DEF_ELE );
+ set_sc( NC_INFRAREDSCAN , SC_INFRAREDSCAN , SI_INFRAREDSCAN , SCB_FLEE );
+ set_sc( NC_ANALYZE , SC_ANALYZE , SI_ANALYZE , SCB_DEF|SCB_DEF2|SCB_MDEF|SCB_MDEF2 );
+ set_sc( NC_MAGNETICFIELD , SC_MAGNETICFIELD , SI_MAGNETICFIELD , SCB_NONE );
+ set_sc( NC_NEUTRALBARRIER , SC_NEUTRALBARRIER , SI_NEUTRALBARRIER , SCB_NONE );
+ set_sc( NC_STEALTHFIELD , SC_STEALTHFIELD , SI_STEALTHFIELD , SCB_NONE );
+ ///**
+ // * Shadow Chaser
+ // **/
+ //set_sc( SC_REPRODUCE , SC__REPRODUCE , SI_REPRODUCE , SCB_NONE );
+ //set_sc( SC_AUTOSHADOWSPELL , SC__AUTOSHADOWSPELL, SI_AUTOSHADOWSPELL , SCB_NONE );
+ //set_sc( SC_SHADOWFORM , SC__SHADOWFORM , SI_SHADOWFORM , SCB_NONE );
+ //set_sc( SC_BODYPAINT , SC__BODYPAINT , SI_BODYPAINTING , SCB_ASPD );
+ //set_sc( SC_INVISIBILITY , SC__INVISIBILITY , SI_INVISIBILITY , SCB_ASPD|SCB_CRI|SCB_ATK_ELE );
+ //set_sc( SC_DEADLYINFECT , SC__DEADLYINFECT , SI_DEADLYINFECT , SCB_NONE );
+ //set_sc( SC_ENERVATION , SC__ENERVATION , SI_ENERVATION , SCB_BATK );
+ //set_sc( SC_GROOMY , SC__GROOMY , SI_GROOMY , SCB_ASPD|SCB_HIT|SCB_SPEED );
+ //set_sc( SC_IGNORANCE , SC__IGNORANCE , SI_IGNORANCE , SCB_NONE );
+ //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_STRIPACCESSORY , SCB_DEX|SCB_INT|SCB_LUK );
+ //set_sc( SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE );
+ //add_sc( SC_CHAOSPANIC , SC_CHAOS );
+ //set_sc( SC_BLOODYLUST , SC__BLOODYLUST , SI_BLOODYLUST , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
+ ///**
+ // * Royal Guard
+ // **/
+ //set_sc( LG_REFLECTDAMAGE , SC_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_DEF2 );
+ //set_sc( LG_BANDING , SC_BANDING , SI_BANDING , SCB_DEF2|SCB_WATK );// Renewal: atk2 & def2
+ //set_sc( LG_PIETY , SC_BENEDICTIO , SI_BENEDICTIO , SCB_DEF_ELE );
+ //set_sc( LG_EARTHDRIVE , SC_EARTHDRIVE , SI_EARTHDRIVE , SCB_DEF|SCB_ASPD );
+ //set_sc( LG_INSPIRATION , SC_INSPIRATION , SI_INSPIRATION , SCB_MAXHP|SCB_WATK|SCB_HIT|SCB_VIT|SCB_AGI|SCB_STR|SCB_DEX|SCB_INT|SCB_LUK);
+ ///**
+ // * Sura
+ // **/
+ //add_sc( SR_DRAGONCOMBO , SC_STUN );
+ //add_sc( SR_EARTHSHAKER , SC_STUN );
+ //set_sc( SR_CRESCENTELBOW , SC_CRESCENTELBOW , SI_CRESCENTELBOW , SCB_NONE );
+ //set_sc( SR_CURSEDCIRCLE , SC_CURSEDCIRCLE_TARGET, SI_CURSEDCIRCLE_TARGET , SCB_NONE );
+ //set_sc( SR_LIGHTNINGWALK , SC_LIGHTNINGWALK , SI_LIGHTNINGWALK , SCB_NONE );
+ //set_sc( SR_RAISINGDRAGON , SC_RAISINGDRAGON , SI_RAISINGDRAGON , SCB_REGEN|SCB_MAXHP|SCB_MAXSP/*|SCB_ASPD*/ );
+ //set_sc( SR_GENTLETOUCH_ENERGYGAIN, SC_GT_ENERGYGAIN , SI_GENTLETOUCH_ENERGYGAIN, SCB_NONE );
+ //set_sc( SR_GENTLETOUCH_CHANGE , SC_GT_CHANGE , SI_GENTLETOUCH_CHANGE , SCB_BATK|SCB_ASPD|SCB_DEF|SCB_MDEF );
+ //set_sc( SR_GENTLETOUCH_REVITALIZE, SC_GT_REVITALIZE , SI_GENTLETOUCH_REVITALIZE, SCB_MAXHP|SCB_DEF2|SCB_REGEN|SCB_ASPD|SCB_SPEED );
+ ///**
+ // * Wanderer / Mistrel
+ // **/
+ //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( WM_POEMOFNETHERWORLD , SC_STOP , SI_NETHERWORLD , SCB_NONE );
+ //set_sc( WM_VOICEOFSIREN , SC_VOICEOFSIREN , SI_VOICEOFSIREN , SCB_NONE );
+ //set_sc( 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 );
+ ///**
+ // * Sorcerer
+ // **/
+ //set_sc( SO_FIREWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE );
+ //set_sc( SO_ELECTRICWALK , SC_PROPERTYWALK , SI_PROPERTYWALK , SCB_NONE );
+ //set_sc( SO_SPELLFIST , SC_SPELLFIST , SI_SPELLFIST , SCB_NONE );
+ //set_sc( SO_CLOUD_KILL , SC_POISON , SI_CLOUDKILL , SCB_NONE );
+ //set_sc( SO_STRIKING , SC_STRIKING , SI_STRIKING , SCB_WATK|SCB_CRI );
+ //set_sc( SO_WARMER , SC_WARMER , SI_WARMER , SCB_NONE );
+ //set_sc( SO_VACUUM_EXTREME , SC_VACUUM_EXTREME , SI_VACUUM_EXTREME , SCB_NONE );
+ //set_sc( SO_ARRULLO , SC_DEEPSLEEP , SI_DEEPSLEEP , SCB_NONE );
+ ///**
+ // * 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( GN_BLOOD_SUCKER , SC_BLOODSUCKER , 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_MANDRAGORA , SC_MANDRAGORA , SI_MANDRAGORA , SCB_INT );
// Storing the target job rather than simply SC_SPIRIT simplifies code later on.
SkillStatusChangeTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
@@ -516,6 +678,81 @@ void initChangeTables(void)
StatusIconChangeTable[SC_MERC_HPUP] = SI_MERC_HPUP;
StatusIconChangeTable[SC_MERC_SPUP] = SI_MERC_SPUP;
StatusIconChangeTable[SC_MERC_HITUP] = SI_MERC_HITUP;
+ // 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_NEUTRALBARRIER_MASTER] = SI_NEUTRALBARRIER_MASTER;
+ StatusIconChangeTable[SC_STEALTHFIELD_MASTER] = SI_STEALTHFIELD_MASTER;
+ StatusIconChangeTable[SC_OVERHEAT] = SI_OVERHEAT;
+ StatusIconChangeTable[SC_OVERHEAT_LIMITPOINT] = SI_OVERHEAT_LIMITPOINT;
+
+ StatusIconChangeTable[SC_HALLUCINATIONWALK_POSTDELAY] = SI_HALLUCINATIONWALK_POSTDELAY;
+ StatusIconChangeTable[SC_TOXIN] = SI_TOXIN;
+ StatusIconChangeTable[SC_PARALYSE] = SI_PARALYSE;
+ StatusIconChangeTable[SC_VENOMBLEED] = SI_VENOMBLEED;
+ StatusIconChangeTable[SC_MAGICMUSHROOM] = SI_MAGICMUSHROOM;
+ StatusIconChangeTable[SC_DEATHHURT] = SI_DEATHHURT;
+ StatusIconChangeTable[SC_PYREXIA] = SI_PYREXIA;
+ StatusIconChangeTable[SC_OBLIVIONCURSE] = SI_OBLIVIONCURSE;
+ StatusIconChangeTable[SC_LEECHESEND] = SI_LEECHESEND;
+
+ StatusIconChangeTable[SC_SHIELDSPELL_DEF] = SI_SHIELDSPELL_DEF;
+ StatusIconChangeTable[SC_SHIELDSPELL_MDEF] = SI_SHIELDSPELL_MDEF;
+ StatusIconChangeTable[SC_SHIELDSPELL_REF] = SI_SHIELDSPELL_REF;
+ StatusIconChangeTable[SC_BANDING_DEFENCE] = SI_BANDING_DEFENCE;
+
+ StatusIconChangeTable[SC_GLOOMYDAY_SK] = SI_GLOOMYDAY;
+
+ StatusIconChangeTable[SC_CURSEDCIRCLE_ATKER] = SI_CURSEDCIRCLE_ATKER;
+
+ StatusIconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE;
+ 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;
+
+ //Genetics New Food Items Status Icons
+ StatusIconChangeTable[SC_SAVAGE_STEAK] = SI_SAVAGE_STEAK;
+ StatusIconChangeTable[SC_COCKTAIL_WARG_BLOOD] = SI_COCKTAIL_WARG_BLOOD;
+ StatusIconChangeTable[SC_MINOR_BBQ] = SI_MINOR_BBQ;
+ StatusIconChangeTable[SC_SIROMA_ICE_TEA] = SI_SIROMA_ICE_TEA;
+ StatusIconChangeTable[SC_DROCERA_HERB_STEAMED] = SI_DROCERA_HERB_STEAMED;
+ StatusIconChangeTable[SC_PUTTI_TAILS_NOODLES] = SI_PUTTI_TAILS_NOODLES;
+
+ StatusIconChangeTable[SC_BOOST500] |= SI_BOOST500;
+ StatusIconChangeTable[SC_FULL_SWING_K] |= SI_FULL_SWING_K;
+ StatusIconChangeTable[SC_MANA_PLUS] |= SI_MANA_PLUS;
+ StatusIconChangeTable[SC_MUSTLE_M] |= SI_MUSTLE_M;
+ StatusIconChangeTable[SC_LIFE_FORCE_F] |= SI_LIFE_FORCE_F;
+ StatusIconChangeTable[SC_EXTRACT_WHITE_POTION_Z] |= SI_EXTRACT_WHITE_POTION_Z;
+ StatusIconChangeTable[SC_VITATA_500] |= SI_VITATA_500;
+ StatusIconChangeTable[SC_EXTRACT_SALAMINE_JUICE] |= SI_EXTRACT_SALAMINE_JUICE;
+
+ // Elemental Spirit's 'side' status change icons.
+ StatusIconChangeTable[SC_CIRCLE_OF_FIRE] = SI_CIRCLE_OF_FIRE;
+ StatusIconChangeTable[SC_FIRE_CLOAK] = SI_FIRE_CLOAK;
+ StatusIconChangeTable[SC_WATER_SCREEN] = SI_WATER_SCREEN;
+ StatusIconChangeTable[SC_WATER_DROP] = SI_WATER_DROP;
+ StatusIconChangeTable[SC_WIND_STEP] = SI_WIND_STEP;
+ StatusIconChangeTable[SC_WIND_CURTAIN] = SI_WIND_CURTAIN;
+ StatusIconChangeTable[SC_SOLID_SKIN] = SI_SOLID_SKIN;
+ StatusIconChangeTable[SC_STONE_SHIELD] = SI_STONE_SHIELD;
+ StatusIconChangeTable[SC_PYROTECHNIC] = SI_PYROTECHNIC;
+ StatusIconChangeTable[SC_HEATER] = SI_HEATER;
+ StatusIconChangeTable[SC_TROPIC] = SI_TROPIC;
+ StatusIconChangeTable[SC_AQUAPLAY] = SI_AQUAPLAY;
+ StatusIconChangeTable[SC_COOLER] = SI_COOLER;
+ StatusIconChangeTable[SC_CHILLY_AIR] = SI_CHILLY_AIR;
+ StatusIconChangeTable[SC_GUST] = SI_GUST;
+ StatusIconChangeTable[SC_BLAST] = SI_BLAST;
+ StatusIconChangeTable[SC_WILD_STORM] = SI_WILD_STORM;
+ StatusIconChangeTable[SC_PETROLOGY] = SI_PETROLOGY;
+ StatusIconChangeTable[SC_CURSED_SOIL] = SI_CURSED_SOIL;
+ StatusIconChangeTable[SC_UPHEAVAL] = SI_UPHEAVAL;
//Other SC which are not necessarily associated to skills.
StatusChangeFlagTable[SC_ASPDPOTION0] = SCB_ASPD;
@@ -573,7 +810,12 @@ void initChangeTables(void)
StatusChangeFlagTable[SC_MERC_HPUP] |= SCB_MAXHP;
StatusChangeFlagTable[SC_MERC_SPUP] |= SCB_MAXSP;
StatusChangeFlagTable[SC_MERC_HITUP] |= SCB_HIT;
-
+#if RE_EDP
+ /**
+ * In RE EDP increases your atk and weapon atk
+ **/
+ StatusChangeFlagTable[SC_EDP] |= SCB_BATK|SCB_WATK;
+#endif
if( !battle_config.display_hallucination ) //Disable Hallucination.
StatusIconChangeTable[SC_HALLUCINATION] = SI_BLANK;
}
@@ -728,6 +970,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
status_change_end(target, SC_HIDING, INVALID_TIMER);
status_change_end(target, SC_CLOAKING, INVALID_TIMER);
status_change_end(target, SC_CHASEWALK, INVALID_TIMER);
+ status_change_end(target, SC_CAMOUFLAGE, INVALID_TIMER);
if ((sce=sc->data[SC_ENDURE]) && !sce->val4) {
//Endure count is only reduced by non-players on non-gvg maps.
//val4 signals infinite endure. [Skotlex]
@@ -745,6 +988,8 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
}
if(sc->data[SC_DANCING] && (unsigned int)hp > status->max_hp>>2)
status_change_end(target, SC_DANCING, INVALID_TIMER);
+ if(sc->data[SC_CLOAKINGEXCEED] && --(sc->data[SC_CLOAKINGEXCEED]->val2) <= 0)
+ status_change_end(target,SC_CLOAKINGEXCEED,-1);
}
unit_skillcastcancel(target, 2);
}
@@ -1176,6 +1421,8 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
}
if (sc->option&OPTION_CHASEWALK && skill_num != ST_CHASEWALK)
return 0;
+ if(sc->option&OPTION_MOUNTING)
+ return 0;//New mounts can't attack nor use skills in the client; this check makes it cheat-safe [Ind]
}
if (target == NULL || target == src) //No further checking needed.
return 1;
@@ -1210,6 +1457,8 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
if (tsc->option&hide_flag && !(status->mode&MD_BOSS) &&
(sd->special_state.perfect_hiding || !(status->mode&MD_DETECTOR)))
return 0;
+ if( tsc->data[SC_CAMOUFLAGE] && !(status->mode&(MD_BOSS|MD_DETECTOR)) && !skill_num )
+ return 0;
}
break;
case BL_ITEM: //Allow targetting of items to pick'em up (or in the case of mobs, to loot them).
@@ -1256,18 +1505,14 @@ int status_check_visibility(struct block_list *src, struct block_list *target)
switch (target->type)
{ //Check for chase-walk/hiding/cloaking opponents.
case BL_PC:
- if(tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) &&
- !(status->mode&MD_BOSS) &&
- (
- ((TBL_PC*)target)->special_state.perfect_hiding ||
- !(status->mode&MD_DETECTOR)
- ))
+ if( (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC_CAMOUFLAGE]) && !(status->mode&MD_BOSS) &&
+ ( ((TBL_PC*)target)->special_state.perfect_hiding || !(status->mode&MD_DETECTOR) ) )
return 0;
break;
default:
- if (tsc && tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) &&
- !(status->mode&(MD_BOSS|MD_DETECTOR)))
- return 0;
+ if( tsc && (tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) || tsc->data[SC_CAMOUFLAGE]) && !(status->mode&(MD_BOSS|MD_DETECTOR)) )
+ return 0;
+
}
return 1;
@@ -1288,7 +1533,24 @@ int status_base_amotion_pc(struct map_session_data* sd, struct status_data* stat
// raw delay adjustment from bAspd bonus
amotion+= sd->aspd_add;
-
+#if RRMODE
+ /**
+ * Bearing a shield decreases your ASPD by a fixed value depending on your class
+ **/
+ if( sd->status.shield )
+ amotion += re_job_db[pc_class2idx(sd->status.class_)][SHIELD_ASPD];
+ /**
+ * RE Absolute aspd modifiers
+ **/
+ if( sd->sc.count ) {
+ int i;
+ if ( sd->sc.data[i=SC_ASPDPOTION3] ||
+ sd->sc.data[i=SC_ASPDPOTION2] ||
+ sd->sc.data[i=SC_ASPDPOTION1] ||
+ sd->sc.data[i=SC_ASPDPOTION0] )
+ amotion -= sd->sc.data[i]->val1*10;
+ }
+#endif
return amotion;
}
@@ -1331,13 +1593,24 @@ static unsigned short status_base_atk(const struct block_list *bl, const struct
static inline unsigned short status_base_matk_max(const struct status_data* status)
{
- return status->int_+(status->int_/5)*(status->int_/5);
+ #if RRMODE
+ return status->matk_max;//In RE maximum MATK signs weapon matk, which we store in this var
+ #else //Original Max MATK Formula
+ return status->int_+(status->int_/5)*(status->int_/5);
+ #endif
}
-
+#if RRMODE
+static inline unsigned short status_base_matk_min(const struct status_data* status, int lvl)
+#else
static inline unsigned short status_base_matk_min(const struct status_data* status)
+#endif
{
- return status->int_+(status->int_/7)*(status->int_/7);
+ #if RRMODE //Renewal MATK Formula
+ return status->int_+(status->int_/2)+(status->dex/5)+(status->luk/3)+(lvl/4);
+ #else //Original Min MATK Formula
+ return status->int_+(status->int_/7)*(status->int_/7);
+ #endif
}
@@ -1350,14 +1623,31 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev
status->hit = status->flee =
status->def2 = status->mdef2 =
status->cri = status->flee2 = 0;
-
+#if RRMODE
+ status->matk_min = status_base_matk_min(status, level);
+#else
status->matk_min = status_base_matk_min(status);
+#endif
status->matk_max = status_base_matk_max(status);
+#if RRMODE //Renewal Formulas
+ status->hit += level + status->dex;//base level + ( every 1 dex = +1 hit )
+ status->hit += status->luk / 3;//every 3 luk = +1 hit
+ status->flee += level + status->agi;//base level + ( every 1 agi = +1 flee )
+ status->flee += status->luk/5;//every 5 luk = +1 flee
+ status->def2 += status->agi / 5;//every 5 agi = +1 def
+ status->def2 += status->vit / 2;//every 2 agi = +1 def
+ status->def2 += level / 2;//every 2 lvls = +1 def
+ status->mdef2 += status->int_ / 2;//every 2 int = +1 mdef
+ status->mdef2 += status->dex / 5;//every 5 dex = +1 mdef
+ status->mdef2 += level /4;//every 4 lvls = +1 mdef
+ //status->matk_min += level/4;//every 4 lvls = +1 matk
+#else //Old Formulas
status->hit += level + status->dex;
status->flee += level + status->agi;
status->def2 += status->vit;
status->mdef2 += status->int_ + (status->vit>>1);
+#endif
if( bl->type&battle_config.enable_critical )
status->cri += status->luk*3 + 10;
@@ -1374,6 +1664,10 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev
status->batk = cap_value(temp, 0, USHRT_MAX);
} else
status->batk = status_base_atk(bl, status);
+#if RRMODE //Renewal ATK Bonus Formula (after atk is calculated)
+ status->batk += status->luk / 3;//every 3 luk = +1ATK
+ status->batk += level / 4;//every 4 levels = +1 ATK
+#endif
if (status->cri)
switch (bl->type) {
case BL_MOB:
@@ -1684,6 +1978,18 @@ static unsigned int status_base_pc_maxsp(struct map_session_data* sd, struct sta
return val;
}
+#if RRMODE
+/**
+ * Renewal Absolute Bonus to be applied after all bonuses were applied (so % bonuses on say, skills, don't affect them)
+ **/
+void status_renewal_postcalc(struct status_data* status, int flag) {
+ if( flag&SCB_FLEE )
+ status->flee += 100;
+ if( flag&SCB_HIT )
+ status->hit += 175;
+ return;
+}
+#endif
//Calculates player data from scratch without counting SC adjustments.
//Should be invoked whenever players raise stats, learn passive skills or change equipment.
@@ -1909,7 +2215,6 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
int r,wlv = sd->inventory_data[index]->wlv;
struct weapon_data *wd;
struct weapon_atk *wa;
-
if (wlv >= MAX_REFINE_BONUS)
wlv = MAX_REFINE_BONUS - 1;
if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) {
@@ -1921,6 +2226,21 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
}
wa->atk += sd->inventory_data[index]->atk;
wa->atk2 = (r=sd->status.inventory[index].refine)*refinebonus[wlv][0];
+ #if RRMODE
+ /**
+ * in RE matk_max is used as the weapon's matk.
+ * += is used so that two-wield weapons (in the case of, say, sinx) bonus stack.
+ **/
+ status->matk_max += sd->inventory_data[index]->matk;
+ /**
+ * Refine Bonus
+ **/
+ status->matk_max += sd->status.inventory[index].refine * refinebonus[wlv][0];
+ /**
+ * In RE weapon level is used in several areas, this way we save performance
+ **/
+ status->wlv = wlv;
+ #endif
if((r-=refinebonus[wlv][2])>0) //Overrefine bonus.
wd->overrefine = r*refinebonus[wlv][1];
@@ -2277,7 +2597,6 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
status->flee += skill*(sd->class_&JOBL_2 && (sd->class_&MAPID_BASEMASK) == MAPID_THIEF? 4 : 3);
if((skill=pc_checkskill(sd,MO_DODGE))>0)
status->flee += (skill*3)>>1;
-
// ----- EQUIPMENT-DEF CALCULATION -----
// Apply relative modifiers from equipment
@@ -2429,7 +2748,6 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
sd->subele[ELE_WIND] += sc->data[SC_ARMOR_RESIST]->val4;
}
}
-
status_cpy(&sd->battle_status, status);
// ----- CLIENT-SIDE REFRESH -----
@@ -2996,18 +3314,26 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
if(flag&SCB_MATK) {
//New matk
+ #if RRMODE
+ status->matk_min = status_base_matk_min(status,status_get_lv(bl));
+ #else
status->matk_min = status_base_matk_min(status);
+ #endif
status->matk_max = status_base_matk_max(status);
if( bl->type&BL_PC && sd->matk_rate != 100 )
{
//Bonuses from previous matk
+ #if RRMODE == 0 //Only changed in non-re [RRInd]
status->matk_max = status->matk_max * sd->matk_rate/100;
+ #endif
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 RRMODE == 0 //Only changed in non-re [RRInd]
+ status->matk_max = status_calc_matk(bl, sc, status->matk_max);
+ #endif
if(sc->data[SC_MAGICPOWER]) { //Store current matk values
sc->mp_matk_min = status->matk_min;
@@ -3088,14 +3414,15 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
status->dmotion = status_calc_dmotion(bl, sc, b_status->dmotion);
}
}
-
+#if RRMODE
+ status_renewal_postcalc(status,flag);
+#endif
if(flag&(SCB_VIT|SCB_MAXHP|SCB_INT|SCB_MAXSP) && bl->type&BL_REGEN)
status_calc_regen(bl, status, status_get_regen_data(bl));
if(flag&SCB_REGEN && bl->type&BL_REGEN)
status_calc_regen_rate(bl, status_get_regen_data(bl), sc);
}
-
/// Recalculates parts of an object's base status and battle status according to the specified flags.
/// Also sends updates to the client wherever applicable.
/// @param flag bitfield of values from enum scb_flag
@@ -3265,6 +3592,11 @@ static unsigned short status_calc_str(struct block_list *bl, struct status_chang
str += ((sc->data[SC_MARIONETTE2]->val3)>>16)&0xFF;
if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && str < 50)
str = 50;
+ /**
+ * RK Rune Skill
+ **/
+ if(sc->data[SC_GIANTGROWTH])
+ str += 30;
return (unsigned short)cap_value(str,0,USHRT_MAX);
}
@@ -3304,6 +3636,11 @@ static unsigned short status_calc_agi(struct block_list *bl, struct status_chang
agi += ((sc->data[SC_MARIONETTE2]->val3)>>8)&0xFF;
if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && agi < 50)
agi = 50;
+ /**
+ * Arch Bishop
+ **/
+ if(sc->data[SC_ADORAMUS])
+ agi -= sc->data[SC_ADORAMUS]->val2;
return (unsigned short)cap_value(agi,0,USHRT_MAX);
}
@@ -3481,6 +3818,13 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
batk += sc->data[SC_GATLINGFEVER]->val3;
if(sc->data[SC_MADNESSCANCEL])
batk += 100;
+#if RE_EDP
+ /**
+ * in RE EDP increases your base atk by atk x Skill Level.
+ **/
+ if( sc->data[SC_EDP] )
+ batk = batk * sc->data[SC_EDP]->val1;
+#endif
return (unsigned short)cap_value(batk,0,USHRT_MAX);
}
@@ -3525,6 +3869,13 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
watk -= watk * sc->data[SC_STRIPWEAPON]->val2/100;
if(sc->data[SC_MERC_ATKUP])
watk += sc->data[SC_MERC_ATKUP]->val2;
+#if RE_EDP
+ /**
+ * in RE EDP increases your weapon atk by watk x Skill Level - 1
+ **/
+ if( sc->data[SC_EDP] && sc->data[SC_EDP]->val1 > 1 )
+ watk = watk * (sc->data[SC_EDP]->val1 - 1);
+#endif
return (unsigned short)cap_value(watk,0,USHRT_MAX);
}
@@ -3563,6 +3914,8 @@ static signed short status_calc_critical(struct block_list *bl, struct status_ch
critical += sc->data[SC_TRUESIGHT]->val2;
if(sc->data[SC_CLOAKING])
critical += critical;
+ if(sc->data[SC_CAMOUFLAGE])
+ critical += 100;
return (short)cap_value(critical,10,SHRT_MAX);
}
@@ -3593,6 +3946,8 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change
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_FEAR])
+ hit -= hit * 20 / 100;
return (short)cap_value(hit,1,SHRT_MAX);
}
@@ -3640,6 +3995,29 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
flee += 10 + sc->data[SC_SPEED]->val1 * 10;
if(sc->data[SC_MERC_FLEEUP])
flee += sc->data[SC_MERC_FLEEUP]->val2;
+ if(sc->data[SC_FEAR])
+ flee -= flee * 20 / 100;
+ if(sc->data[SC_PARALYSE])
+ flee -= flee / 10; // 10% Flee reduction
+ if(sc->data[SC_INFRAREDSCAN])
+ flee -= flee * 30 / 100;
+ if( sc->data[SC__LAZINESS] )
+ flee -= flee * sc->data[SC__LAZINESS]->val3 / 100;
+ if( sc->data[SC_GLOOMYDAY] )
+ flee -= flee * sc->data[SC_GLOOMYDAY]->val2 / 100;
+ if( sc->data[SC_HALLUCINATIONWALK] )
+ flee += sc->data[SC_HALLUCINATIONWALK]->val2;
+ if( sc->data[SC_SATURDAYNIGHTFEVER] )
+ flee -= flee * (40 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100;
+ if( sc->data[SC_WATER_BARRIER] )
+ flee -= sc->data[SC_WATER_BARRIER]->val3;
+ 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_MARSHOFABYSS] )
+ flee -= (9 * sc->data[SC_MARSHOFABYSS]->val3 / 10 + sc->data[SC_MARSHOFABYSS]->val2 / 10) * (bl->type == BL_MOB ? 2 : 1);
+
return (short)cap_value(flee,1,SHRT_MAX);
}
@@ -3696,6 +4074,26 @@ static signed char status_calc_def(struct block_list *bl, struct status_change *
def -= def * sc->data[SC_STRIPSHIELD]->val2/100;
if (sc->data[SC_FLING])
def -= def * (sc->data[SC_FLING]->val2)/100;
+ if( sc->data[SC_FREEZING] )
+ def -= def * 3 / 10;
+ 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__BLOODYLUST] )
+ def -= def * 55 / 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_EARTHDRIVE])
+ def -= def * 25 / 100;
+ if( sc->data[SC_GT_CHANGE] )
+ def -= def * sc->data[SC_GT_CHANGE]->val3 / 100;
+ if( sc->data[SC_ROCK_CRUSHER] )
+ def -= def * sc->data[SC_ROCK_CRUSHER]->val2 / 100;
+ if( sc->data[SC_POWER_OF_GAIA] )
+ def += def * sc->data[SC_POWER_OF_GAIA]->val2 / 100;
return (signed char)cap_value(def,CHAR_MIN,CHAR_MAX);
}
@@ -3728,6 +4126,20 @@ 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_PRESTIGE] )
+ def2 += def2 * sc->data[SC_PRESTIGE]->val1 / 100;
+ if( sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 1 )
+ def2 += sc->data[SC_SHIELDSPELL_REF]->val2;
+ if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 0 )
+ def2 += (5 + sc->data[SC_BANDING]->val1) * (sc->data[SC_BANDING]->val2);
+ if( sc->data[SC_GT_REVITALIZE] )
+ def2 += def2 * ( 50 + 10 * sc->data[SC_GT_REVITALIZE]->val1 ) / 100;
return (short)cap_value(def2,1,SHRT_MAX);
}
@@ -3755,6 +4167,16 @@ static signed char status_calc_mdef(struct block_list *bl, struct status_change
mdef += sc->data[SC_ENDURE]->val1;
if(sc->data[SC_CONCENTRATION])
mdef += 1; //Skill info says it adds a fixed 1 Mdef point.
+ 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])
+ mdef -= mdef * sc->data[SC_GT_CHANGE]->val3 / 100;
+ if(sc->data[SC_WATER_BARRIER])
+ mdef += sc->data[SC_WATER_BARRIER]->val2;
return (signed char)cap_value(mdef,CHAR_MIN,CHAR_MAX);
}
@@ -3768,6 +4190,8 @@ static signed short status_calc_mdef2(struct block_list *bl, struct status_chang
return 0;
if(sc->data[SC_MINDBREAKER])
mdef2 -= mdef2 * sc->data[SC_MINDBREAKER]->val3/100;
+ if(sc->data[SC_ANALYZE])
+ mdef2 -= mdef2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
return (short)cap_value(mdef2,1,SHRT_MAX);
}
@@ -3794,9 +4218,17 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
if( sc->data[SC_FUSION] )
val = 25;
- else
- if( sd && pc_isriding(sd) )
- val = 25;
+ else if( sd ) {
+ if( pc_isriding(sd) || sd->sc.option&(OPTION_DRAGON|OPTION_MOUNTING) )
+ val = 25;//Same bonus
+ else if( sd->sc.option&OPTION_WUGRIDER )
+ val = 15 + 5 * pc_checkskill(sd, RA_WUGRIDER);
+ else if( sd->sc.option&OPTION_MADOGEAR ) {
+ val = (- 10 * (5 - pc_checkskill(sd,NC_MADOLICENCE)));
+ if( sc->data[SC_ACCELERATION] )
+ val += 25;
+ }
+ }
speed_rate -= val;
}
@@ -3821,7 +4253,7 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
if( sc->data[SC_DECREASEAGI] )
val = max( val, 25 );
- if( sc->data[SC_QUAGMIRE] )
+ if( sc->data[SC_QUAGMIRE] || sc->data[SC_HALLUCINATIONWALK_POSTDELAY])
val = max( val, 50 );
if( sc->data[SC_DONTFORGETME] )
val = max( val, sc->data[SC_DONTFORGETME]->val3 );
@@ -3845,6 +4277,24 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
val = max( val, sc->data[SC_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_CAMOUFLAGE] && (sc->data[SC_CAMOUFLAGE]->val3&1) == 0 )
+ val = max( val, sc->data[SC_CAMOUFLAGE]->val1 < 3 ? 300 : 25 * (6 - sc->data[SC_CAMOUFLAGE]->val1) );
+ if( sc->data[SC__GROOMY] )
+ val = max( val, sc->data[SC__GROOMY]->val2);
+ if( sc->data[SC_STEALTHFIELD_MASTER] )
+ val = max( val, 30 );
+ if( sc->data[SC_BANDING_DEFENCE] )
+ val = max( val, sc->data[SC_BANDING_DEFENCE]->val1 );//+90% walking speed.
+ if( sc->data[SC_ROCK_CRUSHER_ATK] )
+ val = max( val, sc->data[SC_ROCK_CRUSHER_ATK]->val2 );
+ if( sc->data[SC_POWER_OF_GAIA] )
+ 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( sd && sd->speed_rate + sd->speed_add_rate > 0 ) // permanent item-based speedup
val = max( val, sd->speed_rate + sd->speed_add_rate );
@@ -3912,7 +4362,12 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
/// Note that the scale of aspd_rate is 1000 = 100%.
static short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int aspd_rate)
{
+#if RRMODE == 0
+ /**
+ * this variable is not used unless in non-RE
+ **/
int i;
+#endif
if(!sc || !sc->count)
return cap_value(aspd_rate,0,SHRT_MAX);
@@ -3981,12 +4436,16 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
else if(sc->data[SC_MADNESSCANCEL])
aspd_rate -= 200;
}
-
+#if RRMODE == 0
+ /**
+ * in RE they give a fixed boost -- we do so along SERVICE4U in status_base_amotion_pc
+ **/
if(sc->data[i=SC_ASPDPOTION3] ||
sc->data[i=SC_ASPDPOTION2] ||
sc->data[i=SC_ASPDPOTION1] ||
sc->data[i=SC_ASPDPOTION0])
aspd_rate -= sc->data[i]->val2;
+#endif
if(sc->data[SC_DONTFORGETME])
aspd_rate += 10 * sc->data[SC_DONTFORGETME]->val2;
if(sc->data[SC_LONGING])
@@ -4007,6 +4466,41 @@ 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_HALLUCINATIONWALK_POSTDELAY] )
+ aspd_rate += 500;
+ if( sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
+ aspd_rate -= sc->data[SC_FIGHTINGSPIRIT]->val2;
+ if( sc->data[SC_PARALYSE] )
+ aspd_rate += 100;
+ if( sc->data[SC__BODYPAINT] )
+ aspd_rate += aspd_rate * (20 + 5 * sc->data[SC__BODYPAINT]->val1) / 100;
+ if( sc->data[SC__INVISIBILITY] )
+ aspd_rate += aspd_rate * sc->data[SC__INVISIBILITY]->val2 / 100;
+ if( sc->data[SC__GROOMY] )
+ aspd_rate += aspd_rate * sc->data[SC__GROOMY]->val2 / 100;
+ if( sc->data[SC_SWINGDANCE] )
+ aspd_rate -= aspd_rate * sc->data[SC_SWINGDANCE]->val2 / 100;
+ if( sc->data[SC_DANCEWITHWUG] )
+ aspd_rate -= aspd_rate * sc->data[SC_DANCEWITHWUG]->val3 / 100;
+ if( sc->data[SC_GLOOMYDAY] )
+ aspd_rate += aspd_rate * sc->data[SC_GLOOMYDAY]->val3 / 100;
+ if( sc->data[SC_EARTHDRIVE] )
+ aspd_rate += aspd_rate * 25 / 100;
+ /*As far I tested the skill there is no ASPD addition is applied. [Jobbie] */
+ //if( sc->data[SC_RAISINGDRAGON] )
+ // aspd_rate -= 100; //FIXME: Need official ASPD bonus of this status. [Jobbie]
+ if( sc->data[SC_GT_CHANGE] )
+ aspd_rate -= aspd_rate * (sc->data[SC_GT_CHANGE]->val2/200) / 100;
+ if( sc->data[SC_GT_REVITALIZE] )
+ aspd_rate -= aspd_rate * sc->data[SC_GT_REVITALIZE]->val2 / 100;
+ if( sc->data[SC_MELON_BOMB] )
+ aspd_rate += aspd_rate * sc->data[SC_MELON_BOMB]->val1 / 100;
+ if( sc->data[SC_BOOST500] )
+ aspd_rate -= aspd_rate * sc->data[SC_BOOST500]->val1/100;
+ if(sc->data[SC_EXTRACT_SALAMINE_JUICE])
+ aspd_rate -= aspd_rate * sc->data[SC_EXTRACT_SALAMINE_JUICE]->val1/100;
return (short)cap_value(aspd_rate,0,SHRT_MAX);
}
@@ -4020,7 +4514,7 @@ static unsigned short status_calc_dmotion(struct block_list *bl, struct status_c
return 0;
if( sc->data[SC_CONCENTRATION] )
return 0;
- if( sc->data[SC_RUN] )
+ if( sc->data[SC_RUN] || sc->data[SC_WUGDASH] )
return 0;
return (unsigned short)cap_value(dmotion,0,USHRT_MAX);
@@ -4045,6 +4539,12 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
if(sc->data[SC_MERC_HPUP])
maxhp += maxhp * sc->data[SC_MERC_HPUP]->val2/100;
+ if(sc->data[SC_EPICLESIS])
+ maxhp += maxhp * 5 * sc->data[SC_EPICLESIS]->val1 / 100;
+ if(sc->data[SC_VENOMBLEED])
+ maxhp -= maxhp * 15 / 100;
+
+
return cap_value(maxhp,1,UINT_MAX);
}
@@ -4078,6 +4578,9 @@ static unsigned char status_calc_element(struct block_list *bl, struct status_ch
return ELE_UNDEAD;
if(sc->data[SC_ELEMENTALCHANGE])
return sc->data[SC_ELEMENTALCHANGE]->val2;
+ if(sc->data[SC_SHAPESHIFT])
+ return sc->data[SC_SHAPESHIFT]->val2;
+
return (unsigned char)cap_value(element,0,UCHAR_MAX);
}
@@ -4096,6 +4599,8 @@ static unsigned char status_calc_element_lv(struct block_list *bl, struct status
return 1;
if(sc->data[SC_ELEMENTALCHANGE])
return sc->data[SC_ELEMENTALCHANGE]->val1;
+ if(sc->data[SC_SHAPESHIFT])
+ return 1;
return (unsigned char)cap_value(lv,1,4);
}
@@ -4567,7 +5072,7 @@ void status_change_init(struct block_list *bl)
//the flag values are the same as in status_change_start.
int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int tick, int flag)
{
- int sc_def, tick_def = 0;
+ int sc_def = 0, tick_def = 0;
struct status_data* status;
struct status_change* sc;
struct map_session_data *sd;
@@ -4618,6 +5123,7 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
sc_def = 3 +status->int_;
break;
case SC_DECREASEAGI:
+ case SC_ADORAMUS://Arch Bishop
if (sd) tick>>=1; //Half duration for players.
case SC_STONE:
case SC_FREEZE:
@@ -4647,6 +5153,40 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
if (sd) //Duration greatly reduced for players.
tick /= 15;
//No defense against it (buff).
+ /**
+ * 3rd stuff
+ **/
+ case SC_WHITEIMPRISON:
+ rate -= (status_get_lv(bl) / 5 + status->vit / 4 + status->agi / 10)*100; // Lineal Reduction of Rate
+ //tick_def = (int)floor(log10(status_get_lv(bl)) * 10.);
+ 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.
+ break;
+ case SC_FREEZING:
+ tick -= 1000 * ((status->vit + status->dex) / 20);
+ tick = max(tick,10000); // Minimum Duration 10s.
+ break;
+ case SC_OBLIVIONCURSE:
+ sc_def = status->int_*4/5; //FIXME: info said this is the formula of status chance. Check again pls. [Jobbie]
+ break;
+ case SC_ELECTRICSHOCKER:
+ case SC_BITE:
+ {
+ if( bl->type == BL_MOB )
+ tick -= 1000 * (status->agi/10);
+ if( sd && type != SC_ELECTRICSHOCKER )
+ tick >>= 1;
+ }
+ break;
+ case SC_CRYSTALIZE:
+ tick -= (1000*(status->vit/10))+(status_get_lv(bl)/50);
+ break;
+ case SC_VACUUM_EXTREME:
+ tick -= 50*status->str;
+ break;
default:
//Effect that cannot be reduced? Likely a buff.
if (!(rand()%10000 < rate))
@@ -4749,7 +5289,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
struct status_change_entry* sce;
struct status_data *status;
struct view_data *vd;
- int opt_flag, calc_flag, undead_flag;
+ int opt_flag, calc_flag, undead_flag, val_flag = 0, tick_time = 0;
nullpo_ret(bl);
sc = status_get_sc(bl);
@@ -4787,16 +5327,27 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
//Check for inmunities / sc fails
switch (type)
{
- case SC_FREEZE:
case SC_STONE:
+ if(sc->data[SC_POWER_OF_GAIA])
+ return 0;
+ case SC_FREEZE:
//Undead are immune to Freeze/Stone
if (undead_flag && !(flag&1))
return 0;
case SC_SLEEP:
case SC_STUN:
+ case SC_FREEZING:
if (sc->opt1)
return 0; //Cannot override other opt1 status changes. [Skotlex]
+ if((type == SC_FREEZE || type == SC_FREEZING) && sc->data[SC_WARMER])
+ return 0; //Immune to Frozen and Freezing status if under Warmer status. [Jobbie]
+ break;
+
+ case SC_BURNING:
+ if(sc->opt1 || sc->data[SC_FREEZING])
+ return 0;
break;
+
case SC_SIGNUMCRUCIS:
//Only affects demons and undead element (but not players)
if((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
@@ -4813,12 +5364,16 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_OVERTHRUST:
if (sc->data[SC_MAXOVERTHRUST])
return 0; //Overthrust can't take effect if under Max Overthrust. [Skotlex]
+ case SC_MAXOVERTHRUST:
+ if( sc->option&OPTION_MADOGEAR )
+ return 0;//Overthrust and Overthrust Max cannot be used on Mado Gear [Ind]
break;
case SC_ADRENALINE:
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_DECREASEAGI] ||
+ sc->option&OPTION_MADOGEAR //Adrenaline doesn't affect Mado Gear [Ind]
)
return 0;
break;
@@ -4830,6 +5385,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
)
return 0;
break;
+ case SC_MAGNIFICAT:
+ if( sc->option&OPTION_MADOGEAR ) //Mado is immune to magnificat
+ break;
case SC_ONEHAND:
case SC_MERC_QUICKEN:
case SC_TWOHANDQUICKEN:
@@ -4844,6 +5402,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_ASSNCROS:
if (sc->data[SC_QUAGMIRE])
return 0;
+ if(sc->option&OPTION_MADOGEAR)
+ return 0;//Mado is immune to increase agi, wind walk, cart boost, etc (others above) [Ind]
break;
case SC_CLOAKING:
//Avoid cloaking with no wall and low skill level. [Skotlex]
@@ -4995,6 +5555,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (sc->data[SC_LUKFOOD] && sc->data[SC_LUKFOOD]->val1 > val1)
return 0;
break;
+ case SC_CAMOUFLAGE:
+ if( sd && pc_checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill_check_camouflage(bl,NULL) )
+ return 0;
+ break;
}
//Check for BOSS resistances
@@ -5003,8 +5567,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
return 0;
switch (type) {
case SC_BLESSING:
- if (!undead_flag && status->race!=RC_DEMON)
- break;
case SC_DECREASEAGI:
case SC_PROVOKE:
case SC_COMA:
@@ -5013,6 +5575,26 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_RICHMANKIM:
case SC_ROKISWEIL:
case SC_FOGWALL:
+ case SC_FREEZING:
+ case SC_BURNING: // Place here until we have info about its behavior on Boss-monsters. [pakpil]
+ case SC_MARSHOFABYSS:
+ case SC_ADORAMUS:
+
+ // Exploid prevention - kRO Fix
+ case SC_PYREXIA:
+ case SC_DEATHHURT:
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
+
+ // Ranger Effects
+ case SC_BITE:
+ case SC_ELECTRICSHOCKER:
+ case SC_MAGNETICFIELD:
+
return 0;
}
}
@@ -5048,6 +5630,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
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_ACCELERATION, INVALID_TIMER);
break;
case SC_ONEHAND:
//Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
@@ -5286,6 +5869,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_EDP: // [Celest]
val2 = val1 + 2; //Chance to Poison enemies.
val3 = 50*(val1+1); //Damage increase (+50 +50*lv%)
+ if( sd )//[Ind] - iROwiki says each level increases its duration by 3 seconds
+ tick += pc_checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
break;
case SC_POISONREACT:
val2=(val1+1)/2 + val1/10; // Number of counters [Skotlex]
@@ -5421,10 +6006,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
//val3 : Brings the skilllv (merged into val1 here)
//val4 : Partner
if (val1 == CG_MOONLIT)
- clif_status_change(bl,SI_MOONLIT,1,tick);
+ clif_status_change(bl,SI_MOONLIT,1,tick,0, 0, 0);
val1|= (val3<<16);
val3 = tick/1000; //Tick duration
- tick = 1000;
+ tick_time = 1000; // [GodLesZ] tick time
break;
case SC_LONGING:
val2 = 500-100*val1; //Aspd penalty.
@@ -5432,9 +6017,14 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_EXPLOSIONSPIRITS:
val2 = 75 + 25*val1; //Cri bonus
break;
+#if RRMODE == 0
+ /**
+ * Only in non-RE it's var is changed
+ **/
case SC_ASPDPOTION0:
case SC_ASPDPOTION1:
case SC_ASPDPOTION2:
+#endif
case SC_ASPDPOTION3:
val2 = 50*(2+type-SC_ASPDPOTION0);
break;
@@ -5455,6 +6045,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
clif_changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
break;
case SC_NOCHAT:
+ // [GodLesZ] FIXME: is this correct? a hardcoded interval of 60sec? what about configuration ?_?
tick = 60000;
val1 = battle_config.manner_system; //Mute filters.
if (sd)
@@ -5486,7 +6077,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_POISON: /* “Ε */
val3 = tick/1000; //Damage iterations
if(val3 < 1) val3 = 1;
- tick = 1000;
+ tick_time = 1000; // [GodLesZ] tick time
//val4: HP damage
if (bl->type == BL_PC)
val4 = (type == SC_DPOISON) ? 3 + status->max_hp/50 : 3 + status->max_hp*3/200;
@@ -5500,7 +6091,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_BLEEDING:
val4 = tick/10000;
if (!val4) val4 = 1;
- tick = 10000;
+ tick_time = 10000; // [GodLesZ] tick time
break;
case SC_S_LIFEPOTION:
case SC_L_LIFEPOTION:
@@ -5511,7 +6102,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if( val2 < 1 ) val2 = 1;
if( (val4 = tick/(val2 * 1000)) < 1 )
val4 = 1;
- tick = val2 * 1000; // val2 = Seconds between heals
+ tick_time = val2 * 1000; // [GodLesZ] tick time
break;
case SC_BOSSMAPINFO:
if( sd != NULL )
@@ -5525,12 +6116,12 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val1 = boss_md->bl.id;
if( (val4 = tick/1000) < 1 )
val4 = 1;
- tick = 1000;
+ tick_time = 1000; // [GodLesZ] tick time
}
break;
case SC_HIDING:
val2 = tick/1000;
- tick = 1000;
+ tick_time = 1000; // [GodLesZ] tick time
val3 = 0; // unused, previously speed adjustment
val4 = val1+3; //Seconds before SP substraction happen.
break;
@@ -5560,7 +6151,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_SIGHTBLASTER:
val3 = skill_get_splash(val2, val1); //Val2 should bring the skill-id.
val2 = tick/250;
- tick = 10;
+ tick_time = 10; // [GodLesZ] tick time
break;
//Permanent effects.
@@ -5631,7 +6222,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 12; //SP cost
val4 = 10000; //Decrease at 10secs intervals.
val3 = tick/val4;
- tick = val4;
+ tick_time = val4; // [GodLesZ] tick time
break;
case SC_PARRYING:
val2 = 20 + val1*3; //Block Chance
@@ -5654,13 +6245,13 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (!val4) val4 = skill_get_time2(status_sc2skill(type),val1);
if (!val4) val4 = 10000; //Val4 holds damage interval
val3 = tick/val4; //val3 holds skill duration
- tick = val4;
+ tick_time = val4; // [GodLesZ] tick time
break;
case SC_GOSPEL:
if(val4 == BCT_SELF) { // self effect
val2 = tick/10000;
- tick = 10000;
+ tick_time = 10000; // [GodLesZ] tick time
status_change_clear_buffs(bl,3); //Remove buffs/debuffs
}
break;
@@ -5926,7 +6517,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_SKA:
val2 = tick/1000;
val3 = rand()%100; //Def changes randomly every second...
- tick = 1000;
+ tick_time = 1000; // [GodLesZ] tick time
break;
case SC_JAILED:
//Val1 is duration in minutes. Use INT_MAX to specify 'unlimited' time.
@@ -6062,6 +6653,487 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_SPL_MATK:
val2 = 2; // Splendide group
break;
+ /**
+ * General
+ **/
+ case SC_FEAR:
+ val2 = 2;
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_BURNING:
+ val4 = tick / 2000; // Total Ticks to Burn!!
+ tick_time = 2000; // [GodLesZ] tick time
+ break;
+ /**
+ * Rune Knight
+ **/
+ case SC_DEATHBOUND:
+ val2 = 500 + 100 * val1;
+ break;
+ case SC_FIGHTINGSPIRIT:
+ val_flag |= 1|2;
+ break;
+ case SC_ABUNDANCE:
+ val4 = tick / 10000;
+ tick_time = 10000; // [GodLesZ] tick time
+ break;
+ case SC_GIANTGROWTH:
+ val2 = 10; // Triple damage success rate.
+ break;
+ /**
+ * Arch Bishop
+ **/
+ case SC_RENOVATIO:
+ val4 = tick / 5000;
+ tick_time = 5000;
+ break;
+ case SC_SECRAMENT:
+ val2 = 10 * val1;
+ break;
+ case SC_VENOMIMPRESS:
+ val2 = 10 * val1;
+ val_flag |= 1|2;
+ break;
+ case SC_POISONINGWEAPON:
+ val_flag |= 1|2|4;
+ break;
+ case SC_WEAPONBLOCKING:
+ val2 = 10 + 2 * val1; // Chance
+ val4 = tick / 3000;
+ tick_time = 3000; // [GodLesZ] tick time
+ val_flag |= 1|2;
+ break;
+ case SC_TOXIN:
+ val4 = tick / 10000;
+ tick_time = 10000; // [GodLesZ] tick time
+ break;
+ case SC_MAGICMUSHROOM:
+ val4 = tick / 4000;
+ tick_time = 4000; // [GodLesZ] tick time
+ break;
+ case SC_PYREXIA:
+ val4 = tick / 3000;
+ tick_time = 4000; // [GodLesZ] tick time
+ break;
+ case SC_LEECHESEND:
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_OBLIVIONCURSE:
+ val4 = tick / 3000;
+ tick_time = 3000; // [GodLesZ] tick time
+ break;
+ case SC_ROLLINGCUTTER:
+ val_flag |= 1;
+ break;
+ case SC_CLOAKINGEXCEED:
+ val2 = ( val1 + 1 ) / 2; // Hits
+ val3 = ( val1 - 1 ) * 10; // Walk speed
+ val_flag |= 1|2|4;
+ if (bl->type == BL_PC)
+ val4 |= battle_config.pc_cloak_check_type&7;
+ else
+ val4 |= battle_config.monster_cloak_check_type&7;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_HALLUCINATIONWALK:
+ val2 = 50 * val1; // Evasion rate of physical attacks. Flee
+ val3 = 10 * val1; // Evasion rate of magical attacks.
+ val_flag |= 1|2|4;
+ break;
+ case SC_WHITEIMPRISON:
+ status_change_end(bl, SC_BURNING, -1);
+ status_change_end(bl, SC_FREEZING, -1);
+ status_change_end(bl, SC_FREEZE, -1);
+ status_change_end(bl, SC_STONE, -1);
+ break;
+ case SC_FREEZING:
+ status_change_end(bl, SC_BURNING, -1);
+ break;
+ case SC_READING_SB:
+ // val2 = sp reduction per second
+ tick_time = 1000; // [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.
+ val4 = tick / 1000;
+ if( val4 < 1 )
+ val4 = 1;
+ tick_time = 1000; // [GodLesZ] tick time
+ val_flag |= 1;
+ break;
+ case SC_SHAPESHIFT:
+ switch( val1 )
+ {
+ case 1: val2 = ELE_FIRE; break;
+ case 2: val2 = ELE_EARTH; break;
+ case 3: val2 = ELE_WIND; break;
+ case 4: val2 = ELE_WATER; break;
+ }
+ break;
+ case SC_ELECTRICSHOCKER:
+ case SC_CRYSTALIZE:
+ val4 = tick / 1000;
+ if( val4 < 1 )
+ val4 = 1;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_CAMOUFLAGE:
+ //val3 |= battle_config.pc_camouflage_check_type&7;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_WUGDASH:
+ val4 = gettick(); //Store time at which you started running.
+ tick = -1;
+ break;
+ case SC__SHADOWFORM:
+ {
+ //struct map_session_data * s_sd = map_id2sd(val2);
+ //if( s_sd )
+ // s_sd->shadowform_id = bl->id;
+ val4 = tick / 1000;
+ val_flag |= 1|2|4;
+ tick_time = 1000; // [GodLesZ] tick time
+ }
+ break;
+ case SC__STRIPACCESSORY:
+ if (!sd)
+ val2 = 20;
+ break;
+ case SC__INVISIBILITY:
+ val2 = 50 - 10 * val1; // ASPD
+ val3 = 20 * val1; // CRITICAL
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ val_flag |= 1|2;
+ break;
+ case SC__ENERVATION:
+ val2 = 20 + 10 * val1; // ATK Reduction
+ val_flag |= 1|2;
+ if( sd ) pc_delspiritball(sd,sd->spiritball,0);
+ break;
+ case SC__GROOMY:
+ val2 = 20 + 10 * val1; //ASPD. Need to confirm if Movement Speed reduction is the same. [Jobbie]
+ val3 = 20 * val1; //HIT
+ val_flag |= 1|2|4;
+ if( sd )
+ { // Removes Animals
+ //if( pc_isriding(sd,OPTION_RIDING|OPTION_RIDING_DRAGON|OPTION_RIDING_WUG) ) pc_setriding(sd, 0);
+ //if( pc_iswarg(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_WUG);
+ if( pc_isfalcon(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_FALCON);
+ if( sd->status.pet_id > 0 ) pet_menu(sd, 3);
+ if( merc_is_hom_active(sd->hd) ) merc_hom_vaporize(sd,1);
+ if( sd->md ) merc_delete(sd->md,3);
+ }
+ break;
+ case SC__LAZINESS:
+ val2 = 10 + 10 * val1; // Cast reduction
+ val3 = 10 * val1; // Flee Reduction
+ val_flag |= 1|2|4;
+ break;
+ case SC__UNLUCKY:
+ val2 = 10 * val1; // Crit and Flee2 Reduction
+ val_flag |= 1|2|4;
+ break;
+ case SC__WEAKNESS:
+ val2 = 10 * val1;
+ val_flag |= 1|2;
+ skill_strip_equip(bl,EQP_WEAPON|EQP_SHIELD,100,val1,tick);
+ break;
+ case SC__BLOODYLUST:
+ val_flag |= 1|2;
+ break;
+ case SC_GN_CARTBOOST:
+ if( val1 < 3 )
+ val2 = 50;
+ else if( val1 < 5 )
+ val2 = 75;
+ else
+ val2 = 100;
+ break;
+ case SC_PROPERTYWALK:
+ val_flag |= 1|2;
+ val3 = 0;
+ break;
+ case SC_WARMER:
+ status_change_end(bl, SC_FREEZE, -1);
+ status_change_end(bl, SC_FREEZING, -1);
+ status_change_end(bl, SC_CRYSTALIZE, -1);
+ break;
+ case SC_STRIKING:
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_BLOODSUCKER:
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_SWINGDANCE:
+ val2 = 4 * val1; // Walk speed and aspd reduction.
+ break;
+ case SC_SYMPHONYOFLOVER:
+ case SC_RUSHWINDMILL:
+ 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:
+ val2 = 10 * val1;
+ break;
+ case SC_HARMONIZE:
+ val2 = 3 + 2 * val1;
+ break;
+ case SC_VOICEOFSIREN:
+ val4 = tick / 2000;
+ tick_time = 2000; // [GodLesZ] tick time
+ break;
+ case SC_DEEPSLEEP:
+ val4 = tick / 2000;
+ tick_time = 2000; // [GodLesZ] tick time
+ break;
+ case SC_SIRCLEOFNATURE:
+ val2 = 1 + val1; //SP consume
+ val3 = 40 * val1; //HP recovery
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_SONGOFMANA:
+ val3 = 10 + (2 * val2);
+ val4 = tick/3000;
+ tick_time = 3000; // [GodLesZ] tick time
+ break;
+ case SC_SATURDAYNIGHTFEVER:
+ if (!val4) val4 = skill_get_time2(status_sc2skill(type),val1);
+ if (!val4) val4 = 3000;
+ val3 = tick/val4;
+ tick_time = val4; // [GodLesZ] tick time
+ break;
+ case SC_GLOOMYDAY:
+ val2 = 3 + 2 * val1; // Flee reduction.
+ val3 = 3 * val1; // ASPD reduction.
+ break;
+ case SC_SITDOWN_FORCE:
+ case SC_BANANA_BOMB_SITDOWN:
+ if( sd && !pc_issit(sd) )
+ {
+ pc_setsit(sd);
+ skill_sit(sd,1);
+ clif_sitting(bl);
+ }
+ break;
+ case SC_DANCEWITHWUG:
+ val3 = (5 * val1) + (1 * val2); //Still need official value.
+ break;
+ case SC_LERADSDEW:
+ val3 = (5 * val1) + (1 * val2);
+ break;
+ case SC_MELODYOFSINK:
+ val3 = (5 * val1) + (1 * val2);
+ break;
+ case SC_BEYONDOFWARCRY:
+ val3 = (5 * val1) + (1 * val2);
+ break;
+ case SC_UNLIMITEDHUMMINGVOICE:
+ {
+ struct unit_data *ud = unit_bl2ud(bl);
+ if( ud == NULL ) return 0;
+ ud->state.skillcastcancel = 0;
+ val3 = 15 - (2 * val2);
+ }
+ break;
+ case SC_REFLECTDAMAGE:
+ val2 = 15 + 5 * val1;
+ val3 = (val1==5)?20:(val1+4)*2; // SP consumption
+ val4 = tick/10000;
+ tick_time = 10000; // [GodLesZ] tick time
+ break;
+ case SC_FORCEOFVANGUARD: // This is not the official way to handle it but I think we should use it. [pakpil]
+ val2 = 20 + 12 * (val1 - 1); // Chance
+ val3 = 5 + (2 * val1); // Max rage counters
+ tick_time = 6000; // [GodLesZ] tick time
+ val_flag |= 1|2|4;
+ break;
+ case SC_EXEEDBREAK:
+ val1 *= 150; // 150 * skill_lv
+ if( sd )
+ { // Chars.
+ struct item_data *id = sd->inventory_data[sd->equip_index[EQI_HAND_R]];
+ if( id ) val1 += (id->weight/10 * id->wlv * status_get_lv(bl) / 100); // (weapon_weight * weapon_level * base_lvl)/100
+ val1 += 15 * sd->status.job_level; // 15 * job_lvl
+ }
+ else // Mobs
+ val1 += (400 * status_get_lv(bl) / 100) + (15 * (status_get_lv(bl) / 2)); // About 1138% at mob_lvl 99. Is an aproximation to a standard weapon. [pakpil]
+ break;
+
+ case SC_PRESTIGE: // Bassed on suggested formula in iRO Wiki and some test, still need more test. [pakpil]
+ val2 = ((status->int_ + status->luk) / 6) + 5; // Chance to evade magic damage.
+ val1 *= 15; // Defence added
+ if( sd )
+ val1 += 10 * pc_checkskill(sd,CR_DEFENDER);
+ val_flag |= 1|2;
+ break;
+ case SC_BANDING:
+ tick_time = 5000; // [GodLesZ] tick time
+ val_flag |= 1;
+ break;
+ case SC_SHIELDSPELL_DEF:
+ case SC_SHIELDSPELL_MDEF:
+ case SC_SHIELDSPELL_REF:
+ val_flag |= 1|2;
+ break;
+ case SC_MAGNETICFIELD:
+ val3 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ break;
+ case SC_INSPIRATION:
+ if( sd )
+ {
+ val2 = (40 * val1) + (3 * sd->status.job_level); // ATK bonus
+ val3 = (sd->status.job_level / 10) * 2 + 12; // All stat bonus
+ }
+ val4 = tick / 1000;
+ tick_time = 1000; // [GodLesZ] tick time
+ status_change_clear_buffs(bl,3); //Remove buffs/debuffs
+ break;
+ case SC_SPELLFIST:
+ case SC_CURSEDCIRCLE_ATKER:
+ val_flag |= 1|2|4;
+ break;
+ case SC_CRESCENTELBOW:
+ val2 = 94 + val1;
+ val_flag |= 1|2;
+ break;
+ case SC_LIGHTNINGWALK:
+ val1 = 88 + 2 * val1;
+ val_flag |= 1;
+ break;
+ case SC_RAISINGDRAGON:
+ val3 = tick / 5000;
+ tick_time = 5000; // [GodLesZ] tick time
+ break;
+ case SC_GT_CHANGE:
+ if( sd ) val2 = (13 * val1 / 2) * sd->status.agi; //Aspd - old formula.
+ val3 = 20 + 1 * val1; //Base Atk, Reduction to DEF & MDEF
+ break;
+ case SC_GT_REVITALIZE:
+ val2 = 5 * val1; //Custom value VIT, ASPD, SPEED bonus.
+ val3 = 60 + 40 * val1; //HP recovery
+ break;
+ case SC_PYROTECHNIC_OPTION:
+ val2 = 60; // Watk TODO: Renewal (Atk2)
+ val3 = 11; // % Increase damage.
+ val_flag |= 1|2|4;
+ break;
+ case SC_HEATER_OPTION:
+ val2 = 120; // Watk. TODO: Renewal (Atk2)
+ val3 = 33; // % Increase effects.
+ val4 = 3; // Change into fire element.
+ val_flag |= 1|2|4;
+ break;
+ case SC_TROPIC_OPTION:
+ val2 = 180; // Watk. TODO: Renewal (Atk2)
+ val3 = MG_FIREBOLT;
+ break;
+ case SC_AQUAPLAY_OPTION:
+ val2 = 40; // Matk. TODO: Renewal (Matk1)
+ val3 = 33; // % Increase effects.
+ val_flag |= 1|2|4;
+ break;
+ case SC_COOLER_OPTION:
+ val2 = 80; // % Freezing chance
+ val3 = 33; // % increased damage
+ val4 = 1; // Change into water elemet
+ val_flag |= 1|2|4;
+ break;
+ case SC_CHILLY_AIR_OPTION:
+ val2 = 120; // Matk. TODO: Renewal (Matk1)
+ val3 = MG_COLDBOLT;
+ val_flag |= 1|2;
+ break;
+ case SC_GUST_OPTION:
+ val2 = 33;
+ val_flag |= 1|2;
+ break;
+ case SC_WIND_STEP_OPTION:
+ val2 = 50; // % Increase speed and flee.
+ break;
+ case SC_BLAST_OPTION:
+ val2 = 33;
+ val3 = 4;
+ val_flag |= 1|2|4;
+ break;
+ case SC_WILD_STORM_OPTION:
+ val2 = MG_LIGHTNINGBOLT;
+ val_flag |= 1|2;
+ break;
+ case SC_PETROLOGY_OPTION:
+ val2 = 5;
+ val3 = 33;
+ val_flag |= 1|2|4;
+ break;
+ case SC_CURSED_SOIL_OPTION:
+ val2 = 10;
+ val3 = 33;
+ val4 = 2;
+ val_flag |= 1|2|4;
+ break;
+ case SC_UPHEAVAL_OPTION:
+ val2 = WZ_EARTHSPIKE;
+ val_flag |= 1|2;
+ break;
+ case SC_CIRCLE_OF_FIRE_OPTION:
+ val2 = 300;
+ val_flag |= 1|2;
+ break;
+ case SC_FIRE_CLOAK_OPTION:
+ case SC_WATER_DROP_OPTION:
+ case SC_WIND_CURTAIN_OPTION:
+ case SC_STONE_SHIELD_OPTION:
+ val2 = 20; // Elemental modifier. Not confirmed.
+ break;
+ case SC_CIRCLE_OF_FIRE:
+ case SC_FIRE_CLOAK:
+ case SC_WATER_DROP:
+ case SC_WATER_SCREEN:
+ case SC_WIND_CURTAIN:
+ case SC_WIND_STEP:
+ case SC_STONE_SHIELD:
+ case SC_SOLID_SKIN:
+ val2 = 10;
+ tick_time = 2000; // [GodLesZ] tick time
+ break;
+ case SC_WATER_BARRIER:
+ val2 = 40; // Increasement. Mdef1 ???
+ val3 = 20; // Reductions. Atk2, Flee1, Matk1 ????
+ val_flag |= 1|2|4;
+ break;
+ case SC_ZEPHYR:
+ val2 = 22; // Flee.
+ break;
+ case SC_TIDAL_WEAPON:
+ val2 = 20; // Increase Elemental's attack.
+ break;
+ case SC_ROCK_CRUSHER:
+ case SC_ROCK_CRUSHER_ATK:
+ case SC_POWER_OF_GAIA:
+ val2 = 33;
+ break;
+ case SC_MELON_BOMB:
+ case SC_BANANA_BOMB:
+ val1 = 15;
+ break;
+ case SC_STOMACHACHE:
+ val2 = 8; // SP consume.
+ val4 = tick / 10000;
+ tick_time = 10000; // [GodLesZ] tick time
+ break;
default:
if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 )
@@ -6107,12 +7179,15 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_CLOSECONFINE2:
case SC_ANKLE:
case SC_SPIDERWEB:
+ case SC_ELECTRICSHOCKER:
unit_stop_walking(bl,1);
break;
case SC_HIDING:
case SC_CLOAKING:
+ case SC_CLOAKINGEXCEED:
case SC_CHASEWALK:
case SC_WEIGHT90:
+ case SC_CAMOUFLAGE:
unit_stop_attack(bl);
break;
case SC_SILENCE:
@@ -6130,6 +7205,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_FREEZE: sc->opt1 = OPT1_FREEZE; break;
case SC_STUN: sc->opt1 = OPT1_STUN; break;
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;
//OPT2
case SC_POISON: sc->opt2 |= OPT2_POISON; break;
case SC_CURSE: sc->opt2 |= OPT2_CURSE; break;
@@ -6234,6 +7311,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
opt_flag = 2;
break;
case SC_CLOAKING:
+ case SC_CLOAKINGEXCEED:
sc->option |= OPTION_CLOAK;
opt_flag = 2;
break;
@@ -6280,10 +7358,15 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
calc_flag&=~SCB_DYE;
}
- if( vd && (pcdb_checkid(vd->class_) || bl->type == BL_MER ) ) //Only for players sprites, client crashes if they receive this for a mob o.O [Skotlex]
- clif_status_change(bl,StatusIconChangeTable[type],1,tick);
+ if( vd && (pcdb_checkid(vd->class_) || bl->type == BL_MER || bl->type == BL_MOB ) )
+ clif_status_change(bl,StatusIconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0);
else if( sd ) //Send packet to self otherwise (disguised player?)
clif_status_load(bl,StatusIconChangeTable[type],1);
+ /**
+ * used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first.
+ **/
+ if( tick_time )
+ tick = tick_time;
//Don't trust the previous sce assignment, in case the SC ended somewhere between there and here.
if((sce=sc->data[type]))
@@ -6337,6 +7420,16 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_MERC_SPUP:
status_percent_heal(bl, 0, 100); // Recover Full SP
break;
+ /**
+ * Ranger
+ **/
+ case SC_WUGDASH:
+ {
+ struct unit_data *ud = unit_bl2ud(bl);
+ if( ud )
+ ud->state.running = unit_wugdash(bl, sd);
+ }
+ break;
case SC_COMBO:
switch (sce->val1) {
case TK_STORMKICK:
@@ -6658,7 +7751,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
if((sce->val1&0xFFFF) == CG_MOONLIT)
- clif_status_change(bl,SI_MOONLIT,0,0);
+ clif_status_change(bl,SI_MOONLIT,0,0,0,0,0);
status_change_end(bl, SC_LONGING, INVALID_TIMER);
}
@@ -6803,6 +7896,88 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
status_change_end(tbl, SC_STOP, INVALID_TIMER);
}
break;
+ /**
+ * 3rd Stuff
+ **/
+ case SC_MILLENNIUMSHIELD:
+ clif_millenniumshield(sd,0);
+ break;
+ case SC_HALLUCINATIONWALK:
+ sc_start(bl,SC_HALLUCINATIONWALK_POSTDELAY,100,sce->val1,skill_get_time2(GC_HALLUCINATIONWALK,sce->val1));
+ break;
+ case SC_WHITEIMPRISON:
+ if( tid == -1 )
+ break; // Terminated by Damage
+ clif_damage(bl,bl,0,0,0,400*sce->val1,0,0,0);
+ status_zap(bl,400*sce->val1,0);
+ break;
+ case SC_WUGDASH:
+ {
+ struct unit_data *ud = unit_bl2ud(bl);
+ if (ud) {
+ ud->state.running = 0;
+ if (ud->walktimer != -1)
+ unit_stop_walking(bl,1);
+ }
+ }
+ break;
+ case SC_ADORAMUS:
+ status_change_end(bl, SC_BLIND, -1);
+ break;
+ /*
+ case SC__SHADOWFORM:
+ {
+ struct map_session_data *s_sd = map_id2sd(sce->val2);
+ if( !s_sd )
+ break;
+ s_sd->shadowform_id = 0;
+ }
+ break;
+ case SC_SITDOWN_FORCE:
+ if( sd && pc_issit(sd) )
+ {
+ pc_setstand(sd);
+ clif_standing(bl,true);
+ }
+ break;
+ case SC_NEUTRALBARRIER_MASTER:
+ case SC_STEALTHFIELD_MASTER:
+ if( sce->val2 )
+ {
+ struct skill_unit_group* group = skill_id2group(sce->val2);
+ sce->val2 = 0;
+ skill_delunitgroup(group);
+ }
+ break;
+ case SC_BANDING:
+ {
+ struct skill_unit_group *group;
+ if(sce->val4)
+ {
+ group = skill_id2group(sce->val4);
+ sce->val4 = 0;
+ skill_delunitgroup(group);
+ }
+ }
+ break;
+ case SC_CURSEDCIRCLE_ATKER:
+ if( sce->val3 )
+ map_foreachinrange(status_change_timer_sub, bl, skill_get_splash(SR_CURSEDCIRCLE, sce->val1),BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, gettick());
+ break;
+ case SC_RAISINGDRAGON:
+ if( sd && sce->val2 && !pc_isdead(sd) )
+ {
+ int i;
+ i = min(sd->spiritball,5);
+ pc_delspiritball(sd, sd->spiritball, 0);
+ status_change_end(bl, SC_EXPLOSIONSPIRITS, -1);
+ while( i > 0 )
+ {
+ pc_addspiritball(sd, skill_get_time(MO_CALLSPIRITS, pc_checkskill(sd,MO_CALLSPIRITS)), 5);
+ --i;
+ }
+ }
+ break;*/
}
opt_flag = 1;
@@ -6832,6 +8007,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
opt_flag|= 2|4; //Check for warp trigger + AoE trigger
break;
case SC_CLOAKING:
+ case SC_CLOAKINGEXCEED:
sc->option &= ~OPTION_CLOAK;
opt_flag|= 2;
break;
@@ -6962,7 +8138,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
//On Aegis, when turning off a status change, first goes the sc packet, then the option packet.
if( vd && (pcdb_checkid(vd->class_) || bl->type == BL_MER ) )
- clif_status_change(bl,StatusIconChangeTable[type],0,0);
+ clif_status_change(bl,StatusIconChangeTable[type],0,0,0,0,0);
else if (sd)
clif_status_load(bl,StatusIconChangeTable[type],0);
@@ -7354,6 +8530,461 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
return 0;
}
break;
+ case SC_ABUNDANCE:
+ if(--(sce->val4) > 0)
+ {
+ if( !sc->data[SC_BERSERK] )
+ status_heal(bl,0,60,0);
+ sc_timer_next(10000+tick, status_change_timer, bl->id, data);
+ }
+ break;
+
+ case SC_PYREXIA:
+ if( --(sce->val4) >= 0 )
+ {
+ bool flag;
+ map_freeblock_lock();
+ clif_damage(bl,bl,tick,status_get_amotion(bl),0,100,0,0,0);
+ status_fix_damage(NULL,bl,100,0);
+ flag = !sc->data[type];
+ map_freeblock_unlock();
+ if( !flag )
+ {
+ if( sce->val4 == 10 )
+ sc_start(bl,SC_BLIND,100,sce->val1,30000); // Blind status for the final 30 seconds
+ sc_timer_next(3000+tick,status_change_timer,bl->id,data);
+ }
+ return 0;
+ }
+ break;
+
+ case SC_LEECHESEND:
+ if( --(sce->val4) >= 0 )
+ {
+ bool flag;
+ int damage = status->max_hp/100;
+ if( sd && (sd->status.class_ == JOB_GUILLOTINE_CROSS || sd->status.class_ == JOB_GUILLOTINE_CROSS_T ) )
+ damage += 3 * status->vit;
+ else
+ damage += 7 * status->vit;
+
+ unit_skillcastcancel(bl,2);
+
+ map_freeblock_lock();
+ status_zap(bl,damage,0);
+ flag = !sc->data[type];
+ map_freeblock_unlock();
+ if( !flag ) {
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data );
+ }
+ return 0;
+ }
+ break;
+
+ case SC_MAGICMUSHROOM:
+ if( --(sce->val4) >= 0 )
+ {
+ bool flag = 0;
+ int damage = status->max_hp * 3 / 100;
+ if( status->hp <= damage )
+ damage = status->hp - 1; // Cannot Kill
+
+ if( damage > 0 )
+ { // 3% Damage each 4 seconds
+ map_freeblock_lock();
+ status_zap(bl,damage,0);
+ flag = !sc->data[type]; // Killed? Should not
+ map_freeblock_unlock();
+ }
+
+ if( !flag )
+ { // Random Skill Cast
+ if( sd )
+ {
+ int mushroom_skillid = 0, i;
+ unit_stop_attack(bl);
+ unit_skillcastcancel(bl,1);
+ do
+ {
+ i = rand() % MAX_SKILL_MAGICMUSHROOM_DB;
+ mushroom_skillid = skill_magicmushroom_db[i].skillid;
+ }
+ while( mushroom_skillid == 0 );
+
+ switch( skill_get_casttype(mushroom_skillid) )
+ { // Magic Mushroom skills are buffs or area damage
+ case CAST_GROUND:
+ skill_castend_pos2(bl,bl->x,bl->y,mushroom_skillid,1,tick,0);
+ break;
+ case CAST_NODAMAGE:
+ skill_castend_nodamage_id(bl,bl,mushroom_skillid,1,tick,0);
+ break;
+ case CAST_DAMAGE:
+ skill_castend_damage_id(bl,bl,mushroom_skillid,1,tick,0);
+ break;
+ }
+ }
+
+ clif_emotion(bl,18);
+ sc_timer_next(4000+tick,status_change_timer,bl->id,data);
+ }
+ return 0;
+ }
+ break;
+
+ case SC_TOXIN:
+ if( --(sce->val4) >= 0 )
+ { //Damage is every 10 seconds including 3%sp drain.
+ bool flag;
+ map_freeblock_lock();
+ clif_damage(bl,bl,tick,status_get_amotion(bl),1,1,0,0,0);
+ status_damage(NULL,bl,1,status->max_sp*3/100,0,16);
+ flag = !sc->data[type];
+ map_freeblock_unlock();
+ if( !flag ) {
+ sc_timer_next(10000 + tick, status_change_timer, bl->id, data );
+ }
+ return 0;
+ }
+ break;
+
+ case SC_OBLIVIONCURSE:
+ if( --(sce->val4) >= 0 )
+ {
+ clif_emotion(bl,1);
+ sc_timer_next(3000 + tick, status_change_timer, bl->id, data );
+ return 0;
+ }
+ break;
+
+ case SC_WEAPONBLOCKING:
+ if( --(sce->val4) >= 0 )
+ {
+ if( !status_charge(bl,0,3) )
+ break;
+ sc_timer_next(3000+tick,status_change_timer,bl->id,data);
+ return 0;
+ }
+ break;
+
+ case SC_CLOAKINGEXCEED:
+ if(!status_charge(bl,0,10-sce->val1))
+ break;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+
+ case SC_RENOVATIO:
+ if( --(sce->val4) >= 0 )
+ {
+ status_heal(bl, status->max_hp * 3 / 100, 0, 2);
+ sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_BURNING:
+ if( --(sce->val4) >= 0 )
+ {
+ struct block_list *src = map_id2bl(sce->val3);
+ int flag, damage = 3 * status_get_max_hp(bl) / 100; // Non Elemental Damage
+ if( status )
+ damage += battle_attr_fix(NULL, bl, sce->val2, ELE_FIRE, status->def_ele, status->ele_lv);
+
+ map_freeblock_lock();
+ status_fix_damage(src,bl,damage,clif_damage(bl,bl,tick,0,0,damage,0,0,0));
+ flag = !sc->data[type];
+ map_freeblock_unlock();
+ if( !flag ) {// Target still lives. [LimitLine]
+ sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
+ }
+ return 0;
+ }
+ break;
+
+ case SC_FEAR:
+ if( --(sce->val4) >= 0 )
+ {
+ if( sce->val2 > 0 )
+ sce->val2--;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ 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 )
+ {
+ if( !status_charge(bl, 0, 1) )
+ break;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_READING_SB:
+ if( !status_charge(bl, 0, sce->val2) )
+ break;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+
+ case SC_ELECTRICSHOCKER:
+ 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);
+ return 0;
+ }
+ break;
+
+ case SC_CAMOUFLAGE:
+ if( !status_charge(bl,0,7 - sce->val1) )
+ break;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+
+ case SC__REPRODUCE:
+ if(!status_charge(bl, 0, 1))
+ break;
+ sc_timer_next(1000+tick, status_change_timer, bl->id, data);
+ return 0;
+
+ case SC__SHADOWFORM:
+ if( --(sce->val4) >= 0 )
+ {
+ if( !status_charge(bl, 0, sce->val1 - (sce->val1 - 1)) )
+ break;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC__INVISIBILITY:
+ if( --(sce->val4) >= 0 )
+ {
+ if( !status_charge(bl, 0, (status->sp * 6 - sce->val1) / 100) )// 6% - skilllv.
+ break;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_STRIKING:
+ if( --(sce->val4) >= 0 )
+ {
+ if( !status_charge(bl,0, sce->val1 ) )
+ break;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_BLOODSUCKER:
+ if( --(sce->val4) >= 0 )
+ {
+ struct block_list *src = map_id2bl(sce->val2);
+ int damage;
+ bool flag;
+ if( !src || (src && (status_isdead(src) || src->m != bl->m || distance_bl(src, bl) >= 12)) )
+ break;
+ map_freeblock_lock();
+ damage = skill_attack(skill_get_type(GN_BLOOD_SUCKER), src, src, bl, GN_BLOOD_SUCKER, sce->val1, tick, 0);
+ flag = !sc->data[type];
+ map_freeblock_unlock();
+ status_heal(src, damage, 0, 0);
+ clif_skill_nodamage(src, bl, GN_BLOOD_SUCKER, 0, 1);
+ if (!flag) {
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ }
+ return 0;
+ }
+ break;
+
+ case SC_VOICEOFSIREN:
+ if( --(sce->val4) >= 0 )
+ {
+ clif_emotion(bl,3);
+ sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_DEEPSLEEP:
+ 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);
+ return 0;
+ }
+ break;
+
+ case SC_SIRCLEOFNATURE:
+ if( --(sce->val4) >= 0 )
+ {
+ if( !status_charge(bl,0,sce->val2) )
+ break;
+ status_heal(bl, sce->val3, 0, 1);
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_SONGOFMANA:
+ if( --(sce->val4) >= 0 )
+ {
+ status_heal(bl,0,sce->val3,3);
+ sc_timer_next(3000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+
+ case SC_SATURDAYNIGHTFEVER:
+ // 1% HP/SP drain every 3 seconds [Jobbie]
+ if( --(sce->val3) >= 0 )
+ {
+ int hp = status->hp / 100;
+ int sp = status->sp / 100;
+ if( !status_charge(bl, hp, sp) )
+ break;
+ sc_timer_next(sce->val4+tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_CRYSTALIZE:
+ if( --(sce->val4) >= 0 )
+ { // Drains 2% of HP and 1% of SP every seconds.
+ status_charge(bl, status->max_hp * 2 / 100, status->max_sp / 100);
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_FORCEOFVANGUARD:
+ if( !status_charge(bl,0,20) )
+ break;
+ sc_timer_next(6000 + tick, status_change_timer, bl->id, data);
+ return 0;
+
+ case SC_BANDING:
+ if( status_charge(bl, 0, 7 - sce->val1) )
+ {
+ //if( sd ) pc_banding(sd, sce->val1);
+ sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_REFLECTDAMAGE:
+ if( --(sce->val4) >= 0 ) {
+ if( !status_charge(bl,0,sce->val3) )
+ break;
+ sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_OVERHEAT_LIMITPOINT:
+ if( --(sce->val1) > 0 ) { // Cooling
+ sc_timer_next(30000 + tick, status_change_timer, bl->id, data);
+ }
+ break;
+
+ case SC_OVERHEAT:
+ {
+ int flag, damage = status->max_hp / 100; // Suggestion 1% each second
+ if( damage >= status->hp ) damage = status->hp - 1; // Do not kill, just keep you with 1 hp minimum
+ map_freeblock_lock();
+ status_fix_damage(NULL,bl,damage,clif_damage(bl,bl,tick,0,0,damage,0,0,0));
+ flag = !sc->data[type];
+ map_freeblock_unlock();
+ if( !flag ) {
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ }
+ }
+ break;
+
+ case SC_MAGNETICFIELD:
+ {
+ if( --(sce->val3) <= 0 )
+ break; // Time out
+ if( sce->val2 == bl->id )
+ {
+ if( !status_charge(bl,0,14 + (3 * sce->val1)) )
+ break; // No more SP status should end, and in the next second will end for the other affected players
+ }
+ else
+ {
+ struct block_list *src = map_id2bl(sce->val2);
+ struct status_change *ssc;
+ if( !src || (ssc = status_get_sc(src)) == NULL || !ssc->data[SC_MAGNETICFIELD] )
+ break; // Source no more under Magnetic Field
+ }
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ }
+ break;
+
+ case SC_INSPIRATION:
+ if(--(sce->val4) >= 0)
+ {
+ int hp = status->max_hp * (7-sce->val1) / 100;
+ int sp = status->max_sp * (9-sce->val1) / 100;
+
+ if( !status_charge(bl,hp,sp) ) break;
+
+ sc_timer_next(1000+tick,status_change_timer,bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_RAISINGDRAGON:
+ // 1% every 5 seconds [Jobbie]
+ if( --(sce->val3)>0 && status_charge(bl, sce->val2, 0) )
+ {
+ if( !sc->data[type] ) return 0;
+ sc_timer_next(5000 + tick, status_change_timer, bl->id, data);
+ return 0;
+ }
+ break;
+
+ case SC_CIRCLE_OF_FIRE:
+ case SC_FIRE_CLOAK:
+ case SC_WATER_DROP:
+ case SC_WATER_SCREEN:
+ case SC_WIND_CURTAIN:
+ case SC_WIND_STEP:
+ case SC_STONE_SHIELD:
+ case SC_SOLID_SKIN:
+ if( !status_charge(bl,0,sce->val2) )
+ {
+ struct block_list *s_bl = battle_get_master(bl);
+ if( s_bl )
+ status_change_end(s_bl,type+1,-1);
+ status_change_end(bl,type,-1);
+ break;
+ }
+ sc_timer_next(2000 + tick, status_change_timer, bl->id, data);
+ return 0;
+
+ case SC_STOMACHACHE:
+ if( --(sce->val4) > 0 )
+ {
+ status_charge(bl,0,sce->val2); // Reduce 8 every 10 seconds.
+ if( sd && !pc_issit(sd) ) // Force to sit every 10 seconds.
+ {
+ pc_stop_walking(sd,1|4);
+ pc_stop_attack(sd);
+ pc_setsit(sd);
+ clif_sitting(bl);
+ }
+ sc_timer_next(10000 + tick, status_change_timer, bl->id, data);
+ }
+ break;
+
}
// default for all non-handled control paths is to end the status
@@ -7384,11 +9015,15 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
case SC_CONCENTRATE:
status_change_end(bl, SC_HIDING, INVALID_TIMER);
status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
+ status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
break;
case SC_RUWACH: /* ƒ‹ƒAƒt */
- if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING])) {
+ if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_CLOAKINGEXCEED])) {
status_change_end(bl, SC_HIDING, INVALID_TIMER);
status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
+ status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
+ status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
if(battle_check_target( src, bl, BCT_ENEMY ) > 0)
skill_attack(BF_MAGIC,src,src,bl,AL_RUWACH,1,tick,0);
}
@@ -7716,6 +9351,25 @@ static int status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_
* size_fix.txt - size adjustment table for weapons
* refine_db.txt - refining data table
*------------------------------------------*/
+#if RRMODE
+static bool status_readdb_job_re(char* fields[], int columns, int current) {
+ int idx, class_;
+ unsigned int i;
+
+ class_ = atoi(fields[0]);
+
+ if(!pcdb_checkid(class_)) {
+ ShowWarning("status_readdb_job_re: Invalid job class %d specified.\n", class_);
+ return false;
+ }
+ idx = pc_class2idx(class_);
+
+ for(i = 0; i < RE_JOB_DB_MAX; i++) {
+ re_job_db[idx][i] = atoi(fields[i+1]);
+ }
+ return true;
+}
+#endif
static bool status_readdb_job1(char* fields[], int columns, int current)
{// Job-specific values (weight, HP, SP, ASPD)
int idx, class_;
@@ -7801,7 +9455,9 @@ int status_readdb(void)
memset(hp_coefficient2, 0, sizeof(hp_coefficient2));
memset(sp_coefficient, 0, sizeof(sp_coefficient));
memset(aspd_base, 0, sizeof(aspd_base));
-
+#if RRMODE
+ memset(re_job_db, 0, sizeof(re_job_db));
+#endif
// job_db2.txt
memset(job_bonus,0,sizeof(job_bonus)); // Job-specific stats bonus
@@ -7828,6 +9484,10 @@ int status_readdb(void)
sv_readdb(db_path, "size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(atkmods), &status_readdb_sizefix);
sv_readdb(db_path, "refine_db.txt", ',', 3+MAX_REFINE+1, 3+MAX_REFINE+1, ARRAYLENGTH(percentrefinery), &status_readdb_refine);
+#if RRMODE
+ sv_readdb(db_path, "re_job_db.txt", ',', 1+RE_JOB_DB_MAX, 1+RE_JOB_DB_MAX, -1, &status_readdb_job_re);
+#endif
+
return 0;
}