summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2013-11-06 15:10:35 -0200
committershennetsind <ind@henn.et>2013-11-06 15:10:35 -0200
commit6f77d070b98c73962a4f45f274a0f5c58a2448e3 (patch)
tree4fa9aa479472fc6cf37803c32df0ad684994b1e5
parent778facb21f822cea549939c8dbee886e1cd342aa (diff)
downloadhercules-6f77d070b98c73962a4f45f274a0f5c58a2448e3.tar.gz
hercules-6f77d070b98c73962a4f45f274a0f5c58a2448e3.tar.bz2
hercules-6f77d070b98c73962a4f45f274a0f5c58a2448e3.tar.xz
hercules-6f77d070b98c73962a4f45f274a0f5c58a2448e3.zip
Modified status_calc_
Replaces the previous 'first' flag with a multi-option flag capable of selectively determining calls where the recalculation must not be hold by delayed damage, and therefore must take place immediately. This fixes issues caused by actions that require immediate recalculation e.g. on-level-up max_hp update, also modified @baselevel where status_calc was being called after the heal and not before, causing it not to be fully healed. Special Thanks to Haruna! <3 Signed-off-by: shennetsind <ind@henn.et>
-rw-r--r--src/map/atcommand.c11
-rw-r--r--src/map/battle.c4
-rw-r--r--src/map/clif.c2
-rw-r--r--src/map/elemental.c2
-rw-r--r--src/map/guild.c2
-rw-r--r--src/map/homunculus.c12
-rw-r--r--src/map/itemdb.c2
-rw-r--r--src/map/mercenary.c2
-rw-r--r--src/map/mob.c6
-rw-r--r--src/map/pc.c64
-rw-r--r--src/map/pet.c16
-rw-r--r--src/map/script.c18
-rw-r--r--src/map/status.c75
-rw-r--r--src/map/status.h38
14 files changed, 132 insertions, 122 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 2abdb5925..7e5d42e69 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -1258,6 +1258,7 @@ ACMD(baselevelup)
sd->status.status_point += status_point;
sd->status.base_level += (unsigned int)level;
+ status_calc_pc(sd, SCO_FORCE);
status_percent_heal(&sd->bl, 100, 100);
clif->misceffect(&sd->bl, 0);
clif->message(fd, msg_txt(21)); // Base level raised.
@@ -1279,13 +1280,13 @@ ACMD(baselevelup)
sd->status.status_point -= status_point;
sd->status.base_level -= (unsigned int)level;
clif->message(fd, msg_txt(22)); // Base level lowered.
+ status_calc_pc(sd, SCO_FORCE);
}
sd->status.base_exp = 0;
clif->updatestatus(sd, SP_STATUSPOINT);
clif->updatestatus(sd, SP_BASELEVEL);
clif->updatestatus(sd, SP_BASEEXP);
clif->updatestatus(sd, SP_NEXTBASEEXP);
- status_calc_pc(sd, 0);
pc->baselevelchanged(sd);
if(sd->status.party_id)
party->send_levelup(sd);
@@ -1338,7 +1339,7 @@ ACMD(joblevelup)
clif->updatestatus(sd, SP_JOBEXP);
clif->updatestatus(sd, SP_NEXTJOBEXP);
clif->updatestatus(sd, SP_SKILLPOINT);
- status_calc_pc(sd, 0);
+ status_calc_pc(sd, SCO_FORCE);
return true;
}
@@ -2352,7 +2353,7 @@ ACMD(param) {
*stats[i] = new_value;
clif->updatestatus(sd, SP_STR + i);
clif->updatestatus(sd, SP_USTR + i);
- status_calc_pc(sd, 0);
+ status_calc_pc(sd, SCO_FORCE);
clif->message(fd, msg_txt(42)); // Stat changed.
} else {
if (value < 0)
@@ -2409,7 +2410,7 @@ ACMD(stat_all) {
}
if (count > 0) { // if at least 1 stat modified
- status_calc_pc(sd, 0);
+ status_calc_pc(sd, SCO_FORCE);
clif->message(fd, msg_txt(84)); // All stats changed!
} else {
if (value < 0)
@@ -6725,7 +6726,7 @@ ACMD(homlevel) {
hd->homunculus.exp += hd->exp_next;
} while( hd->homunculus.level < level && homun->levelup(hd) );
- status_calc_homunculus(hd,0);
+ status_calc_homunculus(hd,SCO_NONE);
status_percent_heal(&hd->bl, 100, 100);
clif->specialeffect(&hd->bl,568,AREA);
return true;
diff --git a/src/map/battle.c b/src/map/battle.c
index 94222f663..499b7e3a0 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -206,7 +206,7 @@ int battle_delay_damage_sub(int tid, int64 tick, int id, intptr_t data) {
if( !target || status->isdead(target) ) {/* nothing we can do */
if( dat->src_type == BL_PC && ( src = map->id2bl(dat->src_id) ) && --((TBL_PC*)src)->delayed_damage == 0 && ((TBL_PC*)src)->state.hold_recalc ) {
((TBL_PC*)src)->state.hold_recalc = 0;
- status_calc_pc(((TBL_PC*)src),0);
+ status_calc_pc(((TBL_PC*)src),SCO_FORCE);
}
ers_free(battle->delay_damage_ers, dat);
return 0;
@@ -237,7 +237,7 @@ int battle_delay_damage_sub(int tid, int64 tick, int id, intptr_t data) {
if( src && src->type == BL_PC && --((TBL_PC*)src)->delayed_damage == 0 && ((TBL_PC*)src)->state.hold_recalc ) {
((TBL_PC*)src)->state.hold_recalc = 0;
- status_calc_pc(((TBL_PC*)src),0);
+ status_calc_pc(((TBL_PC*)src),SCO_FORCE);
}
}
ers_free(battle->delay_damage_ers, dat);
diff --git a/src/map/clif.c b/src/map/clif.c
index c1e7cb1c9..913a94058 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -9473,7 +9473,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
}
map->iwall_get(sd); // Updates Walls Info on this Map to Client
- status_calc_pc(sd, false);/* some conditions are map-dependent so we must recalculate */
+ status_calc_pc(sd, SCO_NONE);/* some conditions are map-dependent so we must recalculate */
sd->state.changemap = false;
if( hChSys.local && hChSys.local_autojoin && !map->list[sd->bl.m].flag.chsysnolocalaj ) {
diff --git a/src/map/elemental.c b/src/map/elemental.c
index f15b735b2..d280f5b81 100644
--- a/src/map/elemental.c
+++ b/src/map/elemental.c
@@ -258,7 +258,7 @@ int elemental_data_received(struct s_elemental *ele, bool flag) {
ed->bl.y = ed->ud.to_y;
map->addiddb(&ed->bl);
- status_calc_elemental(ed,1);
+ status_calc_elemental(ed,SCO_FIRST);
ed->last_spdrain_time = ed->last_thinktime = timer->gettick();
ed->summon_timer = INVALID_TIMER;
elemental->summon_init(ed);
diff --git a/src/map/guild.c b/src/map/guild.c
index 0ae45bede..4dcdb6c46 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -1923,7 +1923,7 @@ int guild_castledatasave(int castle_id, int index, int value)
gc->defense = value;
for (i = 0; i < MAX_GUARDIANS; i++)
if (gc->guardian[i].visible && (gd = map->id2md(gc->guardian[i].id)) != NULL)
- status_calc_mob(gd, 0);
+ status_calc_mob(gd, SCO_NONE);
break;
}
case 4:
diff --git a/src/map/homunculus.c b/src/map/homunculus.c
index 52f0572c0..a7a409011 100644
--- a/src/map/homunculus.c
+++ b/src/map/homunculus.c
@@ -272,7 +272,7 @@ void homunculus_skillup(struct homun_data *hd,uint16 skill_id) {
{
hd->homunculus.hskill[i].lv++;
hd->homunculus.skillpts-- ;
- status_calc_homunculus(hd,0);
+ status_calc_homunculus(hd,SCO_NONE);
if (hd->master) {
clif->homskillup(hd->master, skill_id);
clif->hominfo(hd->master,hd,0);
@@ -413,7 +413,7 @@ bool homunculus_evolve(struct homun_data *hd) {
//status_Calc flag&1 will make current HP/SP be reloaded from hom structure
hom->hp = hd->battle_status.hp;
hom->sp = hd->battle_status.sp;
- status_calc_homunculus(hd,1);
+ status_calc_homunculus(hd,SCO_FIRST);
if (!(battle_config.hom_setting&0x2))
skill->unit_move(&sd->hd->bl,timer->gettick(),1); // apply land skills immediately
@@ -460,7 +460,7 @@ bool homunculus_mutate(struct homun_data *hd, int homun_id) {
hom->hp = hd->battle_status.hp;
hom->sp = hd->battle_status.sp;
hom->prev_class = prev_class;
- status_calc_homunculus(hd,1);
+ status_calc_homunculus(hd,SCO_FIRST);
if (!(battle_config.hom_setting&0x2))
skill->unit_move(&sd->hd->bl,timer->gettick(),1); // apply land skills immediately
@@ -505,7 +505,7 @@ int homunculus_gainexp(struct homun_data *hd,unsigned int exp) {
hd->homunculus.exp = 0;
clif->specialeffect(&hd->bl,568,AREA);
- status_calc_homunculus(hd,0);
+ status_calc_homunculus(hd,SCO_NONE);
status_percent_heal(&hd->bl, 100, 100);
return 0;
}
@@ -757,7 +757,7 @@ bool homunculus_create(struct map_session_data *sd, struct s_homunculus *hom) {
hd->bl.y = hd->ud.to_y;
map->addiddb(&hd->bl);
- status_calc_homunculus(hd,1);
+ status_calc_homunculus(hd,SCO_FIRST);
hd->hungry_timer = INVALID_TIMER;
return true;
@@ -1003,7 +1003,7 @@ bool homunculus_shuffle(struct homun_data *hd) {
memcpy(&hd->homunculus.hskill, &b_skill, sizeof(b_skill));
hd->homunculus.skillpts = skillpts;
clif->homskillinfoblock(sd);
- status_calc_homunculus(hd,0);
+ status_calc_homunculus(hd,SCO_NONE);
status_percent_heal(&hd->bl, 100, 100);
clif->specialeffect(&hd->bl,568,AREA);
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 3fc8d526b..8dd6e9d9d 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -2108,7 +2108,7 @@ void itemdb_reload(void) {
sd->combos.id = NULL;
sd->combos.count = 0;
if( pc->load_combo(sd) > 0 )
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_FORCE);
}
}
diff --git a/src/map/mercenary.c b/src/map/mercenary.c
index 8c74a5e1e..5ea10dc66 100644
--- a/src/map/mercenary.c
+++ b/src/map/mercenary.c
@@ -317,7 +317,7 @@ int merc_data_received(struct s_mercenary *merc, bool flag) {
md->bl.y = md->ud.to_y;
map->addiddb(&md->bl);
- status_calc_mercenary(md,1);
+ status_calc_mercenary(md,SCO_FIRST);
md->contract_timer = INVALID_TIMER;
merc_contract_init(md);
}
diff --git a/src/map/mob.c b/src/map/mob.c
index 97f8ea6c1..3f2ae2a55 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -601,7 +601,7 @@ int mob_spawn_guardian_sub(int tid, int64 tick, int id, intptr_t data) {
memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH);
md->guardian_data->guardup_lv = guardup_lv;
if( guardup_lv )
- status_calc_mob(md, 0); //Give bonuses.
+ status_calc_mob(md, SCO_NONE); //Give bonuses.
return 0;
}
@@ -919,7 +919,7 @@ int mob_spawn (struct mob_data *md)
}
memset(&md->state, 0, sizeof(md->state));
- status_calc_mob(md, 1);
+ status_calc_mob(md, SCO_FIRST);
md->attacked_id = 0;
md->target_id = 0;
md->move_fail_count = 0;
@@ -2725,7 +2725,7 @@ int mob_class_change (struct mob_data *md, int class_)
unit->skillcastcancel(&md->bl, 0);
status->set_viewdata(&md->bl, class_);
clif->class_change(&md->bl, md->vd->class_, 1);
- status_calc_mob(md, 1);
+ status_calc_mob(md, SCO_FIRST);
md->ud.state.speed_changed = 1; //Speed change update.
if (battle_config.monster_class_change_recover) {
diff --git a/src/map/pc.c b/src/map/pc.c
index d1d76fd4c..f5e20b32b 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -1320,7 +1320,7 @@ int pc_reg_received(struct map_session_data *sd)
pc->load_combo(sd);
- status_calc_pc(sd,1);
+ status_calc_pc(sd,SCO_FIRST|SCO_FORCE);
chrif->scdata_request(sd->status.account_id, sd->status.char_id);
intif->Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox
@@ -2028,7 +2028,7 @@ int pc_exeautobonus(struct map_session_data *sd,struct s_autobonus *autobonus)
autobonus->active = timer->add(timer->gettick()+autobonus->duration, pc->endautobonus, sd->bl.id, (intptr_t)autobonus);
sd->state.autobonus |= autobonus->pos;
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
return 0;
}
@@ -2042,7 +2042,7 @@ int pc_endautobonus(int tid, int64 tick, int id, intptr_t data) {
autobonus->active = INVALID_TIMER;
sd->state.autobonus &= ~autobonus->pos;
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
return 0;
}
@@ -3549,7 +3549,7 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) {
} else
clif->addskill(sd,id);
if( !skill->db[index].inf ) //Only recalculate for passive skills.
- status_calc_pc(sd, 0);
+ status_calc_pc(sd, SCO_NONE);
break;
case 1: //Item bonus skill.
if( sd->status.skill[index].id == id ) {
@@ -3583,7 +3583,7 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) {
} else
clif->addskill(sd,id);
if( !skill->db[index].inf ) //Only recalculate for passive skills.
- status_calc_pc(sd, 0);
+ status_calc_pc(sd, SCO_NONE);
break;
default: //Unknown flag?
return 0;
@@ -5789,13 +5789,13 @@ int pc_checkbaselevelup(struct map_session_data *sd) {
} while ((next=pc->nextbaseexp(sd)) > 0 && sd->status.base_exp >= next);
if (battle_config.pet_lv_rate && sd->pd) //<Skotlex> update pet's level
- status_calc_pet(sd->pd,0);
+ status_calc_pet(sd->pd,SCO_NONE);
clif->updatestatus(sd,SP_STATUSPOINT);
clif->updatestatus(sd,SP_BASELEVEL);
clif->updatestatus(sd,SP_BASEEXP);
clif->updatestatus(sd,SP_NEXTBASEEXP);
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_FORCE);
status_percent_heal(&sd->bl,100,100);
if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE) {
@@ -5855,7 +5855,7 @@ int pc_checkjoblevelup(struct map_session_data *sd)
clif->updatestatus(sd,SP_JOBEXP);
clif->updatestatus(sd,SP_NEXTJOBEXP);
clif->updatestatus(sd,SP_SKILLPOINT);
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_FORCE);
clif->misceffect(&sd->bl,1);
if (pc->checkskill(sd, SG_DEVIL) && !pc->nextjobexp(sd))
clif->status_change(&sd->bl,SI_DEVIL1, 1, 0, 0, 0, 1); //Permanent blind effect from SG_DEVIL.
@@ -6143,7 +6143,7 @@ int pc_statusup(struct map_session_data* sd, int type)
val = pc->setstat(sd, type, pc->getstat(sd,type) + 1);
sd->status.status_point -= need;
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
// update increase cost indicator
if( need != pc->need_status_point(sd,type,1) )
@@ -6183,7 +6183,7 @@ int pc_statusup2(struct map_session_data* sd, int type, int val)
max = pc_maxparameter(sd);
val = pc->setstat(sd, type, cap_value(pc->getstat(sd,type) + val, 1, max));
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
// update increase cost indicator
if( need != pc->need_status_point(sd,type,1) )
@@ -6226,7 +6226,7 @@ int pc_skillup(struct map_session_data *sd,uint16 skill_id) {
sd->status.skill[index].lv++;
sd->status.skill_point--;
if( !skill->db[index].inf )
- status_calc_pc(sd,0); // Only recalculate for passive skills.
+ status_calc_pc(sd,SCO_NONE); // Only recalculate for passive skills.
else if( sd->status.skill_point == 0 && (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON) )
pc->calc_skilltree(sd); // Required to grant all TK Ranger skills.
else
@@ -6299,7 +6299,7 @@ int pc_allskillup(struct map_session_data *sd)
sd->status.skill[idx].lv = skill->tree_get_max(id, sd->status.class_); // celest
}
}
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
//Required because if you could level up all skills previously,
//the update will not be sent as only the lv variable changes.
clif->skillinfoblock(sd);
@@ -6389,7 +6389,7 @@ int pc_resetlvl(struct map_session_data* sd,int type)
if ((type == 1 || type == 2 || type == 3) && sd->status.party_id)
party->send_levelup(sd);
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_FORCE);
clif->skillinfoblock(sd);
return 0;
@@ -6454,7 +6454,7 @@ int pc_resetstate(struct map_session_data* sd)
pc_setglobalreg(sd,"TK_MISSION_ID", 0);
}
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
return 1;
}
@@ -6565,7 +6565,7 @@ int pc_resetskill(struct map_session_data* sd, int flag)
if( flag&1 ) {
clif->updatestatus(sd,SP_SKILLPOINT);
clif->skillinfoblock(sd);
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_FORCE);
}
return skill_point;
@@ -6819,7 +6819,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
) { // monster level up [Valaris]
clif->misceffect(&md->bl,0);
md->level++;
- status_calc_mob(md, 0);
+ status_calc_mob(md, SCO_NONE);
status_percent_heal(src,10,0);
if( battle_config.show_mob_info&4 )
@@ -7235,7 +7235,7 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
clif->updatestatus(sd, SP_NEXTBASEEXP);
clif->updatestatus(sd, SP_STATUSPOINT);
clif->updatestatus(sd, SP_BASEEXP);
- status_calc_pc(sd, 0);
+ status_calc_pc(sd, SCO_FORCE);
if(sd->status.party_id)
{
party->send_levelup(sd);
@@ -7252,7 +7252,7 @@ int pc_setparam(struct map_session_data *sd,int type,int val)
// clif->updatestatus(sd, SP_JOBLEVEL); // Gets updated at the bottom
clif->updatestatus(sd, SP_NEXTJOBEXP);
clif->updatestatus(sd, SP_JOBEXP);
- status_calc_pc(sd, 0);
+ status_calc_pc(sd, SCO_FORCE);
break;
case SP_SKILLPOINT:
sd->status.skill_point = val;
@@ -7662,7 +7662,7 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper)
if(sd->status.manner < 0)
clif->changestatus(sd,SP_MANNER,sd->status.manner);
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_FORCE);
pc->checkallowskill(sd);
pc->equiplookall(sd);
@@ -7785,11 +7785,11 @@ int pc_setoption(struct map_session_data *sd,int type)
if( (type&OPTION_RIDING && !(p_type&OPTION_RIDING)) || (type&OPTION_DRAGON && !(p_type&OPTION_DRAGON) && pc->checkskill(sd,RK_DRAGONTRAINING) > 0) ) {
// Mounting
clif->sc_load(&sd->bl,sd->bl.id,AREA,SI_RIDING, 0, 0, 0);
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
} else if( (!(type&OPTION_RIDING) && p_type&OPTION_RIDING) || (!(type&OPTION_DRAGON) && p_type&OPTION_DRAGON) ) {
// Dismount
clif->sc_end(&sd->bl,sd->bl.id,AREA,SI_RIDING);
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
}
#ifndef NEW_CARTS
@@ -7797,11 +7797,11 @@ int pc_setoption(struct map_session_data *sd,int type)
clif->cartlist(sd);
clif->updatestatus(sd, SP_CARTINFO);
if(pc->checkskill(sd, MC_PUSHCART) < 10)
- status_calc_pc(sd,0); //Apply speed penalty.
+ status_calc_pc(sd,SCO_NONE); //Apply speed penalty.
} else if( !( type&OPTION_CART ) && p_type&OPTION_CART ){ //Cart Off
clif->clearcart(sd->fd);
if(pc->checkskill(sd, MC_PUSHCART) < 10)
- status_calc_pc(sd,0); //Remove speed penalty.
+ status_calc_pc(sd,SCO_NONE); //Remove speed penalty.
}
#endif
@@ -7813,18 +7813,18 @@ int pc_setoption(struct map_session_data *sd,int type)
if( (sd->class_&MAPID_THIRDMASK) == MAPID_RANGER ) {
if( type&OPTION_WUGRIDER && !(p_type&OPTION_WUGRIDER) ) { // Mounting
clif->sc_load(&sd->bl,sd->bl.id,AREA,SI_WUGRIDER, 0, 0, 0);
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
} else if( !(type&OPTION_WUGRIDER) && p_type&OPTION_WUGRIDER ) { // Dismount
clif->sc_end(&sd->bl,sd->bl.id,AREA,SI_WUGRIDER);
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
}
}
if( (sd->class_&MAPID_THIRDMASK) == MAPID_MECHANIC ) {
int i;
if( type&OPTION_MADOGEAR && !(p_type&OPTION_MADOGEAR) )
- status_calc_pc(sd, 0);
+ status_calc_pc(sd, SCO_NONE);
else if( !(type&OPTION_MADOGEAR) && p_type&OPTION_MADOGEAR )
- status_calc_pc(sd, 0);
+ status_calc_pc(sd, SCO_NONE);
for( i = 0; i < SC_MAX; i++ ){
if ( !sd->sc.data[i] || !status->get_sc_type(i) )
continue;
@@ -7903,7 +7903,7 @@ int pc_setcart(struct map_session_data *sd,int type) {
}
if(pc->checkskill(sd, MC_PUSHCART) < 10)
- status_calc_pc(sd,0); //Recalc speed penalty.
+ status_calc_pc(sd,SCO_NONE); //Recalc speed penalty.
#else
// Update option
option = sd->sc.option;
@@ -8155,7 +8155,7 @@ int pc_setregistry(struct map_session_data *sd,const char *reg,int val,int type)
i = (!sd->die_counter && (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE);
sd->die_counter = val;
if( i )
- status_calc_pc(sd,0); // Lost the bonus.
+ status_calc_pc(sd,SCO_NONE); // Lost the bonus.
}
else if( !strcmp(reg,"COOK_MASTERY") && sd->cook_mastery != val )
{
@@ -8759,7 +8759,7 @@ int pc_equipitem(struct map_session_data *sd,int n,int req_pos)
}
}
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
if (flag) //Update skill data
clif->skillinfoblock(sd);
@@ -8924,7 +8924,7 @@ int pc_unequipitem(struct map_session_data *sd,int n,int flag) {
if(flag&1 || status_cacl) {
pc->checkallowskill(sd);
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
}
if(sd->sc.data[SC_CRUCIS] && !battle->check_undead(sd->battle_status.race,sd->battle_status.def_ele))
@@ -9029,7 +9029,7 @@ int pc_checkitem(struct map_session_data *sd)
if( calc_flag && sd->state.active ) {
pc->checkallowskill(sd);
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
}
return 0;
diff --git a/src/map/pet.c b/src/map/pet.c
index 7dcf06c02..b75cc5a44 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -65,7 +65,7 @@ void pet_set_intimate(struct pet_data *pd, int value)
pd->pet.intimate = value;
if( (intimate >= battle_config.pet_equip_min_friendly && pd->pet.intimate < battle_config.pet_equip_min_friendly) || (intimate < battle_config.pet_equip_min_friendly && pd->pet.intimate >= battle_config.pet_equip_min_friendly) )
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
}
int pet_create_egg(struct map_session_data *sd, int item_id)
@@ -219,7 +219,7 @@ int pet_hungry(int tid, int64 tick, int id, intptr_t data) {
pd->pet.intimate = 0;
pd->status.speed = pd->db->status.speed;
}
- status_calc_pet(pd, 0);
+ status_calc_pet(pd, SCO_NONE);
clif->send_petdata(sd,pd,1,pd->pet.intimate);
}
clif->send_petdata(sd,pd,2,pd->pet.hungry);
@@ -304,7 +304,7 @@ int pet_return_egg(struct map_session_data *sd, struct pet_data *pd)
pd->pet.incuvate = 1;
unit->free(&pd->bl,CLR_OUTSIGHT);
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
sd->status.pet_id = 0;
return 1;
@@ -360,14 +360,14 @@ int pet_data_init(struct map_session_data *sd, struct s_pet *petinfo)
pd->bl.y = pd->ud.to_y;
map->addiddb(&pd->bl);
- status_calc_pet(pd,1);
+ status_calc_pet(pd,SCO_FIRST);
pd->last_thinktime = timer->gettick();
pd->state.skillbonus = 0;
if( battle_config.pet_status_support )
script->run(pet->db[i].pet_script,0,sd->bl.id,0);
if( pd->petDB && pd->petDB->equip_script )
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
if( battle_config.pet_hungry_delay_rate != 100 )
interval = (pd->petDB->hungry_delay*battle_config.pet_hungry_delay_rate)/100;
@@ -703,7 +703,7 @@ int pet_unequipitem(struct map_session_data *sd, struct pet_data *pd) {
if( pd->state.skillbonus )
{
pd->state.skillbonus = 0;
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
}
if( pd->s_skill && pd->s_skill->timer != INVALID_TIMER )
{
@@ -759,7 +759,7 @@ int pet_food(struct map_session_data *sd, struct pet_data *pd)
}
else if( pd->pet.intimate > 1000 )
pd->pet.intimate = 1000;
- status_calc_pet(pd, 0);
+ status_calc_pet(pd, SCO_NONE);
pd->pet.hungry += pd->petDB->fullness;
if( pd->pet.hungry > 100 )
pd->pet.hungry = 100;
@@ -1062,7 +1062,7 @@ int pet_skill_bonus_timer(int tid, int64 tick, int id, intptr_t data) {
if (pd->state.skillbonus != bonus) {
pd->state.skillbonus = bonus;
- status_calc_pc(sd, 0);
+ status_calc_pc(sd, SCO_NONE);
}
// wait for the next timer
pd->bonus->timer=timer->add(tick+duration,pet->skill_bonus_timer,sd->bl.id,0);
diff --git a/src/map/script.c b/src/map/script.c
index 3b0557235..8fd7f425c 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -12099,7 +12099,7 @@ BUILDIN(nude)
}
if( calcflag )
- status_calc_pc(sd,0);
+ status_calc_pc(sd,SCO_NONE);
return true;
}
@@ -12425,9 +12425,9 @@ BUILDIN(npcwalkto) {
if( nd ) {
unit->bl2ud2(&nd->bl); // ensure nd->ud is safe to edit
if (!nd->status.hp) {
- status_calc_npc(nd, true);
+ status_calc_npc(nd, SCO_FIRST);
} else {
- status_calc_npc(nd, false);
+ status_calc_npc(nd, SCO_NONE);
}
unit->walktoxy(&nd->bl,x,y,0);
}
@@ -14967,9 +14967,9 @@ BUILDIN(unitskilluseid) {
if( bl != NULL ) {
if( bl->type == BL_NPC ) {
if (!((TBL_NPC*)bl)->status.hp) {
- status_calc_npc(((TBL_NPC*)bl), true);
+ status_calc_npc(((TBL_NPC*)bl), SCO_FIRST);
} else {
- status_calc_npc(((TBL_NPC*)bl), false);
+ status_calc_npc(((TBL_NPC*)bl), SCO_NONE);
}
}
unit->skilluse_id(bl, target_id, skill_id, skill_lv);
@@ -15001,9 +15001,9 @@ BUILDIN(unitskillusepos) {
if( bl != NULL ) {
if( bl->type == BL_NPC ) {
if (!((TBL_NPC*)bl)->status.hp) {
- status_calc_npc(((TBL_NPC*)bl), true);
+ status_calc_npc(((TBL_NPC*)bl), SCO_FIRST);
} else {
- status_calc_npc(((TBL_NPC*)bl), false);
+ status_calc_npc(((TBL_NPC*)bl), SCO_NONE);
}
}
unit->skilluse_pos(bl, skill_x, skill_y, skill_id, skill_lv);
@@ -17013,9 +17013,9 @@ BUILDIN(npcskill) {
nd->stat_point = stat_point;
if (!nd->status.hp) {
- status_calc_npc(nd, true);
+ status_calc_npc(nd, SCO_FIRST);
} else {
- status_calc_npc(nd, false);
+ status_calc_npc(nd, SCO_NONE);
}
if (skill->get_inf(skill_id)&INF_GROUND_SKILL) {
diff --git a/src/map/status.c b/src/map/status.c
index c06de4dfe..1df98a957 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -1999,13 +1999,12 @@ void status_calc_misc(struct block_list *bl, struct status_data *st, int level)
//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, bool first) {
+int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt) {
struct status_data *mstatus;
struct block_list *mbl = NULL;
int flag=0;
- if(first)
- { //Set basic level on respawn.
+ if(opt&SCO_FIRST) { //Set basic level on respawn.
if (md->level > 0 && md->level <= MAX_LEVEL && md->level != md->db->lv)
;
else
@@ -2036,7 +2035,7 @@ int status_calc_mob_(struct mob_data* md, bool first) {
aFree(md->base_status);
md->base_status = NULL;
}
- if(first)
+ if(opt&SCO_FIRST)
memcpy(&md->status, &md->db->status, sizeof(struct status_data));
return 0;
}
@@ -2160,18 +2159,18 @@ int status_calc_mob_(struct mob_data* md, bool first) {
}
}
- if( first ) //Initial battle status
+ if( opt&SCO_FIRST ) //Initial battle status
memcpy(&md->status, mstatus, sizeof(struct status_data));
return 1;
}
//Skotlex: Calculates the stats of the given pet.
-int status_calc_pet_(struct pet_data *pd, bool first)
+int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt)
{
nullpo_ret(pd);
- if (first) {
+ if (opt&SCO_FIRST) {
memcpy(&pd->status, &pd->db->status, sizeof(struct status_data));
pd->status.mode = MD_CANMOVE; // pets discard all modes, except walking
pd->status.speed = pd->petDB->speed;
@@ -2189,10 +2188,10 @@ int status_calc_pet_(struct pet_data *pd, bool first)
lv =sd->status.base_level*battle_config.pet_lv_rate/100;
if (lv < 0)
lv = 1;
- if (lv != pd->pet.level || first) {
+ if (lv != pd->pet.level || opt&SCO_FIRST) {
struct status_data *bstat = &pd->db->status, *pstatus = &pd->status;
pd->pet.level = lv;
- if (!first) //Lv Up animation
+ if (! (opt&SCO_FIRST) ) //Lv Up animation
clif->misceffect(&pd->bl, 0);
pstatus->rhw.atk = (bstat->rhw.atk*lv)/pd->db->lv;
pstatus->rhw.atk2 = (bstat->rhw.atk2*lv)/pd->db->lv;
@@ -2214,10 +2213,10 @@ int status_calc_pet_(struct pet_data *pd, bool first)
status->calc_misc(&pd->bl, &pd->status, lv);
- if (!first) //Not done the first time because the pet is not visible yet
+ if (! (opt&SCO_FIRST) ) //Not done the first time because the pet is not visible yet
clif->send_petstatus(sd);
}
- } else if (first) {
+ } else if ( opt&SCO_FIRST ) {
status->calc_misc(&pd->bl, &pd->status, pd->db->lv);
if (!battle_config.pet_lv_rate && pd->pet.level != pd->db->lv)
pd->pet.level = pd->db->lv;
@@ -2295,7 +2294,7 @@ unsigned int status_base_pc_maxsp(struct map_session_data* sd, struct status_dat
//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, bool first) {
+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 = &sd->sc;
@@ -2317,7 +2316,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) {
sd->max_weight = status->max_weight_base[pc->class2idx(sd->status.class_)]+sd->status.str*300;
- if(first) {
+ if(opt&SCO_FIRST) {
//Load Hp/SP from char-received data.
sd->battle_status.hp = sd->status.hp;
sd->battle_status.sp = sd->status.sp;
@@ -2482,7 +2481,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) {
bstatus->def += sd->inventory_data[index]->def;
- if(first && sd->inventory_data[index]->equip_script)
+ if(opt&SCO_FIRST && sd->inventory_data[index]->equip_script)
{ //Execute equip-script on login
script->run(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
if (!calculating)
@@ -2625,7 +2624,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) {
if( k < map->list[sd->bl.m].zone->disabled_items_count )
continue;
- if(first && data->equip_script) {//Execute equip-script on login
+ if(opt&SCO_FIRST && data->equip_script) {//Execute equip-script on login
script->run(data->equip_script,0,sd->bl.id,0);
if (!calculating)
return 1;
@@ -3135,11 +3134,11 @@ int status_calc_pc_(struct map_session_data* sd, bool first) {
return 0;
}
-int status_calc_mercenary_(struct mercenary_data *md, bool first) {
+int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt) {
struct status_data *mstatus = &md->base_status;
struct s_mercenary *merc = &md->mercenary;
- if( first ) {
+ if( opt&SCO_FIRST ) {
memcpy(mstatus, &md->db->status, sizeof(struct status_data));
mstatus->mode = MD_CANMOVE|MD_CANATTACK;
mstatus->hp = mstatus->max_hp;
@@ -3154,7 +3153,7 @@ int status_calc_mercenary_(struct mercenary_data *md, bool first) {
return 0;
}
-int status_calc_homunculus_(struct homun_data *hd, bool first) {
+int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt) {
struct status_data *hstatus = &hd->base_status;
struct s_homunculus *hom = &hd->homunculus;
int skill_lv;
@@ -3167,7 +3166,7 @@ int status_calc_homunculus_(struct homun_data *hd, bool first) {
hstatus->int_ = hom->int_ / 10;
hstatus->luk = hom->luk / 10;
- if (first) { //[orn]
+ if ( opt&SCO_FIRST ) { //[orn]
const struct s_homunculus_db *db = hd->homunculusDB;
hstatus->def_ele = db->element;
hstatus->ele_lv = 1;
@@ -3207,7 +3206,7 @@ int status_calc_homunculus_(struct homun_data *hd, bool first) {
if((skill_lv = homun->checkskill(hd,HLIF_BRAIN)) > 0)
hstatus->max_sp += (1 +skill_lv/2 -skill_lv/4 +skill_lv/5) * hstatus->max_sp / 100;
- if (first) {
+ if ( opt&SCO_FIRST ) {
hd->battle_status.hp = hom->hp;
hd->battle_status.sp = hom->sp;
}
@@ -3231,7 +3230,7 @@ int status_calc_homunculus_(struct homun_data *hd, bool first) {
return 1;
}
-int status_calc_elemental_(struct elemental_data *ed, bool first) {
+int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt) {
struct status_data *estatus = &ed->base_status;
struct s_elemental *ele = &ed->elemental;
struct map_session_data *sd = ed->master;
@@ -3239,7 +3238,7 @@ int status_calc_elemental_(struct elemental_data *ed, bool first) {
if( !sd )
return 0;
- if( first ) {
+ if( opt&SCO_FIRST ) {
memcpy(estatus, &ed->db->status, sizeof(struct status_data));
if( !ele->mode )
estatus->mode = EL_MODE_PASSIVE;
@@ -3270,13 +3269,13 @@ int status_calc_elemental_(struct elemental_data *ed, bool first) {
return 0;
}
-int status_calc_npc_(struct npc_data *nd, bool first) {
+int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt) {
struct status_data *nstatus = &nd->status;
if (!nd)
return 0;
- if (first) {
+ if ( opt&SCO_FIRST ) {
nstatus->hp = 1;
nstatus->sp = 1;
nstatus->max_hp = 1;
@@ -3863,13 +3862,17 @@ 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, bool first) {
+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
if( bl->type == BL_PC && ((TBL_PC*)bl)->delayed_damage != 0 ) {
- ((TBL_PC*)bl)->state.hold_recalc = 1;
- return;
+ if( opt&SCO_FORCE )
+ ((TBL_PC*)bl)->state.hold_recalc = 0;/* clear and move on */
+ else {
+ ((TBL_PC*)bl)->state.hold_recalc = 1;/* flag and stop */
+ return;
+ }
}
// remember previous values
@@ -3878,25 +3881,25 @@ void status_calc_bl_(struct block_list *bl, enum scb_flag flag, bool first) {
if( flag&SCB_BASE ) {// calculate the object's base status too
switch( bl->type ) {
- case BL_PC: status->calc_pc_(BL_CAST(BL_PC,bl), first); break;
- case BL_MOB: status->calc_mob_(BL_CAST(BL_MOB,bl), first); break;
- case BL_PET: status->calc_pet_(BL_CAST(BL_PET,bl), first); break;
- case BL_HOM: status->calc_homunculus_(BL_CAST(BL_HOM,bl), first); break;
- case BL_MER: status->calc_mercenary_(BL_CAST(BL_MER,bl), first); break;
- case BL_ELEM: status->calc_elemental_(BL_CAST(BL_ELEM,bl), first); break;
- case BL_NPC: status->calc_npc_(BL_CAST(BL_NPC,bl), first); break;
+ case BL_PC: status->calc_pc_(BL_CAST(BL_PC,bl), opt); break;
+ case BL_MOB: status->calc_mob_(BL_CAST(BL_MOB,bl), opt); break;
+ case BL_PET: status->calc_pet_(BL_CAST(BL_PET,bl), opt); break;
+ case BL_HOM: status->calc_homunculus_(BL_CAST(BL_HOM,bl), opt); break;
+ case BL_MER: status->calc_mercenary_(BL_CAST(BL_MER,bl), opt); break;
+ case BL_ELEM: status->calc_elemental_(BL_CAST(BL_ELEM,bl), opt); break;
+ case BL_NPC: status->calc_npc_(BL_CAST(BL_NPC,bl), opt); break;
}
}
if( bl->type == BL_PET )
return; // pets are not affected by statuses
- if( first && bl->type == BL_MOB )
+ if( opt&SCO_FIRST && bl->type == BL_MOB )
return; // assume there will be no statuses active
status->calc_bl_main(bl, flag);
- if( first && bl->type == BL_HOM )
+ if( opt&SCO_FIRST && bl->type == BL_HOM )
return; // client update handled by caller
// compare against new values and send client updates
diff --git a/src/map/status.h b/src/map/status.h
index 254f3bfab..e588fbb3f 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -1627,6 +1627,12 @@ enum e_regen {
RGN_SSP = 0x08,
};
+enum e_status_calc_opt {
+ SCO_NONE = 0x0,
+ SCO_FIRST = 0x1, /* trigger the calculations that should take place only onspawn/once */
+ SCO_FORCE = 0x2, /* only relevant to BL_PC types, ensures call bypasses the queue caused by delayed damage */
+};
+
//Define to determine who gets HP/SP consumed on doing skills/etc. [Skotlex]
#define BL_CONSUME (BL_PC|BL_HOM|BL_MER|BL_ELEM)
//Define to determine who has regen
@@ -1810,14 +1816,14 @@ struct status_change {
#define status_change_end(bl,type,tid) status->change_end_(bl,type,tid,__FILE__,__LINE__)
-#define status_calc_bl(bl, flag) status->calc_bl_(bl, (enum scb_flag)(flag), false)
-#define status_calc_mob(md, first) status->calc_bl_(&(md)->bl, SCB_ALL, first)
-#define status_calc_pet(pd, first) status->calc_bl_(&(pd)->bl, SCB_ALL, first)
-#define status_calc_pc(sd, first) status->calc_bl_(&(sd)->bl, SCB_ALL, first)
-#define status_calc_homunculus(hd, first) status->calc_bl_(&(hd)->bl, SCB_ALL, first)
-#define status_calc_mercenary(md, first) status->calc_bl_(&(md)->bl, SCB_ALL, first)
-#define status_calc_elemental(ed, first) status->calc_bl_(&(ed)->bl, SCB_ALL, first)
-#define status_calc_npc(nd, first) status->calc_bl_(&(nd)->bl, SCB_ALL, first)
+#define status_calc_bl(bl, flag) status->calc_bl_(bl, (enum scb_flag)(flag), SCO_NONE)
+#define status_calc_mob(md, opt) status->calc_bl_(&(md)->bl, SCB_ALL, opt)
+#define status_calc_pet(pd, opt) status->calc_bl_(&(pd)->bl, SCB_ALL, opt)
+#define status_calc_pc(sd, opt) status->calc_bl_(&(sd)->bl, SCB_ALL, opt)
+#define status_calc_homunculus(hd, opt) status->calc_bl_(&(hd)->bl, SCB_ALL, opt)
+#define status_calc_mercenary(md, opt) status->calc_bl_(&(md)->bl, SCB_ALL, opt)
+#define status_calc_elemental(ed, opt) status->calc_bl_(&(ed)->bl, SCB_ALL, opt)
+#define status_calc_npc(nd, opt) status->calc_bl_(&(nd)->bl, SCB_ALL, opt)
// bonus values and upgrade chances for refining equipment
struct s_refine_info {
@@ -1911,13 +1917,13 @@ struct status_interface {
int (*change_timer_sub) (struct block_list* bl, va_list ap);
int (*change_clear) (struct block_list* bl, int type);
int (*change_clear_buffs) (struct block_list* bl, int type);
- void (*calc_bl_) (struct block_list *bl, enum scb_flag flag, bool first);
- int (*calc_mob_) (struct mob_data* md, bool first);
- int (*calc_pet_) (struct pet_data* pd, bool first);
- int (*calc_pc_) (struct map_session_data* sd, bool first);
- int (*calc_homunculus_) (struct homun_data *hd, bool first);
- int (*calc_mercenary_) (struct mercenary_data *md, bool first);
- int (*calc_elemental_) (struct elemental_data *ed, bool first);
+ void (*calc_bl_) (struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt);
+ int (*calc_mob_) (struct mob_data* md, enum e_status_calc_opt opt);
+ int (*calc_pet_) (struct pet_data* pd, enum e_status_calc_opt opt);
+ int (*calc_pc_) (struct map_session_data* sd, enum e_status_calc_opt opt);
+ int (*calc_homunculus_) (struct homun_data *hd, enum e_status_calc_opt opt);
+ int (*calc_mercenary_) (struct mercenary_data *md, enum e_status_calc_opt opt);
+ int (*calc_elemental_) (struct elemental_data *ed, enum e_status_calc_opt opt);
void (*calc_misc) (struct block_list *bl, struct status_data *status, int level);
void (*calc_regen) (struct block_list *bl, struct status_data *st, struct regen_data *regen);
void (*calc_regen_rate) (struct block_list *bl, struct regen_data *regen, struct status_change *sc);
@@ -1943,7 +1949,7 @@ struct status_interface {
void (*calc_sigma) (void);
unsigned int (*base_pc_maxhp) (struct map_session_data *sd, struct status_data *st);
unsigned int (*base_pc_maxsp) (struct map_session_data *sd, struct status_data *st);
- int (*calc_npc_) (struct npc_data *nd, bool first);
+ int (*calc_npc_) (struct npc_data *nd, enum e_status_calc_opt opt);
unsigned short (*calc_str) (struct block_list *bl, struct status_change *sc, int str);
unsigned short (*calc_agi) (struct block_list *bl, struct status_change *sc, int agi);
unsigned short (*calc_vit) (struct block_list *bl, struct status_change *sc, int vit);