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.c2269
1 files changed, 1815 insertions, 454 deletions
diff --git a/src/map/status.c b/src/map/status.c
index f704ee0d6..dd528660b 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -35,7 +35,7 @@
#include <stdlib.h>
#include <memory.h>
#include <string.h>
-#include <math.h>
+
//Regen related flags.
enum e_regen
@@ -52,12 +52,17 @@ static int hp_coefficient2[CLASS_COUNT];
static int hp_sigma_val[CLASS_COUNT][MAX_LEVEL+1];
static int sp_coefficient[CLASS_COUNT];
static int aspd_base[CLASS_COUNT][MAX_WEAPON_TYPE]; //[blackhole89]
-static int shield_aspd_base[CLASS_COUNT];
static int refinebonus[MAX_REFINE_BONUS][3]; // Έ˜Bƒ{[ƒiƒXƒe[ƒuƒ‹(refine_db.txt)
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;
@@ -400,7 +405,7 @@ void initChangeTables(void)
set_sc( CASH_INCAGI , SC_INCREASEAGI , SI_INCREASEAGI , SCB_AGI|SCB_SPEED );
set_sc( CASH_ASSUMPTIO , SC_ASSUMPTIO , SI_ASSUMPTIO , SCB_NONE );
- set_sc( ALL_PARTYFLEE , SC_PARTYFLEE , SI_PARTYFLEE , SCB_FLEE );
+ //set_sc( ALL_PARTYFLEE , SC_INCFLEE , SI_PARTYFLEE , SCB_NONE );
set_sc( CR_SHRINK , SC_SHRINK , SI_SHRINK , SCB_NONE );
set_sc( RG_CLOSECONFINE , SC_CLOSECONFINE2 , SI_CLOSECONFINE2 , SCB_NONE );
@@ -413,30 +418,6 @@ void initChangeTables(void)
add_sc( SA_ELEMENTGROUND , SC_ELEMENTALCHANGE );
add_sc( SA_ELEMENTWIND , SC_ELEMENTALCHANGE );
- set_sc( RK_ENCHANTBLADE , SC_ENCHANTBLADE , SI_ENCHANTBLADE , SCB_NONE );
- set_sc( RK_DEATHBOUND , SC_DEATHBOUND , SI_DEATHBOUND , SCB_NONE );
- set_sc( RK_MILLENNIUMSHIELD , SC_MILLENNIUMSHIELD , SI_BLANK , SCB_NONE );
- set_sc( RK_CRUSHSTRIKE , SC_CRUSHSTRIKE , SI_CRUSHSTRIKE , 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_DEF2|SCB_MDEF2 );
- set_sc( RK_VITALITYACTIVATION, SC_VITALITYACTIVATION , SI_VITALITYACTIVATION , SCB_REGEN );
- set_sc( RK_FIGHTINGSPIRIT , SC_FIGHTINGSPIRIT , SI_FIGHTINGSPIRIT , SCB_ASPD );
- set_sc( RK_ABUNDANCE , SC_ABUNDANCE , SI_ABUNDANCE , SCB_NONE );
-
- 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_PRAEFATIO , SC_KYRIE );
- set_sc( AB_EPICLESIS , SC_EPICLESIS , SI_EPICLESIS , SCB_MAXHP );
- 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_NONE );
- set_sc( AB_DUPLELIGHT , SC_DUPLELIGHT , SI_DUPLELIGHT , SCB_NONE );
- set_sc( AB_SECRAMENT , SC_AB_SECRAMENT , SI_AB_SECRAMENT , SCB_NONE );
-
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 );
@@ -470,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,
@@ -514,7 +651,6 @@ void initChangeTables(void)
StatusIconChangeTable[SC_SPL_DEF] = SI_SPL_DEF;
StatusIconChangeTable[SC_MANU_MATK] = SI_MANU_MATK;
StatusIconChangeTable[SC_SPL_MATK] = SI_SPL_MATK;
-
//Cash Items
StatusIconChangeTable[SC_FOOD_STR_CASH] = SI_FOOD_STR_CASH;
StatusIconChangeTable[SC_FOOD_AGI_CASH] = SI_FOOD_AGI_CASH;
@@ -542,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;
@@ -586,8 +797,6 @@ void initChangeTables(void)
StatusChangeFlagTable[SC_SPCOST_RATE] |= SCB_ALL;
StatusChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED;
StatusChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL;
- StatusChangeFlagTable[SC_FEAR] |= SCB_HIT|SCB_FLEE;
-
// Cash Items
StatusChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR;
StatusChangeFlagTable[SC_FOOD_AGI_CASH] = SCB_AGI;
@@ -601,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;
}
@@ -627,6 +841,14 @@ static void initDummyData(void)
dummy_status.mode = MD_CANMOVE;
}
+
+//For copying a status_data structure from b to a, without overwriting current Hp and Sp
+static inline void status_cpy(struct status_data* a, const struct status_data* b)
+{
+ memcpy((void*)&a->max_hp, (const void*)&b->max_hp, sizeof(struct status_data)-(sizeof(a->hp)+sizeof(a->sp)));
+}
+
+
/*==========================================
* Έ˜Bƒ{[ƒiƒX
*------------------------------------------*/
@@ -748,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]
@@ -765,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);
}
@@ -917,9 +1142,6 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
}
if(sp) {
- if (sc && sc->data[SC_BERSERK] && sc->data[SC_ABUNDANCE]) // SP does not regenerate during Frenzy.
- sp = 0;
-
if((unsigned int)sp > status->max_sp - status->sp)
sp = status->max_sp - status->sp;
}
@@ -1199,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;
@@ -1233,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).
@@ -1279,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;
@@ -1299,28 +1521,42 @@ int status_check_visibility(struct block_list *src, struct block_list *target)
// Basic ASPD value
int status_base_amotion_pc(struct map_session_data* sd, struct status_data* status)
{
- int amotion, shield = 0;
+ int amotion;
// base weapon delay
amotion = (sd->status.weapon < MAX_WEAPON_TYPE)
? (aspd_base[pc_class2idx(sd->status.class_)][sd->status.weapon]) // single weapon
: (aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype1] + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2])*7/10; // dual-wield
- if (sd->status.shield)
- shield = shield_aspd_base[pc_class2idx(sd->status.class_)] * 10;
-
// percentual delay reduction from stats
- amotion-= ( amotion - shield ) * (4*status->agi + status->dex)/1000;
-
+ amotion-= amotion * (4*status->agi + status->dex)/1000;
+
// raw delay adjustment from bAspd bonus
amotion+= sd->aspd_add;
-
- return amotion;
+#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;
}
static unsigned short status_base_atk(const struct block_list *bl, const struct status_data *status)
{
- int flag = 0, str, dex, dstr, base;
+ int flag = 0, str, dex, dstr;
if(!(bl->type&battle_config.enable_baseatk))
return 0;
@@ -1338,10 +1574,10 @@ static unsigned short status_base_atk(const struct block_list *bl, const struct
flag = 1;
}
if (flag) {
- base =str = status->dex;
+ str = status->dex;
dex = status->str;
} else {
- base = str = status->str;
+ str = status->str;
dex = status->dex;
}
//Normally only players have base-atk, but homunc have a different batk
@@ -1350,12 +1586,33 @@ static unsigned short status_base_atk(const struct block_list *bl, const struct
dstr = str/10;
str += dstr*dstr;
if (bl->type == BL_PC)
- str = (((TBL_PC*)bl)->status.base_level*10/4 + base*10 + dex*10/5 + status->luk*10/3)/10;
+ str+= dex/5 + status->luk/5;
return cap_value(str, 0, USHRT_MAX);
}
-#define status_base_matk_max(status) (status->int_+(status->int_/5)*(status->int_/5))
-#define status_base_matk_min(status) (status->int_+(status->int_/7)*(status->int_/7))
+
+static inline unsigned short status_base_matk_max(const struct status_data* status)
+{
+ #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
+{
+ #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
+}
+
//Fills in the misc data that can be calculated from the other status info (except for level)
void status_calc_misc(struct block_list *bl, struct status_data *status, int level)
@@ -1366,23 +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);
- //Renewal calculation? HIT is currently coming up too high.
- status->hit += 175 + status->dex + (unsigned short)floor((double)status->luk/3) + level;
- status->flee += 100 + status->agi + level;
-
- // Values are still off by roughly 1~3 points. Getting there though.
- status->def2 += (level*10/2 + status->vit*10/2 + status->agi*10/5)/10;
- if( bl->type != BL_MOB )
- status->mdef2 += (level*10/4 + status->int_*10 + status->vit*10/5 + status->dex*10/5)/10;
- else
- status->mdef2 = status->mdef; // Mobs use their mdef as their mdef2.
-
- //Status MATK = floor(Base Level/4 + INT + INT/2 + DEX/5 + LUK/3)
- status->status_matk = (unsigned short)floor((double)level/4 + (double)status->int_ + (double)status->int_/2 + (double)status->dex/5 + (double)status->luk/3);
+#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;
@@ -1399,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:
@@ -1561,11 +1830,8 @@ int status_calc_mob_(struct mob_data* md, bool first)
status->max_sp += 200 * gc->defense;
status->hp = status->max_hp;
status->sp = status->max_sp;
- if( gc->castle_id < 24 )
- {
- status->def += (gc->defense+2)/3;
- status->mdef += (gc->defense+2)/3;
- }
+ status->def += (gc->defense+2)/3;
+ status->mdef += (gc->defense+2)/3;
}
if(md->class_ != MOBID_EMPERIUM) {
status->batk += status->batk * 10*md->guardian_data->guardup_lv/100;
@@ -1712,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.
@@ -1772,9 +2050,6 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100;
sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100;
sd->regen.state.block = 0;
- sd->fixedcastrate=100;
- sd->weapon_matk = 0;
- sd->equipment_matk = 0;
// zeroed arrays, order follows the order in pc.h.
// add new arrays to the end of zeroed area in pc.h (see comments) and size here. [zzo]
@@ -1818,7 +2093,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)?0:1;
- if (battle_config.character_size && (pc_isriding(sd) || pc_isdragon(sd))) { //[Lupus]
+ if (battle_config.character_size && pc_isriding(sd)) { //[Lupus]
if (sd->class_&JOBL_BABY) {
if (battle_config.character_size&2)
status->size++;
@@ -1940,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) {
@@ -1952,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];
@@ -1979,11 +2268,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
}
}
else if(sd->inventory_data[index]->type == IT_ARMOR) {
- int r = sd->status.inventory[index].refine;
- int per = 0, refine=(r>0)?1:0;
- for(per=1; per<r; per++)
- refine += (per/4) + 1;
- refinedef += refine;
+ refinedef += sd->status.inventory[index].refine*refinebonus[0][0];
if(sd->inventory_data[index]->script) {
run_script(sd->inventory_data[index]->script,0,sd->bl.id,0);
if (!calculating) //Abort, run_script retriggered this. [Skotlex]
@@ -2008,7 +2293,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
memcpy(sd->param_equip,sd->param_bonus,sizeof(sd->param_equip));
memset(sd->param_bonus, 0, sizeof(sd->param_bonus));
- status->def += refinedef;
+ status->def += (refinedef+50)/100;
//Parse Cards
for(i=0;i<EQI_MAX-1;i++) {
@@ -2103,7 +2388,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) || pc_isdragon(sd)) &&
+ if(pc_isriding(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.
@@ -2312,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
@@ -2320,15 +2604,22 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
sd->def_rate = 0;
if(sd->def_rate != 100) {
i = status->def * sd->def_rate/100;
+#if RRMODE
status->def = cap_value(i, SHRT_MIN, SHRT_MAX);
- }
-
+#else
+ status->def = cap_value(i, CHAR_MIN, CHAR_MAX);
+#endif
+ }
+#if RRMODE == 0
+ /**
+ * The following setting does not affect Renewal Mode
+ **/
if (!battle_config.weapon_defense_type && status->def > battle_config.max_def)
{
status->def2 += battle_config.over_def_bonus*(status->def -battle_config.max_def);
- status->def = (unsigned short)battle_config.max_def;
+ status->def = (unsigned char)battle_config.max_def;
}
-
+#endif
// ----- EQUIPMENT-MDEF CALCULATION -----
// Apply relative modifiers from equipment
@@ -2336,15 +2627,22 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
sd->mdef_rate = 0;
if(sd->mdef_rate != 100) {
i = status->mdef * sd->mdef_rate/100;
+#if RRMODE
status->mdef = cap_value(i, SHRT_MIN, SHRT_MAX);
- }
-
+#else
+ status->mdef = cap_value(i, CHAR_MIN, CHAR_MAX);
+#endif
+ }
+#if RRMODE == 0
+ /**
+ * The following setting does not affect Renewal Mode
+ **/
if (!battle_config.magic_defense_type && status->mdef > battle_config.max_def)
{
status->mdef2 += battle_config.over_def_bonus*(status->mdef -battle_config.max_def);
- status->mdef = (signed short)battle_config.max_def;
+ status->mdef = (signed char)battle_config.max_def;
}
-
+#endif
// ----- ASPD CALCULATION -----
// Unlike other stats, ASPD rate modifiers from skills/SCs/items/etc are first all added together, then the final modifier is applied
@@ -2362,8 +2660,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
status->aspd_rate -= ((skill+1)/2) * 10;
if(pc_isriding(sd))
status->aspd_rate += 500-100*pc_checkskill(sd,KN_CAVALIERMASTERY);
- if(pc_isdragon(sd))
- status->aspd_rate += 750-75*pc_checkskill(sd,RK_DRAGONTRAINING); // Officiak is rumoured to be 75+5*skilllv...giving you 125% ASPD?
+
status->adelay = 2*status->amotion;
@@ -2381,8 +2678,6 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
sd->max_weight += 2000*skill;
if(pc_isriding(sd) && pc_checkskill(sd,KN_RIDING)>0)
sd->max_weight += 10000;
- if(pc_isdragon(sd) && (skill=pc_checkskill(sd,RK_DRAGONTRAINING))>0)
- sd->max_weight += 5000+2000*skill; //+200 weight per level of RK_DRAGINTRAINING
if(sc->data[SC_KNOWLEDGE])
sd->max_weight += sd->max_weight*sc->data[SC_KNOWLEDGE]->val1/10;
if((skill=pc_checkskill(sd,ALL_INCCARRY))>0)
@@ -2408,8 +2703,6 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
sd->dsprate = 0;
if(sd->castrate < 0)
sd->castrate = 0;
- if( sd->fixedcastrate < 0 )
- sd->fixedcastrate = 0;
if(sd->delayrate < 0)
sd->delayrate = 0;
if(sd->hprecov_rate < 0)
@@ -2431,17 +2724,6 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
sd->magic_addrace[RC_DRAGON]+=skill;
sd->subrace[RC_DRAGON]+=skill;
}
- if( (skill = pc_checkskill(sd, AB_EUCHARISTICA)) > 0 )
- {
- sd->right_weapon.addrace[RC_DEMON]+=skill;
- sd->right_weapon.addele[ELE_DARK]+=skill;
- sd->left_weapon.addrace[RC_DEMON]+=skill;
- sd->left_weapon.addele[ELE_DARK]+=skill;
- sd->magic_addrace[RC_DEMON]+=skill;
- sd->magic_addele[ELE_DARK]+=skill;
- sd->subrace[RC_DEMON]+=skill;
- sd->subele[ELE_DARK]+=skill;
- }
if(sc->count){
if(sc->data[SC_CONCENTRATE])
@@ -2480,7 +2762,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 -----
@@ -2594,8 +2875,13 @@ int status_calc_homunculus_(struct homun_data *hd, bool first)
status->adelay = status->amotion; //It seems adelay = amotion for Homunculus.
status_calc_misc(&hd->bl, status, hom->level);
+#if RRMODE
+ /**
+ * In RE Mode matk_max is used as source of weaponMATK, but homuns don't have it -- so we swap the values here.
+ **/
+ status->matk_max = status->matk_min;
+#endif
status_cpy(&hd->battle_status, status);
-
return 1;
}
@@ -2612,9 +2898,17 @@ static signed short status_calc_hit(struct block_list *,struct status_change *,i
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 signed short status_calc_def(struct block_list *,struct status_change *,int);
+#if RRMODE
+ static short status_calc_def(struct block_list *bl, struct status_change *sc, int);
+#else
+ static signed char status_calc_def(struct block_list *,struct status_change *,int);
+#endif
static signed short status_calc_def2(struct block_list *,struct status_change *,int);
-static signed short status_calc_mdef(struct block_list *,struct status_change *,int);
+#if RRMODE
+ static short status_calc_mdef(struct block_list *bl, struct status_change *sc, int);
+#else
+ static signed char status_calc_mdef(struct block_list *,struct status_change *,int);
+#endif
static signed short status_calc_mdef2(struct block_list *,struct status_change *,int);
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);
@@ -2792,8 +3086,6 @@ 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_VITALITYACTIVATION] )
- regen->flag &=~RGN_SP;
}
/// Recalculates parts of an object's battle status according to the specified flags.
@@ -2857,7 +3149,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
if(flag&SCB_LUK) {
status->luk = status_calc_luk(bl, sc, b_status->luk);
- flag|=SCB_BATK|SCB_CRI|SCB_FLEE2|SCB_MATK;
+ flag|=SCB_BATK|SCB_CRI|SCB_FLEE2;
}
if(flag&SCB_BATK && b_status->batk) {
@@ -3048,38 +3340,27 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
}
if(flag&SCB_MATK) {
- int wlv = 1, wmatk = 0;
-
//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);
- // iRO Wiki states as of 2011/02/24:
- // Status MATK = floor(Base Level/4 + INT + INT/2 + DEX/5 + LUK/3)
- status->status_matk = status_get_lv(bl)/4 + status->int_ + status->int_/2 + status->dex/5 + status->luk/3;
-
- if( sd )
- {
- short index = sd->equip_index[EQI_HAND_R];
- wmatk = sd->weapon_matk + sd->battle_status.rhw.atk2 + sd->equipment_matk;
- if( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON )
- wlv = sd->inventory_data[index]->wlv;
- }
-
- // Variance = ± 0.1 * Weapon Level * Base Weapon MATK
- // Used in a lot of magical attack calculations still.
- status->matk_min = status->status_matk + wmatk;
- status->matk_max = status->status_matk + wmatk + (wmatk * wlv / 10);
-
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;
@@ -3160,14 +3441,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
@@ -3228,32 +3510,26 @@ void status_calc_bl_(struct block_list* bl, enum scb_flag flag, bool first)
clif_updatestatus(sd,SP_ASPD);
if(b_status.speed != status->speed)
clif_updatestatus(sd,SP_SPEED);
- if(b_status.rhw.atk != status->rhw.atk || b_status.lhw.atk != status->lhw.atk || b_status.batk != status->batk
- || b_status.rhw.atk2 != status->rhw.atk2 || b_status.lhw.atk2 != status->lhw.atk2 || b_status.equipment_atk != status->equipment_atk)
- {
+ if(b_status.rhw.atk != status->rhw.atk || b_status.lhw.atk != status->lhw.atk || b_status.batk != status->batk)
clif_updatestatus(sd,SP_ATK1);
- clif_updatestatus(sd,SP_ATK2);
- clif_updatestatus(sd,SP_MATK1);
- }
- if(b_status.def != status->def || b_status.def2 != status->def2)
- {
+ if(b_status.def != status->def)
clif_updatestatus(sd,SP_DEF1);
+ if(b_status.rhw.atk2 != status->rhw.atk2 || b_status.lhw.atk2 != status->lhw.atk2)
+ clif_updatestatus(sd,SP_ATK2);
+ if(b_status.def2 != status->def2)
clif_updatestatus(sd,SP_DEF2);
- }
if(b_status.flee2 != status->flee2)
clif_updatestatus(sd,SP_FLEE2);
if(b_status.cri != status->cri)
clif_updatestatus(sd,SP_CRITICAL);
if(b_status.matk_max != status->matk_max)
- {
clif_updatestatus(sd,SP_MATK1);
+ if(b_status.matk_min != status->matk_min)
clif_updatestatus(sd,SP_MATK2);
- }
- if(b_status.mdef != status->mdef || b_status.mdef2 != status->mdef2)
- {
+ if(b_status.mdef != status->mdef)
clif_updatestatus(sd,SP_MDEF1);
+ if(b_status.mdef2 != status->mdef2)
clif_updatestatus(sd,SP_MDEF2);
- }
if(b_status.rhw.range != status->rhw.range)
clif_updatestatus(sd,SP_ATTACKRANGE);
if(b_status.max_hp != status->max_hp)
@@ -3343,6 +3619,9 @@ 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;
@@ -3384,6 +3663,9 @@ 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;
@@ -3417,8 +3699,6 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang
vit += sc->data[SC_MARIONETTE2]->val3&0xFF;
if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && vit < 50)
vit = 50;
- if(sc->data[SC_LAUDAAGNUS])
- vit += sc->data[SC_LAUDAAGNUS]->val2;
return (unsigned short)cap_value(vit,0,USHRT_MAX);
}
@@ -3529,8 +3809,6 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang
luk += sc->data[SC_MARIONETTE2]->val4&0xFF;
if(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_HIGH && luk < 50)
luk = 50;
- if(sc->data[SC_LAUDARAMUS])
- luk += sc->data[SC_LAUDARAMUS]->val2;
return (unsigned short)cap_value(luk,0,USHRT_MAX);
}
@@ -3567,6 +3845,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);
}
@@ -3611,6 +3896,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);
}
@@ -3649,6 +3941,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);
}
@@ -3680,7 +3974,7 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change
if(sc->data[SC_MERC_HITUP])
hit += sc->data[SC_MERC_HITUP]->val2;
if(sc->data[SC_FEAR])
- hit -= hit * 20/100;
+ hit -= hit * 20 / 100;
return (short)cap_value(hit,1,SHRT_MAX);
}
@@ -3726,12 +4020,31 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
flee -= sc->data[SC_GATLINGFEVER]->val4;
if(sc->data[SC_SPEED])
flee += 10 + sc->data[SC_SPEED]->val1 * 10;
- 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_FEAR])
- flee -= flee * 20/100;
+ 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);
}
@@ -3748,12 +4061,18 @@ static signed short status_calc_flee2(struct block_list *bl, struct status_chang
return (short)cap_value(flee2,10,SHRT_MAX);
}
-
-static signed short status_calc_def(struct block_list *bl, struct status_change *sc, int def)
+#if RRMODE
+ static short status_calc_def(struct block_list *bl, struct status_change *sc, int def)
+#else
+ static signed char status_calc_def(struct block_list *bl, struct status_change *sc, int def)
+#endif
{
if(!sc || !sc->count)
- return (signed short)cap_value(def,SHRT_MIN,SHRT_MAX);
-
+#if RRMODE
+ return (short)cap_value(def,SHRT_MIN,SHRT_MAX);
+#else
+ return (signed char)cap_value(def,CHAR_MIN,CHAR_MAX);
+#endif
if(sc->data[SC_BERSERK])
return 0;
if(sc->data[SC_SKA])
@@ -3788,8 +4107,31 @@ static signed short 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;
-
- return (signed short)cap_value(def,SHRT_MIN,SHRT_MAX);
+ 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;
+#if RRMODE
+ return (short)cap_value(def,SHRT_MIN,SHRT_MAX);
+#else
+ return (signed char)cap_value(def,CHAR_MIN,CHAR_MAX);
+#endif
}
static signed short status_calc_def2(struct block_list *bl, struct status_change *sc, int def2)
@@ -3820,16 +4162,36 @@ 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_STONEHARDSKIN])
- def2 += sc->data[SC_STONEHARDSKIN]->val3;
+ 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);
}
-static signed short status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef)
+#if RRMODE
+ static short status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef)
+#else
+ static signed char status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef)
+#endif
{
if(!sc || !sc->count)
- return (signed short)cap_value(mdef,SHRT_MIN,SHRT_MAX);
+#if RRMODE
+ return (short)cap_value(mdef,SHRT_MIN,SHRT_MAX);
+#else
+ return (signed char)cap_value(mdef,CHAR_MIN,CHAR_MAX);
+#endif
if(sc->data[SC_BERSERK])
return 0;
@@ -3849,8 +4211,22 @@ static signed short 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.
-
- return (signed short)cap_value(mdef,SHRT_MIN,SHRT_MAX);
+ 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;
+
+#if RRMODE
+ return (short)cap_value(mdef,SHRT_MIN,SHRT_MAX);
+#else
+ return (signed char)cap_value(mdef,CHAR_MIN,CHAR_MAX);
+#endif
}
static signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, int mdef2)
@@ -3862,8 +4238,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_STONEHARDSKIN])
- mdef2 += sc->data[SC_STONEHARDSKIN]->val3;
+ if(sc->data[SC_ANALYZE])
+ mdef2 -= mdef2 * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
return (short)cap_value(mdef2,1,SHRT_MAX);
}
@@ -3890,11 +4266,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;
- if( sd && pc_isdragon(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;
}
@@ -3919,7 +4301,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 );
@@ -3943,8 +4325,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_ADORAMUS] )
- val = max( val, 25 );
+ 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 );
@@ -4012,7 +4410,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);
@@ -4081,12 +4484,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])
@@ -4107,9 +4514,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_FIGHTINGSPIRIT])
- aspd_rate -= sc->data[SC_FIGHTINGSPIRIT]->val3;
-
+ 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);
}
@@ -4123,7 +4562,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);
@@ -4149,7 +4588,10 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
maxhp += maxhp * sc->data[SC_MERC_HPUP]->val2/100;
if(sc->data[SC_EPICLESIS])
- maxhp += maxhp * sc->data[SC_EPICLESIS]->val2/100;
+ 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);
}
@@ -4184,6 +4626,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);
}
@@ -4202,6 +4647,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);
}
@@ -4336,7 +4783,7 @@ struct status_data *status_get_base_status(struct block_list *bl)
}
}
-signed short status_get_def(struct block_list *bl)
+signed char status_get_def(struct block_list *bl)
{
struct unit_data *ud;
struct status_data *status = status_get_status_data(bl);
@@ -4344,7 +4791,11 @@ signed short status_get_def(struct block_list *bl)
ud = unit_bl2ud(bl);
if (ud && ud->skilltimer != INVALID_TIMER)
def -= def * skill_get_castdef(ud->skillid)/100;
+#if RRMODE
return cap_value(def, SHRT_MIN, SHRT_MAX);
+#else
+ return cap_value(def, CHAR_MIN, CHAR_MAX);
+#endif
}
unsigned short status_get_speed(struct block_list *bl)
@@ -4569,22 +5020,6 @@ void status_set_viewdata(struct block_list *bl, int class_)
class_ = JOB_BABY_CRUSADER2;
break;
}
- /*
- else
- if (sd->sc.option&OPTION_DRAGON) // For completeness' sake. These aren't actually needed...except maybe in older clients.
- switch (class_)
- {
- case JOB_RUNE_KNIGHT:
- class_ = JOB_RUNE_KNIGHT2;
- break;
- case JOB_RUNE_KNIGHT_H:
- class_ = JOB_RUNE_KNIGHT_H2;
- break;
- case JOB_BABY_RUNE:
- class_ = JOB_BABY_RUNE2;
- break;
- }
- */
sd->vd.class_ = class_;
clif_get_weapon_view(sd, &sd->vd.weapon, &sd->vd.shield);
sd->vd.head_top = sd->status.head_top;
@@ -4689,7 +5124,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;
@@ -4722,7 +5157,6 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
case SC_STONE:
case SC_QUAGMIRE:
case SC_SUITON:
- case SC_ADORAMUS:
return 0;
}
@@ -4741,7 +5175,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:
+ case SC_ADORAMUS://Arch Bishop
if (sd) tick>>=1; //Half duration for players.
case SC_STONE:
case SC_FREEZE:
@@ -4771,6 +5205,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))
@@ -4873,8 +5341,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 duration = tick;
+ int opt_flag, calc_flag, undead_flag, val_flag = 0, tick_time = 0;
nullpo_ret(bl);
sc = status_get_sc(bl);
@@ -4889,35 +5356,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if( !sc )
return 0; //Unable to receive status changes
- if( sc->data[SC_REFRESH] )
- {
- if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX && type != SC_STUN ) // Immune to all common status ailments except stun (iROWiki)
- return 0;
- switch( type )
- {
- case SC_FEAR:
- case SC_BURNING:
- // Not implemented yet. (kRO 3-x balance update)
- //case SC_POISONINGWEAPON:
- //case SC_TOXIN:
- //case SC_PARALYSE:
- //case SC_VENOMBLEED:
- //case SC_MAGICMUSHROOM:
- //case SC_DEATHHURT:
- //case SC_PYREXIA:
- //case SC_OBLIVIONCURSE:
- //case SC_LEECHESEND:
- //case SC_FROSTMISTY:
- //case SC_MARSHOFABYSS:
- //case SC_DEEP_SLEEP:
- //case SC_COLD:
- //case SC_FREEZE_SP:
- //case SC_MANDRAGORA:
- return 0;
- }
- }
-
- if( status_isdead(bl) )
+ if( status_isdead(bl) && type != SC_NOCHAT ) // SC_NOCHAT should work even on dead characters
return 0;
if( bl->type == BL_MOB && type != SC_SAFETYWALL && type != SC_PNEUMA )
@@ -4940,17 +5379,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_BURNING:
+ 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)
@@ -4967,13 +5416,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_ADORAMUS]
+ sc->option&OPTION_MADOGEAR //Adrenaline doesn't affect Mado Gear [Ind]
)
return 0;
break;
@@ -4981,16 +5433,17 @@ 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_ADORAMUS]
+ sc->data[SC_DECREASEAGI]
)
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:
- if(sc->data[SC_DECREASEAGI] ||
- sc->data[SC_ADORAMUS])
+ if(sc->data[SC_DECREASEAGI])
return 0;
case SC_CONCENTRATE:
case SC_INCREASEAGI:
@@ -5001,6 +5454,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]
@@ -5152,6 +5607,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
@@ -5160,8 +5619,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:
@@ -5170,7 +5627,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;
}
}
@@ -5189,7 +5665,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_INCREASEAGI:
status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER);
- status_change_end(bl, SC_ADORAMUS, INVALID_TIMER);
break;
case SC_QUAGMIRE:
status_change_end(bl, SC_CONCENTRATE, INVALID_TIMER);
@@ -5197,7 +5672,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
//Also blocks the ones below...
case SC_DECREASEAGI:
- case SC_ADORAMUS:
status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
//Also blocks the ones below...
case SC_DONTFORGETME:
@@ -5208,6 +5682,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]
@@ -5255,10 +5730,9 @@ 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] || sc->data[SC_ADORAMUS])
+ if(sc->data[SC_DECREASEAGI])
{ //Cancel Decrease Agi, but take no further effect [Skotlex]
status_change_end(bl, SC_DECREASEAGI, INVALID_TIMER);
- status_change_end(bl, SC_ADORAMUS, INVALID_TIMER);
return 0;
}
break;
@@ -5312,10 +5786,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_FOOD_LUK_CASH:
status_change_end(bl, SC_LUKFOOD, INVALID_TIMER);
break;
- case SC_FIGHTINGSPIRIT:
- if (sc->data[SC_FIGHTINGSPIRIT])
- status_change_end(bl, SC_FIGHTINGSPIRIT, INVALID_TIMER);
- break;
}
//Check for overlapping fails
@@ -5355,8 +5825,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
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_FEAR:
- case SC_BURNING:
return 0;
case SC_COMBO:
case SC_DANCING:
@@ -5413,10 +5881,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
{
case SC_DECREASEAGI:
case SC_INCREASEAGI:
- case SC_ADORAMUS:
val2 = 2 + val1; //Agi change
- if (val3) //Canto Candidus: Add joblv/10 additional AGI (8/31/2011)
- val2 += (val3/10);
break;
case SC_ENDURE:
val2 = 7; // Hit-count [Celest]
@@ -5456,6 +5921,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]
@@ -5466,17 +5933,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_KYRIE:
val2 = status->max_hp * (val1 * 2 + 10) / 100; //%Max HP to absorb
- // val4 holds current about of party memebers when casting AB_PRAEFATIO,
- // as Praefatio's barrier has more health and blocks more hits than Kyrie Elesion.
- if( val4 < 1 ) //== PR_KYRIE
- val3 = (val1 / 2 + 5);
- else
- { //== AB_PRAEFATIO
- val2 += val4 * 2; //Increase barrier strength per party member.
- val3 = 6 + val1;
- }
- if( sd )
- val1 = min(val1,pc_checkskill(sd,PR_KYRIE)); // use skill level to determine barrier health.
+ val3 = (val1 / 2 + 5); //Hits
break;
case SC_MAGICPOWER:
//val1: Skill lv
@@ -5601,10 +6058,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.
@@ -5612,9 +6069,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;
@@ -5635,6 +6097,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)
@@ -5666,7 +6129,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;
@@ -5680,7 +6143,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:
@@ -5691,7 +6154,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 )
@@ -5705,12 +6168,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;
@@ -5740,7 +6203,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.
@@ -5811,7 +6274,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
@@ -5834,13 +6297,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;
@@ -6000,11 +6463,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_BLESSING:
if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC)
- {
val2 = val1;
- if (val3) //Clementia: Add joblv/10 additional STR/INT/DEX (8/31/2011)
- val2 += (val3/10);
- }
else
val2 = 0; //0 -> Half stat.
break;
@@ -6110,7 +6569,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.
@@ -6213,70 +6672,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_KAIZEL:
val2 = 10*val1; //% of life to be revived with
break;
- case SC_MILLENNIUMSHIELD:
- val2 = (rand()%100<20) ? 4 : ((rand()%100<30) ? 3 : ((rand()%100<50) ? 2 : 0)); // 20% for 4, 30% for 3, 50% for 2
- val3 = 1000; // Initial Sheild health. (Additional sheilds health are set in battle.c when shield is broken.)
- if( sd && val2 > 0)
- clif_millenniumshield(sd,val2);
- break;
- case SC_STONEHARDSKIN:
- val2 = (status->hp * 20 / 100);
- if( val2 > 0 )
- status_heal(bl, -val2, 0, 0); // Reduce health by 20%
- if ( sd )
- val3 = (sd->status.job_level * pc_checkskill(sd,RK_RUNEMASTERY)) / 4;
- break;
- case SC_VITALITYACTIVATION:
- val2 = 50; // Increase HP recovery effects by 50%
- val3 = 50; // Reduce SP recovery effects by 50%
- break;
- case SC_FIGHTINGSPIRIT: // attack is handled in battle.c
- //val2 holds the source of the skill (1 = caster, 0 = party member.)
- //official ASPD bonus appears to be (Rune Mastery Level / 10 x 4).
- val3 = 10 * (sd?pc_checkskill(sd,RK_RUNEMASTERY):1); //Kind of dirty means to implement 4aspd increase.
- break;
- case SC_ABUNDANCE:
- val3 = tick / 10000;
- if(val3 < 1)
- val3 = 1;
- tick = 10000;
- break;
- case SC_EPICLESIS:
- val2 = 5 * val1; // % HP gained * level of Epiclesis cast.
- break;
- case SC_ORATIO:
- val2 = 2 * val1; // % Damage increased by level of Oratio cast.
- break;
- case SC_LAUDAAGNUS:
- case SC_LAUDARAMUS:
- val2 = 4+val1; // Bonus status points gained
- break;
- case SC_RENOVATIO:
- val2 = tick / 5000; // Heal every 5 seconds.
- tick = 5000;
- break;
- case SC_EXPIATIO:
- val2 = 5*val1; // DEF reduced by 5*Skill Level percent.
- break;
- case SC_DUPLELIGHT:
- val2 = 10+2*val1; //Chance of MELEE proc
- val3 = 10+2*val1; //Chance of MAGIC proc
- break;
-
- case SC_AB_SECRAMENT:
- val2 = 10*val1; //Fixed cast time reduced by 10*Skill Level
- break;
- case SC_FEAR:
- if (tick < 2000)
- val3 = 2000;
- else
- val3 = tick - 2000;
- tick = 2000;
- break;
- case SC_BURNING:
- val4 = tick/2000;
- tick = 3000;
- break;
// case SC_ARMOR_ELEMENT:
// case SC_ARMOR_RESIST:
// Mod your resistance against elements:
@@ -6310,6 +6705,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 )
@@ -6341,7 +7217,6 @@ 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_BURNING:
if (sd && pc_issit(sd)) //Avoid sprite sync problems.
pc_setstand(sd);
case SC_TRICKDEAD:
@@ -6356,13 +7231,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_FEAR:
+ 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:
@@ -6376,11 +7253,12 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
switch(type)
{
//OPT1
- 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_SLEEP: sc->opt1 = OPT1_SLEEP; break;
- case SC_BURNING: sc->opt1 = OPT1_BURNING; break;
+ 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_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;
@@ -6390,7 +7268,6 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_ANGELUS: sc->opt2 |= OPT2_ANGELUS; break;
case SC_BLEEDING: sc->opt2 |= OPT2_BLEEDING; break;
case SC_DPOISON: sc->opt2 |= OPT2_DPOISON; break;
- case SC_FEAR: sc->opt2 |= OPT2_FEAR; break;
//OPT3
case SC_TWOHANDQUICKEN:
case SC_ONEHAND:
@@ -6486,6 +7363,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;
@@ -6532,11 +7410,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]
- || (bl->type == BL_MOB && type == SC_ORATIO)) ) // Required to show the proper status for monsters. Possible this may need an overhaul.
- clif_status_change(bl,StatusIconChangeTable[type],1,duration);
+ 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]))
@@ -6590,6 +7472,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:
@@ -6725,8 +7617,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
return 0;
if (tid == INVALID_TIMER) {
- if( (type == SC_ENDURE) && sce->val4 )
- //Do not end infinite endure or speed adjustment.
+ if (type == SC_ENDURE && sce->val4)
+ //Do not end infinite endure.
return 0;
if (sce->timer != INVALID_TIMER) //Could be a SC with infinite duration
delete_timer(sce->timer,status_change_timer);
@@ -6911,7 +7803,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);
}
@@ -6919,7 +7811,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
case SC_NOCHAT:
if (sd && sd->status.manner < 0 && tid != INVALID_TIMER)
sd->status.manner = 0;
- if (sd)
+ if (sd && tid == INVALID_TIMER)
{
clif_changestatus(&sd->bl,SP_MANNER,sd->status.manner);
clif_updatestatus(sd,SP_MANNER);
@@ -7056,10 +7948,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:
- if ( sd )
- clif_millenniumshield(sd,0);
+ 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;
@@ -7068,7 +8038,6 @@ 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_BURNING:
sc->opt1 = 0;
break;
@@ -7084,15 +8053,13 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
case SC_SIGNUMCRUCIS:
sc->opt2 &= ~OPT2_SIGNUMCRUCIS;
break;
- case SC_FEAR:
- sc->opt2 &= ~OPT2_FEAR;
- break;
case SC_HIDING:
sc->option &= ~OPTION_HIDE;
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;
@@ -7222,9 +8189,8 @@ 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 )
- || (bl->type == BL_MOB && type == SC_ORATIO)) ) // Required to remove SI_ORATIO indicator from monsters.
- clif_status_change(bl,StatusIconChangeTable[type],0,0);
+ if( vd && (pcdb_checkid(vd->class_) || bl->type == BL_MER ) )
+ clif_status_change(bl,StatusIconChangeTable[type],0,0,0,0,0);
else if (sd)
clif_status_load(bl,StatusIconChangeTable[type],0);
@@ -7617,60 +8583,460 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
case SC_ABUNDANCE:
- if((--sce->val3) > 0)
+ if(--(sce->val4) > 0)
{
- int sp = 60;
- if(sd) {
- if( sd->status.sp < sd->status.max_sp )
+ 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 )
{
- if( sd->status.sp + sp > sd->status.max_sp ) //No overhealing SP.
- sp = sd->status.max_sp - sd->status.sp;
- clif_heal(sd->fd,SP_SP,sp);
- status_heal(bl, 0, sp, 0);
+ 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;
+ }
}
- }
- sc_timer_next(10000+tick, status_change_timer, bl->id, data);
+
+ 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->val2) > 0) {
- int heal = status->max_hp * 3 / 100;
- if( status->hp + heal > status->max_hp )
- heal = status->max_hp - status->hp;
- if(heal > 0)
- {
- clif_heal(sd->fd,SP_HP,heal);
- status_heal(bl, heal, 0, 0);
+ 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);
}
- sc_timer_next(5000+tick, status_change_timer, bl->id, data);
return 0;
}
break;
+
case SC_FEAR:
- if(sce->val3 > 0)
+ if( --(sce->val4) >= 0 )
{
- sc_timer_next(sce->val3+tick, status_change_timer, bl->id, data);
- sce->val3 = 0;
+ if( sce->val2 > 0 )
+ sce->val2--;
+ sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
+ return 0;
}
break;
- case SC_BURNING:
- if(--(sce->val4) >= 0)
+
+ case SC_SPHERE_1:
+ case SC_SPHERE_2:
+ case SC_SPHERE_3:
+ case SC_SPHERE_4:
+ case SC_SPHERE_5:
+ if( --(sce->val4) >= 0 )
{
- int flag, hp = 0;
- struct block_list *src = map_id2bl(sce->val2);
+ 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;
- hp = 1000+(status->max_hp*3 /100);
+ 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();
- clif_damage(bl,bl,tick,status->amotion,0,hp,1,9,0);
- status_damage(src, bl, hp, 0, 0, 1);
+ 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( 3000 + tick, status_change_timer, bl->id, data);
+ 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
@@ -7701,11 +9067,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);
}
@@ -7731,7 +9101,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
/*==========================================
* Clears buffs/debuffs of a character.
- * type&1 -> buffs, type&2 -> debuffs, type&4 -> sc_refresh
+ * type&1 -> buffs, type&2 -> debuffs
*------------------------------------------*/
int status_change_clear_buffs (struct block_list* bl, int type)
{
@@ -7790,13 +9160,6 @@ int status_change_clear_buffs (struct block_list* bl, int type)
case SC_EXPBOOST:
case SC_JEXPBOOST:
case SC_ITEMBOOST:
- case SC_GIANTGROWTH:
- case SC_REFRESH:
- case SC_STONEHARDSKIN:
- case SC_VITALITYACTIVATION:
- case SC_FIGHTINGSPIRIT:
- case SC_ABUNDANCE:
- case SC_MILLENNIUMSHIELD:
continue;
//Debuffs that can be removed.
@@ -7813,33 +9176,8 @@ int status_change_clear_buffs (struct block_list* bl, int type)
case SC_STRIPSHIELD:
case SC_STRIPARMOR:
case SC_STRIPHELM:
- //Cannot be removed by Refresh.
- if (type&4)
- continue;
- case SC_ADORAMUS:
if (!(type&2))
continue;
-
- //Debuffs that can be removed by Refresh..
- case SC_FEAR:
- case SC_BURNING:
- //case SC_POISONINGWEAPON:
- //case SC_TOXIN:
- //case SC_PARALYSE:
- //case SC_VENOMBLEED:
- //case SC_MAGICMUSHROOM:
- //case SC_DEATHHURT:
- //case SC_PYREXIA:
- //case SC_OBLIVIONCURSE:
- //case SC_LEECHESEND:
- //case SC_FROSTMISTY:
- //case SC_MARSHOFABYSS:
- //case SC_DEEP_SLEEP:
- //case SC_COLD:
- //case SC_FREEZE_SP:
- //case SC_MANDRAGORA:
- if (!(type&4))
- continue;
break;
//The rest are buffs that can be removed.
case SC_BERSERK:
@@ -8065,6 +9403,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_;
@@ -8088,7 +9445,6 @@ static bool status_readdb_job1(char* fields[], int columns, int current)
{
aspd_base[idx][i] = atoi(fields[i+5]);
}
- shield_aspd_base[idx] = atoi(fields[MAX_WEAPON_TYPE+5]);
return true;
}
@@ -8151,8 +9507,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));
- memset(shield_aspd_base, 0, sizeof(shield_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
@@ -8174,10 +9531,14 @@ int status_readdb(void)
// read databases
//
- sv_readdb(db_path, "job_db1.txt", ',', 5+MAX_WEAPON_TYPE+1, 5+MAX_WEAPON_TYPE+1, -1, &status_readdb_job1);
- sv_readdb(db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, &status_readdb_job2);
- 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);
+ sv_readdb(db_path, "job_db1.txt", ',', 5+MAX_WEAPON_TYPE, 5+MAX_WEAPON_TYPE, -1, &status_readdb_job1);
+ sv_readdb(db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, &status_readdb_job2);
+ 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;
}