summaryrefslogtreecommitdiff
path: root/src/map/status.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/status.c')
-rw-r--r--src/map/status.c2398
1 files changed, 1357 insertions, 1041 deletions
diff --git a/src/map/status.c b/src/map/status.c
index 926bdb40a..f06bb0330 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -2,7 +2,7 @@
* This file is part of Hercules.
* http://herc.ws - http://github.com/HerculesWS/Hercules
*
- * Copyright (C) 2012-2016 Hercules Dev Team
+ * Copyright (C) 2012-2018 Hercules Dev Team
* Copyright (C) Athena Dev Teams
*
* Hercules is free software: you can redistribute it and/or modify
@@ -25,6 +25,7 @@
#include "map/battle.h"
#include "map/chrif.h"
+#include "map/clan.h"
#include "map/clif.h"
#include "map/elemental.h"
#include "map/guild.h"
@@ -60,17 +61,17 @@
#include <string.h>
#include <time.h>
-struct status_interface status_s;
-struct s_status_dbs statusdbs;
+static struct status_interface status_s;
+static struct s_status_dbs statusdbs;
struct status_interface *status;
/**
-* Returns the status change associated with a skill.
-* @param skill The skill to look up
-* @return The status registered for this skill
-**/
-sc_type status_skill2sc(int skill_id)
+ * Returns the status change associated with a skill.
+ * @param skill The skill to look up
+ * @return The status registered for this skill
+ */
+static sc_type status_skill2sc(int skill_id)
{
int idx;
if( (idx = skill->get_index(skill_id)) == 0 ) {
@@ -81,12 +82,12 @@ sc_type status_skill2sc(int skill_id)
}
/**
-* Returns the FIRST skill (in order of definition in initChangeTables) to use a given status change.
-* Utilized for various duration lookups. Use with caution!
-* @param sc The status to look up
-* @return A skill associated with the status
-**/
-int status_sc2skill(sc_type sc)
+ * Returns the FIRST skill (in order of definition in initChangeTables) to use a given status change.
+ * Utilized for various duration lookups. Use with caution!
+ * @param sc The status to look up
+ * @return A skill associated with the status
+ */
+static int status_sc2skill(sc_type sc)
{
if( sc < 0 || sc >= SC_MAX ) {
ShowError("status_sc2skill: Unsupported status change id %d\n", sc);
@@ -97,11 +98,11 @@ int status_sc2skill(sc_type sc)
}
/**
-* Returns the status calculation flag associated with a given status change.
-* @param sc The status to look up
-* @return The scb_flag registered for this status (see enum scb_flag)
-**/
-unsigned int status_sc2scb_flag(sc_type sc)
+ * Returns the status calculation flag associated with a given status change.
+ * @param sc The status to look up
+ * @return The scb_flag registered for this status (see enum scb_flag)
+ */
+static unsigned int status_sc2scb_flag(sc_type sc)
{
if( sc < 0 || sc >= SC_MAX ) {
ShowError("status_sc2scb_flag: Unsupported status change id %d\n", sc);
@@ -112,11 +113,11 @@ unsigned int status_sc2scb_flag(sc_type sc)
}
/**
-* Returns the bl types which require a status change packet to be sent for a given client status identifier.
-* @param type The client-side status identifier to look up (see enum si_type)
-* @return The bl types relevant to the type (see enum bl_type)
-**/
-int status_type2relevant_bl_types(int type)
+ * Returns the bl types which require a status change packet to be sent for a given client status identifier.
+ * @param type The client-side status identifier to look up (see enum si_type)
+ * @return The bl types relevant to the type (see enum bl_type)
+ */
+static int status_type2relevant_bl_types(int type)
{
if( type < 0 || type >= SI_MAX ) {
ShowError("status_type2relevant_bl_types: Unsupported type %d\n", type);
@@ -126,7 +127,7 @@ int status_type2relevant_bl_types(int type)
return status->dbs->RelevantBLTypes[type];
}
-void status_set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag)
+static void status_set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag)
{
uint16 idx;
if( (idx = skill->get_index(skill_id)) == 0 ) {
@@ -148,7 +149,7 @@ void status_set_sc(uint16 skill_id, sc_type sc, int icon, unsigned int flag)
status->dbs->Skill2SCTable[idx] = sc;
}
-void initChangeTables(void)
+static void initChangeTables(void)
{
#define add_sc(skill,sc) status->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
@@ -159,7 +160,7 @@ void initChangeTables(void)
for (i = 0; i < SC_MAX; i++)
status->dbs->IconChangeTable[i] = SI_BLANK;
- for (i = 0; i < MAX_SKILL; i++)
+ for (i = 0; i < MAX_SKILL_DB; i++)
status->dbs->Skill2SCTable[i] = SC_NONE;
for (i = 0; i < SI_MAX; i++)
@@ -1000,6 +1001,7 @@ void initChangeTables(void)
status->dbs->IconChangeTable[SC_MONSTER_TRANSFORM] = SI_MONSTER_TRANSFORM;
// Costumes
+ status->dbs->IconChangeTable[SC_DRESS_UP] = SI_DRESS_UP;
status->dbs->IconChangeTable[SC_MOONSTAR] = SI_MOONSTAR;
status->dbs->IconChangeTable[SC_SUPER_STAR] = SI_SUPER_STAR;
status->dbs->IconChangeTable[SC_STRANGELIGHTS] = SI_STRANGELIGHTS;
@@ -1018,6 +1020,12 @@ void initChangeTables(void)
// Summoner
status->dbs->IconChangeTable[SC_SPRITEMABLE] = SI_SPRITEMABLE;
+ // Clan System
+ status->dbs->IconChangeTable[SC_CLAN_INFO] = SI_CLAN_INFO;
+
+ // RoDEX
+ status->dbs->IconChangeTable[SC_DAILYSENDMAILCNT] = SI_DAILYSENDMAILCNT;
+
// Other SC which are not necessarily associated to skills.
status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION1] |= SCB_ASPD;
status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION2] |= SCB_ASPD;
@@ -1177,7 +1185,11 @@ void initChangeTables(void)
status->dbs->ChangeFlagTable[SC_MVPCARD_ORCHERO] |= SCB_ALL;
status->dbs->ChangeFlagTable[SC_MVPCARD_ORCLORD] |= SCB_ALL;
+ // Clan System
+ status->dbs->ChangeFlagTable[SC_CLAN_INFO] |= SCB_NONE;
+
// Costumes
+ status->dbs->ChangeFlagTable[SC_DRESS_UP] |= SCB_NONE;
status->dbs->ChangeFlagTable[SC_MOONSTAR] |= SCB_NONE;
status->dbs->ChangeFlagTable[SC_SUPER_STAR] |= SCB_NONE;
status->dbs->ChangeFlagTable[SC_STRANGELIGHTS] |= SCB_NONE;
@@ -1199,7 +1211,7 @@ void initChangeTables(void)
#undef set_sc_with_vfx
}
-void initDummyData(void)
+static void initDummyData(void)
{
memset(&status->dummy, 0, sizeof(status->dummy));
status->dummy.hp =
@@ -1221,17 +1233,22 @@ void initDummyData(void)
}
//For copying a status_data structure from b to a, without overwriting current Hp and Sp
-void status_copy(struct status_data *a, const struct status_data *b)
+static void status_copy(struct status_data *a, const struct status_data *b)
{
nullpo_retv(a);
nullpo_retv(b);
memcpy((void*)&a->max_hp, (const void*)&b->max_hp, sizeof(struct status_data)-(sizeof(a->hp)+sizeof(a->sp)));
}
-//Sets HP to given value. Flag is the flag passed to status->heal in case
-//final value is higher than current (use 2 to make a healing effect display
-//on players) It will always succeed (overrides Berserk block), but it can't kill.
-int status_set_hp(struct block_list *bl, unsigned int hp, int flag)
+/**
+ * Sets HP to the given value.
+ *
+ * @param bl The target unit.
+ * @param hp The desired HP value.
+ * @param flag Additional options. @see enum status_heal_flag. STATUS_HEAL_FORCED is always implied.
+ * @return The amount of HP gained.
+ */
+static int status_set_hp(struct block_list *bl, unsigned int hp, enum status_heal_flag flag)
{
struct status_data *st;
if (hp < 1) return 0;
@@ -1242,14 +1259,19 @@ int status_set_hp(struct block_list *bl, unsigned int hp, int flag)
if (hp > st->max_hp) hp = st->max_hp;
if (hp == st->hp) return 0;
if (hp > st->hp)
- return status->heal(bl, hp - st->hp, 0, 1|flag);
+ return status->heal(bl, hp - st->hp, 0, STATUS_HEAL_FORCED | flag);
return status_zap(bl, st->hp - hp, 0);
}
-//Sets SP to given value. Flag is the flag passed to status->heal in case
-//final value is higher than current (use 2 to make a healing effect display
-//on players)
-int status_set_sp(struct block_list *bl, unsigned int sp, int flag)
+/**
+ * Sets SP to the given value.
+ *
+ * @param bl The target unit.
+ * @param hp The desired SP value.
+ * @param flag Additional options. @see enum status_heal_flag. STATUS_HEAL_FORCED is always implied.
+ * @return The amount of SP gained.
+ */
+static int status_set_sp(struct block_list *bl, unsigned int sp, enum status_heal_flag flag)
{
struct status_data *st;
@@ -1260,11 +1282,11 @@ int status_set_sp(struct block_list *bl, unsigned int sp, int flag)
if (sp > st->max_sp) sp = st->max_sp;
if (sp == st->sp) return 0;
if (sp > st->sp)
- return status->heal(bl, 0, sp - st->sp, 1|flag);
+ return status->heal(bl, 0, sp - st->sp, STATUS_HEAL_FORCED | flag);
return status_zap(bl, 0, st->sp - sp);
}
-int status_charge(struct block_list* bl, int64 hp, int64 sp)
+static int status_charge(struct block_list *bl, int64 hp, int64 sp)
{
nullpo_retr((int)(hp + sp), bl);
if(!(bl->type&BL_CONSUME))
@@ -1277,7 +1299,7 @@ int status_charge(struct block_list* bl, int64 hp, int64 sp)
//If flag&2, fail if target does not has enough to subtract.
//If flag&4, if killed, mob must not give exp/loot.
//flag will be set to &8 when damaging sp of a dead character
-int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, int64 in_sp, int walkdelay, int flag)
+static int status_damage(struct block_list *src, struct block_list *target, int64 in_hp, int64 in_sp, int walkdelay, int flag)
{
struct status_data *st;
struct status_change *sc;
@@ -1292,12 +1314,12 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp,
sp = 0; //Not a valid SP target.
if (hp < 0) { //Assume absorbed damage.
- status->heal(target, -hp, 0, 1);
+ status->heal(target, -hp, 0, STATUS_HEAL_FORCED);
hp = 0;
}
if (sp < 0) {
- status->heal(target, 0, -sp, 1);
+ status->heal(target, 0, -sp, STATUS_HEAL_FORCED);
sp = 0;
}
@@ -1515,9 +1537,16 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp,
return (int)(hp+sp);
}
-//Heals a character. If flag&1, this is forced healing (otherwise stuff like Berserk can block it)
-//If flag&2, when the player is healed, show the HP/SP heal effect.
-int status_heal(struct block_list *bl, int64 in_hp, int64 in_sp, int flag)
+/**
+ * Heals a character.
+ *
+ * @param bl The target unit.
+ * @param in_hp Amount of HP to recover.
+ * @param in_sp Amount of SP to recover.
+ * @param flag Additional options, @see enum status_heal_flag.
+ * @return The amount of HP + SP healed.
+ */
+static int status_heal(struct block_list *bl, int64 in_hp, int64 in_sp, enum status_heal_flag flag)
{
struct status_data *st;
struct status_change *sc;
@@ -1526,7 +1555,9 @@ int status_heal(struct block_list *bl, int64 in_hp, int64 in_sp, int flag)
nullpo_ret(bl);
st = status->get_status_data(bl);
- if (st == &status->dummy || !st->hp)
+ if (st == &status->dummy)
+ return 0;
+ if (st->hp == 0 && (flag & STATUS_HEAL_ALLOWREVIVE) == 0)
return 0;
/* From here onwards, we consider it a 32-type as the client does not support higher and the value doesn't get through percentage modifiers */
@@ -1543,10 +1574,10 @@ int status_heal(struct block_list *bl, int64 in_hp, int64 in_sp, int flag)
hp = 0;
}
- if(hp) {
- if( sc && sc->data[SC_BERSERK] ) {
- if( flag&1 )
- flag &= ~2;
+ if (hp != 0) {
+ if (sc && sc->data[SC_BERSERK] != NULL) {
+ if ((flag & STATUS_HEAL_FORCED) != 0)
+ flag &= ~STATUS_HEAL_SHOWEFFECT;
else
hp = 0;
}
@@ -1581,7 +1612,7 @@ int status_heal(struct block_list *bl, int64 in_hp, int64 in_sp, int flag)
// send hp update to client
switch(bl->type) {
- case BL_PC: pc->heal(BL_UCAST(BL_PC, bl), hp, sp, (flag&2) ? 1 : 0); break;
+ case BL_PC: pc->heal(BL_UCAST(BL_PC, bl), hp, sp, (flag & STATUS_HEAL_SHOWEFFECT) != 0 ? 1 : 0); break;
case BL_MOB: mob->heal(BL_UCAST(BL_MOB, bl), hp); break;
case BL_HOM: homun->healed(BL_UCAST(BL_HOM, bl)); break;
case BL_MER: mercenary->heal(BL_UCAST(BL_MER, bl), hp, sp); break;
@@ -1597,7 +1628,7 @@ int status_heal(struct block_list *bl, int64 in_hp, int64 in_sp, int flag)
//If rates are < 0, percent is of max HP/SP
//If !flag, this is heal, otherwise it is damage.
//Furthermore, if flag==2, then the target must not die from the subtraction.
-int status_percent_change(struct block_list *src, struct block_list *target, signed char hp_rate, signed char sp_rate, int flag)
+static int status_percent_change(struct block_list *src, struct block_list *target, signed char hp_rate, signed char sp_rate, int flag)
{
struct status_data *st;
unsigned int hp = 0, sp = 0;
@@ -1636,21 +1667,21 @@ int status_percent_change(struct block_list *src, struct block_list *target, sig
if (flag)
status->damage(src, target, INT_MAX, 0, 0, (!src||src==target?5:1));
else
- status->heal(target, INT_MAX, 0, 0);
+ status->heal(target, INT_MAX, 0, STATUS_HEAL_DEFAULT);
}
if (sp > INT_MAX) {
sp -= INT_MAX;
if (flag)
status->damage(src, target, 0, INT_MAX, 0, (!src||src==target?5:1));
else
- status->heal(target, 0, INT_MAX, 0);
+ status->heal(target, 0, INT_MAX, STATUS_HEAL_DEFAULT);
}
if (flag)
return status->damage(src, target, hp, sp, 0, (!src||src==target?5:1));
- return status->heal(target, hp, sp, 0);
+ return status->heal(target, hp, sp, STATUS_HEAL_DEFAULT);
}
-int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp)
+static int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp)
{
struct status_data *st;
unsigned int hp, sp;
@@ -1689,7 +1720,7 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per
return 1;
}
-int status_fixed_revive(struct block_list *bl, unsigned int per_hp, unsigned int per_sp)
+static int status_fixed_revive(struct block_list *bl, unsigned int per_hp, unsigned int per_sp)
{
struct status_data *st;
unsigned int hp, sp;
@@ -1727,17 +1758,17 @@ int status_fixed_revive(struct block_list *bl, unsigned int per_hp, unsigned int
}
/*==========================================
-* Checks whether the src can use the skill on the target,
-* taking into account status/option of both source/target. [Skotlex]
-* flag:
-* 0 - Trying to use skill on target.
-* 1 - Cast bar is done.
-* 2 - Skill already pulled off, check is due to ground-based skills or splash-damage ones.
-* src MAY be null to indicate we shouldn't check it, this is a ground-based skill attack.
-* target MAY Be null, in which case the checks are only to see
-* whether the source can cast or not the skill on the ground.
-*------------------------------------------*/
-int status_check_skilluse(struct block_list *src, struct block_list *target, uint16 skill_id, int flag)
+ * Checks whether the src can use the skill on the target,
+ * taking into account status/option of both source/target. [Skotlex]
+ * flag:
+ * 0 - Trying to use skill on target.
+ * 1 - Cast bar is done.
+ * 2 - Skill already pulled off, check is due to ground-based skills or splash-damage ones.
+ * src MAY be null to indicate we shouldn't check it, this is a ground-based skill attack.
+ * target MAY Be null, in which case the checks are only to see
+ * whether the source can cast or not the skill on the ground.
+ *------------------------------------------*/
+static int status_check_skilluse(struct block_list *src, struct block_list *target, uint16 skill_id, int flag)
{
struct status_data *st;
struct status_change *sc=NULL, *tsc;
@@ -1749,6 +1780,9 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
if (src != NULL && src->type != BL_PC && status->isdead(src))
return 0;
+ if (sd != NULL && sd->block_action.skill && skill_id) // *pcblock script command
+ return 0;
+
if (!skill_id) { //Normal attack checks.
if (!(st->mode&MD_CANATTACK))
return 0; //This mode is only needed for melee attacking.
@@ -1768,7 +1802,11 @@ 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->msgtable(sd, MSG_SKILL_CANT_USE_AREA); // This skill cannot be used within this area
+#if PACKETVER >= 20080311
+ clif->skill_mapinfomessage(sd, 2);
+#else
+ clif->messagecolor_self(sd->fd, COLOR_CYAN, msg_sd(sd, 50));
+#endif
} 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 ) )
@@ -2030,7 +2068,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin
//Skotlex: Calculates the initial status for the given mob
//first will only be false when the mob leveled up or got a GuardUp level.
-int status_calc_mob_(struct mob_data *md, enum e_status_calc_opt opt)
+static int status_calc_mob_(struct mob_data *md, enum e_status_calc_opt opt)
{
struct status_data *mstatus;
struct block_list *mbl = NULL;
@@ -2201,7 +2239,7 @@ int status_calc_mob_(struct mob_data *md, enum e_status_calc_opt opt)
}
//Skotlex: Calculates the stats of the given pet.
-int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
+static int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
{
nullpo_ret(pd);
@@ -2263,7 +2301,7 @@ int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
return 1;
}
-unsigned int status_get_base_maxsp(const struct map_session_data *sd, const struct status_data *st)
+static unsigned int status_get_base_maxsp(const struct map_session_data *sd, const struct status_data *st)
{
uint64 val;
@@ -2284,7 +2322,7 @@ unsigned int status_get_base_maxsp(const struct map_session_data *sd, const stru
return (unsigned int)cap_value(val, 0, UINT_MAX);
}
-unsigned int status_get_base_maxhp(const struct map_session_data *sd, const struct status_data *st)
+static unsigned int status_get_base_maxhp(const struct map_session_data *sd, const struct status_data *st)
{
uint64 val;
@@ -2311,20 +2349,77 @@ unsigned int status_get_base_maxhp(const struct map_session_data *sd, const stru
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)
+/**
+ * Calculates the HP that a character will have after death, on respawn.
+ *
+ * @param sd The character to calculate.
+ * @param st The character's status data.
+ */
+static unsigned int status_get_restart_hp(const struct map_session_data *sd, const struct status_data *st)
+{
+ unsigned int hp = 0;
+
+ if (sd->special_state.restart_full_recover)
+ return st->max_hp;
+
+ if ((sd->job & MAPID_BASEMASK) == MAPID_NOVICE && (sd->job & JOBL_2) == 0 && battle_config.restart_hp_rate < 50)
+ hp = st->max_hp / 2;
+ else
+ hp = APPLY_RATE(st->max_hp, battle_config.restart_hp_rate);
+
+ if (hp > 0)
+ return hp;
+
+ return 1;
+}
+
+/**
+ * Calculates the SP that a character will have after death, on respawn.
+ *
+ * @param sd The character to calculate.
+ * @param st The character's status data.
+ */
+static unsigned int status_get_restart_sp(const struct map_session_data *sd, const struct status_data *st)
+{
+ unsigned int sp = 0;
+
+ if (sd->special_state.restart_full_recover)
+ return st->max_sp;
+
+ sp = APPLY_RATE(st->max_sp, battle_config.restart_sp_rate);
+
+ if (sp > 0)
+ return sp;
+
+ return 1; // the minimum for the respawn setting is SP:1
+}
+
+static void status_calc_pc_additional(struct map_session_data *sd, enum e_status_calc_opt opt)
{
/* Just used for Plugin to give bonuses. */
return;
}
+static void status_calc_pc_recover_hp(struct map_session_data *sd, struct status_data *bstatus)
+{
+ nullpo_retv(sd);
+ nullpo_retv(bstatus);
+
+ if ((sd->job & MAPID_BASEMASK) == MAPID_NOVICE && (sd->job & JOBL_2) == 0
+ && battle_config.restart_hp_rate < 50)
+ bstatus->hp = bstatus->max_hp>>1;
+ else
+ bstatus->hp = APPLY_RATE(bstatus->max_hp, battle_config.restart_hp_rate);
+}
+
//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)
+static int status_calc_pc_(struct map_session_data *sd, enum e_status_calc_opt opt)
{
static int calculating = 0; //Check for recursive call preemption. [Skotlex]
struct status_data *bstatus; // pointer to the player's base status
const struct status_change *sc;
- struct s_skill b_skill[MAX_SKILL]; // previous skill tree
+ struct s_skill b_skill[MAX_SKILL_DB]; // previous skill tree
int b_weight, b_max_weight, b_cart_weight_max, // previous weight
i, k, index, skill_lv,refinedef=0;
int64 i64;
@@ -2351,7 +2446,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
sd->regen.sregen = &sd->sregen;
sd->regen.ssregen = &sd->ssregen;
sd->weight=0;
- for(i=0;i<MAX_INVENTORY;i++){
+ for (i = 0; i < sd->status.inventorySize; i++) {
if(sd->status.inventory[i].nameid==0 || sd->inventory_data[i] == NULL)
continue;
sd->weight += sd->inventory_data[i]->weight*sd->status.inventory[i].amount;
@@ -2400,8 +2495,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
bstatus->speed = pSpeed;
}
- //FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex]
- //Give them all modes except these (useful for clones)
+ // FIXME: Most of these stuff should be calculated once, but how do I fix the memset above to do that? [Skotlex]
+ // Give them all modes except these (useful for clones)
bstatus->mode = MD_MASK&~(MD_BOSS|MD_PLANT|MD_DETECTOR|MD_ANGRY|MD_TARGETWEAK);
bstatus->size = ((sd->job & JOBL_BABY) != 0 || (sd->job & MAPID_BASEMASK) == MAPID_SUMMONER)?SZ_SMALL:SZ_MEDIUM;
@@ -2647,6 +2742,45 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
}
}
+ /* parse item options [Smokexyz] */
+ for (i = 0; i < EQI_MAX; i++) {
+ status->current_equip_item_index = index = sd->equip_index[i];
+ status->current_equip_option_index = -1;
+
+ if (i == EQI_HAND_R && sd->equip_index[EQI_HAND_L] == index)
+ continue;
+ else if (i == EQI_HEAD_MID && sd->equip_index[EQI_HEAD_LOW] == index)
+ continue;
+ else if (i == EQI_HEAD_TOP && (sd->equip_index[EQI_HEAD_MID] == index || sd->equip_index[EQI_HEAD_LOW] == index))
+ continue;
+
+ if (index >= 0 && sd->inventory_data[index]) {
+ int j = 0;
+ for (j = 0; j < MAX_ITEM_OPTIONS; j++) {
+ int16 option_index = sd->status.inventory[index].option[j].index;
+ struct itemdb_option *ito = NULL;
+
+ if (option_index == 0 || (ito = itemdb->option_exists(option_index)) == NULL || ito->script == NULL)
+ continue;
+
+ status->current_equip_option_index = j;
+ script->run(ito->script, 0, sd->bl.id, 0);
+
+ if (calculating == 0) //Abort, script->run his function. [Skotlex]
+ return 1;
+ }
+ }
+ }
+
+ status->current_equip_option_index = -1;
+ status->current_equip_item_index = -1;
+
+ // Clan Buffs
+ if (sd->status.clan_id > 0) {
+ struct clan *c = clan->search(sd->status.clan_id);
+ clan->buff_start(sd, c);
+ }
+
status->calc_pc_additional(sd, opt);
if( sd->pd ) { // Pet Bonus
@@ -2675,9 +2809,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
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)
- ) {
+ if ((pc_isridingpeco(sd) || pc_isridingdragon(sd)) && (sd->weapontype == W_1HSPEAR || sd->weapontype == W_2HSPEAR)) {
//When Riding with spear, damage modifier to mid-class becomes
//same as versus large size.
sd->right_weapon.atkmods[1] = sd->right_weapon.atkmods[2];
@@ -2741,8 +2873,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
// Base batk value is set on status->calc_misc
// weapon-type bonus (FIXME: Why is the weapon_atk bonus applied to base attack?)
- if (sd->status.weapon < MAX_SINGLE_WEAPON_TYPE && sd->weapon_atk[sd->status.weapon])
- bstatus->batk += sd->weapon_atk[sd->status.weapon];
+ if (sd->weapontype < MAX_SINGLE_WEAPON_TYPE && sd->weapon_atk[sd->weapontype])
+ bstatus->batk += sd->weapon_atk[sd->weapontype];
// Absolute modifiers from passive skills
#ifndef RENEWAL
if((skill_lv=pc->checkskill(sd,BS_HILTBINDING))>0) // it doesn't work in RE.
@@ -2816,24 +2948,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
// ----- RESPAWN HP/SP -----
//
//Calc respawn hp and store it on base_status
- if (sd->special_state.restart_full_recover)
- {
- bstatus->hp = bstatus->max_hp;
- bstatus->sp = bstatus->max_sp;
- } else {
- if ((sd->job & MAPID_BASEMASK) == MAPID_NOVICE && (sd->job & JOBL_2) == 0
- && battle_config.restart_hp_rate < 50)
- bstatus->hp = bstatus->max_hp>>1;
- else
- bstatus->hp = APPLY_RATE(bstatus->max_hp, battle_config.restart_hp_rate);
- if(!bstatus->hp)
- bstatus->hp = 1;
-
- bstatus->sp = APPLY_RATE(bstatus->max_sp, battle_config.restart_sp_rate);
-
- if( !bstatus->sp ) /* the minimum for the respawn setting is SP:1 */
- bstatus->sp = 1;
- }
+ bstatus->hp = status->get_restart_hp(sd, bstatus);
+ bstatus->sp = status->get_restart_sp(sd, bstatus);
// ----- MISC CALCULATION -----
status->calc_misc(&sd->bl, bstatus, sd->status.base_level);
@@ -2890,10 +3006,10 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
#ifndef RENEWAL
bstatus->hit += skill_lv;
#endif
- if(sd->status.weapon == W_BOW)
+ if (sd->weapontype == W_BOW)
bstatus->rhw.range += skill_lv;
}
- if(sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE) {
+ if (sd->weapontype >= W_REVOLVER && sd->weapontype <= W_GRENADE) {
if((skill_lv=pc->checkskill(sd,GS_SINGLEACTION))>0)
bstatus->hit += 2*skill_lv;
if((skill_lv=pc->checkskill(sd,GS_SNAKEEYE))>0) {
@@ -2901,9 +3017,9 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
bstatus->rhw.range += skill_lv;
}
}
- if( (sd->status.weapon == W_1HAXE || sd->status.weapon == W_2HAXE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0 )
+ if ((sd->weapontype == W_1HAXE || sd->weapontype == 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->weapontype == W_MACE || sd->weapontype == W_2HMACE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0)
bstatus->hit += 2*skill_lv;
if (pc->checkskill(sd, SU_POWEROFLIFE) > 0)
bstatus->hit += 20;
@@ -2963,12 +3079,11 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
// Relative modifiers from passive skills
#ifndef RENEWAL_ASPD
- if((skill_lv=pc->checkskill(sd,SA_ADVANCEDBOOK))>0 && sd->status.weapon == W_BOOK)
+ if (sd->weapontype == W_BOOK && (skill_lv=pc->checkskill(sd,SA_ADVANCEDBOOK)) > 0)
bstatus->aspd_rate -= 5*skill_lv;
if((skill_lv = pc->checkskill(sd,SG_DEVIL)) > 0 && !pc->nextjobexp(sd))
bstatus->aspd_rate -= 30*skill_lv;
- if((skill_lv=pc->checkskill(sd,GS_SINGLEACTION))>0 &&
- (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
+ if (sd->weapontype >= W_REVOLVER && sd->weapontype <= W_GRENADE && (skill_lv=pc->checkskill(sd,GS_SINGLEACTION)) > 0)
bstatus->aspd_rate -= ((skill_lv+1)/2) * 10;
if (pc_isridingpeco(sd))
bstatus->aspd_rate += 500-100*pc->checkskill(sd,KN_CAVALIERMASTERY);
@@ -3223,7 +3338,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt)
return 0;
}
-int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt)
+static int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt)
{
struct status_data *mstatus;
struct s_mercenary *merc;
@@ -3246,7 +3361,7 @@ int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt
return 0;
}
-int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt)
+static int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt)
{
struct status_data *estatus;
struct s_elemental *ele;
@@ -3290,7 +3405,7 @@ int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt
return 0;
}
-int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt)
+static int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt)
{
struct status_data *nstatus;
@@ -3327,7 +3442,7 @@ int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt)
return 0;
}
-int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt)
+static int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt)
{
struct status_data *hstatus;
struct s_homunculus *hom;
@@ -3417,7 +3532,7 @@ int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt)
}
//Calculates base regen values.
-void status_calc_regen(struct block_list *bl, struct status_data *st, struct regen_data *regen)
+static void status_calc_regen(struct block_list *bl, struct status_data *st, struct regen_data *regen)
{
struct map_session_data *sd;
int val, skill_lv, reg_flag;
@@ -3518,7 +3633,7 @@ void status_calc_regen(struct block_list *bl, struct status_data *st, struct reg
}
//Calculates SC related regen rates.
-void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, struct status_change *sc)
+static void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, struct status_change *sc)
{
nullpo_retv(bl);
if (!(bl->type&BL_REGEN) || !regen)
@@ -3642,7 +3757,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
/// Recalculates parts of an object's battle status according to the specified flags.
/// @param flag bitfield of values from enum scb_flag
-void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
+static void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
{
const struct status_data *bst = status->get_base_status(bl);
struct status_data *st = status->get_status_data(bl);
@@ -3858,7 +3973,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
} else {
st->cri = status->calc_critical(bl, sc, bst->cri + 3*(st->luk - bst->luk), true);
}
- if (battle_config.show_katar_crit_bonus && bl->type == BL_PC && BL_UCAST(BL_PC, bl)->status.weapon == W_KATAR) {
+ if (battle_config.show_katar_crit_bonus && bl->type == BL_PC && BL_UCAST(BL_PC, bl)->weapontype == W_KATAR) {
st->cri *= 2;
}
}
@@ -4041,7 +4156,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
/// Also sends updates to the client wherever applicable.
/// @param flag bitfield of values from enum scb_flag
/// @param first if true, will cause status_calc_* functions to run their base status initialization code
-void status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt)
+static void status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt)
{
struct status_data bst; // previous battle status
struct status_data *st; // pointer to current battle status
@@ -4226,7 +4341,7 @@ void status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_ca
}
//Checks whether the source can see and chase target.
-int status_check_visibility(struct block_list *src, struct block_list *target)
+static int status_check_visibility(struct block_list *src, struct block_list *target)
{
int view_range;
struct status_change *tsc = NULL;
@@ -4278,7 +4393,7 @@ int status_check_visibility(struct block_list *src, struct block_list *target)
}
// Basic ASPD value
-int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st)
+static int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st)
{
int amotion;
#ifdef RENEWAL_ASPD /* [malufett/Hercules] */
@@ -4289,11 +4404,11 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st)
nullpo_ret(st);
amotion = status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype1];
- if ( sd->status.weapon > MAX_SINGLE_WEAPON_TYPE)
+ if (sd->weapontype > MAX_SINGLE_WEAPON_TYPE)
amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype2] / 4;
- if ( sd->status.shield )
+ if (sd->has_shield)
amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class)][MAX_SINGLE_WEAPON_TYPE];
- switch ( sd->status.weapon ) {
+ switch (sd->weapontype) {
case W_BOW:
case W_MUSICAL:
case W_WHIP:
@@ -4308,15 +4423,15 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st)
temp = st->dex * st->dex / 5.0f + st->agi * st->agi * 0.5f;
}
temp = (float)(sqrt(temp) * 0.25f) + 0xc4;
- if ( (skill_lv = pc->checkskill(sd, SA_ADVANCEDBOOK)) > 0 && sd->status.weapon == W_BOOK )
+ if (sd->weapontype == W_BOOK && (skill_lv = pc->checkskill(sd, SA_ADVANCEDBOOK)) > 0)
val += (skill_lv - 1) / 2 + 1;
if ( (skill_lv = pc->checkskill(sd, GS_SINGLEACTION)) > 0 )
val += ((skill_lv + 1) / 2);
amotion = ((int)(temp + ((float)(status->calc_aspd(&sd->bl, &sd->sc, 1) + val) * st->agi / 200)) - min(amotion, 200));
#else
// base weapon delay
- amotion = (sd->status.weapon < MAX_SINGLE_WEAPON_TYPE)
- ? (status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->status.weapon]) // single weapon
+ amotion = (sd->weapontype < MAX_SINGLE_WEAPON_TYPE)
+ ? (status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype]) // 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
@@ -4333,7 +4448,7 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st)
return amotion;
}
-unsigned short status_base_atk(const struct block_list *bl, const struct status_data *st)
+static unsigned short status_base_atk(const struct block_list *bl, const struct status_data *st)
{
int flag = 0, str, dex, dstr;
@@ -4343,7 +4458,7 @@ unsigned short status_base_atk(const struct block_list *bl, const struct status_
return 0;
if (bl->type == BL_PC) {
- switch (BL_UCCAST(BL_PC, bl)->status.weapon) {
+ switch (BL_UCCAST(BL_PC, bl)->weapontype) {
case W_BOW:
case W_MUSICAL:
case W_WHIP:
@@ -4393,19 +4508,24 @@ unsigned short status_base_atk(const struct block_list *bl, const struct status_
return cap_value(str, 0, USHRT_MAX);
}
-unsigned short status_base_matk_min(const struct status_data *st)
+static unsigned short status_base_matk_min(const struct status_data *st)
{
nullpo_ret(st);
+#ifdef RENEWAL
+ Assert_ret(0);
+ return 0;
+#else // not RENEWAL
return st->int_ + (st->int_ / 7) * (st->int_ / 7);
+#endif // RENEWAL
}
-unsigned short status_base_matk_max(const struct status_data *st)
+static unsigned short status_base_matk_max(const struct status_data *st)
{
nullpo_ret(st);
return st->int_ + (st->int_ / 5)*(st->int_ / 5);
}
-unsigned short status_base_matk(struct block_list *bl, const struct status_data *st, int level)
+static unsigned short status_base_matk(struct block_list *bl, const struct status_data *st, int level)
{
#ifdef RENEWAL
nullpo_ret(bl);
@@ -4422,12 +4542,13 @@ unsigned short status_base_matk(struct block_list *bl, const struct status_data
return st->int_ + (st->int_ / 2) + (st->dex / 5) + (st->luk / 3) + (level / 4);
}
#else
+ Assert_ret(0);
return 0;
#endif
}
//Fills in the misc data that can be calculated from the other status info (except for level)
-void status_calc_misc(struct block_list *bl, struct status_data *st, int level)
+static void status_calc_misc(struct block_list *bl, struct status_data *st, int level)
{
nullpo_retv(bl);
nullpo_retv(st);
@@ -4509,9 +4630,9 @@ void status_calc_misc(struct block_list *bl, struct status_data *st, int level)
}
/*==========================================
-* Apply shared stat mods from status changes [DracoRPG]
-*------------------------------------------*/
-unsigned short status_calc_str(struct block_list *bl, struct status_change *sc, int str)
+ * Apply shared stat mods from status changes [DracoRPG]
+ *------------------------------------------*/
+static unsigned short status_calc_str(struct block_list *bl, struct status_change *sc, int str)
{
if(!sc || !sc->count)
return cap_value(str,0,USHRT_MAX);
@@ -4574,7 +4695,7 @@ unsigned short status_calc_str(struct block_list *bl, struct status_change *sc,
return (unsigned short)cap_value(str,0,USHRT_MAX);
}
-unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc, int agi)
+static unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc, int agi)
{
if(!sc || !sc->count)
return cap_value(agi,0,USHRT_MAX);
@@ -4637,7 +4758,7 @@ unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc,
return (unsigned short)cap_value(agi,0,USHRT_MAX);
}
-unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc, int vit)
+static unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc, int vit)
{
if(!sc || !sc->count)
return cap_value(vit,0,USHRT_MAX);
@@ -4688,7 +4809,7 @@ unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc,
return (unsigned short)cap_value(vit,0,USHRT_MAX);
}
-unsigned short status_calc_int(struct block_list *bl, struct status_change *sc, int int_)
+static unsigned short status_calc_int(struct block_list *bl, struct status_change *sc, int int_)
{
nullpo_ret(bl);
if(!sc || !sc->count)
@@ -4755,7 +4876,7 @@ unsigned short status_calc_int(struct block_list *bl, struct status_change *sc,
return (unsigned short)cap_value(int_,0,USHRT_MAX);
}
-unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc, int dex)
+static unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc, int dex)
{
nullpo_ret(bl);
if(!sc || !sc->count)
@@ -4818,7 +4939,7 @@ unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc,
return (unsigned short)cap_value(dex,0,USHRT_MAX);
}
-unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc, int luk)
+static unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc, int luk)
{
nullpo_ret(bl);
@@ -4873,7 +4994,7 @@ unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc,
return (unsigned short)cap_value(luk, 0, USHRT_MAX);
}
-unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, int batk, bool viewable)
+static unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, int batk, bool viewable)
{
nullpo_ret(bl);
if(!sc || !sc->count)
@@ -4922,9 +5043,6 @@ unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc,
#ifndef RENEWAL
if(sc->data[SC_LKCONCENTRATION])
batk += batk * sc->data[SC_LKCONCENTRATION]->val2/100;
-#else
- if ( sc->data[SC_NOEQUIPWEAPON] && bl->type != BL_PC )
- batk -= batk * sc->data[SC_NOEQUIPWEAPON]->val2 / 100;
#endif
if(sc->data[SC_SKE])
batk += batk * 3;
@@ -4972,7 +5090,7 @@ unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc,
return (unsigned short)cap_value(batk,0,USHRT_MAX);
}
-unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc, int watk, bool viewable)
+static unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc, int watk, bool viewable)
{
nullpo_ret(bl);
if(!sc || !sc->count)
@@ -5027,7 +5145,7 @@ unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc,
if(sc->data[SC_LKCONCENTRATION])
watk += watk * sc->data[SC_LKCONCENTRATION]->val2/100;
#endif
- if(sc->data[SC_INCATKRATE] && bl->type != BL_MOB)
+ if(sc->data[SC_INCATKRATE])
watk += watk * sc->data[SC_INCATKRATE]->val1/100;
if(sc->data[SC_PROVOKE])
watk += watk * sc->data[SC_PROVOKE]->val3/100;
@@ -5037,10 +5155,8 @@ unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc,
watk += watk * sc->data[SC_HLIF_FLEET]->val3/100;
if(sc->data[SC_CURSE])
watk -= watk * 25/100;
-#ifndef RENEWAL
if(sc->data[SC_NOEQUIPWEAPON] && bl->type != BL_PC)
watk -= watk * sc->data[SC_NOEQUIPWEAPON]->val2/100;
-#endif
if(sc->data[SC__ENERVATION])
watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
if(sc->data[SC_RUSH_WINDMILL])
@@ -5067,7 +5183,7 @@ unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc,
return (unsigned short)cap_value(watk,0,USHRT_MAX);
}
-unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc, int matk)
+static unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc, int matk)
{
#ifdef RENEWAL
if (!sc || !sc->count)
@@ -5098,7 +5214,7 @@ unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc
#endif
}
-unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, int matk, bool viewable)
+static unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, int matk, bool viewable)
{
if (!sc || !sc->count)
return cap_value(matk,0,USHRT_MAX);
@@ -5168,7 +5284,7 @@ unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc,
return (unsigned short)cap_value(matk, 0, USHRT_MAX);
}
-signed short status_calc_critical(struct block_list *bl, struct status_change *sc, int critical, bool viewable)
+static signed short status_calc_critical(struct block_list *bl, struct status_change *sc, int critical, bool viewable)
{
if (!sc || !sc->count)
return cap_value(critical, 10, SHRT_MAX);
@@ -5209,7 +5325,7 @@ signed short status_calc_critical(struct block_list *bl, struct status_change *s
return (short)cap_value(critical, 10, SHRT_MAX);
}
-signed short status_calc_hit(struct block_list *bl, struct status_change *sc, int hit, bool viewable)
+static signed short status_calc_hit(struct block_list *bl, struct status_change *sc, int hit, bool viewable)
{
if (!sc || !sc->count)
@@ -5264,7 +5380,7 @@ signed short status_calc_hit(struct block_list *bl, struct status_change *sc, in
return (short)cap_value(hit, 1, SHRT_MAX);
}
-signed short status_calc_flee(struct block_list *bl, struct status_change *sc, int flee, bool viewable)
+static signed short status_calc_flee(struct block_list *bl, struct status_change *sc, int flee, bool viewable)
{
nullpo_retr(1, bl);
@@ -5361,7 +5477,7 @@ signed short status_calc_flee(struct block_list *bl, struct status_change *sc, i
return (short)cap_value(flee, 1, SHRT_MAX);
}
-signed short status_calc_flee2(struct block_list *bl, struct status_change *sc, int flee2, bool viewable)
+static signed short status_calc_flee2(struct block_list *bl, struct status_change *sc, int flee2, bool viewable)
{
if(!sc || !sc->count)
return cap_value(flee2,10,SHRT_MAX);
@@ -5383,7 +5499,7 @@ signed short status_calc_flee2(struct block_list *bl, struct status_change *sc,
return (short)cap_value(flee2,10,SHRT_MAX);
}
-defType status_calc_def(struct block_list *bl, struct status_change *sc, int def, bool viewable)
+static defType status_calc_def(struct block_list *bl, struct status_change *sc, int def, bool viewable)
{
nullpo_retr(DEFTYPE_MIN, bl);
@@ -5488,7 +5604,7 @@ defType status_calc_def(struct block_list *bl, struct status_change *sc, int def
return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);
}
-signed short status_calc_def2(struct block_list *bl, struct status_change *sc, int def2, bool viewable)
+static signed short status_calc_def2(struct block_list *bl, struct status_change *sc, int def2, bool viewable)
{
nullpo_retr(1, bl);
if(!sc || !sc->count)
@@ -5565,7 +5681,7 @@ 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)
+static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef, bool viewable)
{
if(!sc || !sc->count)
@@ -5622,7 +5738,7 @@ defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int md
return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
}
-signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, int mdef2, bool viewable)
+static signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, int mdef2, bool viewable)
{
if(!sc || !sc->count)
#ifdef RENEWAL
@@ -5661,7 +5777,7 @@ signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc,
#endif
}
-unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc, int speed)
+static unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc, int speed)
{
struct map_session_data *sd = BL_CAST(BL_PC, bl);
int speed_rate = -1;
@@ -5864,7 +5980,7 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc
// flag&1 - fixed value [malufett]
// flag&2 - percentage value
-short status_calc_aspd(struct block_list *bl, struct status_change *sc, short flag)
+static short status_calc_aspd(struct block_list *bl, struct status_change *sc, short flag)
{
#ifdef RENEWAL_ASPD
int pots = 0, bonus = 0;
@@ -5904,7 +6020,7 @@ short status_calc_aspd(struct block_list *bl, struct status_change *sc, short fl
if (bl->type != BL_PC) {
bonus = sc->data[SC_ASSNCROS]->val2;
} else {
- switch (BL_UCCAST(BL_PC, bl)->status.weapon) {
+ switch (BL_UCCAST(BL_PC, bl)->weapontype) {
case W_BOW:
case W_REVOLVER:
case W_RIFLE:
@@ -5996,7 +6112,7 @@ short status_calc_aspd(struct block_list *bl, struct status_change *sc, short fl
#endif
}
-short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int aspd)
+static short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int aspd)
{
nullpo_ret(bl);
if (!sc || !sc->count)
@@ -6016,7 +6132,7 @@ short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int
/// Calculates an object's ASPD modifier (alters the base amotion value).
/// Note that the scale of aspd_rate is 1000 = 100%.
-short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int aspd_rate)
+static short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int aspd_rate)
{
int i;
@@ -6065,7 +6181,7 @@ short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int
if (bl->type != BL_PC) {
max = sc->data[SC_ASSNCROS]->val2;
} else {
- switch (BL_UCCAST(BL_PC, bl)->status.weapon) {
+ switch (BL_UCCAST(BL_PC, bl)->weapontype) {
case W_BOW:
case W_REVOLVER:
case W_RIFLE:
@@ -6159,7 +6275,7 @@ short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int
return (short)cap_value(aspd_rate,0,SHRT_MAX);
}
-unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion)
+static unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion)
{
nullpo_ret(bl);
// It has been confirmed on official servers that MvP mobs have no dmotion even without endure
@@ -6177,7 +6293,7 @@ unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *
return (unsigned short)cap_value(dmotion,0,USHRT_MAX);
}
-unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, uint64 maxhp)
+static unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, uint64 maxhp)
{
if (!sc || !sc->count)
@@ -6257,7 +6373,7 @@ unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc,
return (unsigned int)cap_value(maxhp, 1, UINT_MAX);
}
-unsigned int status_calc_maxsp(struct block_list *bl, struct status_change *sc, unsigned int maxsp)
+static unsigned int status_calc_maxsp(struct block_list *bl, struct status_change *sc, unsigned int maxsp)
{
if (!sc || !sc->count)
return cap_value(maxsp, 1, UINT_MAX);
@@ -6296,7 +6412,7 @@ unsigned int status_calc_maxsp(struct block_list *bl, struct status_change *sc,
return cap_value(maxsp, 1, UINT_MAX);
}
-unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element)
+static unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element)
{
if(!sc || !sc->count)
return element;
@@ -6317,7 +6433,7 @@ unsigned char status_calc_element(struct block_list *bl, struct status_change *s
return (unsigned char)cap_value(element,0,UCHAR_MAX);
}
-unsigned char status_calc_element_lv(struct block_list *bl, struct status_change *sc, int lv)
+static unsigned char status_calc_element_lv(struct block_list *bl, struct status_change *sc, int lv)
{
if(!sc || !sc->count)
return lv;
@@ -6340,7 +6456,7 @@ 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)
+static unsigned char status_calc_attack_element(struct block_list *bl, struct status_change *sc, int element)
{
if(!sc || !sc->count)
return element;
@@ -6381,7 +6497,7 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch
* @param mode The starting mode.
* @return The calculated mode.
*/
-uint32 status_calc_mode(const struct block_list *bl, const struct status_change *sc, uint32 mode)
+static uint32 status_calc_mode(const struct block_list *bl, const struct status_change *sc, uint32 mode)
{
if (sc == NULL || sc->count == 0)
return mode & MD_MASK;
@@ -6402,7 +6518,7 @@ uint32 status_calc_mode(const struct block_list *bl, const struct status_change
* @param bl The requested bl.
* @return The bl's name or NULL if not available.
*/
-const char *status_get_name(const struct block_list *bl)
+static const char *status_get_name(const struct block_list *bl)
{
nullpo_ret(bl);
switch (bl->type) {
@@ -6422,12 +6538,12 @@ const char *status_get_name(const struct block_list *bl)
}
/*==========================================
-* Get the class of the current bl
-* return
-* 0 = fail
-* class_id = success
-*------------------------------------------*/
-int status_get_class(const struct block_list *bl)
+ * Get the class of the current bl
+ * return
+ * 0 = fail
+ * class_id = success
+ *------------------------------------------*/
+static int status_get_class(const struct block_list *bl)
{
nullpo_ret(bl);
switch (bl->type) {
@@ -6442,12 +6558,12 @@ int status_get_class(const struct block_list *bl)
return 0;
}
/*==========================================
-* Get the base level of the current bl
-* return
-* 1 = fail
-* level = success
-*------------------------------------------*/
-int status_get_lv(const struct block_list *bl)
+ * Get the base level of the current bl
+ * return
+ * 1 = fail
+ * level = success
+ *------------------------------------------*/
+static int status_get_lv(const struct block_list *bl)
{
nullpo_ret(bl);
switch (bl->type) {
@@ -6462,7 +6578,7 @@ int status_get_lv(const struct block_list *bl)
return 1;
}
-struct regen_data *status_get_regen_data(struct block_list *bl)
+static struct regen_data *status_get_regen_data(struct block_list *bl)
{
nullpo_retr(NULL, bl);
switch (bl->type) {
@@ -6475,7 +6591,7 @@ struct regen_data *status_get_regen_data(struct block_list *bl)
}
}
-struct status_data *status_get_status_data(struct block_list *bl)
+static struct status_data *status_get_status_data(struct block_list *bl)
{
nullpo_retr(&status->dummy, bl);
@@ -6496,7 +6612,7 @@ struct status_data *status_get_status_data(struct block_list *bl)
}
}
-struct status_data *status_get_base_status(struct block_list *bl)
+static struct status_data *status_get_base_status(struct block_list *bl)
{
nullpo_retr(NULL, bl);
switch (bl->type) {
@@ -6520,7 +6636,7 @@ struct status_data *status_get_base_status(struct block_list *bl)
}
}
-defType status_get_def(struct block_list *bl)
+static defType status_get_def(struct block_list *bl)
{
struct unit_data *ud;
struct status_data *st = status->get_status_data(bl);
@@ -6532,7 +6648,7 @@ defType status_get_def(struct block_list *bl)
return cap_value(def, DEFTYPE_MIN, DEFTYPE_MAX);
}
-unsigned short status_get_speed(struct block_list *bl)
+static unsigned short status_get_speed(struct block_list *bl)
{
nullpo_ret(bl);
if (bl->type == BL_NPC) //Only BL with speed data but no status_data [Skotlex]
@@ -6540,7 +6656,7 @@ unsigned short status_get_speed(struct block_list *bl)
return status->get_status_data(bl)->speed;
}
-int status_get_party_id(const struct block_list *bl)
+static int status_get_party_id(const struct block_list *bl)
{
nullpo_ret(bl);
switch (bl->type) {
@@ -6596,7 +6712,7 @@ int status_get_party_id(const struct block_list *bl)
return 0;
}
-int status_get_guild_id(const struct block_list *bl)
+static int status_get_guild_id(const struct block_list *bl)
{
nullpo_ret(bl);
switch (bl->type) {
@@ -6662,7 +6778,7 @@ int status_get_guild_id(const struct block_list *bl)
return 0;
}
-int status_get_emblem_id(const struct block_list *bl)
+static int status_get_emblem_id(const struct block_list *bl)
{
nullpo_ret(bl);
switch (bl->type) {
@@ -6724,7 +6840,7 @@ int status_get_emblem_id(const struct block_list *bl)
return 0;
}
-int status_get_mexp(const struct block_list *bl)
+static int status_get_mexp(const struct block_list *bl)
{
nullpo_ret(bl);
if (bl->type == BL_MOB)
@@ -6734,7 +6850,7 @@ int status_get_mexp(const struct block_list *bl)
return 0;
}
-int status_get_race2(const struct block_list *bl)
+static int status_get_race2(const struct block_list *bl)
{
nullpo_ret(bl);
if (bl->type == BL_MOB)
@@ -6744,13 +6860,13 @@ int status_get_race2(const struct block_list *bl)
return 0;
}
-int status_isdead(struct block_list *bl)
+static int status_isdead(struct block_list *bl)
{
nullpo_ret(bl);
return status->get_status_data(bl)->hp == 0;
}
-int status_isimmune(struct block_list *bl)
+static int status_isimmune(struct block_list *bl)
{
struct status_change *sc = NULL;
nullpo_ret(bl);
@@ -6767,14 +6883,14 @@ int status_isimmune(struct block_list *bl)
return 0;
}
-struct view_data *status_get_viewdata(struct block_list *bl)
+static struct view_data *status_get_viewdata(struct block_list *bl)
{
nullpo_retr(NULL, bl);
switch (bl->type) {
case BL_PC: return &BL_UCAST(BL_PC, bl)->vd;
case BL_MOB: return BL_UCAST(BL_MOB, bl)->vd;
case BL_PET: return &BL_UCAST(BL_PET, bl)->vd;
- case BL_NPC: return BL_UCAST(BL_NPC, bl)->vd;
+ case BL_NPC: return &BL_UCAST(BL_NPC, bl)->vd;
case BL_HOM: return BL_UCAST(BL_HOM, bl)->vd;
case BL_MER: return BL_UCAST(BL_MER, bl)->vd;
case BL_ELEM: return BL_UCAST(BL_ELEM, bl)->vd;
@@ -6782,7 +6898,7 @@ struct view_data *status_get_viewdata(struct block_list *bl)
return NULL;
}
-void status_set_viewdata(struct block_list *bl, int class_)
+static void status_set_viewdata(struct block_list *bl, int class_)
{
struct view_data* vd;
nullpo_retv(bl);
@@ -6829,34 +6945,31 @@ void status_set_viewdata(struct block_list *bl, int class_)
}
sd->vd.class = class_;
clif->get_weapon_view(sd, &sd->vd.weapon, &sd->vd.shield);
- sd->vd.head_top = sd->status.head_top;
- sd->vd.head_mid = sd->status.head_mid;
- sd->vd.head_bottom = sd->status.head_bottom;
+ sd->vd.head_top = sd->status.look.head_top;
+ sd->vd.head_mid = sd->status.look.head_mid;
+ sd->vd.head_bottom = sd->status.look.head_bottom;
sd->vd.hair_style = cap_value(sd->status.hair,0,battle_config.max_hair_style);
sd->vd.hair_color = cap_value(sd->status.hair_color,0,battle_config.max_hair_color);
sd->vd.cloth_color = cap_value(sd->status.clothes_color,0,battle_config.max_cloth_color);
- sd->vd.robe = sd->status.robe;
+ sd->vd.robe = sd->status.look.robe;
sd->vd.body_style = sd->status.body;
sd->vd.sex = sd->status.sex;
if (sd->vd.cloth_color) {
- if (sd->sc.option&OPTION_WEDDING && battle_config.wedding_ignorepalette)
- sd->vd.cloth_color = 0;
- if (sd->sc.option&OPTION_XMAS && battle_config.xmas_ignorepalette)
- sd->vd.cloth_color = 0;
- if (sd->sc.option&OPTION_SUMMER && battle_config.summer_ignorepalette)
- sd->vd.cloth_color = 0;
- if (sd->sc.option&OPTION_HANBOK && battle_config.hanbok_ignorepalette)
- sd->vd.cloth_color = 0;
- if (sd->sc.option&OPTION_OKTOBERFEST /* TODO: config? */)
+ if ((sd->sc.option & OPTION_WEDDING) != 0 && battle_config.wedding_ignorepalette == true)
+ sd->vd.cloth_color = 0;
+ if ((sd->sc.option & OPTION_XMAS) != 0 && battle_config.xmas_ignorepalette == true)
+ sd->vd.cloth_color = 0;
+ if ((sd->sc.option & OPTION_SUMMER) != 0 && battle_config.summer_ignorepalette == true)
+ sd->vd.cloth_color = 0;
+ if ((sd->sc.option & OPTION_HANBOK) != 0 && battle_config.hanbok_ignorepalette == true)
+ sd->vd.cloth_color = 0;
+ if ((sd->sc.option & OPTION_OKTOBERFEST) != 0 && battle_config.oktoberfest_ignorepalette == true)
+ sd->vd.cloth_color = 0;
+ if ((sd->sc.option & OPTION_SUMMER2) != 0 && battle_config.summer2_ignorepalette == true)
sd->vd.cloth_color = 0;
}
- if (sd->vd.body_style
- && (sd->sc.option&OPTION_WEDDING
- || sd->sc.option&OPTION_XMAS
- || sd->sc.option&OPTION_SUMMER
- || sd->sc.option&OPTION_HANBOK
- || sd->sc.option&OPTION_OKTOBERFEST))
+ if (sd->vd.body_style != 0 && (sd->sc.option & OPTION_COSTUME) != 0)
sd->vd.body_style = 0;
} else if (vd != NULL) {
memcpy(&sd->vd, vd, sizeof(struct view_data));
@@ -6895,10 +7008,14 @@ void status_set_viewdata(struct block_list *bl, int class_)
case BL_NPC:
{
struct npc_data *nd = BL_UCAST(BL_NPC, bl);
- if (vd != NULL)
- nd->vd = vd;
- else
+ if (vd != NULL) {
+ memcpy(&nd->vd, vd, sizeof(struct view_data));
+ } else if (pc->db_checkid(class_)) {
+ memset(&nd->vd, 0, sizeof(struct view_data));
+ nd->vd.class = class_;
+ } else {
ShowError("status_set_viewdata (NPC): No view data for class %d (name=%s)\n", class_, nd->name);
+ }
}
break;
case BL_HOM: //[blackhole89]
@@ -6932,7 +7049,7 @@ void status_set_viewdata(struct block_list *bl, int class_)
}
/// Returns the status_change data of bl or NULL if it doesn't exist.
-struct status_change *status_get_sc(struct block_list *bl)
+static struct status_change *status_get_sc(struct block_list *bl)
{
if (bl != NULL) {
switch (bl->type) {
@@ -6947,7 +7064,7 @@ struct status_change *status_get_sc(struct block_list *bl)
return NULL;
}
-void status_change_init(struct block_list *bl)
+static void status_change_init(struct block_list *bl)
{
struct status_change *sc = status->get_sc(bl);
nullpo_retv(sc);
@@ -6960,7 +7077,7 @@ void status_change_init(struct block_list *bl)
* @see status_change_start for the expected parameters.
* @return the adjusted duration based on flag values.
*/
-int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, int flag)
+static int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int tick, int flag)
{
//Percentual resistance: 10000 = 100% Resist
//Example: 50% -> sc_def=5000 -> 25%; 5000ms -> tick_def=5000 -> 2500ms
@@ -7324,7 +7441,7 @@ int status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_typ
}
/* [Ind/Hercules] fast-checkin sc-display array */
-void status_display_add(struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3)
+static void status_display_add(struct map_session_data *sd, enum sc_type type, int dval1, int dval2, int dval3)
{
struct sc_display_entry *entry;
int i;
@@ -7353,7 +7470,7 @@ void status_display_add(struct map_session_data *sd, enum sc_type type, int dval
sd->sc_display[ sd->sc_display_count - 1 ] = entry;
}
-void status_display_remove(struct map_session_data *sd, enum sc_type type)
+static void status_display_remove(struct map_session_data *sd, enum sc_type type)
{
int i;
@@ -7387,6 +7504,7 @@ void status_display_remove(struct map_session_data *sd, enum sc_type type)
}
}
}
+
/**
* Starts a status change.
*
@@ -7404,7 +7522,7 @@ void status_display_remove(struct map_session_data *sd, enum sc_type type)
* @retval 0 if no status change happened.
* @retval 1 if the status change was successfully applied.
*/
-int status_change_start(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag)
+static int status_change_start(struct block_list *src, struct block_list *bl, enum sc_type type, int rate, int val1, int val2, int val3, int val4, int tick, int flag)
{
struct map_session_data *sd = NULL;
struct status_change* sc;
@@ -7438,73 +7556,8 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
#endif // 0
}
- if( sc->data[SC_REFRESH] ) {
- if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX) // Confirmed.
- return 0; // Immune to status ailements
- switch( type ) {
- case SC_DEEP_SLEEP:
- case SC__CHAOS:
- case SC_BURNING:
- case SC_STUN:
- case SC_SLEEP:
- case SC_CURSE:
- case SC_STONE:
- case SC_POISON:
- case SC_BLIND:
- case SC_SILENCE:
- case SC_BLOODING:
- case SC_FREEZE:
- case SC_FROSTMISTY:
- case SC_COLD:
- case SC_TOXIN:
- case SC_PARALYSE:
- case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
- case SC_DEATHHURT:
- case SC_PYREXIA:
- case SC_OBLIVIONCURSE:
- case SC_MARSHOFABYSS:
- case SC_MANDRAGORA:
- return 0;
- }
- } else if( sc->data[SC_INSPIRATION] ) {
- if( type >= SC_COMMON_MIN && type <= SC_COMMON_MAX )
- return 0; // Immune to status ailements
- switch( type ) {
- case SC_POISON:
- case SC_BLIND:
- case SC_STUN:
- case SC_SILENCE:
- case SC__CHAOS:
- case SC_STONE:
- case SC_SLEEP:
- case SC_BLOODING:
- case SC_CURSE:
- case SC_BURNING:
- case SC_FROSTMISTY:
- case SC_FREEZE:
- case SC_COLD:
- case SC_FEAR:
- case SC_TOXIN:
- case SC_PARALYSE:
- case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
- case SC_DEATHHURT:
- case SC_PYREXIA:
- case SC_OBLIVIONCURSE:
- case SC_LEECHESEND:
- case SC_DEEP_SLEEP:
- case SC_SATURDAY_NIGHT_FEVER:
- case SC__BODYPAINT:
- case SC__ENERVATION:
- case SC__GROOMY:
- case SC__IGNORANCE:
- case SC__LAZINESS:
- case SC__UNLUCKY:
- case SC__WEAKNESS:
- return 0;
- }
- }
+ if (status->is_immune_to_status(sc, type))
+ return 0;
sd = BL_CAST(BL_PC, bl);
@@ -7514,8 +7567,8 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if( !tick ) return 0;
}
- undead_flag = battle->check_undead(st->race,st->def_ele);
- //Check for inmunities / sc fails
+ undead_flag = battle->check_undead(st->race, st->def_ele);
+ // Check for inmunities / sc fails
switch (type) {
case SC_DRUMBATTLE:
case SC_NIBELUNGEN:
@@ -7737,30 +7790,6 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
if (sc->data[SC_FOOD_LUK_CASH] && sc->data[SC_FOOD_LUK_CASH]->val1 > val1)
return 0;
break;
- case SC_FOOD_STR_CASH:
- if (sc->data[SC_FOOD_STR] && sc->data[SC_FOOD_STR]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_AGI_CASH:
- if (sc->data[SC_FOOD_AGI] && sc->data[SC_FOOD_AGI]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_VIT_CASH:
- if (sc->data[SC_FOOD_VIT] && sc->data[SC_FOOD_VIT]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_INT_CASH:
- if (sc->data[SC_FOOD_INT] && sc->data[SC_FOOD_INT]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_DEX_CASH:
- if (sc->data[SC_FOOD_DEX] && sc->data[SC_FOOD_DEX]->val1 > val1)
- return 0;
- break;
- case SC_FOOD_LUK_CASH:
- if (sc->data[SC_FOOD_LUK] && sc->data[SC_FOOD_LUK]->val1 > val1)
- return 0;
- break;
case SC_CAMOUFLAGE:
if( sd && pc->checkskill(sd, RA_CAMOUFLAGE) < 3 && !skill->check_camouflage(bl,NULL) )
return 0;
@@ -7804,310 +7833,14 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
}
//Check for BOSS resistances
- if(st->mode&MD_BOSS && !(flag&SCFLAG_NOAVOID)) {
- if (type>=SC_COMMON_MIN && type <= SC_COMMON_MAX)
+ if (st->mode & MD_BOSS && !(flag & SCFLAG_NOAVOID)) {
+ if (status->is_boss_resist_sc(type))
return 0;
- switch (type) {
- case SC_BLESSING:
- case SC_DEC_AGI:
- case SC_PROVOKE:
- case SC_COMA:
- case SC_GRAVITATION:
- case SC_NJ_SUITON:
- case SC_RICHMANKIM:
- case SC_ROKISWEIL:
- case SC_FOGWALL:
- case SC_FROSTMISTY:
- case SC_BURNING:
- case SC_MARSHOFABYSS:
- case SC_ADORAMUS:
- case SC_NEEDLE_OF_PARALYZE:
- case SC_DEEP_SLEEP:
- case SC_COLD:
-
- // Exploit prevention - kRO Fix
- case SC_PYREXIA:
- case SC_DEATHHURT:
- case SC_TOXIN:
- case SC_PARALYSE:
- case SC_VENOMBLEED:
- case SC_MAGICMUSHROOM:
- case SC_OBLIVIONCURSE:
- case SC_LEECHESEND:
-
- // Ranger Effects
- case SC_WUGBITE:
- case SC_ELECTRICSHOCKER:
- case SC_MAGNETICFIELD:
-
- // Masquerades
- case SC__ENERVATION:
- case SC__GROOMY:
- case SC__LAZINESS:
- case SC__UNLUCKY:
- case SC__WEAKNESS:
- case SC__IGNORANCE:
-
- // Other Effects
- case SC_VACUUM_EXTREME:
- case SC_NETHERWORLD:
- case SC_FRESHSHRIMP:
- case SC_SV_ROOTTWIST:
- case SC_BITESCAR:
- return 0;
- }
}
//Before overlapping fail, one must check for status cured.
- switch (type) {
- case SC_BLESSING:
- //TO-DO Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
- //but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
- if ((!undead_flag && st->race!=RC_DEMON) || bl->type == BL_PC) {
- status_change_end(bl, SC_CURSE, INVALID_TIMER);
- if (sc->data[SC_STONE] && sc->opt1 == OPT1_STONE)
- status_change_end(bl, SC_STONE, INVALID_TIMER);
- }
- if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
- status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
- break;
- case SC_INC_AGI:
- status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
- if(sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
- status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
- break;
- case SC_QUAGMIRE:
- status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
- status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER);
- status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
- FALLTHROUGH
- //Also blocks the ones below...
- case SC_DEC_AGI:
- case SC_ADORAMUS:
- status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
- //Also blocks the ones below...
- FALLTHROUGH
- case SC_DONTFORGETME:
- status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
- status_change_end(bl, SC_ADRENALINE, INVALID_TIMER);
- status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
- status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_ACCELERATION, INVALID_TIMER);
- break;
- case SC_ONEHANDQUICKEN:
- //Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
- status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
- break;
- case SC_OVERTHRUSTMAX:
- //Cancels Normal Overthrust. [Skotlex]
- status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
- break;
- case SC_KYRIE:
- //Cancels Assumptio
- status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
- break;
- case SC_MAGNIFICAT:
- //Cancels Offertorium
- status_change_end(bl, SC_OFFERTORIUM, INVALID_TIMER);
- break;
- case SC_OFFERTORIUM:
- //Cancels Magnificat
- status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
- break;
- case SC_DELUGE:
- if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND])
- status_change_end(bl, SC_BLIND, INVALID_TIMER);
- break;
- case SC_SILENCE:
- if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
- status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
- break;
- case SC_HIDING:
- status_change_end(bl, SC_RG_CCONFINE_M, INVALID_TIMER);
- status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER);
- break;
- case SC_BERSERK:
- if( val3 == SC__BLOODYLUST )
- break;
- if(battle_config.berserk_cancels_buffs) {
- status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
- status_change_end(bl, SC_PARRYING, INVALID_TIMER);
- status_change_end(bl, SC_AURABLADE, INVALID_TIMER);
- status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
- }
- #ifdef RENEWAL
- else {
- status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
- }
- #endif
- break;
- case SC_ASSUMPTIO:
- status_change_end(bl, SC_KYRIE, INVALID_TIMER);
- status_change_end(bl, SC_KAITE, INVALID_TIMER);
- break;
- case SC_KAITE:
- status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
- break;
- case SC_CARTBOOST:
- if (sc->data[SC_DEC_AGI] || sc->data[SC_ADORAMUS]) {
- //Cancel Decrease Agi, but take no further effect [Skotlex]
- status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
- status_change_end(bl, SC_ADORAMUS, INVALID_TIMER);
- return 0;
- }
- break;
- case SC_FUSION:
- status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
- break;
- case SC_GS_ADJUSTMENT:
- status_change_end(bl, SC_GS_MADNESSCANCEL, INVALID_TIMER);
- break;
- case SC_GS_MADNESSCANCEL:
- status_change_end(bl, SC_GS_ADJUSTMENT, INVALID_TIMER);
- break;
- //NPC_CHANGEUNDEAD will debuff Blessing and Agi Up
- case SC_PROPERTYUNDEAD:
- status_change_end(bl, SC_BLESSING, INVALID_TIMER);
- status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
- break;
- case SC_FOOD_STR:
- status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_AGI:
- status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_VIT:
- status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_INT:
- status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_DEX:
- status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_LUK:
- status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER);
- break;
- case SC_FOOD_STR_CASH:
- status_change_end(bl, SC_FOOD_STR, INVALID_TIMER);
- break;
- case SC_FOOD_AGI_CASH:
- status_change_end(bl, SC_FOOD_AGI, INVALID_TIMER);
- break;
- case SC_FOOD_VIT_CASH:
- status_change_end(bl, SC_FOOD_VIT, INVALID_TIMER);
- break;
- case SC_FOOD_INT_CASH:
- status_change_end(bl, SC_FOOD_INT, INVALID_TIMER);
- break;
- case SC_FOOD_DEX_CASH:
- status_change_end(bl, SC_FOOD_DEX, INVALID_TIMER);
- break;
- case SC_FOOD_LUK_CASH:
- status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER);
- break;
- case SC_GM_BATTLE:
- status_change_end(bl, SC_GM_BATTLE2, INVALID_TIMER);
- break;
- case SC_GM_BATTLE2:
- status_change_end(bl, SC_GM_BATTLE, INVALID_TIMER);
- break;
- case SC_ENDURE:
- if( val4 == 1 )
- status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
- break;
- case SC_FIGHTINGSPIRIT:
- case SC_OVERED_BOOST:
- status_change_end(bl, type, INVALID_TIMER); // Remove previous one.
- break;
- case SC_MARSHOFABYSS:
- status_change_end(bl, SC_INCAGI, INVALID_TIMER);
- status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
- status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
- break;
- //Group A Status (doesn't overlap)
- case SC_SWING:
- case SC_SYMPHONY_LOVE:
- case SC_MOONLIT_SERENADE:
- case SC_RUSH_WINDMILL:
- case SC_ECHOSONG:
- case SC_HARMONIZE:
- case SC_FRIGG_SONG:
- if (type != SC_SWING) status_change_end(bl, SC_SWING, INVALID_TIMER);
- if (type != SC_SYMPHONY_LOVE) status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER);
- if (type != SC_MOONLIT_SERENADE) status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER);
- if (type != SC_RUSH_WINDMILL) status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER);
- if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
- if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
- if (type != SC_FRIGG_SONG) status_change_end(bl, SC_FRIGG_SONG, INVALID_TIMER);
- break;
- //Group B Status
- case SC_SIREN:
- case SC_DEEP_SLEEP:
- case SC_SIRCLEOFNATURE:
- case SC_LERADS_DEW:
- case SC_MELODYOFSINK:
- case SC_BEYOND_OF_WARCRY:
- case SC_UNLIMITED_HUMMING_VOICE:
- case SC_GLOOMYDAY:
- case SC_SONG_OF_MANA:
- case SC_DANCE_WITH_WUG:
- if (type != SC_SIREN) status_change_end(bl, SC_SIREN, INVALID_TIMER);
- if (type != SC_DEEP_SLEEP) status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER);
- if (type != SC_SIRCLEOFNATURE) status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER);
- if (type != SC_LERADS_DEW) status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER);
- if (type != SC_MELODYOFSINK) status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
- if (type != SC_BEYOND_OF_WARCRY) status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER);
- if (type != SC_UNLIMITED_HUMMING_VOICE) status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER);
- if (type != SC_GLOOMYDAY) status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
- if (type != SC_SONG_OF_MANA) status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER);
- if (type != SC_DANCE_WITH_WUG) status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER);
- break;
- case SC_REFLECTSHIELD:
- status_change_end(bl, SC_LG_REFLECTDAMAGE, INVALID_TIMER);
- break;
- case SC_LG_REFLECTDAMAGE:
- status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
- break;
- case SC_SHIELDSPELL_DEF:
- case SC_SHIELDSPELL_MDEF:
- case SC_SHIELDSPELL_REF:
- status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
- status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER);
- status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER);
- status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
- break;
- case SC_GENTLETOUCH_ENERGYGAIN:
- case SC_GENTLETOUCH_CHANGE:
- case SC_GENTLETOUCH_REVITALIZE:
- if( type != SC_GENTLETOUCH_REVITALIZE )
- status_change_end(bl, SC_GENTLETOUCH_REVITALIZE, INVALID_TIMER);
- if( type != SC_GENTLETOUCH_ENERGYGAIN )
- status_change_end(bl, SC_GENTLETOUCH_ENERGYGAIN, INVALID_TIMER);
- if( type != SC_GENTLETOUCH_CHANGE )
- status_change_end(bl, SC_GENTLETOUCH_CHANGE, INVALID_TIMER);
- break;
- case SC_INVINCIBLE:
- status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER);
- break;
- case SC_INVINCIBLEOFF:
- status_change_end(bl, SC_INVINCIBLE, INVALID_TIMER);
- break;
- case SC_MAGICPOWER:
- status_change_end(bl, type, INVALID_TIMER);
- break;
- }
+ if (status->end_sc_before_start(bl, st, sc, type, undead_flag, val1, val2, val3, val4))
+ return 0;
//Check for overlapping fails
if( (sce = sc->data[type]) ) {
@@ -8463,8 +8196,10 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_SUMMER:
case SC_HANBOK:
case SC_OKTOBERFEST:
- if (!vd) return 0;
- //Store previous values as they could be removed.
+ case SC_DRESS_UP:
+ if (vd == NULL)
+ return 0;
+ // Store previous values as they could be removed.
unit->stop_attack(bl);
break;
case SC_NOCHAT:
@@ -8599,6 +8334,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_TURNKICK_READY:
case SC_DODGE_READY:
case SC_PUSH_CART:
+ case SC_DAILYSENDMAILCNT:
tick = INFINITE_DURATION;
break;
@@ -9729,10 +9465,10 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
return 0;
PER( 100 / (status_get_max_hp(bl) / hp), lv );
- status->heal(bl, (!(hp%2) ? (6-lv) *4 / 100 : -(lv*4) / 100), 0, 1);
+ status->heal(bl, (!(hp%2) ? (6-lv) *4 / 100 : -(lv*4) / 100), 0, STATUS_HEAL_FORCED);
PER( 100 / (status_get_max_sp(bl) / sp), lv );
- status->heal(bl, 0,(!(sp%2) ? (6-lv) *3 / 100 : -(lv*3) / 100), 1);
+ status->heal(bl, 0,(!(sp%2) ? (6-lv) *3 / 100 : -(lv*3) / 100), STATUS_HEAL_FORCED);
}
#undef PER
break;
@@ -9853,25 +9589,25 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val3 = 25 * val1; // Move speed reduction
break;
default:
- 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);
+ if (status->change_start_unknown_sc(src, bl, type, calc_flag, rate, val1, val2, val3, val4, tick, flag)) {
return 0;
}
}
- } else { //Special considerations when loading SC data.
- switch( type ) {
+ } else { // Special considerations when loading SC data.
+ switch (type) {
case SC_WEDDING:
case SC_XMAS:
case SC_SUMMER:
case SC_HANBOK:
case SC_OKTOBERFEST:
- if( !vd ) break;
+ case SC_DRESS_UP:
+ if (vd == NULL)
+ break;
clif->changelook(bl, LOOK_BASE, vd->class);
- clif->changelook(bl,LOOK_WEAPON,0);
- clif->changelook(bl,LOOK_SHIELD,0);
- clif->changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
- clif->changelook(bl,LOOK_BODY2,0);
+ clif->changelook(bl, LOOK_WEAPON, 0);
+ clif->changelook(bl, LOOK_SHIELD, 0);
+ clif->changelook(bl, LOOK_CLOTHES_COLOR, vd->cloth_color);
+ clif->changelook(bl, LOOK_BODY2, 0);
break;
case SC_KAAHI:
val4 = INVALID_TIMER;
@@ -9880,27 +9616,247 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
}
/* values that must be set regardless of SCFLAG_LOADED e.g. val_flag */
- switch(type) {
+ val_flag = status->get_val_flag(type);
+
+ /* [Ind/Hercules] */
+ status->change_start_display(sd, type, val1, val2, val3, val4);
+
+ //Those that make you stop attacking/walking....
+ status->change_start_stop_action(bl, type);
+
+ // Set option as needed.
+ opt_flag = status->change_start_set_option(bl, sc, type, val1, val2, val3, val4);
+
+ //On Aegis, when turning on a status change, first goes the option packet, then the sc packet.
+ if(opt_flag) {
+ clif->changeoption(bl);
+ if( sd && opt_flag&0x4 ) {
+ if (vd)
+ clif->changelook(bl, LOOK_BASE, vd->class);
+ clif->changelook(bl,LOOK_WEAPON,0);
+ clif->changelook(bl,LOOK_SHIELD,0);
+ if (vd)
+ clif->changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
+ }
+ }
+ if (calc_flag&SCB_DYE) {
+ //Reset DYE color
+ if (vd && vd->cloth_color) {
+ val4 = vd->cloth_color;
+ clif->changelook(bl,LOOK_CLOTHES_COLOR,0);
+ }
+ calc_flag&=~SCB_DYE;
+ }
+
+#if 0 //Currently No SC's use this
+ if (calc_flag&SCB_BODY) {
+ //Reset Body Style
+ if (vd && vd->body_style) {
+ val4 = vd->body_style;
+ clif->changelook(bl,LOOK_BODY2,0);
+ }
+ calc_flag&=~SCB_BODY;
+ }
+#endif
+
+ 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.
+ **/
+ if( tick_time )
+ tick = tick_time;
+
+ //Don't trust the previous sce assignment, in case the SC ended somewhere between there and here.
+ if((sce=sc->data[type])) {// reuse old sc
+ if( sce->timer != INVALID_TIMER )
+ timer->delete(sce->timer, status->change_timer);
+ } else {// new sc
+ ++(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;
+ } else {
+ sce->timer = INVALID_TIMER; //Infinite duration
+ sce->infinite_duration = true;
+ if( sd )
+ chrif->save_scdata_single(sd->status.account_id,sd->status.char_id,type,sce);
+ }
+
+ if (calc_flag)
+ status_calc_bl(bl,calc_flag);
+
+ if(sd && sd->pd)
+ pet->sc_check(sd, type); //Skotlex: Pet Status Effect Healing
+
+ switch (type) {
+ case SC_BERSERK:
+ if (!(sce->val2)) { //don't heal if already set
+ status->heal(bl, st->max_hp, 0, STATUS_HEAL_FORCED); //Do not use percent_heal as this healing must override BERSERK's block.
+ status->set_sp(bl, 0, STATUS_HEAL_DEFAULT); //Damage all SP
+ }
+ sce->val2 = 5 * st->max_hp / 100;
+ break;
+ case SC_HLIF_CHANGE:
+ status_percent_heal(bl, 100, 100);
+ break;
+ case SC_RUN:
+ {
+ struct unit_data *ud = unit->bl2ud(bl);
+ if( ud )
+ ud->state.running = unit->run(bl, NULL, SC_RUN);
+ }
+ break;
+ case SC_CASH_BOSS_ALARM:
+ if( sd )
+ clif->bossmapinfo(sd->fd, map->id2boss(sce->val1), 0); // First Message
+ break;
+ case SC_MER_HP:
+ status_percent_heal(bl, 100, 0); // Recover Full HP
+ break;
+ case SC_MER_SP:
+ status_percent_heal(bl, 0, 100); // Recover Full SP
+ break;
+ case SC_PROMOTE_HEALTH_RESERCH:
+ status_percent_heal(bl, sce->val4, 0);
+ break;
+ case SC_ENERGY_DRINK_RESERCH:
+ status_percent_heal(bl, 0, sce->val4);
+ break;
+ /**
+ * Ranger
+ **/
+ case SC_WUGDASH:
+ {
+ struct unit_data *ud = unit->bl2ud(bl);
+ if( ud )
+ ud->state.running = unit->run(bl, sd, SC_WUGDASH);
+ }
+ break;
+ case SC_COMBOATTACK:
+ switch (sce->val1) {
+ case TK_STORMKICK:
+ clif->skill_nodamage(bl,bl,TK_READYSTORM,1,1);
+ break;
+ case TK_DOWNKICK:
+ clif->skill_nodamage(bl,bl,TK_READYDOWN,1,1);
+ break;
+ case TK_TURNKICK:
+ clif->skill_nodamage(bl,bl,TK_READYTURN,1,1);
+ break;
+ case TK_COUNTER:
+ clif->skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
+ break;
+ case MO_COMBOFINISH:
+ case CH_TIGERFIST:
+ case CH_CHAINCRUSH:
+ if (sd)
+ clif->skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL);
+ break;
+ case TK_JUMPKICK:
+ if (sd)
+ clif->skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL);
+ break;
+ case MO_TRIPLEATTACK:
+ if (sd && pc->checkskill(sd, SR_DRAGONCOMBO) > 0)
+ clif->skillinfo(sd,SR_DRAGONCOMBO, INF_SELF_SKILL);
+ break;
+ case SR_FALLENEMPIRE:
+ if (sd){
+ clif->skillinfo(sd,SR_GATEOFHELL, INF_SELF_SKILL);
+ clif->skillinfo(sd,SR_TIGERCANNON, INF_SELF_SKILL);
+ }
+ break;
+ }
+ break;
+ case SC_RAISINGDRAGON:
+ sce->val2 = st->max_hp / 100;// Officially tested its 1%hp drain. [Jobbie]
+ break;
+ }
+
+ if( opt_flag&2 && sd && sd->touching_id )
+ npc->touchnext_areanpc(sd,false); // run OnTouch_ on next char in range
+
+ return 1;
+}
+
+static bool status_change_start_unknown_sc(struct block_list *src, struct block_list *bl, enum sc_type type, int calc_flag, int rate, int val1, int val2, int val3, int val4, int tick, int flag)
+{
+ Assert_retr(false, type >= SC_NONE && type < SC_MAX);
+ 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 true;
+ }
+ return false;
+}
+
+static void status_change_start_display(struct map_session_data *sd, enum sc_type type, int val1, int val2, int val3, int val4)
+{
+ Assert_retv(type >= SC_NONE && type < SC_MAX);
+
+ if (sd && status->dbs->DisplayType[type]) {
+ int dval1 = 0, dval2 = 0, dval3 = 0;
+ switch (type) {
+ case SC_ALL_RIDING:
+ dval1 = 1;
+ break;
+ case SC_CLAN_INFO:
+ dval1 = val1;
+ dval2 = val2;
+ dval3 = val3;
+ break;
+ default: /* all others: just copy val1 */
+ dval1 = val1;
+ break;
+ }
+ status->display_add(sd, type, dval1, dval2, dval3);
+ }
+}
+
+/**
+ * Return val_flag based on sc type.
+ *
+ * @param type Status change type.
+ *
+ * @retval val_flag.
+ */
+static int status_get_val_flag(enum sc_type type)
+{
+ int val_flag = 0;
+ switch (type) {
+ case SC_CLAN_INFO:
+ val_flag |= 1 | 2;
+ break;
case SC_FIGHTINGSPIRIT:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_VENOMIMPRESS:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_POISONINGWEAPON:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_WEAPONBLOCKING:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_ROLLINGCUTTER:
val_flag |= 1;
break;
case SC_CLOAKINGEXCEED:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_HALLUCINATIONWALK:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_SUMMON1:
case SC_SUMMON2:
@@ -9910,34 +9866,34 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
val_flag |= 1;
break;
case SC__SHADOWFORM:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC__INVISIBILITY:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC__ENERVATION:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC__GROOMY:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC__LAZINESS:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC__UNLUCKY:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC__WEAKNESS:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_PROPERTYWALK:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_FORCEOFVANGUARD:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_PRESTIGE:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_BANDING:
val_flag |= 1;
@@ -9945,56 +9901,56 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_SHIELDSPELL_DEF:
case SC_SHIELDSPELL_MDEF:
case SC_SHIELDSPELL_REF:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_SPELLFIST:
case SC_CURSEDCIRCLE_ATKER:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_CRESCENTELBOW:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_LIGHTNINGWALK:
val_flag |= 1;
break;
case SC_PYROTECHNIC_OPTION:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_HEATER_OPTION:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_AQUAPLAY_OPTION:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_COOLER_OPTION:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_CHILLY_AIR_OPTION:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_GUST_OPTION:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_BLAST_OPTION:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_WILD_STORM_OPTION:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_PETROLOGY_OPTION:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_CURSED_SOIL_OPTION:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_UPHEAVAL_OPTION:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_CIRCLE_OF_FIRE_OPTION:
- val_flag |= 1|2;
+ val_flag |= 1 | 2;
break;
case SC_WATER_BARRIER:
- val_flag |= 1|2|4;
+ val_flag |= 1 | 2 | 4;
break;
case SC_KYOUGAKU:
val_flag |= 1;
@@ -10006,91 +9962,33 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
case SC_OVERLAPEXPUP:
val_flag |= 1;
break;
+ case SC_DAILYSENDMAILCNT:
+ val_flag |= 1 | 2;
+ break;
}
+ return val_flag;
+}
- /* [Ind/Hercules] */
- if( sd && status->dbs->DisplayType[type] ) {
- int dval1 = 0, dval2 = 0, dval3 = 0;
- switch( type ) {
- case SC_ALL_RIDING:
- dval1 = 1;
- break;
- default: /* all others: just copy val1 */
- dval1 = val1;
- break;
- }
- status->display_add(sd,type,dval1,dval2,dval3);
- }
+/**
+ * Set new status values.
+ *
+ * @param bl Status change target bl.
+ * @param sc Current statuses.
+ * @param type Status change type.
+ * @param val1 Additional value (meaning depends on type).
+ * @param val2 Additional value (meaning depends on type).
+ * @param val3 Additional value (meaning depends on type).
+ * @param val4 Additional value (meaning depends on type).
+ *
+ * @retval option flag.
+ */
+static int status_change_start_set_option(struct block_list *bl, struct status_change *sc, enum sc_type type, int val1, int val2, int val3, int val4)
+{
+ int opt_flag = 1;
- //Those that make you stop attacking/walking....
+ nullpo_retr(true, bl);
+ nullpo_retr(true, sc);
switch (type) {
- case SC_VACUUM_EXTREME:
- if(!map_flag_gvg(bl->m))
- unit->stop_walking(bl,1);
- break;
- case SC_FREEZE:
- case SC_STUN:
- case SC_SLEEP:
- case SC_STONE:
- case SC_DEEP_SLEEP:
- if (sd && pc_issit(sd)) //Avoid sprite sync problems.
- pc->setstand(sd);
- FALLTHROUGH
- case SC_TRICKDEAD:
- status_change_end(bl, SC_DANCING, INVALID_TIMER);
- // Cancel cast when get status [LuzZza]
- if (battle_config.sc_castcancel&bl->type)
- unit->skillcastcancel(bl, 0);
- FALLTHROUGH
- case SC_FALLENEMPIRE:
- case SC_WHITEIMPRISON:
- unit->stop_attack(bl);
- FALLTHROUGH
- case SC_STOP:
- case SC_CONFUSION:
- case SC_RG_CCONFINE_M:
- case SC_RG_CCONFINE_S:
- case SC_SPIDERWEB:
- case SC_ELECTRICSHOCKER:
- case SC_WUGBITE:
- case SC_THORNS_TRAP:
- case SC__MANHOLE:
- case SC__CHAOS:
- case SC_COLD:
- case SC_CURSEDCIRCLE_ATKER:
- case SC_CURSEDCIRCLE_TARGET:
- case SC_FEAR:
- case SC_MEIKYOUSISUI:
- case SC_NEEDLE_OF_PARALYZE:
- case SC_DEATHBOUND:
- case SC_NETHERWORLD:
- case SC_SV_ROOTTWIST:
- 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, STOPWALKING_FLAG_FIXPOS);
- break;
- case SC_HIDING:
- case SC_CLOAKING:
- case SC_CLOAKINGEXCEED:
- case SC_CHASEWALK:
- case SC_WEIGHTOVER90:
- case SC_CAMOUFLAGE:
- case SC_SIREN:
- case SC_ALL_RIDING:
- case SC_SUHIDE:
- unit->stop_attack(bl);
- break;
- case SC_SILENCE:
- if (battle_config.sc_castcancel&bl->type)
- unit->skillcastcancel(bl, 0);
- break;
- }
-
- // Set option as needed.
- opt_flag = 1;
- switch(type) {
//OPT1
case SC_STONE: sc->opt1 = OPT1_STONEWAIT; break;
case SC_FREEZE: sc->opt1 = OPT1_FREEZE; break;
@@ -10168,7 +10066,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
break;
#endif // 0
case SC_DANCING:
- if ((val1&0xFFFF) == CG_MOONLIT)
+ if ((val1 & 0xFFFF) == CG_MOONLIT)
sc->opt3 |= OPT3_MOONLIT;
opt_flag = 0;
break;
@@ -10254,6 +10152,10 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
sc->option |= OPTION_OKTOBERFEST;
opt_flag |= 0x4;
break;
+ case SC_DRESS_UP:
+ sc->option |= OPTION_SUMMER2;
+ opt_flag |= 0x4;
+ break;
case SC__FEINTBOMB_MASTER:
sc->option |= OPTION_INVISIBLE;
opt_flag |= 0x4;
@@ -10261,179 +10163,508 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t
default:
opt_flag = 0;
}
+ return opt_flag;
+}
- //On Aegis, when turning on a status change, first goes the option packet, then the sc packet.
- if(opt_flag) {
- clif->changeoption(bl);
- if( sd && opt_flag&0x4 ) {
- if (vd)
- clif->changelook(bl, LOOK_BASE, vd->class);
- clif->changelook(bl,LOOK_WEAPON,0);
- clif->changelook(bl,LOOK_SHIELD,0);
- if (vd)
- clif->changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color);
- }
- }
- if (calc_flag&SCB_DYE) {
- //Reset DYE color
- if (vd && vd->cloth_color) {
- val4 = vd->cloth_color;
- clif->changelook(bl,LOOK_CLOTHES_COLOR,0);
- }
- calc_flag&=~SCB_DYE;
- }
-
-#if 0 //Currently No SC's use this
- if (calc_flag&SCB_BODY) {
- //Reset Body Style
- if (vd && vd->body_style) {
- val4 = vd->body_style;
- clif->changelook(bl,LOOK_BODY2,0);
+/**
+ * Stop actions before start new sc.
+ *
+ * @param bl Status change target bl.
+ * @param type Status change type.
+ */
+static void status_change_start_stop_action(struct block_list *bl, enum sc_type type)
+{
+ nullpo_retv(bl);
+ switch (type) {
+ case SC_VACUUM_EXTREME:
+ if (!map_flag_gvg(bl->m))
+ unit->stop_walking(bl,1);
+ break;
+ case SC_FREEZE:
+ case SC_STUN:
+ case SC_SLEEP:
+ case SC_STONE:
+ case SC_DEEP_SLEEP: {
+ struct map_session_data *sd = BL_CAST(BL_PC, bl);
+ if (sd && pc_issit(sd)) //Avoid sprite sync problems.
+ pc->setstand(sd);
+ FALLTHROUGH
}
- calc_flag&=~SCB_BODY;
- }
-#endif
-
- 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.
- **/
- if( tick_time )
- tick = tick_time;
-
- //Don't trust the previous sce assignment, in case the SC ended somewhere between there and here.
- if((sce=sc->data[type])) {// reuse old sc
- if( sce->timer != INVALID_TIMER )
- timer->delete(sce->timer, status->change_timer);
- } else {// new sc
- ++(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;
- } else {
- sce->timer = INVALID_TIMER; //Infinite duration
- sce->infinite_duration = true;
- if( sd )
- chrif->save_scdata_single(sd->status.account_id,sd->status.char_id,type,sce);
+ case SC_TRICKDEAD:
+ status_change_end(bl, SC_DANCING, INVALID_TIMER);
+ // Cancel cast when get status [LuzZza]
+ if (battle_config.sc_castcancel&bl->type)
+ unit->skillcastcancel(bl, 0);
+ FALLTHROUGH
+ case SC_FALLENEMPIRE:
+ case SC_WHITEIMPRISON:
+ unit->stop_attack(bl);
+ FALLTHROUGH
+ case SC_STOP:
+ case SC_CONFUSION:
+ case SC_RG_CCONFINE_M:
+ case SC_RG_CCONFINE_S:
+ case SC_SPIDERWEB:
+ case SC_ELECTRICSHOCKER:
+ case SC_WUGBITE:
+ case SC_THORNS_TRAP:
+ case SC__MANHOLE:
+ case SC__CHAOS:
+ case SC_COLD:
+ case SC_CURSEDCIRCLE_ATKER:
+ case SC_CURSEDCIRCLE_TARGET:
+ case SC_FEAR:
+ case SC_MEIKYOUSISUI:
+ case SC_NEEDLE_OF_PARALYZE:
+ case SC_DEATHBOUND:
+ case SC_NETHERWORLD:
+ case SC_SV_ROOTTWIST:
+ 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, STOPWALKING_FLAG_FIXPOS);
+ break;
+ case SC_HIDING:
+ case SC_CLOAKING:
+ case SC_CLOAKINGEXCEED:
+ case SC_CHASEWALK:
+ case SC_WEIGHTOVER90:
+ case SC_CAMOUFLAGE:
+ case SC_SIREN:
+ case SC_ALL_RIDING:
+ case SC_SUHIDE:
+ unit->stop_attack(bl);
+ break;
+ case SC_SILENCE:
+ if (battle_config.sc_castcancel & bl->type)
+ unit->skillcastcancel(bl, 0);
+ break;
}
+}
- if (calc_flag)
- status_calc_bl(bl,calc_flag);
-
- if(sd && sd->pd)
- pet->sc_check(sd, type); //Skotlex: Pet Status Effect Healing
+/**
+ * End sc before starting other sc.
+ *
+ * @param bl Status change target bl.
+ * @param st Status change data.
+ * @param sc Current statuses.
+ * @param type Status change type.
+ * @param undead_flag is bl undead.
+ * @param val1 Additional value (meaning depends on type).
+ * @param val2 Additional value (meaning depends on type).
+ * @param val3 Additional value (meaning depends on type).
+ * @param val4 Additional value (meaning depends on type).
+ *
+ * @retval false if no status change happened, or the other sc can be started regardless.
+ * @retval true if the status change was successfully applied and the other sc shouldn't be started.
+ */
+static bool status_end_sc_before_start(struct block_list *bl, struct status_data *st, struct status_change *sc, enum sc_type type, int undead_flag, int val1, int val2, int val3, int val4)
+{
+ nullpo_retr(true, bl);
+ nullpo_retr(true, st);
+ nullpo_retr(true, sc);
switch (type) {
- case SC_BERSERK:
- if (!(sce->val2)) { //don't heal if already set
- status->heal(bl, st->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
- status->set_sp(bl, 0, 0); //Damage all SP
+ case SC_BLESSING:
+ // TODO: Blessing and Agi up should do 1 damage against players on Undead Status, even on PvM
+ // but cannot be plagiarized (this requires aegis investigation on packets and official behavior) [Brainstorm]
+ if ((undead_flag == 0 && st->race != RC_DEMON) || bl->type == BL_PC) {
+ bool prevent_start = false;
+ if (sc->data[SC_CURSE] != NULL) {
+ prevent_start = true;
+ status_change_end(bl, SC_CURSE, INVALID_TIMER);
+ }
+ if (sc->data[SC_STONE] != NULL && sc->opt1 == OPT1_STONE) {
+ prevent_start = true;
+ status_change_end(bl, SC_STONE, INVALID_TIMER);
+ }
+ if (prevent_start)
+ return true;
}
- sce->val2 = 5 * st->max_hp / 100;
+ if (sc->data[SC_SOULLINK] != NULL && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
+ status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
break;
- case SC_HLIF_CHANGE:
- status_percent_heal(bl, 100, 100);
+ case SC_INC_AGI:
+ status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
+ if (sc->data[SC_SOULLINK] && sc->data[SC_SOULLINK]->val2 == SL_HIGH)
+ status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
break;
- case SC_RUN:
- {
- struct unit_data *ud = unit->bl2ud(bl);
- if( ud )
- ud->state.running = unit->run(bl, NULL, SC_RUN);
- }
+ case SC_QUAGMIRE:
+ status_change_end(bl, SC_CONCENTRATION, INVALID_TIMER);
+ status_change_end(bl, SC_TRUESIGHT, INVALID_TIMER);
+ status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
+ FALLTHROUGH
+ //Also blocks the ones below...
+ case SC_DEC_AGI:
+ case SC_ADORAMUS:
+ status_change_end(bl, SC_CARTBOOST, INVALID_TIMER);
+ //Also blocks the ones below...
+ FALLTHROUGH
+ case SC_DONTFORGETME:
+ status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
+ status_change_end(bl, SC_ADRENALINE, INVALID_TIMER);
+ status_change_end(bl, SC_ADRENALINE2, INVALID_TIMER);
+ status_change_end(bl, SC_SPEARQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_ACCELERATION, INVALID_TIMER);
break;
- case SC_CASH_BOSS_ALARM:
- if( sd )
- clif->bossmapinfo(sd->fd, map->id2boss(sce->val1), 0); // First Message
+ case SC_ONEHANDQUICKEN:
+ //Removes the Aspd potion effect, as reported by Vicious. [Skotlex]
+ status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
break;
- case SC_MER_HP:
- status_percent_heal(bl, 100, 0); // Recover Full HP
+ case SC_OVERTHRUSTMAX:
+ //Cancels Normal Overthrust. [Skotlex]
+ status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
break;
- case SC_MER_SP:
- status_percent_heal(bl, 0, 100); // Recover Full SP
+ case SC_KYRIE:
+ //Cancels Assumptio
+ status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
break;
- case SC_PROMOTE_HEALTH_RESERCH:
- status_percent_heal(bl, sce->val4, 0);
+ case SC_MAGNIFICAT:
+ //Cancels Offertorium
+ status_change_end(bl, SC_OFFERTORIUM, INVALID_TIMER);
break;
- case SC_ENERGY_DRINK_RESERCH:
- status_percent_heal(bl, 0, sce->val4);
+ case SC_OFFERTORIUM:
+ //Cancels Magnificat
+ status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
break;
- /**
- * Ranger
- **/
- case SC_WUGDASH:
- {
- struct unit_data *ud = unit->bl2ud(bl);
- if( ud )
- ud->state.running = unit->run(bl, sd, SC_WUGDASH);
- }
+ case SC_DELUGE:
+ if (sc->data[SC_FOGWALL] && sc->data[SC_BLIND])
+ status_change_end(bl, SC_BLIND, INVALID_TIMER);
break;
- case SC_COMBOATTACK:
- switch (sce->val1) {
- case TK_STORMKICK:
- clif->skill_nodamage(bl,bl,TK_READYSTORM,1,1);
- break;
- case TK_DOWNKICK:
- clif->skill_nodamage(bl,bl,TK_READYDOWN,1,1);
- break;
- case TK_TURNKICK:
- clif->skill_nodamage(bl,bl,TK_READYTURN,1,1);
- break;
- case TK_COUNTER:
- clif->skill_nodamage(bl,bl,TK_READYCOUNTER,1,1);
- break;
- case MO_COMBOFINISH:
- case CH_TIGERFIST:
- case CH_CHAINCRUSH:
- if (sd)
- clif->skillinfo(sd,MO_EXTREMITYFIST, INF_SELF_SKILL);
- break;
- case TK_JUMPKICK:
- if (sd)
- clif->skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL);
- break;
- case MO_TRIPLEATTACK:
- if (sd && pc->checkskill(sd, SR_DRAGONCOMBO) > 0)
- clif->skillinfo(sd,SR_DRAGONCOMBO, INF_SELF_SKILL);
- break;
- case SR_FALLENEMPIRE:
- if (sd){
- clif->skillinfo(sd,SR_GATEOFHELL, INF_SELF_SKILL);
- clif->skillinfo(sd,SR_TIGERCANNON, INF_SELF_SKILL);
- }
+ case SC_SILENCE:
+ if (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF)
+ status_change_end(bl, SC_GOSPEL, INVALID_TIMER);
+ break;
+ case SC_HIDING:
+ status_change_end(bl, SC_RG_CCONFINE_M, INVALID_TIMER);
+ status_change_end(bl, SC_RG_CCONFINE_S, INVALID_TIMER);
+ break;
+ case SC_BERSERK:
+ if (val3 == SC__BLOODYLUST)
break;
+ if (battle_config.berserk_cancels_buffs) {
+ status_change_end(bl, SC_ONEHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
+ status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
+ status_change_end(bl, SC_PARRYING, INVALID_TIMER);
+ status_change_end(bl, SC_AURABLADE, INVALID_TIMER);
+ status_change_end(bl, SC_MER_QUICKEN, INVALID_TIMER);
+ }
+ #ifdef RENEWAL
+ else {
+ status_change_end(bl, SC_TWOHANDQUICKEN, INVALID_TIMER);
}
+ #endif
break;
- case SC_RAISINGDRAGON:
- sce->val2 = st->max_hp / 100;// Officially tested its 1%hp drain. [Jobbie]
+ case SC_ASSUMPTIO:
+ status_change_end(bl, SC_KYRIE, INVALID_TIMER);
+ status_change_end(bl, SC_KAITE, INVALID_TIMER);
+ break;
+ case SC_KAITE:
+ status_change_end(bl, SC_ASSUMPTIO, INVALID_TIMER);
+ break;
+ case SC_CARTBOOST:
+ if (sc->data[SC_DEC_AGI] || sc->data[SC_ADORAMUS]) {
+ //Cancel Decrease Agi, but take no further effect [Skotlex]
+ status_change_end(bl, SC_DEC_AGI, INVALID_TIMER);
+ status_change_end(bl, SC_ADORAMUS, INVALID_TIMER);
+ return true;
+ }
+ break;
+ case SC_FUSION:
+ status_change_end(bl, SC_SOULLINK, INVALID_TIMER);
+ break;
+ case SC_GS_ADJUSTMENT:
+ status_change_end(bl, SC_GS_MADNESSCANCEL, INVALID_TIMER);
+ break;
+ case SC_GS_MADNESSCANCEL:
+ status_change_end(bl, SC_GS_ADJUSTMENT, INVALID_TIMER);
+ break;
+ //NPC_CHANGEUNDEAD will debuff Blessing and Agi Up
+ case SC_PROPERTYUNDEAD:
+ status_change_end(bl, SC_BLESSING, INVALID_TIMER);
+ status_change_end(bl, SC_INC_AGI, INVALID_TIMER);
+ break;
+ case SC_FOOD_STR:
+ status_change_end(bl, SC_FOOD_STR, INVALID_TIMER);
+ break;
+ case SC_FOOD_AGI:
+ status_change_end(bl, SC_FOOD_AGI, INVALID_TIMER);
+ break;
+ case SC_FOOD_VIT:
+ status_change_end(bl, SC_FOOD_VIT, INVALID_TIMER);
+ break;
+ case SC_FOOD_INT:
+ status_change_end(bl, SC_FOOD_INT, INVALID_TIMER);
+ break;
+ case SC_FOOD_DEX:
+ status_change_end(bl, SC_FOOD_DEX, INVALID_TIMER);
+ break;
+ case SC_FOOD_LUK:
+ status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER);
+ break;
+ case SC_FOOD_STR_CASH:
+ status_change_end(bl, SC_FOOD_STR, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_STR_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_AGI_CASH:
+ status_change_end(bl, SC_FOOD_AGI, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_AGI_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_VIT_CASH:
+ status_change_end(bl, SC_FOOD_VIT, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_VIT_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_INT_CASH:
+ status_change_end(bl, SC_FOOD_INT, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_INT_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_DEX_CASH:
+ status_change_end(bl, SC_FOOD_DEX, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_DEX_CASH, INVALID_TIMER);
+ break;
+ case SC_FOOD_LUK_CASH:
+ status_change_end(bl, SC_FOOD_LUK, INVALID_TIMER);
+ status_change_end(bl, SC_FOOD_LUK_CASH, INVALID_TIMER);
+ break;
+ case SC_GM_BATTLE:
+ status_change_end(bl, SC_GM_BATTLE2, INVALID_TIMER);
+ break;
+ case SC_GM_BATTLE2:
+ status_change_end(bl, SC_GM_BATTLE, INVALID_TIMER);
+ break;
+ case SC_ENDURE:
+ if (val4 == 1)
+ status_change_end(bl, SC_LKCONCENTRATION, INVALID_TIMER);
+ break;
+ case SC_FIGHTINGSPIRIT:
+ case SC_OVERED_BOOST:
+ status_change_end(bl, type, INVALID_TIMER); // Remove previous one.
+ break;
+ case SC_MARSHOFABYSS:
+ status_change_end(bl, SC_INCAGI, INVALID_TIMER);
+ status_change_end(bl, SC_WINDWALK, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION1, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION2, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_POTION3, INVALID_TIMER);
+ status_change_end(bl, SC_ATTHASTE_INFINITY, INVALID_TIMER);
+ break;
+ //Group A Status (doesn't overlap)
+ case SC_SWING:
+ case SC_SYMPHONY_LOVE:
+ case SC_MOONLIT_SERENADE:
+ case SC_RUSH_WINDMILL:
+ case SC_ECHOSONG:
+ case SC_HARMONIZE:
+ case SC_FRIGG_SONG:
+ if (type != SC_SWING) status_change_end(bl, SC_SWING, INVALID_TIMER);
+ if (type != SC_SYMPHONY_LOVE) status_change_end(bl, SC_SYMPHONY_LOVE, INVALID_TIMER);
+ if (type != SC_MOONLIT_SERENADE) status_change_end(bl, SC_MOONLIT_SERENADE, INVALID_TIMER);
+ if (type != SC_RUSH_WINDMILL) status_change_end(bl, SC_RUSH_WINDMILL, INVALID_TIMER);
+ if (type != SC_ECHOSONG) status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
+ if (type != SC_HARMONIZE) status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
+ if (type != SC_FRIGG_SONG) status_change_end(bl, SC_FRIGG_SONG, INVALID_TIMER);
+ break;
+ //Group B Status
+ case SC_SIREN:
+ case SC_DEEP_SLEEP:
+ case SC_SIRCLEOFNATURE:
+ case SC_LERADS_DEW:
+ case SC_MELODYOFSINK:
+ case SC_BEYOND_OF_WARCRY:
+ case SC_UNLIMITED_HUMMING_VOICE:
+ case SC_GLOOMYDAY:
+ case SC_SONG_OF_MANA:
+ case SC_DANCE_WITH_WUG:
+ if (type != SC_SIREN) status_change_end(bl, SC_SIREN, INVALID_TIMER);
+ if (type != SC_DEEP_SLEEP) status_change_end(bl, SC_DEEP_SLEEP, INVALID_TIMER);
+ if (type != SC_SIRCLEOFNATURE) status_change_end(bl, SC_SIRCLEOFNATURE, INVALID_TIMER);
+ if (type != SC_LERADS_DEW) status_change_end(bl, SC_LERADS_DEW, INVALID_TIMER);
+ if (type != SC_MELODYOFSINK) status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
+ if (type != SC_BEYOND_OF_WARCRY) status_change_end(bl, SC_BEYOND_OF_WARCRY, INVALID_TIMER);
+ if (type != SC_UNLIMITED_HUMMING_VOICE) status_change_end(bl, SC_UNLIMITED_HUMMING_VOICE, INVALID_TIMER);
+ if (type != SC_GLOOMYDAY) status_change_end(bl, SC_GLOOMYDAY, INVALID_TIMER);
+ if (type != SC_SONG_OF_MANA) status_change_end(bl, SC_SONG_OF_MANA, INVALID_TIMER);
+ if (type != SC_DANCE_WITH_WUG) status_change_end(bl, SC_DANCE_WITH_WUG, INVALID_TIMER);
+ break;
+ case SC_REFLECTSHIELD:
+ status_change_end(bl, SC_LG_REFLECTDAMAGE, INVALID_TIMER);
+ break;
+ case SC_LG_REFLECTDAMAGE:
+ status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
+ break;
+ case SC_SHIELDSPELL_DEF:
+ case SC_SHIELDSPELL_MDEF:
+ case SC_SHIELDSPELL_REF:
+ status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
+ status_change_end(bl, SC_SHIELDSPELL_DEF, INVALID_TIMER);
+ status_change_end(bl, SC_SHIELDSPELL_MDEF, INVALID_TIMER);
+ status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
+ break;
+ case SC_GENTLETOUCH_ENERGYGAIN:
+ case SC_GENTLETOUCH_CHANGE:
+ case SC_GENTLETOUCH_REVITALIZE:
+ if (type != SC_GENTLETOUCH_REVITALIZE)
+ status_change_end(bl, SC_GENTLETOUCH_REVITALIZE, INVALID_TIMER);
+ if (type != SC_GENTLETOUCH_ENERGYGAIN)
+ status_change_end(bl, SC_GENTLETOUCH_ENERGYGAIN, INVALID_TIMER);
+ if (type != SC_GENTLETOUCH_CHANGE)
+ status_change_end(bl, SC_GENTLETOUCH_CHANGE, INVALID_TIMER);
+ break;
+ case SC_INVINCIBLE:
+ status_change_end(bl, SC_INVINCIBLEOFF, INVALID_TIMER);
+ break;
+ case SC_INVINCIBLEOFF:
+ status_change_end(bl, SC_INVINCIBLE, INVALID_TIMER);
+ break;
+ case SC_MAGICPOWER:
+ status_change_end(bl, type, INVALID_TIMER);
break;
}
- if( opt_flag&2 && sd && sd->touching_id )
- npc->touchnext_areanpc(sd,false); // run OnTouch_ on next char in range
+ return false;
+}
- return 1;
+/**
+ * Check is boss resist to given sc.
+ *
+ * @param type Status change type.
+ *
+ * @retval true if boss resist.
+ * @retval false if boss not resist.
+ */
+static bool status_is_boss_resist_sc(enum sc_type type)
+{
+ if (type >= SC_COMMON_MIN && type <= SC_COMMON_MAX)
+ return true;
+ switch (type) {
+ case SC_BLESSING:
+ case SC_DEC_AGI:
+ case SC_PROVOKE:
+ case SC_COMA:
+ case SC_GRAVITATION:
+ case SC_NJ_SUITON:
+ case SC_RICHMANKIM:
+ case SC_ROKISWEIL:
+ case SC_FOGWALL:
+ case SC_FROSTMISTY:
+ case SC_BURNING:
+ case SC_MARSHOFABYSS:
+ case SC_ADORAMUS:
+ case SC_NEEDLE_OF_PARALYZE:
+ case SC_DEEP_SLEEP:
+ case SC_COLD:
+
+ // Exploit prevention - kRO Fix
+ case SC_PYREXIA:
+ case SC_DEATHHURT:
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
+
+ // Ranger Effects
+ case SC_WUGBITE:
+ case SC_ELECTRICSHOCKER:
+ case SC_MAGNETICFIELD:
+
+ // Masquerades
+ case SC__ENERVATION:
+ case SC__GROOMY:
+ case SC__LAZINESS:
+ case SC__UNLUCKY:
+ case SC__WEAKNESS:
+ case SC__IGNORANCE:
+
+ // Other Effects
+ case SC_VACUUM_EXTREME:
+ case SC_NETHERWORLD:
+ case SC_FRESHSHRIMP:
+ case SC_SV_ROOTTWIST:
+ case SC_BITESCAR:
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Initial check for current statuses immune to given sc.
+ *
+ * @param sc Current statuses.
+ * @param type Status change type.
+ *
+ * @retval true if immune resist.
+ * @retval false if not immune resist.
+ */
+static bool status_is_immune_to_status(struct status_change *sc, enum sc_type type)
+{
+ nullpo_retr(true, sc);
+ if (sc->data[SC_REFRESH]) {
+ if (type >= SC_COMMON_MIN && type <= SC_COMMON_MAX) // Confirmed.
+ return true; // Immune to status ailements
+ switch (type) {
+ case SC__CHAOS:
+ case SC_STONE:
+ case SC_FROSTMISTY:
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_DEATHHURT:
+ case SC_PYREXIA:
+ case SC_OBLIVIONCURSE:
+ case SC_MARSHOFABYSS:
+ case SC_MANDRAGORA:
+ return true;
+ }
+ } else if (sc->data[SC_INSPIRATION]) {
+ if (type >= SC_COMMON_MIN && type <= SC_COMMON_MAX)
+ return true; // Immune to status ailements
+ switch (type) {
+ case SC__CHAOS:
+ case SC_STONE:
+ case SC_FROSTMISTY:
+ case SC_TOXIN:
+ case SC_PARALYSE:
+ case SC_VENOMBLEED:
+ case SC_MAGICMUSHROOM:
+ case SC_DEATHHURT:
+ case SC_PYREXIA:
+ case SC_OBLIVIONCURSE:
+ case SC_LEECHESEND:
+ case SC_SATURDAY_NIGHT_FEVER:
+ case SC__BODYPAINT:
+ case SC__ENERVATION:
+ case SC__GROOMY:
+ case SC__IGNORANCE:
+ case SC__LAZINESS:
+ case SC__UNLUCKY:
+ case SC__WEAKNESS:
+ return true;
+ }
+ }
+ return false;
}
/*==========================================
-* Ending all status except those listed.
-* @TODO maybe usefull for dispel instead reseting a liste there.
-* type:
-* 0 - PC killed -> Place here statuses that do not dispel on death.
-* 1 - If for some reason status_change_end decides to still keep the status when quitting.
-* 2 - Do clif
-* 3 - Do not remove some permanent/time-independent effects
-*------------------------------------------*/
-int status_change_clear(struct block_list* bl, int type)
+ * Ending all status except those listed.
+ * @TODO maybe usefull for dispel instead reseting a liste there.
+ * type:
+ * 0 - PC killed -> Place here statuses that do not dispel on death.
+ * 1 - If for some reason status_change_end decides to still keep the status when quitting.
+ * 2 - Do clif
+ * 3 - Do not remove some permanent/time-independent effects
+ *------------------------------------------*/
+static int status_change_clear(struct block_list *bl, int type)
{
struct status_change* sc;
int i;
@@ -10490,9 +10721,9 @@ int status_change_clear(struct block_list* bl, int type)
}
/*==========================================
-* Special condition we want to effectuate, check before ending a status.
-*------------------------------------------*/
-int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line)
+ * Special condition we want to effectuate, check before ending a status.
+ *------------------------------------------*/
+static int status_change_end_(struct block_list *bl, enum sc_type type, int tid, const char *file, int line)
{
struct map_session_data *sd;
struct status_change *sc;
@@ -10594,7 +10825,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
if (begin_spurt && sce->val1 >= 7
&& DIFF_TICK(timer->gettick(), starttick) <= 1000
- && (!sd || (sd->weapontype1 == 0 && sd->weapontype2 == 0))
+ && (!sd || (sd->weapontype1 == W_FIST && sd->weapontype2 == W_FIST))
)
sc_start(bl, bl,SC_STRUP,100,sce->val1,skill->get_time2(status->sc2skill(type), sce->val1));
}
@@ -10797,7 +11028,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
status_percent_heal(bl, 100, 0);
status_change_end(bl, SC__BLOODYLUST, INVALID_TIMER);
} else if(st->hp > 100 && sce->val2) //If val2 is removed, no HP penalty (dispelled?) [Skotlex]
- status->set_hp(bl, 100, 0);
+ status->set_hp(bl, 100, STATUS_HEAL_DEFAULT);
if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2) {
sc->data[SC_ENDURE]->val4 = 0;
status_change_end(bl, SC_ENDURE, INVALID_TIMER);
@@ -10849,8 +11080,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
if (tid == INVALID_TIMER)
break;
// "lose almost all their HP and SP" on natural expiration.
- status->set_hp(bl, 10, 0);
- status->set_sp(bl, 10, 0);
+ status->set_hp(bl, 10, STATUS_HEAL_DEFAULT);
+ status->set_sp(bl, 10, STATUS_HEAL_DEFAULT);
break;
case SC_AUTOTRADE:
if (tid == INVALID_TIMER)
@@ -11062,6 +11293,10 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
sc->option &= ~OPTION_OKTOBERFEST;
opt_flag |= 0x4;
break;
+ case SC_DRESS_UP:
+ sc->option &= ~OPTION_SUMMER2;
+ opt_flag |= 0x4;
+ break;
case SC__FEINTBOMB_MASTER:
sc->option &= ~OPTION_INVISIBLE;
opt_flag |= 0x4;
@@ -11231,7 +11466,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
return 1;
}
-int kaahi_heal_timer(int tid, int64 tick, int id, intptr_t data) {
+static int kaahi_heal_timer(int tid, int64 tick, int id, intptr_t data)
+{
struct block_list *bl;
struct status_change *sc;
struct status_change_entry *sce;
@@ -11256,17 +11492,17 @@ int kaahi_heal_timer(int tid, int64 tick, int id, intptr_t data) {
hp = st->max_hp - st->hp;
if (hp > sce->val2)
hp = sce->val2;
- if (hp)
- status->heal(bl, hp, 0, 2);
+ if (hp != 0)
+ status->heal(bl, hp, 0, STATUS_HEAL_SHOWEFFECT);
sce->val4 = INVALID_TIMER;
return 1;
}
/*==========================================
-* For recusive status, like for each 5s we drop sp etc.
-* Reseting the end timer.
-*------------------------------------------*/
-int status_change_timer(int tid, int64 tick, int id, intptr_t data)
+ * For recusive status, like for each 5s we drop sp etc.
+ * Reseting the end timer.
+ *------------------------------------------*/
+static int status_change_timer(int tid, int64 tick, int id, intptr_t data)
{
enum sc_type type = (sc_type)data;
struct block_list *bl;
@@ -11388,24 +11624,26 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data)
break;
case SC_POISON:
- if(st->hp <= max(st->max_hp>>2, sce->val4)) //Stop damaging after 25% HP left.
+ if (st->hp <= max(st->max_hp / 4, sce->val4)) //Stop damaging after 25% HP left.
break;
FALLTHROUGH
case SC_DPOISON:
if (--(sce->val3) > 0) {
- if (!sc->data[SC_SLOWPOISON]) {
- if( sce->val2 && bl->type == BL_MOB ) {
- struct block_list* src = map->id2bl(sce->val2);
- if (src != NULL)
- mob->log_damage(BL_UCAST(BL_MOB, bl), src, sce->val4);
- }
- map->freeblock_lock();
- status_zap(bl, sce->val4, 0);
- if (sc->data[type]) { // Check if the status still last ( can be dead since then ).
- sc_timer_next(1000 + tick, status->change_timer, bl->id, data );
- }
- map->freeblock_unlock();
+ if (sc->data[SC_SLOWPOISON] != NULL) {
+ sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
+ return 0;
+ }
+ if (sce->val2 != 0 && bl->type == BL_MOB) {
+ struct block_list* src = map->id2bl(sce->val2);
+ if (src != NULL)
+ mob->log_damage(BL_UCAST(BL_MOB, bl), src, sce->val4);
+ }
+ map->freeblock_lock();
+ status_zap(bl, sce->val4, 0);
+ if (sc->data[type] != NULL) { // Check if the status still last (can be dead since then).
+ sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
}
+ map->freeblock_unlock();
return 0;
}
break;
@@ -11461,7 +11699,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data)
int hp = 0;
if (st->hp < st->max_hp)
hp = (sce->val1 < 0) ? (int)(sd->status.max_hp * -1 * sce->val1 / 100.) : sce->val1 ;
- status->heal(bl, hp, 0, 2);
+ status->heal(bl, hp, 0, STATUS_HEAL_SHOWEFFECT);
sc_timer_next((sce->val2 * 1000) + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -11610,7 +11848,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data)
break;
case SC_ABUNDANCE:
if(--(sce->val4) > 0) {
- status->heal(bl,0,60,0);
+ status->heal(bl, 0, 60, STATUS_HEAL_DEFAULT);
sc_timer_next(10000+tick, status->change_timer, bl->id, data);
}
break;
@@ -11726,7 +11964,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data)
heal = ~heal + 1;
map->freeblock_lock();
- status->heal(bl, heal, 0, 2);
+ status->heal(bl, heal, 0, STATUS_HEAL_SHOWEFFECT);
if( sc->data[type] ) {
sc_timer_next(5000 + tick, status->change_timer, bl->id, data);
}
@@ -11849,7 +12087,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data)
if ( sc->data[type] ) {
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
}
- status->heal(src, damage*(5 + 5 * sce->val1)/100, 0, 0); // 5 + 5% per level
+ status->heal(src, damage*(5 + 5 * sce->val1)/100, 0, STATUS_HEAL_DEFAULT); // 5 + 5% per level
map->freeblock_unlock();
return 0;
}
@@ -11866,7 +12104,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data)
case SC_DEEP_SLEEP:
if( --(sce->val4) >= 0 )
{// Recovers 3% of the player's MaxHP/MaxSP every 2 seconds.
- status->heal(bl, st->max_hp * 3 / 100, st->max_sp * 3 / 100, 2);
+ status->heal(bl, st->max_hp * 3 / 100, st->max_sp * 3 / 100, STATUS_HEAL_SHOWEFFECT);
sc_timer_next(2000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -11876,7 +12114,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data)
if( --(sce->val4) >= 0 ) {
if( !status->charge(bl,0,sce->val3) )
break;
- status->heal(bl, sce->val2, 0, 1);
+ status->heal(bl, sce->val2, 0, STATUS_HEAL_FORCED);
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -11884,7 +12122,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data)
case SC_SONG_OF_MANA:
if( --(sce->val4) >= 0 ) {
- status->heal(bl,0,sce->val3,3);
+ status->heal(bl, 0, sce->val3, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT);
sc_timer_next(5000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -12078,7 +12316,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data)
return 0;
case SC_MEIKYOUSISUI:
if( --(sce->val4) > 0 ) {
- status->heal(bl, st->max_hp * (sce->val1+1) / 100, st->max_sp * sce->val1 / 100, 0);
+ status->heal(bl, st->max_hp * (sce->val1+1) / 100, st->max_sp * sce->val1 / 100, STATUS_HEAL_DEFAULT);
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -12114,7 +12352,7 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data)
break;
case SC_FRIGG_SONG:
if( --(sce->val4) > 0 ) {
- status->heal(bl, sce->val3, 0, 0);
+ status->heal(bl, sce->val3, 0, STATUS_HEAL_DEFAULT);
sc_timer_next(1000 + tick, status->change_timer, bl->id, data);
return 0;
}
@@ -12140,9 +12378,9 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data)
}
/*==========================================
-* Foreach iteration of repetitive status
-*------------------------------------------*/
-int status_change_timer_sub(struct block_list* bl, va_list ap)
+ * Foreach iteration of repetitive status
+ *------------------------------------------*/
+static int status_change_timer_sub(struct block_list *bl, va_list ap)
{
struct status_change* tsc;
@@ -12218,10 +12456,17 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
return 0;
}
-int status_get_total_def(struct block_list *src) { return status->get_status_data(src)->def2 + (short)status->get_def(src); }
-int status_get_total_mdef(struct block_list *src) { return status->get_status_data(src)->mdef2 + (short)status_get_mdef(src); }
+static int status_get_total_def(struct block_list *src)
+{
+ return status->get_status_data(src)->def2 + (short)status->get_def(src);
+}
+
+static int status_get_total_mdef(struct block_list *src)
+{
+ return status->get_status_data(src)->mdef2 + (short)status_get_mdef(src);
+}
-int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int flag)
+static int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int flag)
{
#ifdef RENEWAL
int min = 0, max = 0;
@@ -12284,13 +12529,13 @@ int status_get_weapon_atk(struct block_list *bl, struct weapon_atk *watk, int fl
}
/**
-* Get bl's matk_max and matk_min values depending on flag
-* @param flag
-* 0 - Get MATK
-* 1 - Get MATK w/o SC bonuses
-* 3 - Get MATK w/o EATK & SC bonuses
-**/
-void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_max, unsigned short *matk_min)
+ * Get bl's matk_max and matk_min values depending on flag
+ * @param flag
+ * 0 - Get MATK
+ * 1 - Get MATK w/o SC bonuses
+ * 3 - Get MATK w/o EATK & SC bonuses
+ */
+static void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_max, unsigned short *matk_min)
{
struct status_data *st;
struct status_change *sc;
@@ -12402,9 +12647,9 @@ void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_m
#undef status_get_homluk
/**
-* Gets a random matk value depending on min matk and max matk
-**/
-unsigned short status_get_rand_matk(unsigned short matk_max, unsigned short matk_min)
+ * Gets a random matk value depending on min matk and max matk
+ */
+static unsigned short status_get_rand_matk(unsigned short matk_max, unsigned short matk_min)
{
if ( matk_max > matk_min )
return matk_min + rnd() % (matk_max - matk_min);
@@ -12413,17 +12658,17 @@ unsigned short status_get_rand_matk(unsigned short matk_max, unsigned short matk
}
/**
-* Get bl's matk value depending on flag
-* @param flag [malufett]
-* 1 - Get MATK w/o SC bonuses
-* 2 - Get modified MATK
-* 3 - Get MATK w/o eATK & SC bonuses
-* @retval 1 failure
-* @retval MATK success
-*
-* Shouldn't change _any_ value! [Panikon]
-**/
-int status_get_matk(struct block_list *bl, int flag)
+ * Get bl's matk value depending on flag
+ * @param flag [malufett]
+ * 1 - Get MATK w/o SC bonuses
+ * 2 - Get modified MATK
+ * 3 - Get MATK w/o eATK & SC bonuses
+ * @retval 1 failure
+ * @retval MATK success
+ *
+ * Shouldn't change _any_ value! [Panikon]
+ */
+static int status_get_matk(struct block_list *bl, int flag)
{
struct status_data *st;
unsigned short matk_max, matk_min;
@@ -12450,9 +12695,9 @@ int status_get_matk(struct block_list *bl, int flag)
}
/**
-* Updates bl's MATK values
-**/
-void status_update_matk(struct block_list *bl)
+ * Updates bl's MATK values
+ */
+static void status_update_matk(struct block_list *bl)
{
struct status_data *st;
struct status_change *sc;
@@ -12477,11 +12722,11 @@ void status_update_matk(struct block_list *bl)
}
/*==========================================
-* Clears buffs/debuffs of a character.
-* type&1 -> buffs, type&2 -> debuffs
-* type&4 -> especific debuffs(implemented with refresh)
-*------------------------------------------*/
-int status_change_clear_buffs (struct block_list* bl, int type)
+ * Clears buffs/debuffs of a character.
+ * type&1 -> buffs, type&2 -> debuffs
+ * type&4 -> especific debuffs(implemented with refresh)
+ *------------------------------------------*/
+static int status_change_clear_buffs(struct block_list *bl, int type)
{
int i;
struct status_change *sc= status->get_sc(bl);
@@ -12543,7 +12788,7 @@ int status_change_clear_buffs (struct block_list* bl, int type)
return 0;
}
-int status_change_spread(struct block_list *src, struct block_list *bl)
+static int status_change_spread(struct block_list *src, struct block_list *bl)
{
int i, flag = 0;
struct status_change *sc = status->get_sc(src);
@@ -12634,7 +12879,7 @@ int status_change_spread(struct block_list *src, struct block_list *bl)
}
//Natural regen related stuff.
-int status_natural_heal(struct block_list* bl, va_list args)
+static int status_natural_heal(struct block_list *bl, va_list args)
{
struct regen_data *regen;
struct status_data *st;
@@ -12689,7 +12934,7 @@ int status_natural_heal(struct block_list* bl, va_list args)
sregen->tick.hp += val;
while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval) {
sregen->tick.hp -= battle_config.natural_heal_skill_interval;
- if(status->heal(bl, sregen->hp, 0, 3) < sregen->hp) {
+ if (status->heal(bl, sregen->hp, 0, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT) < sregen->hp) {
//Full
flag&=~(RGN_HP|RGN_SHP);
break;
@@ -12704,7 +12949,7 @@ int status_natural_heal(struct block_list* bl, va_list args)
sregen->tick.sp += val;
while(sregen->tick.sp >= (unsigned int)battle_config.natural_heal_skill_interval) {
sregen->tick.sp -= battle_config.natural_heal_skill_interval;
- if(status->heal(bl, 0, sregen->sp, 3) < sregen->sp) {
+ if (status->heal(bl, 0, sregen->sp, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT) < sregen->sp) {
//Full
flag&=~(RGN_SP|RGN_SSP);
break;
@@ -12753,7 +12998,7 @@ int status_natural_heal(struct block_list* bl, va_list args)
val += regen->hp;
regen->tick.hp -= battle_config.natural_healhp_interval;
} while(regen->tick.hp >= (unsigned int)battle_config.natural_healhp_interval);
- if (status->heal(bl, val, 0, 1) < val)
+ if (status->heal(bl, val, 0, STATUS_HEAL_FORCED) < val)
flag&=~RGN_SHP; //full.
}
}
@@ -12772,7 +13017,7 @@ int status_natural_heal(struct block_list* bl, va_list args)
val += regen->sp;
regen->tick.sp -= battle_config.natural_healsp_interval;
} while(regen->tick.sp >= (unsigned int)battle_config.natural_healsp_interval);
- if (status->heal(bl, 0, val, 1) < val)
+ if (status->heal(bl, 0, val, STATUS_HEAL_FORCED) < val)
flag&=~RGN_SSP; //full.
}
}
@@ -12789,7 +13034,7 @@ int status_natural_heal(struct block_list* bl, va_list args)
while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval) {
sregen->tick.hp -= battle_config.natural_heal_skill_interval;
- if(status->heal(bl, sregen->hp, 0, 3) < sregen->hp)
+ if (status->heal(bl, sregen->hp, 0, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT) < sregen->hp)
break; //Full
}
}
@@ -12814,7 +13059,7 @@ int status_natural_heal(struct block_list* bl, va_list args)
}
}
sregen->tick.sp -= battle_config.natural_heal_skill_interval;
- if(status->heal(bl, 0, val, 3) < val)
+ if (status->heal(bl, 0, val, STATUS_HEAL_FORCED | STATUS_HEAL_SHOWEFFECT) < val)
break; //Full
}
}
@@ -12822,7 +13067,7 @@ int status_natural_heal(struct block_list* bl, va_list args)
}
//Natural heal main timer.
-int status_natural_heal_timer(int tid, int64 tick, int id, intptr_t data)
+static int status_natural_heal_timer(int tid, int64 tick, int id, intptr_t data)
{
// This difference is always positive and lower than UINT_MAX (~24 days)
status->natural_heal_diff_tick = (unsigned int)cap_value(DIFF_TICK(tick,status->natural_heal_prev_tick), 0, UINT_MAX);
@@ -12832,21 +13077,25 @@ int status_natural_heal_timer(int tid, int64 tick, int id, intptr_t data)
}
/**
-* Get the chance to upgrade a piece of equipment.
-* @param wlv The weapon type of the item to refine (see see enum refine_type)
-* @param refine The target refine level
-* @return The chance to refine the item, in percent (0~100)
-**/
-int status_get_refine_chance(enum refine_type wlv, int refine)
+ * Get the chance to upgrade a piece of equipment.
+ * @param wlv The weapon type of the item to refine (see see enum refine_type)
+ * @param refine The target refine level
+ * @return The chance to refine the item, in percent (0~100)
+ */
+static int status_get_refine_chance(enum refine_type wlv, int refine, enum refine_chance_type type)
{
Assert_ret((int)wlv >= REFINE_TYPE_ARMOR && wlv < REFINE_TYPE_MAX);
- if ( refine < 0 || refine >= MAX_REFINE)
- return 0;
- return status->dbs->refine_info[wlv].chance[refine];
+ if (refine < 0 || refine >= MAX_REFINE)
+ return 0;
+
+ if (type >= REFINE_CHANCE_TYPE_MAX)
+ return 0;
+
+ return status->dbs->refine_info[wlv].chance[type][refine];
}
-int status_get_sc_type(sc_type type)
+static int status_get_sc_type(sc_type type)
{
if( type <= SC_NONE || type >= SC_MAX )
@@ -12855,10 +13104,11 @@ int status_get_sc_type(sc_type type)
return status->dbs->sc_conf[type];
}
-void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *jdb)
+static void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *jdb)
{
struct config_setting_t *temp = NULL;
int i32 = 0;
+ const char *str = NULL;
struct {
const char *name;
@@ -12893,6 +13143,38 @@ void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *
#endif
};
+ /**
+ * @field BaseExpGroup must be read before any other that deal with exp tables.
+ */
+ if (libconfig->setting_lookup_string(jdb, "BaseExpGroup", &str) != 0) {
+ int i = 0;
+ ARR_FIND(0, VECTOR_LENGTH(pc->class_exp_groups[CLASS_EXP_TABLE_BASE]), i, strcmp(str, VECTOR_INDEX(pc->class_exp_groups[CLASS_EXP_TABLE_BASE], i).name) == 0);
+ if (i == VECTOR_LENGTH(pc->class_exp_groups[CLASS_EXP_TABLE_BASE])) {
+ ShowError("status_read_job_db: Unknown Base Exp Group '%s' provided for entry '%s'\n", str, name);
+ } else {
+ pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_BASE] = &VECTOR_INDEX(pc->class_exp_groups[CLASS_EXP_TABLE_BASE], i);
+ }
+ } else {
+ ShowError("status_read_job_db: BaseExpGroup setting not found for entry '%s', skipping..\n", name);
+ return;
+ }
+
+ /**
+ * @field JobExpGroup must be read before any other that deal with exp tables.
+ */
+ if (libconfig->setting_lookup_string(jdb, "JobExpGroup", &str) != 0) {
+ int i = 0;
+ ARR_FIND(0, VECTOR_LENGTH(pc->class_exp_groups[CLASS_EXP_TABLE_JOB]), i, strcmp(str, VECTOR_INDEX(pc->class_exp_groups[CLASS_EXP_TABLE_JOB], i).name) == 0);
+ if (i == VECTOR_LENGTH(pc->class_exp_groups[CLASS_EXP_TABLE_JOB])) {
+ ShowError("status_read_job_db: Unknown Job Exp Group '%s' provided for entry '%s'\n", str, name);
+ } else {
+ pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_JOB] = &VECTOR_INDEX(pc->class_exp_groups[CLASS_EXP_TABLE_JOB], i);
+ }
+ } else {
+ ShowError("status_read_job_db: JobExpGroup setting not found for entry '%s', skipping..\n", name);
+ return;
+ }
+
if ((temp = libconfig->setting_get_member(jdb, "Inherit"))) {
int nidx = 0;
const char *iname;
@@ -12917,7 +13199,7 @@ void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *
} else {
avg_increment = 5;
}
- for ( ; i <= pc->max_level[idx][0]; i++) {
+ for ( ; i <= pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_BASE]->max_level; i++) {
status->dbs->HP_table[idx][i] = min(base + avg_increment * i, battle_config.max_hp);
}
@@ -12932,7 +13214,7 @@ void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *
} else {
avg_increment = 1;
}
- for ( ; i <= pc->max_level[idx][0]; i++) {
+ for ( ; i <= pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_BASE]->max_level; i++) {
status->dbs->SP_table[idx][i] = min(base + avg_increment * i, battle_config.max_sp);
}
}
@@ -12958,7 +13240,7 @@ void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *
} else {
avg_increment = 5;
}
- for ( ; i <= pc->max_level[idx][0]; i++) {
+ for ( ; i <= pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_BASE]->max_level; i++) {
status->dbs->HP_table[idx][i] = min(base + avg_increment * i, battle_config.max_hp);
}
}
@@ -12984,7 +13266,7 @@ void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *
} else {
avg_increment = 1;
}
- for ( ; i <= pc->max_level[idx][0]; i++) {
+ for ( ; i <= pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_BASE]->max_level; i++) {
status->dbs->SP_table[idx][i] = min(base + avg_increment * i, battle_config.max_sp);
}
}
@@ -13026,7 +13308,7 @@ void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *
} else {
avg_increment = 5;
}
- for (++level; level <= pc->max_level[idx][0]; ++level) { /* limit only to possible maximum level of the given class */
+ for (++level; level <= pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_BASE]->max_level; ++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 */
}
}
@@ -13046,20 +13328,21 @@ void status_read_job_db_sub(int idx, const char *name, struct config_setting_t *
} else {
avg_increment = 1;
}
- for (++level; level <= pc->max_level[idx][0]; level++ ) {
+ for (++level; level <= pc->dbs->class_exp_table[idx][CLASS_EXP_TABLE_BASE]->max_level; level++) {
status->dbs->SP_table[idx][level] = min(base + avg_increment * level, battle_config.max_sp);
}
}
}
+/* [malufett/Hercules] */
/*------------------------------------------
-* DB reading.
-* job_db.conf - weight, hp, sp, aspd
-* job_db2.txt - job level stat bonuses
-* size_fix.txt - size adjustment table for weapons
-* refine_db.txt - refining data table
-*------------------------------------------*/
-void status_read_job_db(void) /* [malufett/Hercules] */
+ * DB reading.
+ * job_db.conf - weight, hp, sp, aspd
+ * job_db2.txt - job level stat bonuses
+ * size_fix.txt - size adjustment table for weapons
+ * refine_db.txt - refining data table
+ *------------------------------------------*/
+static void status_read_job_db(void)
{
int i = 0;
struct config_t job_db_conf;
@@ -13073,7 +13356,7 @@ void status_read_job_db(void) /* [malufett/Hercules] */
if (!libconfig->load_file(&job_db_conf, config_filename))
return;
- while ( (jdb = libconfig->setting_get_elem(job_db_conf.root, i++)) ) {
+ while ((jdb = libconfig->setting_get_elem(job_db_conf.root, i++))) {
int class, idx;
const char *name = config_setting_name(jdb);
@@ -13085,11 +13368,12 @@ void status_read_job_db(void) /* [malufett/Hercules] */
idx = pc->class2idx(class);
status->read_job_db_sub(idx, name, jdb);
}
+
ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, config_filename);
libconfig->destroy(&job_db_conf);
}
-bool status_readdb_job2(char* fields[], int columns, int current)
+static bool status_readdb_job2(char *fields[], int columns, int current)
{
int idx, class, i;
@@ -13109,7 +13393,7 @@ bool status_readdb_job2(char* fields[], int columns, int current)
return true;
}
-bool status_readdb_sizefix(char* fields[], int columns, int current)
+static bool status_readdb_sizefix(char *fields[], int columns, int current)
{
unsigned int i;
@@ -13133,7 +13417,7 @@ bool status_readdb_sizefix(char* fields[], int columns, int current)
* validation errors.
* @return # of the validated entry, or 0 in case of failure.
*/
-int status_readdb_refine_libconfig_sub(struct config_setting_t *r, const char *name, const char *source)
+static int status_readdb_refine_libconfig_sub(struct config_setting_t *r, const char *name, const char *source)
{
struct config_setting_t *rate = NULL;
int type = REFINE_TYPE_ARMOR, bonus_per_level = 0, rnd_bonus_v = 0, rnd_bonus_lv = 0;
@@ -13168,54 +13452,84 @@ int status_readdb_refine_libconfig_sub(struct config_setting_t *r, const char *n
if ((rate=libconfig->setting_get_member(r, "Rates")) != NULL && config_setting_is_group(rate)) {
struct config_setting_t *t = NULL;
bool duplicate[MAX_REFINE];
- int bonus[MAX_REFINE], rnd_bonus[MAX_REFINE], chance[MAX_REFINE];
- int i;
+ int bonus[MAX_REFINE], rnd_bonus[MAX_REFINE];
+ int chance[REFINE_CHANCE_TYPE_MAX][MAX_REFINE];
+ int i, j;
+
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;
- }
+ for (i = 0; i < REFINE_CHANCE_TYPE_MAX; i++)
+ for (j = 0; j < MAX_REFINE; j++)
+ chance[i][j] = 100; // default value for all rates.
+
i = 0;
+ j = 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) {
+
+ 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;
+
+ if (libconfig->setting_lookup_int(t, "NormalChance", &i32) != 0)
+ chance[REFINE_CHANCE_TYPE_NORMAL][level] = i32;
+ else
+ chance[REFINE_CHANCE_TYPE_NORMAL][level] = 100;
+
+ if (libconfig->setting_lookup_int(t, "EnrichedChance", &i32) != 0)
+ chance[REFINE_CHANCE_TYPE_ENRICHED][level] = i32;
+ else
+ chance[REFINE_CHANCE_TYPE_ENRICHED][level] = level > 10 ? 0 : 100; // enriched ores up to +10 only.
+
+ if (libconfig->setting_lookup_int(t, "EventNormalChance", &i32) != 0)
+ chance[REFINE_CHANCE_TYPE_E_NORMAL][level] = i32;
else
- chance[level] = 100;
- if (libconfig->setting_lookup_int(t, "Bonus", &i32))
+ chance[REFINE_CHANCE_TYPE_E_NORMAL][level] = 100;
+
+ if (libconfig->setting_lookup_int(t, "EventEnrichedChance", &i32) != 0)
+ chance[REFINE_CHANCE_TYPE_E_ENRICHED][level] = i32;
+ else
+ chance[REFINE_CHANCE_TYPE_E_ENRICHED][level] = level > 10 ? 0 : 100; // enriched ores up to +10 only.
+
+ if (libconfig->setting_lookup_int(t, "Bonus", &i32) != 0)
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].chance[REFINE_CHANCE_TYPE_NORMAL][i] = chance[REFINE_CHANCE_TYPE_NORMAL][i];
+ status->dbs->refine_info[type].chance[REFINE_CHANCE_TYPE_E_NORMAL][i] = chance[REFINE_CHANCE_TYPE_E_NORMAL][i];
+ status->dbs->refine_info[type].chance[REFINE_CHANCE_TYPE_ENRICHED][i] = chance[REFINE_CHANCE_TYPE_ENRICHED][i];
+ status->dbs->refine_info[type].chance[REFINE_CHANCE_TYPE_E_ENRICHED][i] = chance[REFINE_CHANCE_TYPE_E_ENRICHED][i];
status->dbs->refine_info[type].randombonus_max[i] = rnd_bonus[i];
- bonus[i] += bonus_per_level + (i > 0 ? bonus[i-1] : 0);
+ 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;
+
+ return type + 1;
}
/**
@@ -13224,7 +13538,7 @@ int status_readdb_refine_libconfig_sub(struct config_setting_t *r, const char *n
* @param *filename File name, relative to the database path.
* @return The number of found entries.
*/
-int status_readdb_refine_libconfig(const char *filename)
+static int status_readdb_refine_libconfig(const char *filename)
{
bool duplicate[REFINE_TYPE_MAX];
struct config_t refine_db_conf;
@@ -13232,7 +13546,7 @@ int status_readdb_refine_libconfig(const char *filename)
char filepath[256];
int i = 0, count = 0;
- sprintf(filepath, "%s/%s", map->db_path, filename);
+ safesnprintf(filepath, sizeof(filepath), "%s/%s", map->db_path, filename);
if (!libconfig->load_file(&refine_db_conf, filepath))
return 0;
@@ -13256,7 +13570,7 @@ int status_readdb_refine_libconfig(const char *filename)
return count;
}
-bool status_readdb_scconfig(char* fields[], int columns, int current)
+static bool status_readdb_scconfig(char *fields[], int columns, int current)
{
int val = 0;
char* type = fields[0];
@@ -13282,7 +13596,7 @@ bool status_readdb_scconfig(char* fields[], int columns, int current)
* size_fixe.txt
* refine_db.txt
**/
-int status_readdb(void)
+static int status_readdb(void)
{
int i, j;
@@ -13309,15 +13623,6 @@ int status_readdb(void)
for(j = 0; j < MAX_SINGLE_WEAPON_TYPE; j++)
status->dbs->atkmods[i][j] = 100;
- // refine_db.txt
- for(i=0;i<ARRAYLENGTH(status->dbs->refine_info);i++) {
- for(j=0;j<MAX_REFINE; j++) {
- 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);
@@ -13326,13 +13631,15 @@ int status_readdb(void)
sv->readdb(map->db_path, "sc_config.txt", ',', 2, 2, SC_MAX, status->readdb_scconfig);
status->read_job_db();
+ pc->validate_levels();
+
return 0;
}
/*==========================================
-* Status db init and destroy.
-*------------------------------------------*/
-int do_init_status(bool minimal)
+ * Status db init and destroy.
+ *------------------------------------------*/
+static int do_init_status(bool minimal)
{
if (minimal)
return 0;
@@ -13349,16 +13656,16 @@ int do_init_status(bool minimal)
return 0;
}
-void do_final_status(void)
+static void do_final_status(void)
{
ers_destroy(status->data_ers);
}
/*=====================================
-* Default Functions : status.h
-* Generated by HerculesInterfaceMaker
-* created by Susu
-*-------------------------------------*/
+ * Default Functions : status.h
+ * Generated by HerculesInterfaceMaker
+ * created by Susu
+ *-------------------------------------*/
void status_defaults(void)
{
status = &status_s;
@@ -13429,11 +13736,18 @@ void status_defaults(void)
status->change_clear = status_change_clear;
status->change_clear_buffs = status_change_clear_buffs;
+ status->is_immune_to_status = status_is_immune_to_status;
+ status->is_boss_resist_sc = status_is_boss_resist_sc;
+ status->end_sc_before_start = status_end_sc_before_start;
+ status->change_start_stop_action = status_change_start_stop_action;
+ status->change_start_set_option = status_change_start_set_option;
+ status->get_val_flag = status_get_val_flag;
status->calc_bl_ = status_calc_bl_;
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_pc_recover_hp = status_calc_pc_recover_hp;
status->calc_homunculus_ = status_calc_homunculus_;
status->calc_mercenary_ = status_calc_mercenary_;
status->calc_elemental_ = status_calc_elemental_;
@@ -13470,6 +13784,8 @@ void status_defaults(void)
status->base_atk = status_base_atk;
status->get_base_maxhp = status_get_base_maxhp;
status->get_base_maxsp = status_get_base_maxsp;
+ status->get_restart_hp = status_get_restart_hp;
+ status->get_restart_sp = status_get_restart_sp;
status->calc_npc_ = status_calc_npc_;
status->calc_str = status_calc_str;
status->calc_agi = status_calc_agi;
@@ -13496,6 +13812,8 @@ void status_defaults(void)
status->calc_ematk = status_calc_ematk;
status->calc_bl_main = status_calc_bl_main;
status->display_add = status_display_add;
+ status->change_start_display = status_change_start_display;
+ status->change_start_unknown_sc = status_change_start_unknown_sc;
status->display_remove = status_display_remove;
status->natural_heal = status_natural_heal;
status->natural_heal_timer = status_natural_heal_timer;
@@ -13508,8 +13826,6 @@ void status_defaults(void)
status->read_job_db_sub = status_read_job_db_sub;
status->set_sc = status_set_sc;
status->copy = status_copy;
-#ifndef RENEWAL
status->base_matk_min = status_base_matk_min;
-#endif // RENEWAL
status->base_matk_max = status_base_matk_max;
}