diff options
Diffstat (limited to 'src/map/status.c')
-rw-r--r-- | src/map/status.c | 1406 |
1 files changed, 737 insertions, 669 deletions
diff --git a/src/map/status.c b/src/map/status.c index 018647459..7a7a4f415 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -4,9 +4,39 @@ #define HERCULES_CORE -#include "../config/core.h" // ANTI_MAYAP_CHEAT, DBPATH, DEFTYPE_MAX, DEFTYPE_MIN, DEVOTION_REFLECT_DAMAGE, RENEWAL, RENEWAL_ASPD, RENEWAL_EDP +#include "config/core.h" // ANTI_MAYAP_CHEAT, DBPATH, DEFTYPE_MAX, DEFTYPE_MIN, DEVOTION_REFLECT_DAMAGE, RENEWAL, RENEWAL_ASPD, RENEWAL_EDP #include "status.h" +#include "map/battle.h" +#include "map/chrif.h" +#include "map/clif.h" +#include "map/elemental.h" +#include "map/guild.h" +#include "map/homunculus.h" +#include "map/itemdb.h" +#include "map/map.h" +#include "map/mercenary.h" +#include "map/mob.h" +#include "map/npc.h" +#include "map/path.h" +#include "map/pc.h" +#include "map/pet.h" +#include "map/script.h" +#include "map/skill.h" +#include "map/skill.h" +#include "map/unit.h" +#include "map/vending.h" +#include "common/cbasetypes.h" +#include "common/ers.h" +#include "common/memmgr.h" +#include "common/nullpo.h" +#include "common/random.h" +#include "common/showmsg.h" +#include "common/strlib.h" +#include "common/timer.h" +#include "common/utils.h" +#include "common/conf.h" + #include <math.h> #include <memory.h> #include <stdio.h> @@ -14,36 +44,10 @@ #include <string.h> #include <time.h> -#include "battle.h" -#include "chrif.h" -#include "clif.h" -#include "elemental.h" -#include "guild.h" -#include "homunculus.h" -#include "itemdb.h" -#include "map.h" -#include "mercenary.h" -#include "mob.h" -#include "npc.h" -#include "path.h" -#include "pc.h" -#include "pet.h" -#include "script.h" -#include "skill.h" -#include "skill.h" -#include "unit.h" -#include "vending.h" -#include "../common/cbasetypes.h" -#include "../common/ers.h" -#include "../common/malloc.h" -#include "../common/nullpo.h" -#include "../common/random.h" -#include "../common/showmsg.h" -#include "../common/strlib.h" -#include "../common/timer.h" -#include "../common/utils.h" - struct status_interface status_s; +struct s_status_dbs statusdbs; + +struct status_interface *status; /** * Returns the status change associated with a skill. @@ -56,7 +60,7 @@ sc_type status_skill2sc(int skill_id) { ShowError("status_skill2sc: Unsupported skill id %d\n", skill_id); return SC_NONE; } - return status->Skill2SCTable[idx]; + return status->dbs->Skill2SCTable[idx]; } /** @@ -72,7 +76,7 @@ int status_sc2skill(sc_type sc) return 0; } - return status->SkillChangeTable[sc]; + return status->dbs->SkillChangeTable[sc]; } /** @@ -87,7 +91,7 @@ unsigned int status_sc2scb_flag(sc_type sc) return SCB_NONE; } - return status->ChangeFlagTable[sc]; + return status->dbs->ChangeFlagTable[sc]; } /** @@ -102,7 +106,7 @@ int status_type2relevant_bl_types(int type) return BL_NUL; } - return status->RelevantBLTypes[type]; + return status->dbs->RelevantBLTypes[type]; } static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag) { @@ -116,35 +120,35 @@ static void set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag) { return; } - if( status->SkillChangeTable[sc] == 0 ) - status->SkillChangeTable[sc] = skill_id; - if( status->IconChangeTable[sc] == SI_BLANK ) - status->IconChangeTable[sc] = icon; - status->ChangeFlagTable[sc] |= flag; + if( status->dbs->SkillChangeTable[sc] == 0 ) + status->dbs->SkillChangeTable[sc] = skill_id; + if( status->dbs->IconChangeTable[sc] == SI_BLANK ) + status->dbs->IconChangeTable[sc] = icon; + status->dbs->ChangeFlagTable[sc] |= flag; - if( status->Skill2SCTable[idx] == SC_NONE ) - status->Skill2SCTable[idx] = sc; + if( status->dbs->Skill2SCTable[idx] == SC_NONE ) + status->dbs->Skill2SCTable[idx] = sc; } void initChangeTables(void) { #define add_sc(skill,sc) set_sc((skill),(sc),SI_BLANK,SCB_NONE) // indicates that the status displays a visual effect for the affected unit, and should be sent to the client for all supported units -#define set_sc_with_vfx(skill, sc, icon, flag) do { set_sc((skill), (sc), (icon), (flag)); if((icon) < SI_MAX) status->RelevantBLTypes[(icon)] |= BL_SCEFFECT; } while(0) +#define set_sc_with_vfx(skill, sc, icon, flag) do { set_sc((skill), (sc), (icon), (flag)); if((icon) < SI_MAX) status->dbs->RelevantBLTypes[(icon)] |= BL_SCEFFECT; } while(0) int i; for (i = 0; i < SC_MAX; i++) - status->IconChangeTable[i] = SI_BLANK; + status->dbs->IconChangeTable[i] = SI_BLANK; for (i = 0; i < MAX_SKILL; i++) - status->Skill2SCTable[i] = SC_NONE; + status->dbs->Skill2SCTable[i] = SC_NONE; for (i = 0; i < SI_MAX; i++) - status->RelevantBLTypes[i] = BL_PC; + status->dbs->RelevantBLTypes[i] = BL_PC; - memset(status->SkillChangeTable, 0, sizeof(status->SkillChangeTable)); - memset(status->ChangeFlagTable, 0, sizeof(status->ChangeFlagTable)); - memset(status->DisplayType, 0, sizeof(status->DisplayType)); + memset(status->dbs->SkillChangeTable, 0, sizeof(status->dbs->SkillChangeTable)); + memset(status->dbs->ChangeFlagTable, 0, sizeof(status->dbs->ChangeFlagTable)); + memset(status->dbs->DisplayType, 0, sizeof(status->dbs->DisplayType)); //First we define the skill for common ailments. These are used in skill_additional_effect through sc cards. [Skotlex] set_sc( NPC_PETRIFYATTACK , SC_STONE , SI_BLANK , SCB_DEF_ELE|SCB_DEF|SCB_MDEF ); @@ -754,303 +758,303 @@ void initChangeTables(void) { set_sc_with_vfx( GN_ILLUSIONDOPING , SC_ILLUSIONDOPING , SI_ILLUSIONDOPING , SCB_HIT ); // Storing the target job rather than simply SC_SOULLINK simplifies code later on. - status->Skill2SCTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST, - status->Skill2SCTable[SL_MONK] = (sc_type)MAPID_MONK, - status->Skill2SCTable[SL_STAR] = (sc_type)MAPID_STAR_GLADIATOR, - status->Skill2SCTable[SL_SAGE] = (sc_type)MAPID_SAGE, - status->Skill2SCTable[SL_CRUSADER] = (sc_type)MAPID_CRUSADER, - status->Skill2SCTable[SL_SUPERNOVICE] = (sc_type)MAPID_SUPER_NOVICE, - status->Skill2SCTable[SL_KNIGHT] = (sc_type)MAPID_KNIGHT, - status->Skill2SCTable[SL_WIZARD] = (sc_type)MAPID_WIZARD, - status->Skill2SCTable[SL_PRIEST] = (sc_type)MAPID_PRIEST, - status->Skill2SCTable[SL_BARDDANCER] = (sc_type)MAPID_BARDDANCER, - status->Skill2SCTable[SL_ROGUE] = (sc_type)MAPID_ROGUE, - status->Skill2SCTable[SL_ASSASIN] = (sc_type)MAPID_ASSASSIN, - status->Skill2SCTable[SL_BLACKSMITH] = (sc_type)MAPID_BLACKSMITH, - status->Skill2SCTable[SL_HUNTER] = (sc_type)MAPID_HUNTER, - status->Skill2SCTable[SL_SOULLINKER] = (sc_type)MAPID_SOUL_LINKER, + status->dbs->Skill2SCTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST, + status->dbs->Skill2SCTable[SL_MONK] = (sc_type)MAPID_MONK, + status->dbs->Skill2SCTable[SL_STAR] = (sc_type)MAPID_STAR_GLADIATOR, + status->dbs->Skill2SCTable[SL_SAGE] = (sc_type)MAPID_SAGE, + status->dbs->Skill2SCTable[SL_CRUSADER] = (sc_type)MAPID_CRUSADER, + status->dbs->Skill2SCTable[SL_SUPERNOVICE] = (sc_type)MAPID_SUPER_NOVICE, + status->dbs->Skill2SCTable[SL_KNIGHT] = (sc_type)MAPID_KNIGHT, + status->dbs->Skill2SCTable[SL_WIZARD] = (sc_type)MAPID_WIZARD, + status->dbs->Skill2SCTable[SL_PRIEST] = (sc_type)MAPID_PRIEST, + status->dbs->Skill2SCTable[SL_BARDDANCER] = (sc_type)MAPID_BARDDANCER, + status->dbs->Skill2SCTable[SL_ROGUE] = (sc_type)MAPID_ROGUE, + status->dbs->Skill2SCTable[SL_ASSASIN] = (sc_type)MAPID_ASSASSIN, + status->dbs->Skill2SCTable[SL_BLACKSMITH] = (sc_type)MAPID_BLACKSMITH, + status->dbs->Skill2SCTable[SL_HUNTER] = (sc_type)MAPID_HUNTER, + status->dbs->Skill2SCTable[SL_SOULLINKER] = (sc_type)MAPID_SOUL_LINKER, //Status that don't have a skill associated. - status->IconChangeTable[SC_WEIGHTOVER50] = SI_WEIGHTOVER50; - status->IconChangeTable[SC_WEIGHTOVER90] = SI_WEIGHTOVER90; - status->IconChangeTable[SC_ATTHASTE_POTION1] = SI_ATTHASTE_POTION1; - status->IconChangeTable[SC_ATTHASTE_POTION2] = SI_ATTHASTE_POTION2; - status->IconChangeTable[SC_ATTHASTE_POTION3] = SI_ATTHASTE_POTION3; - status->IconChangeTable[SC_ATTHASTE_INFINITY] = SI_ATTHASTE_INFINITY; - status->IconChangeTable[SC_MOVHASTE_HORSE] = SI_MOVHASTE_HORSE; - status->IconChangeTable[SC_MOVHASTE_INFINITY] = SI_MOVHASTE_INFINITY; - status->IconChangeTable[SC_CHASEWALK2] = SI_INCSTR; - status->IconChangeTable[SC_MIRACLE] = SI_SOULLINK; - status->IconChangeTable[SC_CLAIRVOYANCE] = SI_CLAIRVOYANCE; - status->IconChangeTable[SC_FOOD_STR] = SI_FOOD_STR; - status->IconChangeTable[SC_FOOD_AGI] = SI_FOOD_AGI; - status->IconChangeTable[SC_FOOD_VIT] = SI_FOOD_VIT; - status->IconChangeTable[SC_FOOD_INT] = SI_FOOD_INT; - status->IconChangeTable[SC_FOOD_DEX] = SI_FOOD_DEX; - status->IconChangeTable[SC_FOOD_LUK] = SI_FOOD_LUK; - status->IconChangeTable[SC_FOOD_BASICAVOIDANCE]= SI_FOOD_BASICAVOIDANCE; - status->IconChangeTable[SC_FOOD_BASICHIT] = SI_FOOD_BASICHIT; - status->IconChangeTable[SC_MANU_ATK] = SI_MANU_ATK; - status->IconChangeTable[SC_MANU_DEF] = SI_MANU_DEF; - status->IconChangeTable[SC_SPL_ATK] = SI_SPL_ATK; - status->IconChangeTable[SC_SPL_DEF] = SI_SPL_DEF; - status->IconChangeTable[SC_MANU_MATK] = SI_MANU_MATK; - status->IconChangeTable[SC_SPL_MATK] = SI_SPL_MATK; - status->IconChangeTable[SC_PLUSATTACKPOWER] = SI_PLUSATTACKPOWER; - status->IconChangeTable[SC_PLUSMAGICPOWER] = SI_PLUSMAGICPOWER; + status->dbs->IconChangeTable[SC_WEIGHTOVER50] = SI_WEIGHTOVER50; + status->dbs->IconChangeTable[SC_WEIGHTOVER90] = SI_WEIGHTOVER90; + status->dbs->IconChangeTable[SC_ATTHASTE_POTION1] = SI_ATTHASTE_POTION1; + status->dbs->IconChangeTable[SC_ATTHASTE_POTION2] = SI_ATTHASTE_POTION2; + status->dbs->IconChangeTable[SC_ATTHASTE_POTION3] = SI_ATTHASTE_POTION3; + status->dbs->IconChangeTable[SC_ATTHASTE_INFINITY] = SI_ATTHASTE_INFINITY; + status->dbs->IconChangeTable[SC_MOVHASTE_HORSE] = SI_MOVHASTE_HORSE; + status->dbs->IconChangeTable[SC_MOVHASTE_INFINITY] = SI_MOVHASTE_INFINITY; + status->dbs->IconChangeTable[SC_CHASEWALK2] = SI_INCSTR; + status->dbs->IconChangeTable[SC_MIRACLE] = SI_SOULLINK; + status->dbs->IconChangeTable[SC_CLAIRVOYANCE] = SI_CLAIRVOYANCE; + status->dbs->IconChangeTable[SC_FOOD_STR] = SI_FOOD_STR; + status->dbs->IconChangeTable[SC_FOOD_AGI] = SI_FOOD_AGI; + status->dbs->IconChangeTable[SC_FOOD_VIT] = SI_FOOD_VIT; + status->dbs->IconChangeTable[SC_FOOD_INT] = SI_FOOD_INT; + status->dbs->IconChangeTable[SC_FOOD_DEX] = SI_FOOD_DEX; + status->dbs->IconChangeTable[SC_FOOD_LUK] = SI_FOOD_LUK; + status->dbs->IconChangeTable[SC_FOOD_BASICAVOIDANCE]= SI_FOOD_BASICAVOIDANCE; + status->dbs->IconChangeTable[SC_FOOD_BASICHIT] = SI_FOOD_BASICHIT; + status->dbs->IconChangeTable[SC_MANU_ATK] = SI_MANU_ATK; + status->dbs->IconChangeTable[SC_MANU_DEF] = SI_MANU_DEF; + status->dbs->IconChangeTable[SC_SPL_ATK] = SI_SPL_ATK; + status->dbs->IconChangeTable[SC_SPL_DEF] = SI_SPL_DEF; + status->dbs->IconChangeTable[SC_MANU_MATK] = SI_MANU_MATK; + status->dbs->IconChangeTable[SC_SPL_MATK] = SI_SPL_MATK; + status->dbs->IconChangeTable[SC_PLUSATTACKPOWER] = SI_PLUSATTACKPOWER; + status->dbs->IconChangeTable[SC_PLUSMAGICPOWER] = SI_PLUSMAGICPOWER; //Cash Items - status->IconChangeTable[SC_FOOD_STR_CASH] = SI_FOOD_STR_CASH; - status->IconChangeTable[SC_FOOD_AGI_CASH] = SI_FOOD_AGI_CASH; - status->IconChangeTable[SC_FOOD_VIT_CASH] = SI_FOOD_VIT_CASH; - status->IconChangeTable[SC_FOOD_DEX_CASH] = SI_FOOD_DEX_CASH; - status->IconChangeTable[SC_FOOD_INT_CASH] = SI_FOOD_INT_CASH; - status->IconChangeTable[SC_FOOD_LUK_CASH] = SI_FOOD_LUK_CASH; - status->IconChangeTable[SC_CASH_PLUSEXP] = SI_CASH_PLUSEXP; - status->IconChangeTable[SC_CASH_RECEIVEITEM] = SI_CASH_RECEIVEITEM; - status->IconChangeTable[SC_CASH_PLUSONLYJOBEXP] = SI_CASH_PLUSONLYJOBEXP; - status->IconChangeTable[SC_CASH_DEATHPENALTY] = SI_CASH_DEATHPENALTY; - status->IconChangeTable[SC_CASH_BOSS_ALARM] = SI_CASH_BOSS_ALARM; - status->IconChangeTable[SC_PROTECT_DEF] = SI_PROTECT_DEF; - status->IconChangeTable[SC_PROTECT_MDEF] = SI_PROTECT_MDEF; - status->IconChangeTable[SC_CRITICALPERCENT] = SI_CRITICALPERCENT; - status->IconChangeTable[SC_PLUSAVOIDVALUE] = SI_PLUSAVOIDVALUE; - status->IconChangeTable[SC_HEALPLUS] = SI_HEALPLUS; - status->IconChangeTable[SC_S_LIFEPOTION] = SI_S_LIFEPOTION; - status->IconChangeTable[SC_L_LIFEPOTION] = SI_L_LIFEPOTION; - status->IconChangeTable[SC_ATKER_BLOOD] = SI_ATKER_BLOOD; - status->IconChangeTable[SC_TARGET_BLOOD] = SI_TARGET_BLOOD; + status->dbs->IconChangeTable[SC_FOOD_STR_CASH] = SI_FOOD_STR_CASH; + status->dbs->IconChangeTable[SC_FOOD_AGI_CASH] = SI_FOOD_AGI_CASH; + status->dbs->IconChangeTable[SC_FOOD_VIT_CASH] = SI_FOOD_VIT_CASH; + status->dbs->IconChangeTable[SC_FOOD_DEX_CASH] = SI_FOOD_DEX_CASH; + status->dbs->IconChangeTable[SC_FOOD_INT_CASH] = SI_FOOD_INT_CASH; + status->dbs->IconChangeTable[SC_FOOD_LUK_CASH] = SI_FOOD_LUK_CASH; + status->dbs->IconChangeTable[SC_CASH_PLUSEXP] = SI_CASH_PLUSEXP; + status->dbs->IconChangeTable[SC_CASH_RECEIVEITEM] = SI_CASH_RECEIVEITEM; + status->dbs->IconChangeTable[SC_CASH_PLUSONLYJOBEXP] = SI_CASH_PLUSONLYJOBEXP; + status->dbs->IconChangeTable[SC_CASH_DEATHPENALTY] = SI_CASH_DEATHPENALTY; + status->dbs->IconChangeTable[SC_CASH_BOSS_ALARM] = SI_CASH_BOSS_ALARM; + status->dbs->IconChangeTable[SC_PROTECT_DEF] = SI_PROTECT_DEF; + status->dbs->IconChangeTable[SC_PROTECT_MDEF] = SI_PROTECT_MDEF; + status->dbs->IconChangeTable[SC_CRITICALPERCENT] = SI_CRITICALPERCENT; + status->dbs->IconChangeTable[SC_PLUSAVOIDVALUE] = SI_PLUSAVOIDVALUE; + status->dbs->IconChangeTable[SC_HEALPLUS] = SI_HEALPLUS; + status->dbs->IconChangeTable[SC_S_LIFEPOTION] = SI_S_LIFEPOTION; + status->dbs->IconChangeTable[SC_L_LIFEPOTION] = SI_L_LIFEPOTION; + status->dbs->IconChangeTable[SC_ATKER_BLOOD] = SI_ATKER_BLOOD; + status->dbs->IconChangeTable[SC_TARGET_BLOOD] = SI_TARGET_BLOOD; // Mercenary Bonus Effects - status->IconChangeTable[SC_MER_FLEE] = SI_MER_FLEE; - status->IconChangeTable[SC_MER_ATK] = SI_MER_ATK; - status->IconChangeTable[SC_MER_HP] = SI_MER_HP; - status->IconChangeTable[SC_MER_SP] = SI_MER_SP; - status->IconChangeTable[SC_MER_HIT] = SI_MER_HIT; + status->dbs->IconChangeTable[SC_MER_FLEE] = SI_MER_FLEE; + status->dbs->IconChangeTable[SC_MER_ATK] = SI_MER_ATK; + status->dbs->IconChangeTable[SC_MER_HP] = SI_MER_HP; + status->dbs->IconChangeTable[SC_MER_SP] = SI_MER_SP; + status->dbs->IconChangeTable[SC_MER_HIT] = SI_MER_HIT; // Warlock Spheres - status->IconChangeTable[SC_SUMMON1] = SI_SPHERE_1; - status->IconChangeTable[SC_SUMMON2] = SI_SPHERE_2; - status->IconChangeTable[SC_SUMMON3] = SI_SPHERE_3; - status->IconChangeTable[SC_SUMMON4] = SI_SPHERE_4; - status->IconChangeTable[SC_SUMMON5] = SI_SPHERE_5; + status->dbs->IconChangeTable[SC_SUMMON1] = SI_SPHERE_1; + status->dbs->IconChangeTable[SC_SUMMON2] = SI_SPHERE_2; + status->dbs->IconChangeTable[SC_SUMMON3] = SI_SPHERE_3; + status->dbs->IconChangeTable[SC_SUMMON4] = SI_SPHERE_4; + status->dbs->IconChangeTable[SC_SUMMON5] = SI_SPHERE_5; // Warlock Preserved spells - status->IconChangeTable[SC_SPELLBOOK1] = SI_SPELLBOOK1; - status->IconChangeTable[SC_SPELLBOOK2] = SI_SPELLBOOK2; - status->IconChangeTable[SC_SPELLBOOK3] = SI_SPELLBOOK3; - status->IconChangeTable[SC_SPELLBOOK4] = SI_SPELLBOOK4; - status->IconChangeTable[SC_SPELLBOOK5] = SI_SPELLBOOK5; - status->IconChangeTable[SC_SPELLBOOK6] = SI_SPELLBOOK6; - status->IconChangeTable[SC_SPELLBOOK7] = SI_SPELLBOOK7; - - status->IconChangeTable[SC_NEUTRALBARRIER_MASTER] = SI_NEUTRALBARRIER_MASTER; - status->IconChangeTable[SC_STEALTHFIELD_MASTER] = SI_STEALTHFIELD_MASTER; - status->IconChangeTable[SC_OVERHEAT] = SI_OVERHEAT; - status->IconChangeTable[SC_OVERHEAT_LIMITPOINT] = SI_OVERHEAT_LIMITPOINT; - - status->IconChangeTable[SC_HALLUCINATIONWALK_POSTDELAY] = SI_HALLUCINATIONWALK_POSTDELAY; - status->IconChangeTable[SC_TOXIN] = SI_TOXIN; - status->IconChangeTable[SC_PARALYSE] = SI_PARALYSE; - status->IconChangeTable[SC_VENOMBLEED] = SI_VENOMBLEED; - status->IconChangeTable[SC_MAGICMUSHROOM] = SI_MAGICMUSHROOM; - status->IconChangeTable[SC_DEATHHURT] = SI_DEATHHURT; - status->IconChangeTable[SC_PYREXIA] = SI_PYREXIA; - status->IconChangeTable[SC_OBLIVIONCURSE] = SI_OBLIVIONCURSE; - status->IconChangeTable[SC_LEECHESEND] = SI_LEECHESEND; - - status->IconChangeTable[SC_SHIELDSPELL_DEF] = SI_SHIELDSPELL_DEF; - status->IconChangeTable[SC_SHIELDSPELL_MDEF] = SI_SHIELDSPELL_MDEF; - status->IconChangeTable[SC_SHIELDSPELL_REF] = SI_SHIELDSPELL_REF; - status->IconChangeTable[SC_BANDING_DEFENCE] = SI_BANDING_DEFENCE; - - status->IconChangeTable[SC_CURSEDCIRCLE_ATKER] = SI_CURSEDCIRCLE_ATKER; - - status->IconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE; - status->IconChangeTable[SC_MYSTERIOUS_POWDER] = SI_MYSTERIOUS_POWDER; - status->IconChangeTable[SC_MELON_BOMB] = SI_MELON_BOMB; - status->IconChangeTable[SC_BANANA_BOMB] = SI_BANANA_BOMB; - status->IconChangeTable[SC_BANANA_BOMB_SITDOWN_POSTDELAY] = SI_BANANA_BOMB_SITDOWN_POSTDELAY; + status->dbs->IconChangeTable[SC_SPELLBOOK1] = SI_SPELLBOOK1; + status->dbs->IconChangeTable[SC_SPELLBOOK2] = SI_SPELLBOOK2; + status->dbs->IconChangeTable[SC_SPELLBOOK3] = SI_SPELLBOOK3; + status->dbs->IconChangeTable[SC_SPELLBOOK4] = SI_SPELLBOOK4; + status->dbs->IconChangeTable[SC_SPELLBOOK5] = SI_SPELLBOOK5; + status->dbs->IconChangeTable[SC_SPELLBOOK6] = SI_SPELLBOOK6; + status->dbs->IconChangeTable[SC_SPELLBOOK7] = SI_SPELLBOOK7; + + status->dbs->IconChangeTable[SC_NEUTRALBARRIER_MASTER] = SI_NEUTRALBARRIER_MASTER; + status->dbs->IconChangeTable[SC_STEALTHFIELD_MASTER] = SI_STEALTHFIELD_MASTER; + status->dbs->IconChangeTable[SC_OVERHEAT] = SI_OVERHEAT; + status->dbs->IconChangeTable[SC_OVERHEAT_LIMITPOINT] = SI_OVERHEAT_LIMITPOINT; + + status->dbs->IconChangeTable[SC_HALLUCINATIONWALK_POSTDELAY] = SI_HALLUCINATIONWALK_POSTDELAY; + status->dbs->IconChangeTable[SC_TOXIN] = SI_TOXIN; + status->dbs->IconChangeTable[SC_PARALYSE] = SI_PARALYSE; + status->dbs->IconChangeTable[SC_VENOMBLEED] = SI_VENOMBLEED; + status->dbs->IconChangeTable[SC_MAGICMUSHROOM] = SI_MAGICMUSHROOM; + status->dbs->IconChangeTable[SC_DEATHHURT] = SI_DEATHHURT; + status->dbs->IconChangeTable[SC_PYREXIA] = SI_PYREXIA; + status->dbs->IconChangeTable[SC_OBLIVIONCURSE] = SI_OBLIVIONCURSE; + status->dbs->IconChangeTable[SC_LEECHESEND] = SI_LEECHESEND; + + status->dbs->IconChangeTable[SC_SHIELDSPELL_DEF] = SI_SHIELDSPELL_DEF; + status->dbs->IconChangeTable[SC_SHIELDSPELL_MDEF] = SI_SHIELDSPELL_MDEF; + status->dbs->IconChangeTable[SC_SHIELDSPELL_REF] = SI_SHIELDSPELL_REF; + status->dbs->IconChangeTable[SC_BANDING_DEFENCE] = SI_BANDING_DEFENCE; + + status->dbs->IconChangeTable[SC_CURSEDCIRCLE_ATKER] = SI_CURSEDCIRCLE_ATKER; + + status->dbs->IconChangeTable[SC_STOMACHACHE] = SI_STOMACHACHE; + status->dbs->IconChangeTable[SC_MYSTERIOUS_POWDER] = SI_MYSTERIOUS_POWDER; + status->dbs->IconChangeTable[SC_MELON_BOMB] = SI_MELON_BOMB; + status->dbs->IconChangeTable[SC_BANANA_BOMB] = SI_BANANA_BOMB; + status->dbs->IconChangeTable[SC_BANANA_BOMB_SITDOWN_POSTDELAY] = SI_BANANA_BOMB_SITDOWN_POSTDELAY; //Genetics New Food Items Status Icons - status->IconChangeTable[SC_SAVAGE_STEAK] = SI_SAVAGE_STEAK; - status->IconChangeTable[SC_COCKTAIL_WARG_BLOOD] = SI_COCKTAIL_WARG_BLOOD; - status->IconChangeTable[SC_MINOR_BBQ] = SI_MINOR_BBQ; - status->IconChangeTable[SC_SIROMA_ICE_TEA] = SI_SIROMA_ICE_TEA; - status->IconChangeTable[SC_DROCERA_HERB_STEAMED] = SI_DROCERA_HERB_STEAMED; - status->IconChangeTable[SC_PUTTI_TAILS_NOODLES] = SI_PUTTI_TAILS_NOODLES; - - status->IconChangeTable[SC_BOOST500] |= SI_BOOST500; - status->IconChangeTable[SC_FULL_SWING_K] |= SI_FULL_SWING_K; - status->IconChangeTable[SC_MANA_PLUS] |= SI_MANA_PLUS; - status->IconChangeTable[SC_MUSTLE_M] |= SI_MUSTLE_M; - status->IconChangeTable[SC_LIFE_FORCE_F] |= SI_LIFE_FORCE_F; - status->IconChangeTable[SC_EXTRACT_WHITE_POTION_Z] |= SI_EXTRACT_WHITE_POTION_Z; - status->IconChangeTable[SC_VITATA_500] |= SI_VITATA_500; - status->IconChangeTable[SC_EXTRACT_SALAMINE_JUICE] |= SI_EXTRACT_SALAMINE_JUICE; + status->dbs->IconChangeTable[SC_SAVAGE_STEAK] = SI_SAVAGE_STEAK; + status->dbs->IconChangeTable[SC_COCKTAIL_WARG_BLOOD] = SI_COCKTAIL_WARG_BLOOD; + status->dbs->IconChangeTable[SC_MINOR_BBQ] = SI_MINOR_BBQ; + status->dbs->IconChangeTable[SC_SIROMA_ICE_TEA] = SI_SIROMA_ICE_TEA; + status->dbs->IconChangeTable[SC_DROCERA_HERB_STEAMED] = SI_DROCERA_HERB_STEAMED; + status->dbs->IconChangeTable[SC_PUTTI_TAILS_NOODLES] = SI_PUTTI_TAILS_NOODLES; + + status->dbs->IconChangeTable[SC_BOOST500] |= SI_BOOST500; + status->dbs->IconChangeTable[SC_FULL_SWING_K] |= SI_FULL_SWING_K; + status->dbs->IconChangeTable[SC_MANA_PLUS] |= SI_MANA_PLUS; + status->dbs->IconChangeTable[SC_MUSTLE_M] |= SI_MUSTLE_M; + status->dbs->IconChangeTable[SC_LIFE_FORCE_F] |= SI_LIFE_FORCE_F; + status->dbs->IconChangeTable[SC_EXTRACT_WHITE_POTION_Z] |= SI_EXTRACT_WHITE_POTION_Z; + status->dbs->IconChangeTable[SC_VITATA_500] |= SI_VITATA_500; + status->dbs->IconChangeTable[SC_EXTRACT_SALAMINE_JUICE] |= SI_EXTRACT_SALAMINE_JUICE; // Elemental Spirit's 'side' status change icons. - status->IconChangeTable[SC_CIRCLE_OF_FIRE] = SI_CIRCLE_OF_FIRE; - status->IconChangeTable[SC_FIRE_CLOAK] = SI_FIRE_CLOAK; - status->IconChangeTable[SC_WATER_SCREEN] = SI_WATER_SCREEN; - status->IconChangeTable[SC_WATER_DROP] = SI_WATER_DROP; - status->IconChangeTable[SC_WIND_STEP] = SI_WIND_STEP; - status->IconChangeTable[SC_WIND_CURTAIN] = SI_WIND_CURTAIN; - status->IconChangeTable[SC_SOLID_SKIN] = SI_SOLID_SKIN; - status->IconChangeTable[SC_STONE_SHIELD] = SI_STONE_SHIELD; - status->IconChangeTable[SC_PYROTECHNIC] = SI_PYROTECHNIC; - status->IconChangeTable[SC_HEATER] = SI_HEATER; - status->IconChangeTable[SC_TROPIC] = SI_TROPIC; - status->IconChangeTable[SC_AQUAPLAY] = SI_AQUAPLAY; - status->IconChangeTable[SC_COOLER] = SI_COOLER; - status->IconChangeTable[SC_CHILLY_AIR] = SI_CHILLY_AIR; - status->IconChangeTable[SC_GUST] = SI_GUST; - status->IconChangeTable[SC_BLAST] = SI_BLAST; - status->IconChangeTable[SC_WILD_STORM] = SI_WILD_STORM; - status->IconChangeTable[SC_PETROLOGY] = SI_PETROLOGY; - status->IconChangeTable[SC_CURSED_SOIL] = SI_CURSED_SOIL; - status->IconChangeTable[SC_UPHEAVAL] = SI_UPHEAVAL; - status->IconChangeTable[SC_PUSH_CART] = SI_ON_PUSH_CART; - status->IconChangeTable[SC_REBOUND] = SI_REBOUND; - status->IconChangeTable[SC_ALL_RIDING] = SI_ALL_RIDING; - status->IconChangeTable[SC_MONSTER_TRANSFORM] = SI_MONSTER_TRANSFORM; - status->IconChangeTable[SC_MOONSTAR] = SI_MOONSTAR; - status->IconChangeTable[SC_SUPER_STAR] = SI_SUPER_STAR; - status->IconChangeTable[SC_STRANGELIGHTS] = SI_STRANGELIGHTS; - status->IconChangeTable[SC_DECORATION_OF_MUSIC] = SI_DECORATION_OF_MUSIC; + status->dbs->IconChangeTable[SC_CIRCLE_OF_FIRE] = SI_CIRCLE_OF_FIRE; + status->dbs->IconChangeTable[SC_FIRE_CLOAK] = SI_FIRE_CLOAK; + status->dbs->IconChangeTable[SC_WATER_SCREEN] = SI_WATER_SCREEN; + status->dbs->IconChangeTable[SC_WATER_DROP] = SI_WATER_DROP; + status->dbs->IconChangeTable[SC_WIND_STEP] = SI_WIND_STEP; + status->dbs->IconChangeTable[SC_WIND_CURTAIN] = SI_WIND_CURTAIN; + status->dbs->IconChangeTable[SC_SOLID_SKIN] = SI_SOLID_SKIN; + status->dbs->IconChangeTable[SC_STONE_SHIELD] = SI_STONE_SHIELD; + status->dbs->IconChangeTable[SC_PYROTECHNIC] = SI_PYROTECHNIC; + status->dbs->IconChangeTable[SC_HEATER] = SI_HEATER; + status->dbs->IconChangeTable[SC_TROPIC] = SI_TROPIC; + status->dbs->IconChangeTable[SC_AQUAPLAY] = SI_AQUAPLAY; + status->dbs->IconChangeTable[SC_COOLER] = SI_COOLER; + status->dbs->IconChangeTable[SC_CHILLY_AIR] = SI_CHILLY_AIR; + status->dbs->IconChangeTable[SC_GUST] = SI_GUST; + status->dbs->IconChangeTable[SC_BLAST] = SI_BLAST; + status->dbs->IconChangeTable[SC_WILD_STORM] = SI_WILD_STORM; + status->dbs->IconChangeTable[SC_PETROLOGY] = SI_PETROLOGY; + status->dbs->IconChangeTable[SC_CURSED_SOIL] = SI_CURSED_SOIL; + status->dbs->IconChangeTable[SC_UPHEAVAL] = SI_UPHEAVAL; + status->dbs->IconChangeTable[SC_PUSH_CART] = SI_ON_PUSH_CART; + status->dbs->IconChangeTable[SC_REBOUND] = SI_REBOUND; + status->dbs->IconChangeTable[SC_ALL_RIDING] = SI_ALL_RIDING; + status->dbs->IconChangeTable[SC_MONSTER_TRANSFORM] = SI_MONSTER_TRANSFORM; + status->dbs->IconChangeTable[SC_MOONSTAR] = SI_MOONSTAR; + status->dbs->IconChangeTable[SC_SUPER_STAR] = SI_SUPER_STAR; + status->dbs->IconChangeTable[SC_STRANGELIGHTS] = SI_STRANGELIGHTS; + status->dbs->IconChangeTable[SC_DECORATION_OF_MUSIC] = SI_DECORATION_OF_MUSIC; //Other SC which are not necessarily associated to skills. - status->ChangeFlagTable[SC_ATTHASTE_POTION1] = SCB_ASPD; - status->ChangeFlagTable[SC_ATTHASTE_POTION2] = SCB_ASPD; - status->ChangeFlagTable[SC_ATTHASTE_POTION3] = SCB_ASPD; - status->ChangeFlagTable[SC_ATTHASTE_INFINITY] = SCB_ASPD; - status->ChangeFlagTable[SC_MOVHASTE_HORSE] = SCB_SPEED; - status->ChangeFlagTable[SC_MOVHASTE_INFINITY] = SCB_SPEED; - status->ChangeFlagTable[SC_PLUSATTACKPOWER] = SCB_BATK; - status->ChangeFlagTable[SC_PLUSMAGICPOWER] = SCB_MATK; - status->ChangeFlagTable[SC_INCALLSTATUS] |= SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK; - status->ChangeFlagTable[SC_CHASEWALK2] |= SCB_STR; - status->ChangeFlagTable[SC_INCAGI] |= SCB_AGI; - status->ChangeFlagTable[SC_INCVIT] |= SCB_VIT; - status->ChangeFlagTable[SC_INCINT] |= SCB_INT; - status->ChangeFlagTable[SC_INCDEX] |= SCB_DEX; - status->ChangeFlagTable[SC_INCLUK] |= SCB_LUK; - status->ChangeFlagTable[SC_INCHIT] |= SCB_HIT; - status->ChangeFlagTable[SC_INCHITRATE] |= SCB_HIT; - status->ChangeFlagTable[SC_INCFLEE] |= SCB_FLEE; - status->ChangeFlagTable[SC_INCFLEERATE] |= SCB_FLEE; - status->ChangeFlagTable[SC_MTF_HITFLEE] |= SCB_HIT|SCB_FLEE; - status->ChangeFlagTable[SC_CRITICALPERCENT] |= SCB_CRI; - status->ChangeFlagTable[SC_INCASPDRATE] |= SCB_ASPD; - status->ChangeFlagTable[SC_PLUSAVOIDVALUE] |= SCB_FLEE2; - status->ChangeFlagTable[SC_INCMHPRATE] |= SCB_MAXHP; - status->ChangeFlagTable[SC_INCMSPRATE] |= SCB_MAXSP; - status->ChangeFlagTable[SC_INCMHP] |= SCB_MAXHP; - status->ChangeFlagTable[SC_MTF_MHP] |= SCB_MAXHP; - status->ChangeFlagTable[SC_INCMSP] |= SCB_MAXSP; - status->ChangeFlagTable[SC_MTF_MSP] |= SCB_MAXSP; - status->ChangeFlagTable[SC_INCATKRATE] |= SCB_BATK|SCB_WATK; - status->ChangeFlagTable[SC_INCMATKRATE] |= SCB_MATK; - status->ChangeFlagTable[SC_INCDEFRATE] |= SCB_DEF; - status->ChangeFlagTable[SC_FOOD_STR] |= SCB_STR; - status->ChangeFlagTable[SC_FOOD_AGI] |= SCB_AGI; - status->ChangeFlagTable[SC_FOOD_VIT] |= SCB_VIT; - status->ChangeFlagTable[SC_FOOD_INT] |= SCB_INT; - status->ChangeFlagTable[SC_FOOD_DEX] |= SCB_DEX; - status->ChangeFlagTable[SC_FOOD_LUK] |= SCB_LUK; - status->ChangeFlagTable[SC_FOOD_BASICHIT] |= SCB_HIT; - status->ChangeFlagTable[SC_FOOD_BASICAVOIDANCE] |= SCB_FLEE; - status->ChangeFlagTable[SC_BATKFOOD] |= SCB_BATK; - status->ChangeFlagTable[SC_WATKFOOD] |= SCB_WATK; - status->ChangeFlagTable[SC_MATKFOOD] |= SCB_MATK; - status->ChangeFlagTable[SC_ARMORPROPERTY] |= SCB_ALL; - status->ChangeFlagTable[SC_ARMOR_RESIST] |= SCB_ALL; - status->ChangeFlagTable[SC_ATKER_BLOOD] |= SCB_ALL; - status->ChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED; - status->ChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL; + status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION1] = SCB_ASPD; + status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION2] = SCB_ASPD; + status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION3] = SCB_ASPD; + status->dbs->ChangeFlagTable[SC_ATTHASTE_INFINITY] = SCB_ASPD; + status->dbs->ChangeFlagTable[SC_MOVHASTE_HORSE] = SCB_SPEED; + status->dbs->ChangeFlagTable[SC_MOVHASTE_INFINITY] = SCB_SPEED; + status->dbs->ChangeFlagTable[SC_PLUSATTACKPOWER] = SCB_BATK; + status->dbs->ChangeFlagTable[SC_PLUSMAGICPOWER] = SCB_MATK; + status->dbs->ChangeFlagTable[SC_INCALLSTATUS] |= SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK; + status->dbs->ChangeFlagTable[SC_CHASEWALK2] |= SCB_STR; + status->dbs->ChangeFlagTable[SC_INCAGI] |= SCB_AGI; + status->dbs->ChangeFlagTable[SC_INCVIT] |= SCB_VIT; + status->dbs->ChangeFlagTable[SC_INCINT] |= SCB_INT; + status->dbs->ChangeFlagTable[SC_INCDEX] |= SCB_DEX; + status->dbs->ChangeFlagTable[SC_INCLUK] |= SCB_LUK; + status->dbs->ChangeFlagTable[SC_INCHIT] |= SCB_HIT; + status->dbs->ChangeFlagTable[SC_INCHITRATE] |= SCB_HIT; + status->dbs->ChangeFlagTable[SC_INCFLEE] |= SCB_FLEE; + status->dbs->ChangeFlagTable[SC_INCFLEERATE] |= SCB_FLEE; + status->dbs->ChangeFlagTable[SC_MTF_HITFLEE] |= SCB_HIT|SCB_FLEE; + status->dbs->ChangeFlagTable[SC_CRITICALPERCENT] |= SCB_CRI; + status->dbs->ChangeFlagTable[SC_INCASPDRATE] |= SCB_ASPD; + status->dbs->ChangeFlagTable[SC_PLUSAVOIDVALUE] |= SCB_FLEE2; + status->dbs->ChangeFlagTable[SC_INCMHPRATE] |= SCB_MAXHP; + status->dbs->ChangeFlagTable[SC_INCMSPRATE] |= SCB_MAXSP; + status->dbs->ChangeFlagTable[SC_INCMHP] |= SCB_MAXHP; + status->dbs->ChangeFlagTable[SC_MTF_MHP] |= SCB_MAXHP; + status->dbs->ChangeFlagTable[SC_INCMSP] |= SCB_MAXSP; + status->dbs->ChangeFlagTable[SC_MTF_MSP] |= SCB_MAXSP; + status->dbs->ChangeFlagTable[SC_INCATKRATE] |= SCB_BATK|SCB_WATK; + status->dbs->ChangeFlagTable[SC_INCMATKRATE] |= SCB_MATK; + status->dbs->ChangeFlagTable[SC_INCDEFRATE] |= SCB_DEF; + status->dbs->ChangeFlagTable[SC_FOOD_STR] |= SCB_STR; + status->dbs->ChangeFlagTable[SC_FOOD_AGI] |= SCB_AGI; + status->dbs->ChangeFlagTable[SC_FOOD_VIT] |= SCB_VIT; + status->dbs->ChangeFlagTable[SC_FOOD_INT] |= SCB_INT; + status->dbs->ChangeFlagTable[SC_FOOD_DEX] |= SCB_DEX; + status->dbs->ChangeFlagTable[SC_FOOD_LUK] |= SCB_LUK; + status->dbs->ChangeFlagTable[SC_FOOD_BASICHIT] |= SCB_HIT; + status->dbs->ChangeFlagTable[SC_FOOD_BASICAVOIDANCE] |= SCB_FLEE; + status->dbs->ChangeFlagTable[SC_BATKFOOD] |= SCB_BATK; + status->dbs->ChangeFlagTable[SC_WATKFOOD] |= SCB_WATK; + status->dbs->ChangeFlagTable[SC_MATKFOOD] |= SCB_MATK; + status->dbs->ChangeFlagTable[SC_ARMORPROPERTY] |= SCB_ALL; + status->dbs->ChangeFlagTable[SC_ARMOR_RESIST] |= SCB_ALL; + status->dbs->ChangeFlagTable[SC_ATKER_BLOOD] |= SCB_ALL; + status->dbs->ChangeFlagTable[SC_WALKSPEED] |= SCB_SPEED; + status->dbs->ChangeFlagTable[SC_ITEMSCRIPT] |= SCB_ALL; // Cash Items - status->ChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR; - status->ChangeFlagTable[SC_FOOD_AGI_CASH] = SCB_AGI; - status->ChangeFlagTable[SC_FOOD_VIT_CASH] = SCB_VIT; - status->ChangeFlagTable[SC_FOOD_DEX_CASH] = SCB_DEX; - status->ChangeFlagTable[SC_FOOD_INT_CASH] = SCB_INT; - status->ChangeFlagTable[SC_FOOD_LUK_CASH] = SCB_LUK; + status->dbs->ChangeFlagTable[SC_FOOD_STR_CASH] = SCB_STR; + status->dbs->ChangeFlagTable[SC_FOOD_AGI_CASH] = SCB_AGI; + status->dbs->ChangeFlagTable[SC_FOOD_VIT_CASH] = SCB_VIT; + status->dbs->ChangeFlagTable[SC_FOOD_DEX_CASH] = SCB_DEX; + status->dbs->ChangeFlagTable[SC_FOOD_INT_CASH] = SCB_INT; + status->dbs->ChangeFlagTable[SC_FOOD_LUK_CASH] = SCB_LUK; // Mercenary Bonus Effects - status->ChangeFlagTable[SC_MER_FLEE] |= SCB_FLEE; - status->ChangeFlagTable[SC_MER_ATK] |= SCB_WATK; - status->ChangeFlagTable[SC_MER_HP] |= SCB_MAXHP; - status->ChangeFlagTable[SC_MER_SP] |= SCB_MAXSP; - status->ChangeFlagTable[SC_MER_HIT] |= SCB_HIT; + status->dbs->ChangeFlagTable[SC_MER_FLEE] |= SCB_FLEE; + status->dbs->ChangeFlagTable[SC_MER_ATK] |= SCB_WATK; + status->dbs->ChangeFlagTable[SC_MER_HP] |= SCB_MAXHP; + status->dbs->ChangeFlagTable[SC_MER_SP] |= SCB_MAXSP; + status->dbs->ChangeFlagTable[SC_MER_HIT] |= SCB_HIT; // Guillotine Cross Poison Effects - status->ChangeFlagTable[SC_PARALYSE] |= SCB_FLEE|SCB_SPEED|SCB_ASPD; - status->ChangeFlagTable[SC_VENOMBLEED] |= SCB_MAXHP; - status->ChangeFlagTable[SC_MAGICMUSHROOM] |= SCB_REGEN; - status->ChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN; - status->ChangeFlagTable[SC_PYREXIA] |= SCB_HIT|SCB_FLEE; - status->ChangeFlagTable[SC_OBLIVIONCURSE] |= SCB_REGEN; + status->dbs->ChangeFlagTable[SC_PARALYSE] |= SCB_FLEE|SCB_SPEED|SCB_ASPD; + status->dbs->ChangeFlagTable[SC_VENOMBLEED] |= SCB_MAXHP; + status->dbs->ChangeFlagTable[SC_MAGICMUSHROOM] |= SCB_REGEN; + status->dbs->ChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN; + status->dbs->ChangeFlagTable[SC_PYREXIA] |= SCB_HIT|SCB_FLEE; + status->dbs->ChangeFlagTable[SC_OBLIVIONCURSE] |= SCB_REGEN; // RG status - status->ChangeFlagTable[SC_SHIELDSPELL_DEF] |= SCB_WATK; - status->ChangeFlagTable[SC_SHIELDSPELL_REF] |= SCB_DEF; + status->dbs->ChangeFlagTable[SC_SHIELDSPELL_DEF] |= SCB_WATK; + status->dbs->ChangeFlagTable[SC_SHIELDSPELL_REF] |= SCB_DEF; // Meca status - status->ChangeFlagTable[SC_STEALTHFIELD_MASTER] |= SCB_SPEED; - - status->ChangeFlagTable[SC_SAVAGE_STEAK] |= SCB_STR; - status->ChangeFlagTable[SC_COCKTAIL_WARG_BLOOD] |= SCB_INT; - status->ChangeFlagTable[SC_MINOR_BBQ] |= SCB_VIT; - status->ChangeFlagTable[SC_SIROMA_ICE_TEA] |= SCB_DEX; - status->ChangeFlagTable[SC_DROCERA_HERB_STEAMED] |= SCB_AGI; - status->ChangeFlagTable[SC_PUTTI_TAILS_NOODLES] |= SCB_LUK; - status->ChangeFlagTable[SC_BOOST500] |= SCB_ASPD; - status->ChangeFlagTable[SC_FULL_SWING_K] |= SCB_BATK; - status->ChangeFlagTable[SC_MANA_PLUS] |= SCB_MATK; - status->ChangeFlagTable[SC_MUSTLE_M] |= SCB_MAXHP; - status->ChangeFlagTable[SC_LIFE_FORCE_F] |= SCB_MAXSP; - status->ChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN; - status->ChangeFlagTable[SC_VITATA_500] |= SCB_REGEN; - status->ChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD; - status->ChangeFlagTable[SC_REBOUND] |= SCB_SPEED|SCB_REGEN; - status->ChangeFlagTable[SC_DEFSET] |= SCB_DEF|SCB_DEF2; - status->ChangeFlagTable[SC_MDEFSET] |= SCB_MDEF|SCB_MDEF2; - status->ChangeFlagTable[SC_MYSTERIOUS_POWDER] |= SCB_MAXHP; - - status->ChangeFlagTable[SC_ALL_RIDING] = SCB_SPEED; - status->ChangeFlagTable[SC_WEDDING] = SCB_SPEED; - - status->ChangeFlagTable[SC_MTF_ASPD] = SCB_ASPD|SCB_HIT; - status->ChangeFlagTable[SC_MTF_MATK] = SCB_MATK; - status->ChangeFlagTable[SC_MTF_MLEATKED] |= SCB_ALL; - - status->ChangeFlagTable[SC_MOONSTAR] |= SCB_NONE; - status->ChangeFlagTable[SC_SUPER_STAR] |= SCB_NONE; - status->ChangeFlagTable[SC_STRANGELIGHTS] |= SCB_NONE; - status->ChangeFlagTable[SC_DECORATION_OF_MUSIC] |= SCB_NONE; - - /* status->DisplayType Table [Ind/Hercules] */ - status->DisplayType[SC_ALL_RIDING] = true; - status->DisplayType[SC_PUSH_CART] = true; - status->DisplayType[SC_SUMMON1] = true; - status->DisplayType[SC_SUMMON2] = true; - status->DisplayType[SC_SUMMON3] = true; - status->DisplayType[SC_SUMMON4] = true; - status->DisplayType[SC_SUMMON5] = true; - status->DisplayType[SC_CAMOUFLAGE] = true; - status->DisplayType[SC_DUPLELIGHT] = true; - status->DisplayType[SC_ORATIO] = true; - status->DisplayType[SC_FROSTMISTY] = true; - status->DisplayType[SC_VENOMIMPRESS] = true; - status->DisplayType[SC_HALLUCINATIONWALK] = true; - status->DisplayType[SC_ROLLINGCUTTER] = true; - status->DisplayType[SC_BANDING] = true; - status->DisplayType[SC_COLD] = true; - status->DisplayType[SC_DEEP_SLEEP] = true; - status->DisplayType[SC_CURSEDCIRCLE_ATKER] = true; - status->DisplayType[SC_CURSEDCIRCLE_TARGET] = true; - status->DisplayType[SC_BLOOD_SUCKER] = true; - status->DisplayType[SC__SHADOWFORM] = true; - status->DisplayType[SC_MONSTER_TRANSFORM] = true; - status->DisplayType[SC_MOONSTAR] = true; - status->DisplayType[SC_SUPER_STAR] = true; - status->DisplayType[SC_STRANGELIGHTS] = true; - status->DisplayType[SC_DECORATION_OF_MUSIC] = true; + status->dbs->ChangeFlagTable[SC_STEALTHFIELD_MASTER] |= SCB_SPEED; + + status->dbs->ChangeFlagTable[SC_SAVAGE_STEAK] |= SCB_STR; + status->dbs->ChangeFlagTable[SC_COCKTAIL_WARG_BLOOD] |= SCB_INT; + status->dbs->ChangeFlagTable[SC_MINOR_BBQ] |= SCB_VIT; + status->dbs->ChangeFlagTable[SC_SIROMA_ICE_TEA] |= SCB_DEX; + status->dbs->ChangeFlagTable[SC_DROCERA_HERB_STEAMED] |= SCB_AGI; + status->dbs->ChangeFlagTable[SC_PUTTI_TAILS_NOODLES] |= SCB_LUK; + status->dbs->ChangeFlagTable[SC_BOOST500] |= SCB_ASPD; + status->dbs->ChangeFlagTable[SC_FULL_SWING_K] |= SCB_BATK; + status->dbs->ChangeFlagTable[SC_MANA_PLUS] |= SCB_MATK; + status->dbs->ChangeFlagTable[SC_MUSTLE_M] |= SCB_MAXHP; + status->dbs->ChangeFlagTable[SC_LIFE_FORCE_F] |= SCB_MAXSP; + status->dbs->ChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN; + status->dbs->ChangeFlagTable[SC_VITATA_500] |= SCB_REGEN; + status->dbs->ChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD; + status->dbs->ChangeFlagTable[SC_REBOUND] |= SCB_SPEED|SCB_REGEN; + status->dbs->ChangeFlagTable[SC_DEFSET] |= SCB_DEF|SCB_DEF2; + status->dbs->ChangeFlagTable[SC_MDEFSET] |= SCB_MDEF|SCB_MDEF2; + status->dbs->ChangeFlagTable[SC_MYSTERIOUS_POWDER] |= SCB_MAXHP; + + status->dbs->ChangeFlagTable[SC_ALL_RIDING] = SCB_SPEED; + status->dbs->ChangeFlagTable[SC_WEDDING] = SCB_SPEED; + + status->dbs->ChangeFlagTable[SC_MTF_ASPD] = SCB_ASPD|SCB_HIT; + status->dbs->ChangeFlagTable[SC_MTF_MATK] = SCB_MATK; + status->dbs->ChangeFlagTable[SC_MTF_MLEATKED] |= SCB_ALL; + + status->dbs->ChangeFlagTable[SC_MOONSTAR] |= SCB_NONE; + status->dbs->ChangeFlagTable[SC_SUPER_STAR] |= SCB_NONE; + status->dbs->ChangeFlagTable[SC_STRANGELIGHTS] |= SCB_NONE; + status->dbs->ChangeFlagTable[SC_DECORATION_OF_MUSIC] |= SCB_NONE; + + /* status->dbs->DisplayType Table [Ind/Hercules] */ + status->dbs->DisplayType[SC_ALL_RIDING] = true; + status->dbs->DisplayType[SC_PUSH_CART] = true; + status->dbs->DisplayType[SC_SUMMON1] = true; + status->dbs->DisplayType[SC_SUMMON2] = true; + status->dbs->DisplayType[SC_SUMMON3] = true; + status->dbs->DisplayType[SC_SUMMON4] = true; + status->dbs->DisplayType[SC_SUMMON5] = true; + status->dbs->DisplayType[SC_CAMOUFLAGE] = true; + status->dbs->DisplayType[SC_DUPLELIGHT] = true; + status->dbs->DisplayType[SC_ORATIO] = true; + status->dbs->DisplayType[SC_FROSTMISTY] = true; + status->dbs->DisplayType[SC_VENOMIMPRESS] = true; + status->dbs->DisplayType[SC_HALLUCINATIONWALK] = true; + status->dbs->DisplayType[SC_ROLLINGCUTTER] = true; + status->dbs->DisplayType[SC_BANDING] = true; + status->dbs->DisplayType[SC_COLD] = true; + status->dbs->DisplayType[SC_DEEP_SLEEP] = true; + status->dbs->DisplayType[SC_CURSEDCIRCLE_ATKER] = true; + status->dbs->DisplayType[SC_CURSEDCIRCLE_TARGET] = true; + status->dbs->DisplayType[SC_BLOOD_SUCKER] = true; + status->dbs->DisplayType[SC__SHADOWFORM] = true; + status->dbs->DisplayType[SC_MONSTER_TRANSFORM] = true; + status->dbs->DisplayType[SC_MOONSTAR] = true; + status->dbs->DisplayType[SC_SUPER_STAR] = true; + status->dbs->DisplayType[SC_STRANGELIGHTS] = true; + status->dbs->DisplayType[SC_DECORATION_OF_MUSIC] = true; if( !battle_config.display_hallucination ) //Disable Hallucination. - status->IconChangeTable[SC_ILLUSION] = SI_BLANK; + status->dbs->IconChangeTable[SC_ILLUSION] = SI_BLANK; #undef add_sc #undef set_sc_with_vfx } @@ -1076,7 +1080,6 @@ void initDummyData(void) status->dummy.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) { @@ -1189,12 +1192,12 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, struct status_change_entry *sce; #ifdef DEVOTION_REFLECT_DAMAGE - if(src && (sce = sc->data[SC_DEVOTION])) { + if (src && (sce = sc->data[SC_DEVOTION]) != NULL) { struct block_list *d_bl = map->id2bl(sce->val1); if(d_bl &&((d_bl->type == BL_MER && ((TBL_MER *)d_bl)->master && ((TBL_MER *)d_bl)->master->bl.id == target->id) || (d_bl->type == BL_PC && ((TBL_PC *)d_bl)->devotion[sce->val2] == target->id)) && check_distance_bl(target, d_bl, sce->val3)) { - clif->damage(d_bl, d_bl, 0, 0, hp, 0, 0, 0); + clif->damage(d_bl, d_bl, 0, 0, hp, 0, BDT_NORMAL, 0); status_fix_damage(NULL, d_bl, hp, 0); return 0; } @@ -1261,7 +1264,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, } if( src && target->type == BL_PC && (((TBL_PC*)target)->disguise) > 0 ) {// stop walking when attacked in disguise to prevent walk-delay bug - unit->stop_walking( target, 1 ); + unit->stop_walking(target, STOPWALKING_FLAG_FIXPOS); } if (st->hp || (flag&8)) { @@ -1344,7 +1347,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, unit->remove_map(target,CLR_DEAD,ALC_MARK); else { //Some death states that would normally be handled by unit_remove_map unit->stop_attack(target); - unit->stop_walking(target,1); + unit->stop_walking(target, STOPWALKING_FLAG_FIXPOS); unit->skillcastcancel(target,0); clif->clearunit_area(target,CLR_DEAD); skill->unit_move(target,timer->gettick(),4); @@ -1585,7 +1588,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin //on dead characters, said checks are left to skill.c [Skotlex] if (target && status->isdead(target)) return 0; - if( src && (sc = status->get_sc(src)) && sc->data[SC_COLD] && src->type != BL_MOB) + if( src && (sc = status->get_sc(src)) != NULL && sc->data[SC_COLD] && src->type != BL_MOB) return 0; } @@ -1596,13 +1599,13 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin for(i = 0; i < map->list[src->m].zone->disabled_skills_count; i++) { if( skill_id == map->list[src->m].zone->disabled_skills[i]->nameid && (map->list[src->m].zone->disabled_skills[i]->type&src->type) ) { - if( src->type == BL_PC ) - clif->msg((TBL_PC*)src, SKILL_CANT_USE_AREA); // This skill cannot be used within this area - else if( src->type == BL_MOB && map->list[src->m].zone->disabled_skills[i]->subtype != MZS_NONE ) { - if( st->mode&MD_BOSS ) { /** is boss **/ + if (src->type == BL_PC) { + clif->msgtable((TBL_PC*)src, MSG_SKILL_CANT_USE_AREA); // This skill cannot be used within this area + } else if (src->type == BL_MOB && map->list[src->m].zone->disabled_skills[i]->subtype != MZS_NONE) { + if( st->mode&MD_BOSS ) { /* is boss */ if( !( map->list[src->m].zone->disabled_skills[i]->subtype&MZS_BOSS ) ) break; - } else { /** is not boss **/ + } else { /* is not boss */ if( map->list[src->m].zone->disabled_skills[i]->subtype&MZS_BOSS ) break; } @@ -1627,7 +1630,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin break; case AL_TELEPORT: //Should fail when used on top of Land Protector [Skotlex] - if (src && map->getcell(src->m, src->x, src->y, CELL_CHKLANDPROTECTOR) + if (src && map->getcell(src->m, src, src->x, src->y, CELL_CHKLANDPROTECTOR) && !(st->mode&MD_BOSS) && (src->type != BL_PC || ((TBL_PC*)src)->skillitem != skill_id)) return 0; @@ -1656,10 +1659,15 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin return 0; if (sc->data[SC_DC_WINKCHARM] && target && !flag) { //Prevents skill usage - if( unit->bl2ud(src) && (unit->bl2ud(src))->walktimer == INVALID_TIMER ) - unit->walktobl(src, map->id2bl(sc->data[SC_DC_WINKCHARM]->val2), 3, 1); - clif->emotion(src, E_LV); - return 0; + struct block_list *winkcharm_target = map->id2bl(sc->data[SC_DC_WINKCHARM]->val2); + if (winkcharm_target != NULL) { + if (unit->bl2ud(src) && (unit->bl2ud(src))->walktimer == INVALID_TIMER) + unit->walktobl(src, map->id2bl(sc->data[SC_DC_WINKCHARM]->val2), 3, 1); + clif->emotion(src, E_LV); + return 0; + } else { + status_change_end(src, SC_DC_WINKCHARM, INVALID_TIMER); + } } if (sc->data[SC_BLADESTOP]) { @@ -1867,14 +1875,14 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) { if (md->special_state.size) flag|=2; - if( md->guardian_data && md->guardian_data->g - && (guardup_lv = guild->checkskill(md->guardian_data->g,GD_GUARDUP)) ) + if (md->guardian_data && md->guardian_data->g + && (guardup_lv = guild->checkskill(md->guardian_data->g,GD_GUARDUP)) > 0) flag|=4; if (battle_config.slaves_inherit_speed && md->master_id) flag|=8; - if (md->master_id && md->special_state.ai>1) + if (md->master_id && md->special_state.ai > AI_ATTACK) flag|=16; if (!flag) @@ -1910,8 +1918,8 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) { //Max HP setting from Summon Flora/marine Sphere struct unit_data *ud = unit->bl2ud(mbl); //Remove special AI when this is used by regular mobs. - if (mbl->type == BL_MOB && !((TBL_MOB*)mbl)->special_state.ai) - md->special_state.ai = 0; + if (mbl->type == BL_MOB && ((TBL_MOB*)mbl)->special_state.ai == AI_NONE) + md->special_state.ai = AI_NONE; if (ud) { // different levels of HP according to skill level if (ud->skill_id == AM_SPHEREMINE) { @@ -1944,7 +1952,6 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) { mstatus->speed -= cap_value(diff, 0, mstatus->speed - 10); } - if (flag&2 && battle_config.mob_size_influence) { // change for sized monsters [Valaris] if (md->special_state.size==SZ_MEDIUM) { @@ -2084,7 +2091,7 @@ int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt) unsigned int status_get_base_maxsp(struct map_session_data* sd, struct status_data *st) { uint64 val = pc->class2idx(sd->status.class_); - val = status->SP_table[val][sd->status.base_level]; + val = status->dbs->SP_table[val][sd->status.base_level]; if ( sd->class_&JOBL_UPPER ) val += val * 25 / 100; @@ -2101,7 +2108,7 @@ unsigned int status_get_base_maxsp(struct map_session_data* sd, struct status_da unsigned int status_get_base_maxhp(struct map_session_data *sd, struct status_data *st) { uint64 val = pc->class2idx(sd->status.class_); - val = status->HP_table[val][sd->status.base_level]; + val = status->dbs->HP_table[val][sd->status.base_level]; if ( (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99 ) val += 2000; //Supernovice lvl99 hp bonus. @@ -2121,6 +2128,11 @@ unsigned int status_get_base_maxhp(struct map_session_data *sd, struct status_da return (unsigned int)cap_value(val,0,UINT_MAX); } +void status_calc_pc_additional(struct map_session_data* sd, enum e_status_calc_opt opt) { + /* Just used for Plugin to give bonuses. */ + return; +} + //Calculates player data from scratch without counting SC adjustments. //Should be invoked whenever players raise stats, learn passive skills or change equipment. int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { @@ -2143,7 +2155,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { pc->calc_skilltree(sd); // SkillTree calculation - sd->max_weight = status->max_weight_base[pc->class2idx(sd->status.class_)]+sd->status.str*300; + sd->max_weight = status->dbs->max_weight_base[pc->class2idx(sd->status.class_)]+sd->status.str*300; if(opt&SCO_FIRST) { //Load Hp/SP from char-received data. @@ -2181,40 +2193,11 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100; sd->regen.state.block = 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] - memset (sd->param_bonus, 0, sizeof(sd->param_bonus) - + sizeof(sd->param_equip) - + sizeof(sd->subele) - + sizeof(sd->subrace) - + sizeof(sd->subrace2) - + sizeof(sd->subsize) - + sizeof(sd->reseff) - + sizeof(sd->weapon_coma_ele) - + sizeof(sd->weapon_coma_race) - + sizeof(sd->weapon_atk) - + sizeof(sd->weapon_atk_rate) - + sizeof(sd->arrow_addele) - + sizeof(sd->arrow_addrace) - + sizeof(sd->arrow_addsize) - + sizeof(sd->magic_addele) - + sizeof(sd->magic_addrace) - + sizeof(sd->magic_addsize) - + sizeof(sd->magic_atk_ele) - + sizeof(sd->critaddrace) - + sizeof(sd->expaddrace) - + sizeof(sd->ignore_mdef) - + sizeof(sd->ignore_def) - + sizeof(sd->sp_gain_race) - + sizeof(sd->sp_gain_race_attack) - + sizeof(sd->hp_gain_race_attack) -#ifdef RENEWAL - + sizeof(sd->race_tolerance) -#endif - ); + // zeroed arrays + memset(ZEROED_BLOCK_POS(sd), 0, ZEROED_BLOCK_SIZE(sd)); - memset (&sd->right_weapon.overrefine, 0, sizeof(sd->right_weapon) - sizeof(sd->right_weapon.atkmods)); - memset (&sd->left_weapon.overrefine, 0, sizeof(sd->left_weapon) - sizeof(sd->left_weapon.atkmods)); + memset(ZEROED_BLOCK_POS(&(sd->right_weapon)), 0, ZEROED_BLOCK_SIZE(&(sd->right_weapon))); + memset(ZEROED_BLOCK_POS(&(sd->left_weapon)), 0, ZEROED_BLOCK_SIZE(&(sd->left_weapon))); if (sd->special_state.intravision && !sd->sc.data[SC_CLAIRVOYANCE]) //Clear intravision as long as nothing else is using it clif->sc_end(&sd->bl,sd->bl.id,SELF,SI_CLAIRVOYANCE); @@ -2246,41 +2229,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { } bstatus->aspd_rate = 1000; bstatus->ele_lv = 1; - bstatus->race = RC_DEMIHUMAN; - - //zero up structures... - memset(&sd->autospell,0,sizeof(sd->autospell) - + sizeof(sd->autospell2) - + sizeof(sd->autospell3) - + sizeof(sd->addeff) - + sizeof(sd->addeff2) - + sizeof(sd->addeff3) - + sizeof(sd->skillatk) - + sizeof(sd->skillusesprate) - + sizeof(sd->skillusesp) - + sizeof(sd->skillheal) - + sizeof(sd->skillheal2) - + sizeof(sd->hp_loss) - + sizeof(sd->sp_loss) - + sizeof(sd->hp_regen) - + sizeof(sd->sp_regen) - + sizeof(sd->skillblown) - + sizeof(sd->skillcast) - + sizeof(sd->add_def) - + sizeof(sd->add_mdef) - + sizeof(sd->add_mdmg) - + sizeof(sd->add_drop) - + sizeof(sd->itemhealrate) - + sizeof(sd->subele2) - + sizeof(sd->skillcooldown) - + sizeof(sd->skillfixcast) - + sizeof(sd->skillvarcast) - + sizeof(sd->skillfixcastrate) - + sizeof(sd->def_set_race) - + sizeof(sd->mdef_set_race) - ); - - memset (&sd->bonus, 0,sizeof(sd->bonus)); + bstatus->race = RC_PLAYER; // Autobonus pc->delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),true); @@ -2319,7 +2268,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { if (opt&SCO_FIRST && sd->inventory_data[index]->equip_script) { //Execute equip-script on login - script->run(sd->inventory_data[index]->equip_script,0,sd->bl.id,0); + script->run_item_equip_script(sd, sd->inventory_data[index], 0); if (!calculating) return 1; } @@ -2343,27 +2292,27 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { } wa->atk += sd->inventory_data[index]->atk; if ( (r = sd->status.inventory[index].refine) ) - wa->atk2 = status->refine_info[wlv].bonus[r-1] / 100; + wa->atk2 = status->dbs->refine_info[wlv].bonus[r-1] / 100; #ifdef RENEWAL wa->matk += sd->inventory_data[index]->matk; wa->wlv = wlv; if( r && sd->weapontype1 != W_BOW ) // renewal magic attack refine bonus - wa->matk += status->refine_info[wlv].bonus[r-1] / 100; + wa->matk += status->dbs->refine_info[wlv].bonus[r-1] / 100; #endif //Overrefined bonus. if (r) - wd->overrefine = status->refine_info[wlv].randombonus_max[r-1] / 100; + wd->overrefine = status->dbs->refine_info[wlv].randombonus_max[r-1] / 100; wa->range += sd->inventory_data[index]->range; if(sd->inventory_data[index]->script) { if (wd == &sd->left_weapon) { sd->state.lr_flag = 1; - script->run(sd->inventory_data[index]->script,0,sd->bl.id,0); + script->run_use_script(sd, sd->inventory_data[index], 0); sd->state.lr_flag = 0; } else - script->run(sd->inventory_data[index]->script,0,sd->bl.id,0); + script->run_use_script(sd, sd->inventory_data[index], 0); if (!calculating) //Abort, script->run retriggered this. [Skotlex] return 1; } @@ -2382,11 +2331,11 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { else if(sd->inventory_data[index]->type == IT_ARMOR) { int r; if ( (r = sd->status.inventory[index].refine) ) - refinedef += status->refine_info[REFINE_TYPE_ARMOR].bonus[r-1]; + refinedef += status->dbs->refine_info[REFINE_TYPE_ARMOR].bonus[r-1]; if(sd->inventory_data[index]->script) { if( i == EQI_HAND_L ) //Shield sd->state.lr_flag = 3; - script->run(sd->inventory_data[index]->script,0,sd->bl.id,0); + script->run_use_script(sd, sd->inventory_data[index], 0); if( i == EQI_HAND_L ) //Shield sd->state.lr_flag = 0; if (!calculating) //Abort, script->run retriggered this. [Skotlex] @@ -2402,7 +2351,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { sd->bonus.arrow_atk += sd->inventory_data[index]->atk; sd->state.lr_flag = 2; if( !itemdb_is_GNthrowable(sd->inventory_data[index]->nameid) ) //don't run scripts on throwable items - script->run(sd->inventory_data[index]->script,0,sd->bl.id,0); + script->run_use_script(sd, sd->inventory_data[index], 0); sd->state.lr_flag = 0; if (!calculating) //Abort, script->run retriggered status_calc_pc. [Skotlex] return 1; @@ -2480,7 +2429,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { continue; if(opt&SCO_FIRST && data->equip_script) {//Execute equip-script on login - script->run(data->equip_script,0,sd->bl.id,0); + script->run_item_equip_script(sd, data, 0); if (!calculating) return 1; } @@ -2490,10 +2439,10 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) { //Left hand status. sd->state.lr_flag = 1; - script->run(data->script,0,sd->bl.id,0); + script->run_use_script(sd, data, 0); sd->state.lr_flag = 0; } else - script->run(data->script,0,sd->bl.id,0); + script->run_use_script(sd, data, 0); if (!calculating) //Abort, script->run his function. [Skotlex] return 1; } @@ -2503,9 +2452,11 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { if( sc->count && sc->data[SC_ITEMSCRIPT] ) { struct item_data *data = itemdb->exists(sc->data[SC_ITEMSCRIPT]->val1); if( data && data->script ) - script->run(data->script,0,sd->bl.id,0); + script->run_use_script(sd, data, 0); } + status->calc_pc_additional(sd, opt); + if( sd->pd ) { // Pet Bonus struct pet_data *pd = sd->pd; if( pd && pd->petDB && pd->petDB->equip_script && pd->pet.intimate >= battle_config.pet_equip_min_friendly ) @@ -2525,12 +2476,12 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { sd->bonus.splash_range += sd->bonus.splash_add_range; // Damage modifiers from weapon type - sd->right_weapon.atkmods[0] = status->atkmods[0][sd->weapontype1]; - sd->right_weapon.atkmods[1] = status->atkmods[1][sd->weapontype1]; - sd->right_weapon.atkmods[2] = status->atkmods[2][sd->weapontype1]; - sd->left_weapon.atkmods[0] = status->atkmods[0][sd->weapontype2]; - sd->left_weapon.atkmods[1] = status->atkmods[1][sd->weapontype2]; - sd->left_weapon.atkmods[2] = status->atkmods[2][sd->weapontype2]; + sd->right_weapon.atkmods[0] = status->dbs->atkmods[0][sd->weapontype1]; + sd->right_weapon.atkmods[1] = status->dbs->atkmods[1][sd->weapontype1]; + sd->right_weapon.atkmods[2] = status->dbs->atkmods[2][sd->weapontype1]; + sd->left_weapon.atkmods[0] = status->dbs->atkmods[0][sd->weapontype2]; + sd->left_weapon.atkmods[1] = status->dbs->atkmods[1][sd->weapontype2]; + sd->left_weapon.atkmods[2] = status->dbs->atkmods[2][sd->weapontype2]; if ((pc_isridingpeco(sd) || pc_isridingdragon(sd)) && (sd->status.weapon==W_1HSPEAR || sd->status.weapon==W_2HSPEAR) @@ -2546,9 +2497,9 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { // Job bonuses index = pc->class2idx(sd->status.class_); for(i=0;i<(int)sd->status.job_level && i<MAX_LEVEL;i++){ - if(!status->job_bonus[index][i]) + if(!status->dbs->job_bonus[index][i]) continue; - switch(status->job_bonus[index][i]) { + switch(status->dbs->job_bonus[index][i]) { case 1: bstatus->str++; break; case 2: bstatus->agi++; break; case 3: bstatus->vit++; break; @@ -2650,7 +2601,6 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { if( (skill_lv = pc->checkskill(sd,WM_LESSON)) > 0 ) bstatus->max_sp += 30 * skill_lv; - // Apply relative modifiers from equipment if(sd->sprate < 0) sd->sprate = 0; @@ -2752,7 +2702,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { } if( (sd->status.weapon == W_1HAXE || sd->status.weapon == W_2HAXE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0 ) bstatus->hit += 3*skill_lv; - if((sd->status.weapon == W_MACE || sd->status.weapon == W_2HMACE) && ((skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0)) + if((sd->status.weapon == W_MACE || sd->status.weapon == W_2HMACE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0) bstatus->hit += 2*skill_lv; // ----- FLEE CALCULATION ----- @@ -2829,7 +2779,6 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { #endif bstatus->adelay = 2*bstatus->amotion; - // ----- DMOTION ----- // i = 800-bstatus->agi*4; @@ -3090,7 +3039,7 @@ int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt) { nstatus->def_ele = ELE_NEUTRAL; nstatus->ele_lv = 1; - nstatus->race = RC_DEMIHUMAN; + nstatus->race = RC_PLAYER; nstatus->size = nd->size; nstatus->rhw.range = 1 + nstatus->size; nstatus->mode = (MD_CANMOVE|MD_CANATTACK); @@ -3144,6 +3093,8 @@ int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) { hstatus->aspd_rate = 1000; #ifdef RENEWAL + hstatus->def = 0; + amotion = hd->homunculusDB->baseASPD; amotion = amotion - amotion * (hstatus->dex + hom->dex_value) / 1000 - (hstatus->agi + hom->agi_value) * amotion / 250; #else @@ -3158,7 +3109,6 @@ int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) { hstatus->amotion = cap_value(amotion, battle_config.max_aspd, 2000); hstatus->adelay = hstatus->amotion; //It seems adelay = amotion for Homunculus. - hstatus->max_hp = hom->max_hp; hstatus->max_sp = hom->max_sp; @@ -3586,12 +3536,6 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) { st->cri = status->calc_critical(bl, sc, bst->cri, true); else st->cri = status->calc_critical(bl, sc, bst->cri + 3*(st->luk - bst->luk), true); - /** - * after status_calc_critical so the bonus is applied despite if you have or not a sc bugreport:5240 - **/ - if( bl->type == BL_PC && ((TBL_PC*)bl)->status.weapon == W_KATAR ) - st->cri <<= 1; - } if(flag&SCB_FLEE2 && bst->flee2) { @@ -3619,7 +3563,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) { if (!(st->mode&MD_CANATTACK)) unit->stop_attack(bl); if (!(st->mode&MD_CANMOVE)) - unit->stop_walking(bl,1); + unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); } // No status changes alter these yet. @@ -3982,11 +3926,11 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st) #ifdef RENEWAL_ASPD /* [malufett/Hercules] */ float temp; int skill_lv, val = 0; - amotion = status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype1]; + amotion = status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype1]; if ( sd->status.weapon > MAX_WEAPON_TYPE ) - amotion += status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2] / 4; + amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2] / 4; if ( sd->status.shield ) - amotion += status->aspd_base[pc->class2idx(sd->status.class_)][MAX_WEAPON_TYPE]; + amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class_)][MAX_WEAPON_TYPE]; switch ( sd->status.weapon ) { case W_BOW: case W_MUSICAL: case W_WHIP: case W_REVOLVER: @@ -4006,8 +3950,8 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st) #else // base weapon delay amotion = (sd->status.weapon < MAX_WEAPON_TYPE) - ? (status->aspd_base[pc->class2idx(sd->status.class_)][sd->status.weapon]) // single weapon - : (status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype1] + status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2]) * 7 / 10; // dual-wield + ? (status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->status.weapon]) // single weapon + : (status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype1] + status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2]) * 7 / 10; // dual-wield // percentual delay reduction from stats amotion -= amotion * (4 * st->agi + st->dex) / 1000; @@ -4111,7 +4055,7 @@ void status_calc_misc(struct block_list *bl, struct status_data *st, int level) if ( bl->type == BL_HOM ) { st->def2 = status_get_homvit(bl) + status_get_homagi(bl) / 2; st->mdef2 = (status_get_homvit(bl) + status_get_homint(bl)) / 2; - st->def += status_get_homvit(bl) + level / 2; + st->def += status_get_homvit(bl) + level / 2; // Increase. Already initialized in status_calc_homunculus_ st->mdef = (int)(((float)status_get_homvit(bl) + level) / 4 + (float)status_get_homint(bl) / 2); st->hit = level + st->dex + 150; st->flee = level + status_get_homagi(bl); @@ -5133,7 +5077,6 @@ signed short status_calc_def2(struct block_list *bl, struct status_change *sc, i #endif } - defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef, bool viewable) { if(!sc || !sc->count) @@ -5202,7 +5145,7 @@ signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, if(sc->data[SC_MINDBREAKER]) mdef2 -= mdef2 * sc->data[SC_MINDBREAKER]->val3/100; #ifdef RENEWAL - if(sc && sc->data[SC_ASSUMPTIO]) + if (sc->data[SC_ASSUMPTIO]) mdef2 <<= 1; return (short)cap_value(mdef2,SHRT_MIN,SHRT_MAX); #else @@ -5847,7 +5790,6 @@ unsigned char status_calc_element_lv(struct block_list *bl, struct status_change return (unsigned char)cap_value(lv,1,4); } - unsigned char status_calc_attack_element(struct block_list *bl, struct status_change *sc, int element) { if(!sc || !sc->count) @@ -6022,7 +5964,7 @@ int status_get_party_id(struct block_list *bl) { struct mob_data *md=(TBL_MOB*)bl; if( md->master_id > 0 ) { struct map_session_data *msd; - if (md->special_state.ai && (msd = map->id2sd(md->master_id)) != NULL) + if (md->special_state.ai != AI_NONE && (msd = map->id2sd(md->master_id)) != NULL) return msd->status.party_id; return -md->master_id; } @@ -6065,7 +6007,7 @@ int status_get_guild_id(struct block_list *bl) { // Guardian guild data may not been available yet, castle data is always set return (md->guardian_data->g)?md->guardian_data->g->guild_id:md->guardian_data->castle->guild_id; } - if( md->special_state.ai && (msd = map->id2sd(md->master_id)) != NULL ) + if (md->special_state.ai != AI_NONE && (msd = map->id2sd(md->master_id)) != NULL) return msd->status.guild_id; //Alchemist's mobs [Skotlex] break; } @@ -6107,7 +6049,7 @@ int status_get_emblem_id(struct block_list *bl) { struct mob_data *md = (struct mob_data *)bl; if (md->guardian_data) //Guardian's guild [Skotlex] return (md->guardian_data->g) ? md->guardian_data->g->emblem_id:0; - if (md->special_state.ai && (msd = map->id2sd(md->master_id)) != NULL) + if (md->special_state.ai != AI_NONE && (msd = map->id2sd(md->master_id)) != NULL) return msd->guild_emblem_id; //Alchemist's mobs [Skotlex] } break; @@ -6290,7 +6232,7 @@ void status_set_viewdata(struct block_list *bl, int class_) if (vd) nd->vd = vd; else - ShowError("status_set_viewdata (NPC): No view data for class %d\n", class_); + ShowError("status_set_viewdata (NPC): No view data for class %d (name=%s)\n", class_, nd->name); } break; case BL_HOM: //[blackhole89] @@ -6579,9 +6521,6 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ case SC_COLD: tick_def2 = bst->vit*100 + status->get_lv(bl)*20; break; - case SC_VACUUM_EXTREME: - tick_def2 = bst->str*50; - break; case SC_MANDRAGORA: sc_def = (st->vit + st->luk)*20; break; @@ -7036,7 +6975,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t i = sd->equip_index[EQI_HAND_R]; if (i>=0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_WEAPON) { opt_flag|=2; - pc->unequipitem(sd,i,3); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } if (!opt_flag) return 0; } @@ -7052,7 +6991,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t i = sd->equip_index[EQI_HAND_L]; if ( i < 0 || !sd->inventory_data[i] || sd->inventory_data[i]->type != IT_ARMOR ) return 0; - pc->unequipitem(sd,i,3); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; @@ -7064,7 +7003,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t i = sd->equip_index[EQI_ARMOR]; if ( i < 0 || !sd->inventory_data[i] ) return 0; - pc->unequipitem(sd,i,3); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; @@ -7076,7 +7015,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t i = sd->equip_index[EQI_HEAD_TOP]; if ( i < 0 || !sd->inventory_data[i] ) return 0; - pc->unequipitem(sd,i,3); + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); } if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC break; @@ -7146,12 +7085,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t if( !(sd->bonus.unstripable_equip&EQP_ACC_L) ) { i = sd->equip_index[EQI_ACC_L]; if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR ) - pc->unequipitem(sd,i,3); //L-Accessory + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); //L-Accessory } if( !(sd->bonus.unstripable_equip&EQP_ACC_R) ) { i = sd->equip_index[EQI_ACC_R]; if( i >= 0 && sd->inventory_data[i] && sd->inventory_data[i]->type == IT_ARMOR ) - pc->unequipitem(sd,i,3); //R-Accessory + pc->unequipitem(sd, i, PCUNEQUIPITEM_RECALC|PCUNEQUIPITEM_FORCE); //R-Accessory } if( i < 0 ) return 0; @@ -7382,7 +7321,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER); break; case SC_ENDURE: - if( val4 ) + if( val4 == 1 ) status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER); break; case SC_FIGHTINGSPIRIT: @@ -7585,7 +7524,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t } vd = status->get_viewdata(bl); - calc_flag = status->ChangeFlagTable[type]; + calc_flag = status->dbs->ChangeFlagTable[type]; if(!(flag&SCFLAG_LOADED)) { // Do not parse val settings when loading SCs switch(type) { case SC_ADORAMUS: @@ -7601,12 +7540,13 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t struct map_session_data *tsd; if( sd ) { int i; - for( i = 0; i < 5; i++ ) { - if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) ) + for( i = 0; i < MAX_PC_DEVOTION; i++ ) { + if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL) status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_ALL); } - } else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) ) + } else if (bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) != NULL) { status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_ALL); + } } //val4 signals infinite endure (if val4 == 2 it is infinite endure from Berserk) if( val4 ) @@ -7700,12 +7640,13 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t struct map_session_data *tsd; if( sd ) { int i; - for( i = 0; i < 5; i++ ) { - if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) ) + for( i = 0; i < MAX_PC_DEVOTION; i++ ) { + if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL) status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL); } - } else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) ) + } else if (bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) != NULL) { status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL); + } } break; case SC_NOEQUIPWEAPON: @@ -7958,13 +7899,14 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t if( bl->type&(BL_PC|BL_MER) ) { if( sd ) { - for( i = 0; i < 5; i++ ) { - if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) ) + for( i = 0; i < MAX_PC_DEVOTION; i++ ) { + if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL) status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL); } } - else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) ) + else if (bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag && (tsd = ((TBL_MER*)bl)->master) != NULL) { status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL); + } } } break; @@ -7978,9 +7920,9 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t if (sd) { struct map_session_data *tsd; int i; - for (i = 0; i < 5; i++) { + for (i = 0; i < MAX_PC_DEVOTION; i++) { //See if there are devoted characters, and pass the status to them. [Skotlex] - if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i]))) + if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL) status->change_start(bl, &tsd->bl,type,10000,val1,5+val1*5,val3,val4,tick,SCFLAG_NOAVOID); } } @@ -8117,7 +8059,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t struct block_list *d_bl; struct status_change *d_sc; - if ((d_bl = map->id2bl(val1)) && (d_sc = status->get_sc(d_bl)) && d_sc->count) { + if ((d_bl = map->id2bl(val1)) && (d_sc = status->get_sc(d_bl)) != NULL && d_sc->count) { // Inherits Status From Source const enum sc_type types[] = { SC_AUTOGUARD, SC_DEFENDER, SC_REFLECTSHIELD, SC_ENDURE }; int i = (map_flag_gvg(bl->m) || map->list[bl->m].flag.battleground)?2:3; @@ -8871,6 +8813,9 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t else val2 = val2 / 4 * val1; // STAT DEF increase: [(Caster VIT / 4) x Skill Level] break; + case SC_GENTLETOUCH_ENERGYGAIN: + val2 = 10 + 5 * val1; + break; case SC_PYROTECHNIC_OPTION: val2 = 60; break; @@ -9016,6 +8961,9 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t { int hp = status_get_hp(bl), sp = status_get_sp(bl), lv = 5; + if (sp < 1) sp = 1; + if (hp < 1) hp = 1; + if( rnd()%100 > (25 + 10 * val1) - status_get_int(bl) / 2) return 0; @@ -9113,7 +9061,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t val2 = 20+(20*val1); break; default: - if (calc_flag == SCB_NONE && status->SkillChangeTable[type] == 0 && status->IconChangeTable[type] == 0) { + if (calc_flag == SCB_NONE && status->dbs->SkillChangeTable[type] == 0 && status->dbs->IconChangeTable[type] == 0) { //Status change with no calc, no icon, and no skill associated...? ShowError("UnknownStatusChange [%d]\n", type); return 0; @@ -9267,7 +9215,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t } /* [Ind/Hercules] */ - if( sd && status->DisplayType[type] ) { + if( sd && status->dbs->DisplayType[type] ) { int dval1 = 0, dval2 = 0, dval3 = 0; switch( type ) { case SC_ALL_RIDING: @@ -9319,11 +9267,11 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t case SC_NEEDLE_OF_PARALYZE: case SC_DEATHBOUND: case SC_NETHERWORLD: - unit->stop_walking(bl,1); + unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); break; case SC_ANKLESNARE: if( battle_config.skill_trap_type || !map_flag_gvg(bl->m) ) - unit->stop_walking(bl,1); + unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); break; case SC_HIDING: case SC_CLOAKING: @@ -9560,8 +9508,8 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t calc_flag&=~SCB_DYE; } - if(!(flag&SCFLAG_NOICON) && !(flag&SCFLAG_LOADED && status->DisplayType[type])) - clif->status_change(bl,status->IconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0); + if(!(flag&SCFLAG_NOICON) && !(flag&SCFLAG_LOADED && status->dbs->DisplayType[type])) + clif->status_change(bl,status->dbs->IconChangeTable[type],1,tick,(val_flag&1)?val1:1,(val_flag&2)?val2:0,(val_flag&4)?val3:0); /** * used as temporary storage for scs with interval ticks, so that the actual duration is sent to the client first. @@ -9577,12 +9525,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t ++(sc->count); sce = sc->data[type] = ers_alloc(status->data_ers, struct status_change_entry); } - + sce->val1 = val1; sce->val2 = val2; sce->val3 = val3; sce->val4 = val4; - + if (tick >= 0) { sce->timer = timer->add(timer->gettick() + tick, status->change_timer, bl->id, type); sce->infinite_duration = false; @@ -9773,7 +9721,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const return 0; st = status->get_status_data(bl); - + if( sd && sce->infinite_duration && !sd->state.loggingout ) chrif->del_scdata_single(sd->status.account_id,sd->status.char_id,type); @@ -9808,7 +9756,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const sc->data[type] = NULL; - if( sd && status->DisplayType[type] ) { + if( sd && status->dbs->DisplayType[type] ) { status->display_remove(sd,type); } @@ -9818,7 +9766,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const #endif vd = status->get_viewdata(bl); - calc_flag = status->ChangeFlagTable[type]; + calc_flag = status->dbs->ChangeFlagTable[type]; switch(type) { case SC_GRANITIC_ARMOR: { @@ -9845,7 +9793,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const begin_spurt = false; ud->state.running = 0; if (ud->walktimer != INVALID_TIMER) - unit->stop_walking(bl,1); + unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); } if (begin_spurt && sce->val1 >= 7 && DIFF_TICK(timer->gettick(), starttick) <= 1000 @@ -9868,8 +9816,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const if( bl->type == BL_PC ) { // Clear Status from others int i; - for( i = 0; i < 5; i++ ) { - if( sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) && tsd->sc.data[type] ) + for( i = 0; i < MAX_PC_DEVOTION; i++ ) { + if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL && tsd->sc.data[type]) status_change_end(&tsd->bl, type, INVALID_TIMER); } } else if( bl->type == BL_MER && ((TBL_MER*)bl)->devotion_flag ) { @@ -9930,7 +9878,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const sd->delunit_prevline = line; } - if (sce->val4 && sce->val4 != BCT_SELF && (dsd=map->id2sd(sce->val4))) { + if (sce->val4 && sce->val4 != BCT_SELF && (dsd=map->id2sd(sce->val4)) != NULL) { // end status on partner as well dsc = dsd->sc.data[SC_DANCING]; if (dsc) { @@ -9955,7 +9903,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const } sce->val2 = 0; - + if( group ) skill->del_unitgroup(group,ALC_MARK); } @@ -9989,11 +9937,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const if (src && sc2 && sc2->data[SC_RG_CCONFINE_M]) { //If status was already ended, do nothing. //Decrease count - if (--(sc2->data[SC_RG_CCONFINE_M]->val1) <= 0) //No more holds, free him up. + if (--(sc2->data[SC_RG_CCONFINE_M]->val2) <= 0) //No more holds, free him up. status_change_end(src, SC_RG_CCONFINE_M, INVALID_TIMER); } } - /* Fall through */ + break; case SC_RG_CCONFINE_M: if (sce->val2 > 0) { //Caster has been unlocked... nearby chars need to be unlocked. @@ -10119,12 +10067,13 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const struct block_list *tbl = map->id2bl(sce->val2); struct status_change *tsc = NULL; sce->val2 = 0; - if( tbl && (tsc = status->get_sc(tbl)) && tsc->data[SC_STOP] && tsc->data[SC_STOP]->val2 == bl->id ) + if (tbl && (tsc = status->get_sc(tbl)) != NULL && tsc->data[SC_STOP] && tsc->data[SC_STOP]->val2 == bl->id) status_change_end(tbl, SC_STOP, INVALID_TIMER); } break; case SC_LKCONCENTRATION: - status_change_end(bl, SC_ENDURE, INVALID_TIMER); + if (sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 != 2) + status_change_end(bl, SC_ENDURE, INVALID_TIMER); break; /** * 3rd Stuff @@ -10140,7 +10089,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const struct block_list* src = map->id2bl(sce->val2); if( tid == -1 || !src) break; // Terminated by Damage - status_fix_damage(src,bl,400*sce->val1,clif->damage(bl,bl,0,0,400*sce->val1,0,0,0)); + status_fix_damage(src,bl,400*sce->val1,clif->damage(bl,bl,0,0,400*sce->val1,0,BDT_NORMAL,0)); } break; case SC_WUGDASH: @@ -10149,7 +10098,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const if (ud) { ud->state.running = 0; if (ud->walktimer != -1) - unit->stop_walking(bl,1); + unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); } } break; @@ -10192,15 +10141,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const map->foreachinrange(status->change_timer_sub, bl, battle_config.area_size,BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, timer->gettick()); break; case SC_RAISINGDRAGON: - if( sd && sce->val2 && !pc_isdead(sd) ) { + if ( sd && sce->val2 && !pc_isdead(sd) ) { int i; - i = min(sd->spiritball,5); - pc->delspiritball(sd, sd->spiritball, 0); + if ( (i = (sd->spiritball - 5)) > 0 ) + pc->delspiritball(sd, i, 0); status_change_end(bl, SC_EXPLOSIONSPIRITS, INVALID_TIMER); - while( i > 0 ) { - pc->addspiritball(sd, skill->get_time(MO_CALLSPIRITS, pc->checkskill(sd,MO_CALLSPIRITS)), 5); - --i; - } } break; case SC_CURSEDCIRCLE_TARGET: @@ -10465,7 +10410,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const } //On Aegis, when turning off a status change, first goes the sc packet, then the option packet. - clif->sc_end(bl,bl->id,AREA,status->IconChangeTable[type]); + clif->sc_end(bl,bl->id,AREA,status->dbs->IconChangeTable[type]); if( opt_flag&8 ) //bugreport:681 clif->changeoption2(bl); @@ -10487,7 +10432,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const skill->unit_move(bl,timer->gettick(),1); if (opt_flag & 2 && sd) { - if (map->getcell(bl->m,bl->x,bl->y,CELL_CHKNPC)) + if (map->getcell(bl->m, bl, bl->x, bl->y, CELL_CHKNPC)) npc->touch_areanpc(sd,bl->m,bl->x,bl->y); //Trigger on-touch event. else npc->untouch_areanpc(sd, bl->m, bl->x, bl->y); @@ -10504,10 +10449,7 @@ int kaahi_heal_timer(int tid, int64 tick, int id, intptr_t data) { struct status_data *st; int hp; - if(!( (bl=map->id2bl(id)) - && (sc=status->get_sc(bl)) - && (sce=sc->data[SC_KAAHI]) - )) + if ((bl=map->id2bl(id)) == NULL || (sc=status->get_sc(bl)) == NULL || (sce=sc->data[SC_KAAHI]) == NULL) return 0; if(sce->val4 != tid) { @@ -10551,7 +10493,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { sc = status->get_sc(bl); st = status->get_status_data(bl); - if (!(sc && (sce = sc->data[type]))) { + if (!sc || (sce = sc->data[type]) == NULL) { ShowDebug("status_change_timer: Null pointer id: %d data: %"PRIdPTR" bl-type: %d\n", id, data, bl->type); return 0; } @@ -10560,7 +10502,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { ShowError("status_change_timer: Mismatch for type %d: %d != %d (bl id %d)\n",type,tid,sce->timer, bl->id); return 0; } - + sce->timer = INVALID_TIMER; sd = BL_CAST(BL_PC, bl); @@ -10639,12 +10581,12 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { case SC_STONE: if(sc->opt1 == OPT1_STONEWAIT && sce->val3) { sce->val4 = 0; - unit->stop_walking(bl,1); + unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); unit->stop_attack(bl); sc->opt1 = OPT1_STONE; clif->changeoption(bl); sc_timer_next(1000+tick, status->change_timer, bl->id, data ); - status_calc_bl(bl, status->ChangeFlagTable[type]); + status_calc_bl(bl, status->dbs->ChangeFlagTable[type]); return 0; } if(--(sce->val3) > 0) { @@ -10686,14 +10628,16 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { case SC_KNOWLEDGE: if (!sd) break; - if (bl->m == sd->feel_map[0].m - || bl->m == sd->feel_map[1].m - || bl->m == sd->feel_map[2].m - ) { - //Timeout will be handled by pc->setpos - sce->timer = INVALID_TIMER; - return 0; + { + int i; + for (i = 0; i < MAX_PC_FEELHATE; i++) { + if (bl->m == sd->feel_map[i].m) { + //Timeout will be handled by pc->setpos + sce->timer = INVALID_TIMER; + return 0; + } } + } break; case SC_BLOODING: @@ -10880,7 +10824,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { case SC_PYREXIA: if( --(sce->val4) > 0 ) { map->freeblock_lock(); - clif->damage(bl,bl,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,0,0); + clif->damage(bl,bl,status_get_amotion(bl),status_get_dmotion(bl)+500,100,0,BDT_NORMAL,0); status_fix_damage(NULL,bl,100,0); if( sc->data[type] ) { sc_timer_next(3000+tick,status->change_timer,bl->id,data); @@ -10896,7 +10840,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { damage += st->vit * (sce->val1 - 3); unit->skillcastcancel(bl,2); map->freeblock_lock(); - status->damage(bl, bl, damage, 0, clif->damage(bl,bl,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,0,0), 1); + status->damage(bl, bl, damage, 0, clif->damage(bl,bl,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,BDT_NORMAL,0), 1); if( sc->data[type] ) { sc_timer_next(1000 + tick, status->change_timer, bl->id, data ); } @@ -10928,7 +10872,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { unit->skillcastcancel(bl,0); do { int i = rnd() % MAX_SKILL_MAGICMUSHROOM_DB; - mushroom_skill_id = skill->magicmushroom_db[i].skill_id; + mushroom_skill_id = skill->dbs->magicmushroom_db[i].skill_id; } while (mushroom_skill_id == 0); switch( skill->get_casttype(mushroom_skill_id) ) { // Magic Mushroom skills are buffs or area damage @@ -10958,7 +10902,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { if( --(sce->val4) > 0 ) { //Damage is every 10 seconds including 3%sp drain. map->freeblock_lock(); - clif->damage(bl,bl,status_get_amotion(bl),1,1,0,0,0); + clif->damage(bl,bl,status_get_amotion(bl),1,1,0,BDT_NORMAL,0); status->damage(NULL, bl, 1, st->max_sp * 3 / 100, 0, 0); //cancel dmg only if cancelable if( sc->data[type] ) { sc_timer_next(10000 + tick, status->change_timer, bl->id, data ); @@ -10996,15 +10940,14 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { int heal = st->max_hp * 3 / 100; if (sc->count && sc->data[SC_AKAITSUKI] && heal) heal = ~heal + 1; - + map->freeblock_lock(); - status->heal(bl, heal, 0, 2); if( sc->data[type] ) { sc_timer_next(5000 + tick, status->change_timer, bl->id, data); } map->freeblock_unlock(); - + return 0; } break; @@ -11015,7 +10958,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { int damage = 1000 + 3 * status_get_max_hp(bl) / 100; // Deals fixed (1000 + 3%*MaxHP) map->freeblock_lock(); - clif->damage(bl,bl,0,0,damage,1,9,0); //damage is like endure effect with no walk delay + clif->damage(bl,bl,0,0,damage,1,BDT_MULTIENDURE,0); //damage is like endure effect with no walk delay status->damage(src, bl, damage, 0, 0, 1); if( sc->data[type]){ // Target still lives. [LimitLine] @@ -11117,7 +11060,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { break; map->freeblock_lock(); damage = sce->val3; - status->damage(src, bl, damage, 0, clif->damage(bl,bl,st->amotion,st->dmotion+200,damage,1,0,0), 1); + status->damage(src, bl, damage, 0, clif->damage(bl,bl,st->amotion,st->dmotion+200,damage,1,BDT_NORMAL,0), 1); unit->skillcastcancel(bl,1); if ( sc->data[type] ) { sc_timer_next(1000 + tick, status->change_timer, bl->id, data); @@ -11163,7 +11106,6 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { } break; - case SC_SATURDAY_NIGHT_FEVER: if( --(sce->val3) >= 0 ) { if( !status->charge(bl, st->max_hp * 1 / 100, st->max_sp * 1 / 100) ) @@ -11225,7 +11167,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { int damage = st->max_hp / 100; // Suggestion 1% each second if( damage >= st->hp ) damage = st->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,0,0,damage,0,0,0)); + status_fix_damage(NULL,bl,damage,clif->damage(bl,bl,0,0,damage,0,BDT_NORMAL,0)); if( sc->data[type] ) { sc_timer_next(1000 + tick, status->change_timer, bl->id, data); } @@ -11323,7 +11265,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) { 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_walking(sd, STOPWALKING_FLAG_FIXPOS|STOPWALKING_FLAG_NEXTCELL); pc_stop_attack(sd); pc_setsit(sd); clif->sitting(bl); @@ -11507,7 +11449,7 @@ int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int fl short index = sd->equip_index[EQI_HAND_R], refine; if ( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON && (refine = sd->status.inventory[index].refine) < 16 && refine ) { - int r = status->refine_info[watk->wlv].randombonus_max[refine + (4 - watk->wlv)] / 100; + int r = status->dbs->refine_info[watk->wlv].randombonus_max[refine + (4 - watk->wlv)] / 100; if ( r ) max += (rnd() % 100) % r + 1; } @@ -11606,7 +11548,7 @@ void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_m short index = sd->equip_index[EQI_HAND_R], refine; if ( index >= 0 && sd->inventory_data[index] && sd->inventory_data[index]->type == IT_WEAPON && (refine = sd->status.inventory[index].refine) < 16 && refine ) { - int r = status->refine_info[sd->inventory_data[index]->wlv].randombonus_max[refine + (4 - sd->inventory_data[index]->wlv)] / 100; + int r = status->dbs->refine_info[sd->inventory_data[index]->wlv].randombonus_max[refine + (4 - sd->inventory_data[index]->wlv)] / 100; if ( r ) *matk_max += (rnd() % 100) % r + 1; } @@ -11704,7 +11646,7 @@ int status_change_clear_buffs (struct block_list* bl, int type) { return 0; map->freeblock_lock(); - + if (type&6) //Debuffs for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++) status_change_end(bl, (sc_type)i, INVALID_TIMER); @@ -11751,9 +11693,9 @@ int status_change_clear_buffs (struct block_list* bl, int type) { } status_change_end(bl, (sc_type)i, INVALID_TIMER); } - + map->freeblock_unlock(); - + return 0; } @@ -11886,7 +11828,7 @@ int status_natural_heal(struct block_list* bl, va_list args) { if (flag&(RGN_SHP|RGN_SSP) && regen->ssregen - && (vd = status->get_viewdata(bl)) + && (vd = status->get_viewdata(bl)) != NULL && vd->dead_sit == 2 ) { //Apply sitting regen bonus. @@ -12049,7 +11991,7 @@ int status_get_refine_chance(enum refine_type wlv, int refine) { if ( refine < 0 || refine >= MAX_REFINE) return 0; - return status->refine_info[wlv].chance[refine]; + return status->dbs->refine_info[wlv].chance[refine]; } int status_get_sc_type(sc_type type) { @@ -12057,7 +11999,7 @@ int status_get_sc_type(sc_type type) { if( type <= SC_NONE || type >= SC_MAX ) return 0; - return status->sc_conf[type]; + return status->dbs->sc_conf[type]; } void status_read_job_db_sub(int idx, const char *name, config_setting_t *jdb) @@ -12099,81 +12041,106 @@ void status_read_job_db_sub(int idx, const char *name, config_setting_t *jdb) }; if ((temp = libconfig->setting_get_member(jdb, "Inherit"))) { - int nidx = 0, iidx, w; + int nidx = 0; const char *iname; while ((iname = libconfig->setting_get_string_elem(temp, nidx++))) { - int iclass, ave, total = 0; + int i, iidx, iclass, avg_increment, base; if ((iclass = pc->check_job_name(iname)) == -1) { ShowWarning("status_read_job_db: '%s' trying to inherit unknown '%s'!\n", name, iname); continue; } iidx = pc->class2idx(iclass); - status->max_weight_base[idx] = status->max_weight_base[iidx]; - memcpy(&status->aspd_base[idx], &status->aspd_base[iidx], sizeof(status->aspd_base[iidx])); - for (w = 1; w <= MAX_LEVEL && status->HP_table[iidx][w]; w++) { - status->HP_table[idx][w] = status->HP_table[iidx][w]; - total += status->HP_table[idx][w] - status->HP_table[idx][w - 1]; + status->dbs->max_weight_base[idx] = status->dbs->max_weight_base[iidx]; + memcpy(&status->dbs->aspd_base[idx], &status->dbs->aspd_base[iidx], sizeof(status->dbs->aspd_base[iidx])); + + for (i = 1; i <= MAX_LEVEL && status->dbs->HP_table[iidx][i]; i++) { + status->dbs->HP_table[idx][i] = status->dbs->HP_table[iidx][i]; } - ave = total / (w - 1); - for ( ; w <= pc->max_level[idx][0]; w++) { - status->HP_table[idx][w] = min(ave * w, battle_config.max_hp); + base = (i > 1 ? status->dbs->HP_table[idx][1] : 35); // Safe value if none are specified + if (i > 2) { + if (i >= MAX_LEVEL + 1) + i = MAX_LEVEL; + avg_increment = (status->dbs->HP_table[idx][i] - base) / (i - 1); + } else { + avg_increment = 5; } - total = 0; - for (w = 1; w <= MAX_LEVEL && status->SP_table[iidx][w]; w++) { - status->SP_table[idx][w] = status->SP_table[iidx][w]; - total += status->SP_table[idx][w] - status->SP_table[idx][w - 1]; + for ( ; i <= pc->max_level[idx][0]; i++) { + status->dbs->HP_table[idx][i] = min(base + avg_increment * i, battle_config.max_hp); } - ave = total / (w - 1); - for ( ; w <= pc->max_level[idx][0]; w++) { - status->SP_table[idx][w] = min(ave * w, battle_config.max_sp); + + for (i = 1; i <= MAX_LEVEL && status->dbs->SP_table[iidx][i]; i++) { + status->dbs->SP_table[idx][i] = status->dbs->SP_table[iidx][i]; + } + base = (i > 1 ? status->dbs->SP_table[idx][1] : 10); // Safe value if none are specified + if (i > 2) { + if (i >= MAX_LEVEL + 1) + i = MAX_LEVEL; + avg_increment = (status->dbs->SP_table[idx][i] - base) / (i - 1); + } else { + avg_increment = 1; + } + for ( ; i <= pc->max_level[idx][0]; i++) { + status->dbs->SP_table[idx][i] = min(base + avg_increment * i, battle_config.max_sp); } } } if ((temp = libconfig->setting_get_member(jdb, "InheritHP"))) { - int nidx = 0, iidx; + int nidx = 0; const char *iname; while ((iname = libconfig->setting_get_string_elem(temp, nidx++))) { - int iclass, w, ave, total = 0; + int i, iidx, iclass, avg_increment, base; if ((iclass = pc->check_job_name(iname)) == -1) { ShowWarning("status_read_job_db: '%s' trying to inherit unknown '%s' HP!\n", name, iname); continue; } iidx = pc->class2idx(iclass); - for (w = 1; w <= MAX_LEVEL && status->HP_table[iidx][w]; w++) { - status->HP_table[idx][w] = status->HP_table[iidx][w]; - total += status->HP_table[idx][w] - status->HP_table[idx][w - 1]; + for (i = 1; i <= MAX_LEVEL && status->dbs->HP_table[iidx][i]; i++) { + status->dbs->HP_table[idx][i] = status->dbs->HP_table[iidx][i]; + } + base = (i > 1 ? status->dbs->HP_table[idx][1] : 35); // Safe value if none are specified + if (i > 2) { + if (i >= MAX_LEVEL + 1) + i = MAX_LEVEL; + avg_increment = (status->dbs->HP_table[idx][i] - base) / (i - 1); + } else { + avg_increment = 5; } - ave = total / (w - 1); - for ( ; w <= pc->max_level[idx][0]; w++ ) { - status->HP_table[idx][w] = min(ave * w, battle_config.max_hp); + for ( ; i <= pc->max_level[idx][0]; i++) { + status->dbs->HP_table[idx][i] = min(base + avg_increment * i, battle_config.max_hp); } } } if ((temp = libconfig->setting_get_member(jdb, "InheritSP"))) { - int nidx = 0, iidx, ave, total = 0; + int nidx = 0; const char *iname; while ((iname = libconfig->setting_get_string_elem(temp, nidx++))) { - int iclass, w; + int i, iidx, iclass, avg_increment, base; if ((iclass = pc->check_job_name(iname)) == -1) { ShowWarning("status_read_job_db: '%s' trying to inherit unknown '%s' SP!\n", name, iname); continue; } iidx = pc->class2idx(iclass); - for (w = 1; w <= MAX_LEVEL && status->SP_table[iidx][w]; w++) { - status->SP_table[idx][w] = status->SP_table[iidx][w]; - total += status->SP_table[idx][w] - status->SP_table[idx][w-1]; + for (i = 1; i <= MAX_LEVEL && status->dbs->SP_table[iidx][i]; i++) { + status->dbs->SP_table[idx][i] = status->dbs->SP_table[iidx][i]; + } + base = (i > 1 ? status->dbs->SP_table[idx][1] : 10); // Safe value if none are specified + if (i > 2) { + if (i >= MAX_LEVEL + 1) + i = MAX_LEVEL; + avg_increment = (status->dbs->SP_table[idx][i] - base) / (i - 1); + } else { + avg_increment = 1; } - ave = total / (w - 1); - for ( ; w <= pc->max_level[idx][0]; w++) { - status->SP_table[idx][w] = min(ave * w, battle_config.max_sp); + for ( ; i <= pc->max_level[idx][0]; i++) { + status->dbs->SP_table[idx][i] = min(avg_increment * i, battle_config.max_sp); } } } if (libconfig->setting_lookup_int(jdb, "Weight", &i32)) - status->max_weight_base[idx] = i32; - else if (!status->max_weight_base[idx]) - status->max_weight_base[idx] = 20000; + status->dbs->max_weight_base[idx] = i32; + else if (!status->dbs->max_weight_base[idx]) + status->dbs->max_weight_base[idx] = 20000; if ((temp = libconfig->setting_get_member(jdb, "BaseASPD"))) { int widx = 0; @@ -12184,7 +12151,7 @@ void status_read_job_db_sub(int idx, const char *name, config_setting_t *jdb) ARR_FIND(0, wlen, w, strcmp(wnames[w].name, wname) == 0); if (w != wlen) { - status->aspd_base[idx][wnames[w].id] = libconfig->setting_get_int(wpn); + status->dbs->aspd_base[idx][wnames[w].id] = libconfig->setting_get_int(wpn); } else { ShowWarning("status_read_job_db: unknown weapon type '%s'!\n", wname); } @@ -12192,28 +12159,42 @@ void status_read_job_db_sub(int idx, const char *name, config_setting_t *jdb) } if ((temp = libconfig->setting_get_member(jdb, "HPTable"))) { - int level = 0, ave, total = 0; + int level = 0, avg_increment, base; config_setting_t *hp = NULL; - while ((hp = libconfig->setting_get_elem(temp, level++))) { - status->HP_table[idx][level] = i32 = min(libconfig->setting_get_int(hp), battle_config.max_hp); - total += i32 - status->HP_table[idx][level - 1]; + while (level <= MAX_LEVEL && (hp = libconfig->setting_get_elem(temp, level)) != NULL) { + i32 = libconfig->setting_get_int(hp); + status->dbs->HP_table[idx][++level] = min(i32, battle_config.max_hp); + } + base = (level > 0 ? status->dbs->HP_table[idx][1] : 35); // Safe value if none are specified + if (level > 2) { + if (level >= MAX_LEVEL + 1) + level = MAX_LEVEL; + avg_increment = (status->dbs->HP_table[idx][level] - base) / level; + } else { + avg_increment = 5; } - ave = total / (level - 1); - for ( ; level <= pc->max_level[idx][0]; level++ ) { /* limit only to possible maximum level of the given class */ - status->HP_table[idx][level] = min(ave * level, battle_config.max_hp); /* some are still empty? then let's use the average increase */ + for (++level; level <= pc->max_level[idx][0]; ++level) { /* limit only to possible maximum level of the given class */ + status->dbs->HP_table[idx][level] = min(base + avg_increment * level, battle_config.max_hp); /* some are still empty? then let's use the average increase */ } } if ((temp = libconfig->setting_get_member(jdb, "SPTable"))) { - int level = 0, ave, total = 0; + int level = 0, avg_increment, base; config_setting_t *sp = NULL; - while ((sp = libconfig->setting_get_elem(temp, level++))) { - status->SP_table[idx][level] = i32 = min(libconfig->setting_get_int(sp), battle_config.max_sp); - total += i32 - status->SP_table[idx][level - 1]; + while (level <= MAX_LEVEL && (sp = libconfig->setting_get_elem(temp, level)) != NULL) { + i32 = libconfig->setting_get_int(sp); + status->dbs->SP_table[idx][++level] = min(i32, battle_config.max_sp); + } + base = (level > 0 ? status->dbs->SP_table[idx][1] : 10); // Safe value if none are specified + if (level > 2) { + if (level >= MAX_LEVEL + 1) + level = MAX_LEVEL; + avg_increment = (status->dbs->SP_table[idx][level] - base) / level; + } else { + avg_increment = 1; } - ave = total / (level - 1); for ( ; level <= pc->max_level[idx][0]; level++ ) { - status->SP_table[idx][level] = min(ave * level, battle_config.max_sp); + status->dbs->SP_table[idx][level] = min(base + avg_increment * level, battle_config.max_sp); } } } @@ -12229,11 +12210,10 @@ void status_read_job_db(void) { /* [malufett/Hercules] */ int i = 0; config_t job_db_conf; config_setting_t *jdb = NULL; - const char *config_filename = #ifdef RENEWAL_ASPD - "db/re/job_db.conf"; + const char *config_filename = "db/re/job_db.conf"; #else - "db/pre-re/job_db.conf"; + const char *config_filename = "db/pre-re/job_db.conf"; #endif if ( libconfig->read_file(&job_db_conf, config_filename) ) { @@ -12271,7 +12251,7 @@ bool status_readdb_job2(char* fields[], int columns, int current) for(i = 1; i < columns; i++) { - status->job_bonus[idx][i-1] = atoi(fields[i]); + status->dbs->job_bonus[idx][i-1] = atoi(fields[i]); } return true; } @@ -12282,43 +12262,141 @@ bool status_readdb_sizefix(char* fields[], int columns, int current) for(i = 0; i < MAX_WEAPON_TYPE; i++) { - status->atkmods[current][i] = atoi(fields[i]); + status->dbs->atkmods[current][i] = atoi(fields[i]); } return true; } -bool status_readdb_refine(char* fields[], int columns, int current) +/** + * Processes a refine_db.conf entry. + * + * @param *r Libconfig setting entry. It is expected to be valid and it + * won't be freed (it is care of the caller to do so if + * necessary) + * @param n Ordinal number of the entry, to be displayed in case of + * validation errors. + * @param *source Source of the entry (file name), to be displayed in case of + * validation errors. + * @return # of the validated entry, or 0 in case of failure. + */ +int status_readdb_refine_libconfig_sub(config_setting_t *r, const char *name, const char *source) { - int i, bonus_per_level, random_bonus, random_bonus_start_level; - - current = atoi(fields[0]); - - if (current < 0 || current >= REFINE_TYPE_MAX) - return false; - - bonus_per_level = atoi(fields[1]); - random_bonus_start_level = atoi(fields[2]); - random_bonus = atoi(fields[3]); - - for(i = 0; i < MAX_REFINE; i++) - { - char* delim; - - if (!(delim = strchr(fields[4+i], ':'))) - return false; - - *delim = '\0'; - - status->refine_info[current].chance[i] = atoi(fields[4+i]); + config_setting_t *rate = NULL; + int type = REFINE_TYPE_ARMOR, bonus_per_level = 0, rnd_bonus_v = 0, rnd_bonus_lv = 0; + char lv[4]; + nullpo_ret(r); + nullpo_ret(name); + nullpo_ret(source); + + if (strncmp(name, "Armors", 6) == 0) { + type = REFINE_TYPE_ARMOR; + } else if (strncmp(name, "WeaponLevel", 11) != 0 || !strspn(&name[strlen(name)-1], "0123456789") || (type = atoi(strncpy(lv, name+11, 2))) == REFINE_TYPE_ARMOR) { + ShowError("status_readdb_refine_libconfig_sub: Invalid key name for entry '%s' in \"%s\", skipping.\n", name, source); + return 0; + } + if (type < REFINE_TYPE_ARMOR || type >= REFINE_TYPE_MAX) { + ShowError("status_readdb_refine_libconfig_sub: Out of range level for entry '%s' in \"%s\", skipping.\n", name, source); + return 0; + } + if (!libconfig->setting_lookup_int(r, "StatsPerLevel", &bonus_per_level)) { + ShowWarning("status_readdb_refine_libconfig_sub: Missing StatsPerLevel for entry '%s' in \"%s\", skipping.\n", name, source); + return 0; + } + if (!libconfig->setting_lookup_int(r, "RandomBonusStartLevel", &rnd_bonus_lv)) { + ShowWarning("status_readdb_refine_libconfig_sub: Missing RandomBonusStartLevel for entry '%s' in \"%s\", skipping.\n", name, source); + return 0; + } + if (!libconfig->setting_lookup_int(r, "RandomBonusValue", &rnd_bonus_v)) { + ShowWarning("status_readdb_refine_libconfig_sub: Missing RandomBonusValue for entry '%s' in \"%s\", skipping.\n", name, source); + return 0; + } - if (i >= random_bonus_start_level - 1) - status->refine_info[current].randombonus_max[i] = random_bonus * (i - random_bonus_start_level + 2); + if ((rate=libconfig->setting_get_member(r, "Rates")) != NULL && config_setting_is_group(rate)) { + config_setting_t *t = NULL; + bool duplicate[MAX_REFINE]; + int bonus[MAX_REFINE], rnd_bonus[MAX_REFINE], chance[MAX_REFINE]; + int i; + memset(&duplicate, 0, sizeof(duplicate)); + memset(&bonus, 0, sizeof(bonus)); + memset(&rnd_bonus, 0, sizeof(rnd_bonus)); + + for (i = 0; i < MAX_REFINE; i++) { + chance[i] = 100; + } + i = 0; + while ((t = libconfig->setting_get_elem(rate,i++)) != NULL && config_setting_is_group(t)) { + int level = 0, i32; + char *rlvl = config_setting_name(t); + memset(&lv, 0, sizeof(lv)); + if (!strspn(&rlvl[strlen(rlvl)-1], "0123456789") || (level = atoi(strncpy(lv, rlvl+2, 3))) <= 0) { + ShowError("status_readdb_refine_libconfig_sub: Invalid refine level format '%s' for entry %s in \"%s\"... skipping.\n", rlvl, name, source); + continue; + } + if (level <= 0 || level > MAX_REFINE) { + ShowError("status_readdb_refine_libconfig_sub: Out of range refine level '%s' for entry %s in \"%s\"... skipping.\n", rlvl, name, source); + continue; + } + level--; + if (duplicate[level]) { + ShowWarning("status_readdb_refine_libconfig_sub: duplicate rate '%s' for entry %s in \"%s\", overwriting previous entry...\n", rlvl, name, source); + } else { + duplicate[level] = true; + } + if (libconfig->setting_lookup_int(t, "Chance", &i32)) + chance[level] = i32; + else + chance[level] = 100; + if (libconfig->setting_lookup_int(t, "Bonus", &i32)) + bonus[level] += i32; + if (level >= rnd_bonus_lv - 1) + rnd_bonus[level] = rnd_bonus_v * (level - rnd_bonus_lv + 2); + } + for (i = 0; i < MAX_REFINE; i++) { + status->dbs->refine_info[type].chance[i] = chance[i]; + status->dbs->refine_info[type].randombonus_max[i] = rnd_bonus[i]; + bonus[i] += bonus_per_level + (i > 0 ? bonus[i-1] : 0); + status->dbs->refine_info[type].bonus[i] = bonus[i]; + } + } else { + ShowWarning("status_readdb_refine_libconfig_sub: Missing refine rates for entry '%s' in \"%s\", skipping.\n", name, source); + return 0; + } + return type+1; +} - status->refine_info[current].bonus[i] = bonus_per_level + atoi(delim+1); - if (i > 0) - status->refine_info[current].bonus[i] += status->refine_info[current].bonus[i-1]; +/** + * Reads from a libconfig-formatted refine_db.conf file. + * + * @param *filename File name, relative to the database path. + * @return The number of found entries. + */ +int status_readdb_refine_libconfig(const char *filename) { + bool duplicate[REFINE_TYPE_MAX]; + config_t refine_db_conf; + config_setting_t *r; + char filepath[256]; + int i = 0, count = 0,type = 0; + + sprintf(filepath, "%s/%s", map->db_path, filename); + memset(&duplicate,0,sizeof(duplicate)); + if( libconfig->read_file(&refine_db_conf, filepath) ) { + ShowError("can't read %s\n", filepath); + return 0; } - return true; + + while((r = libconfig->setting_get_elem(refine_db_conf.root,i++))) { + char *name = config_setting_name(r); + if((type=status->readdb_refine_libconfig_sub(r, name, filename))) { + if( duplicate[type-1] ) { + ShowWarning("status_readdb_refine_libconfig: duplicate entry for %s in \"%s\", overwriting previous entry...\n", name, filename); + } else duplicate[type-1] = true; + count++; + } + } + libconfig->destroy(&refine_db_conf); + ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename); + + return count; } bool status_readdb_scconfig(char* fields[], int columns, int current) { @@ -12330,7 +12408,7 @@ bool status_readdb_scconfig(char* fields[], int columns, int current) { return false; } - status->sc_conf[val] = (int)strtol(fields[1], NULL, 0); + status->dbs->sc_conf[val] = (int)strtol(fields[1], NULL, 0); return true; } @@ -12347,41 +12425,41 @@ int status_readdb(void) // initialize databases to default // - if( runflag == MAPSERVER_ST_RUNNING ) {//not necessary during boot + if( core->runflag == MAPSERVER_ST_RUNNING ) {//not necessary during boot // reset job_db.conf data - memset(status->max_weight_base, 0, sizeof(status->max_weight_base)); - memset(status->HP_table, 0, sizeof(status->HP_table)); - memset(status->SP_table, 0, sizeof(status->SP_table)); + memset(status->dbs->max_weight_base, 0, sizeof(status->dbs->max_weight_base)); + memset(status->dbs->HP_table, 0, sizeof(status->dbs->HP_table)); + memset(status->dbs->SP_table, 0, sizeof(status->dbs->SP_table)); // reset job_db2.txt data - memset(status->job_bonus,0,sizeof(status->job_bonus)); // Job-specific stats bonus + memset(status->dbs->job_bonus,0,sizeof(status->dbs->job_bonus)); // Job-specific stats bonus } for ( i = 0; i < CLASS_COUNT; i++ ) { for ( j = 0; j < MAX_WEAPON_TYPE; j++ ) - status->aspd_base[i][j] = 2000; + status->dbs->aspd_base[i][j] = 2000; #ifdef RENEWAL_ASPD - status->aspd_base[i][MAX_WEAPON_TYPE] = 0; + status->dbs->aspd_base[i][MAX_WEAPON_TYPE] = 0; #endif } // size_fix.txt - for(i = 0; i < ARRAYLENGTH(status->atkmods); i++) + for(i = 0; i < ARRAYLENGTH(status->dbs->atkmods); i++) for(j = 0; j < MAX_WEAPON_TYPE; j++) - status->atkmods[i][j] = 100; + status->dbs->atkmods[i][j] = 100; // refine_db.txt - for(i=0;i<ARRAYLENGTH(status->refine_info);i++) { + for(i=0;i<ARRAYLENGTH(status->dbs->refine_info);i++) { for(j=0;j<MAX_REFINE; j++) { - status->refine_info[i].chance[j] = 100; - status->refine_info[i].bonus[j] = 0; - status->refine_info[i].randombonus_max[j] = 0; + status->dbs->refine_info[i].chance[j] = 100; + status->dbs->refine_info[i].bonus[j] = 0; + status->dbs->refine_info[i].randombonus_max[j] = 0; } } // read databases // sv->readdb(map->db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, status->readdb_job2); - sv->readdb(map->db_path, DBPATH"size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(status->atkmods), status->readdb_sizefix); - sv->readdb(map->db_path, DBPATH"refine_db.txt", ',', 4+MAX_REFINE, 4+MAX_REFINE, ARRAYLENGTH(status->refine_info), status->readdb_refine); + sv->readdb(map->db_path, DBPATH"size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(status->dbs->atkmods), status->readdb_sizefix); + status->readdb_refine_libconfig(DBPATH"refine_db.conf"); sv->readdb(map->db_path, "sc_config.txt", ',', 2, 2, SC_MAX, status->readdb_scconfig); status->read_job_db(); @@ -12417,6 +12495,7 @@ void do_final_status(void) { *-------------------------------------*/ void status_defaults(void) { status = &status_s; + status->dbs = &statusdbs; /* vars */ //we need it for new cards 15 Feb 2005, to check if the combo cards are insrerted into the CURRENT weapon only @@ -12424,21 +12503,8 @@ void status_defaults(void) { status->current_equip_item_index = 0; //Contains inventory index of an equipped item. To pass it into the EQUP_SCRIPT [Lupus] status->current_equip_card_id = 0; //To prevent card-stacking (from jA) [Skotlex] - memset(status->max_weight_base,0,sizeof(status->max_weight_base) - + sizeof(status->HP_table) - + sizeof(status->SP_table) - + sizeof(status->aspd_base) - + sizeof(status->Skill2SCTable) - + sizeof(status->IconChangeTable) - + sizeof(status->ChangeFlagTable) - + sizeof(status->SkillChangeTable) - + sizeof(status->RelevantBLTypes) - + sizeof(status->DisplayType) - + sizeof(status->refine_info) - + sizeof(status->atkmods) - + sizeof(status->job_bonus) - + sizeof(status->sc_conf) - ); + // These macros are used instead of a sum of sizeof(), to ensure that padding won't interfere with our size, and code won't rot when adding more fields + memset(ZEROED_BLOCK_POS(status->dbs), 0, ZEROED_BLOCK_SIZE(status->dbs)); status->data_ers = NULL; memset(&status->dummy, 0, sizeof(status->dummy)); @@ -12500,6 +12566,7 @@ void status_defaults(void) { status->calc_mob_ = status_calc_mob_; status->calc_pet_ = status_calc_pet_; status->calc_pc_ = status_calc_pc_; + status->calc_pc_additional = status_calc_pc_additional; status->calc_homunculus_ = status_calc_homunculus_; status->calc_mercenary_ = status_calc_mercenary_; status->calc_elemental_ = status_calc_elemental_; @@ -12567,7 +12634,8 @@ void status_defaults(void) { status->natural_heal_timer = status_natural_heal_timer; status->readdb_job2 = status_readdb_job2; status->readdb_sizefix = status_readdb_sizefix; - status->readdb_refine = status_readdb_refine; + status->readdb_refine_libconfig = status_readdb_refine_libconfig; + status->readdb_refine_libconfig_sub = status_readdb_refine_libconfig_sub; status->readdb_scconfig = status_readdb_scconfig; status->read_job_db = status_read_job_db; status->read_job_db_sub = status_read_job_db_sub; |