Modified status_calc_* to support multiple options. (Hercules 6f77d07)

This commit is contained in:
aleos89
2014-05-20 10:41:15 -04:00
parent 2688d78e6a
commit 2732176786
16 changed files with 263 additions and 240 deletions

View File

@@ -1398,6 +1398,7 @@ ACMD_FUNC(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_displaymessage(fd, msg_txt(sd,21)); // Base level raised.
@@ -1419,13 +1420,13 @@ ACMD_FUNC(baselevelup)
sd->status.status_point -= status_point;
sd->status.base_level -= (unsigned int)level;
clif_displaymessage(fd, msg_txt(sd,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);
@@ -1479,7 +1480,7 @@ ACMD_FUNC(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 0;
}
@@ -2539,7 +2540,7 @@ ACMD_FUNC(param)
*status[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_displaymessage(fd, msg_txt(sd,42)); // Stat changed.
} else {
if (value < 0)
@@ -2610,7 +2611,7 @@ ACMD_FUNC(stat_all)
}
if (count > 0) { // if at least 1 stat modified
status_calc_pc(sd, 0);
status_calc_pc(sd, SCO_FORCE);
clif_displaymessage(fd, msg_txt(sd,84)); // All stats changed!
} else {
if (value < 0)
@@ -7146,13 +7147,14 @@ ACMD_FUNC(homlevel)
for (i = 1; i <= level && hd->exp_next; i++){
hd->homunculus.exp += hd->exp_next;
if( !hom_levelup(hd) ){
if( !hom_levelup(hd) )
break;
}
}
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 0;
}

View File

@@ -213,16 +213,22 @@ struct delay_damage {
enum damage_lv dmg_lv;
unsigned short attack_type;
bool additional_effects;
enum bl_type src_type;
};
int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) {
struct delay_damage *dat = (struct delay_damage *)data;
if ( dat ) {
struct block_list* src;
struct block_list* src = NULL;
struct block_list* target = map_id2bl(dat->target_id);
if( !target || status_isdead(target) ) {/* nothing we can do */
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), SCO_FORCE);
}
ers_free(delay_damage_ers, dat);
return 0;
}
@@ -248,12 +254,17 @@ int battle_delay_damage_sub(int tid, unsigned int tick, int id, intptr_t data) {
status_fix_damage(target, target, dat->damage, dat->delay);
map_freeblock_unlock();
}
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), SCO_FORCE);
}
}
ers_free(delay_damage_ers, dat);
return 0;
}
int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects)
int battle_delay_damage(unsigned int tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, int ddelay, bool additional_effects)
{
struct delay_damage *dat;
struct status_change *sc;
@@ -286,18 +297,24 @@ int battle_delay_damage (unsigned int tick, int amotion, struct block_list *src,
dat->delay = ddelay;
dat->distance = distance_bl(src, target)+10; //Attack should connect regardless unless you teleported.
dat->additional_effects = additional_effects;
dat->src_type = src->type;
if (src->type != BL_PC && amotion > 1000)
amotion = 1000; //Aegis places a damage-delay cap of 1 sec to non player attacks. [Skotlex]
if( src->type == BL_PC )
((TBL_PC*)src)->delayed_damage++;
add_timer(tick+amotion, battle_delay_damage_sub, 0, (intptr_t)dat);
return 0;
}
int battle_attr_ratio(int atk_elem,int def_type, int def_lv){
int battle_attr_ratio(int atk_elem,int def_type, int def_lv) {
if (atk_elem < ELE_NEUTRAL || atk_elem >= ELE_ALL)
return 100;
if (def_type < ELE_NEUTRAL || def_type > ELE_ALL || def_lv < 1 || def_lv > 4)
return 100;
return attr_fix_table[def_lv-1][atk_elem][def_type];
}
@@ -2569,12 +2586,10 @@ struct Damage battle_calc_damage_parts(struct Damage wd, struct block_list *src,
wd.statusAtk += battle_calc_status_attack(sstatus, EQI_HAND_R);
wd.statusAtk2 += battle_calc_status_attack(sstatus, EQI_HAND_L);
if (skill_id || (sd && sd->sc.data[SC_SEVENWIND])) {
// Mild Wind applies element to status ATK as well as weapon ATK [helvetica]
if (skill_id || (sd && sd->sc.data[SC_SEVENWIND])) { // Mild Wind applies element to status ATK as well as weapon ATK [helvetica]
wd.statusAtk = (int)battle_attr_fix(src, target, wd.statusAtk, right_element, tstatus->def_ele, tstatus->ele_lv);
wd.statusAtk2 = (int)battle_attr_fix(src, target, wd.statusAtk, left_element, tstatus->def_ele, tstatus->ele_lv);
}
else { // status atk is considered neutral on normal attacks [helvetica]
} else { // status atk is considered neutral on normal attacks [helvetica]
wd.statusAtk = (int)battle_attr_fix(src, target, wd.statusAtk, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv);
wd.statusAtk2 = (int)battle_attr_fix(src, target, wd.statusAtk, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv);
}
@@ -4775,6 +4790,7 @@ void battle_do_reflect(int attack_type, struct Damage *wd, struct block_list* sr
}
}
}
/*============================================
* Calculate "weapon"-type attacks and skills
*--------------------------------------------
@@ -5886,7 +5902,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
memset(&md,0,sizeof(md));
if( src == NULL || target == NULL ){
if (src == NULL || target == NULL) {
nullpo_info(NLP_MARK);
return md;
}
@@ -5918,8 +5934,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
//Skill Range Criteria
md.flag |= battle_range_type(src, target, skill_id, skill_lv);
switch( skill_id )
{
switch (skill_id) {
case NC_MAGMA_ERUPTION:
md.damage = 1200 + 400 * skill_lv;
break;
@@ -7281,7 +7296,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
if(s_guild && t_guild && (s_guild == t_guild || (!(flag&BCT_SAMEGUILD) && guild_isallied(s_guild, t_guild))))
state |= BCT_GUILD;
}
} //end non pvp/gvg chk rivality
} //end non pvp/gvg chk rivality
if( !state ) //If not an enemy, nor a guild, nor party, nor yourself, it's neutral.
state = BCT_NEUTRAL;

View File

@@ -1897,7 +1897,7 @@ int chrif_load_bsdata(int fd) {
calc = true;
}
if (calc)
status_calc_pc(sd,false);
status_calc_pc(sd,SCO_NONE);
return 0;
}

View File

@@ -9758,7 +9758,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;
// Instances do not need their own channels

View File

@@ -263,7 +263,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 = gettick();
ed->summon_timer = INVALID_TIMER;
ed->masterteleport_timer = INVALID_TIMER;

View File

@@ -1876,7 +1876,7 @@ int guild_castledatasave(int castle_id, int index, int value) {
for (i = 0; i < MAX_GUARDIANS; i++){
struct mob_data *gd;
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;
}

View File

@@ -300,7 +300,7 @@ void hom_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);
@@ -417,8 +417,7 @@ int hom_evolution(struct homun_data *hd)
struct map_session_data *sd;
nullpo_ret(hd);
if(!hd->homunculusDB->evo_class || hd->homunculus.class_ == hd->homunculusDB->evo_class)
{
if(!hd->homunculusDB->evo_class || hd->homunculus.class_ == hd->homunculusDB->evo_class) {
clif_emotion(&hd->bl, E_SWT);
return 0 ;
}
@@ -456,7 +455,7 @@ int hom_evolution(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,gettick(),1); // apply land skills immediately
@@ -510,7 +509,7 @@ int hom_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,gettick(),1); // apply land skills immediately
@@ -556,7 +555,7 @@ int hom_gainexp(struct homun_data *hd,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;
}
@@ -785,7 +784,8 @@ int hom_search(int key,int type)
}
// Create homunc structure
void hom_alloc(struct map_session_data *sd, struct s_homunculus *hom) {
void hom_alloc(struct map_session_data *sd, struct s_homunculus *hom)
{
struct homun_data *hd;
int i = 0;
@@ -823,7 +823,8 @@ void hom_alloc(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);
status_percent_heal(&hd->bl, 100, 100);
hd->hungry_timer = INVALID_TIMER;
hd->masterteleport_timer = INVALID_TIMER;
@@ -1093,7 +1094,7 @@ int hom_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);

View File

@@ -1753,14 +1753,13 @@ 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);
}
}
mapit_free(iter);
}
/**
* Finalizing Item DB
*/

View File

@@ -341,7 +341,8 @@ void merc_contract_init(struct mercenary_data *md) {
* @param flag : if inter-serv request was sucessfull
* @return false:failure, true:sucess
*/
bool mercenary_recv_data(struct s_mercenary *merc, bool flag){
bool mercenary_recv_data(struct s_mercenary *merc, bool flag)
{
struct map_session_data *sd;
struct mercenary_data *md;
struct s_mercenary_db *db;
@@ -349,15 +350,13 @@ bool mercenary_recv_data(struct s_mercenary *merc, bool flag){
if( (sd = map_charid2sd(merc->char_id)) == NULL )
return false;
if( !flag || i < 0 )
{ // Not created - loaded - DB info
if( !flag || i < 0 ) { // Not created - loaded - DB info
sd->status.mer_id = 0;
return false;
}
db = &mercenary_db[i];
if( !sd->md )
{
if( !sd->md ) {
sd->md = md = (struct mercenary_data*)aCalloc(1,sizeof(struct mercenary_data));
md->bl.type = BL_MER;
md->bl.id = npc_get_new_npc_id();
@@ -379,13 +378,11 @@ bool mercenary_recv_data(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;
md->masterteleport_timer = INVALID_TIMER;
merc_contract_init(md);
}
else
{
} else {
memcpy(&sd->md->mercenary, merc, sizeof(struct s_mercenary));
md = sd->md;
}
@@ -394,8 +391,7 @@ bool mercenary_recv_data(struct s_mercenary *merc, bool flag){
mercenary_set_calls(md, 1);
sd->status.mer_id = merc->mercenary_id;
if( md && md->bl.prev == NULL && sd->bl.prev != NULL )
{
if( md && md->bl.prev == NULL && sd->bl.prev != NULL ) {
if(map_addblock(&md->bl))
return false;
clif_spawn(&md->bl);

View File

@@ -612,7 +612,7 @@ static int mob_spawn_guardian_sub(int tid, unsigned int tick, int id, intptr_t d
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;
}
@@ -943,14 +943,13 @@ 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;
md->ud.state.attack_continue = 0;
md->ud.target_to = 0;
if( md->spawn_timer != INVALID_TIMER )
{
if( md->spawn_timer != INVALID_TIMER ) {
delete_timer(md->spawn_timer, mob_delayspawn);
md->spawn_timer = INVALID_TIMER;
}
@@ -2796,7 +2795,7 @@ int mob_class_change (struct mob_data *md, int mob_id)
unit_skillcastcancel(&md->bl, 0);
status_set_viewdata(&md->bl, mob_id);
clif_mob_class_change(md,md->vd->class_);
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) {

View File

@@ -1093,6 +1093,8 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
sd->guild_x = -1;
sd->guild_y = -1;
sd->delayed_damage = 0;
// Event Timers
for( i = 0; i < MAX_EVENTTIMER; i++ )
sd->eventtimer[i] = INVALID_TIMER;
@@ -1313,7 +1315,7 @@ int pc_reg_received(struct map_session_data *sd)
pc_check_available_item(sd); // Check for invalid(ated) items.
pc_load_combo(sd);
status_calc_pc(sd,1);
status_calc_pc(sd, (enum e_status_calc_opt)(SCO_FIRST|SCO_FORCE));
chrif_scdata_request(sd->status.account_id, sd->status.char_id);
chrif_skillcooldown_request(sd->status.account_id, sd->status.char_id);
chrif_bsdata_request(sd->status.char_id);
@@ -2070,7 +2072,7 @@ void pc_exeautobonus(struct map_session_data *sd,struct s_autobonus *autobonus)
autobonus->active = 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);
}
int pc_endautobonus(int tid, unsigned int tick, int id, intptr_t data)
@@ -2083,7 +2085,7 @@ int pc_endautobonus(int tid, unsigned int 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;
}
@@ -3660,10 +3662,10 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag)
} else
clif_addskill(sd,id);
if( !skill_get_inf(id) ) //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[id].id == id ){
if( sd->status.skill[id].id == id ) {
if( sd->status.skill[id].lv >= level )
return 0;
if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT ) //Non-granted skill, store it's level.
@@ -3675,7 +3677,7 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag)
sd->status.skill[id].lv = level;
break;
case 2: //Add skill bonus on top of what you had.
if( sd->status.skill[id].id == id ){
if( sd->status.skill[id].id == id ) {
if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT )
sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv; // Store previous level.
} else {
@@ -3694,7 +3696,7 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag)
} else
clif_addskill(sd,id);
if( !skill_get_inf(id) ) //Only recalculate for passive skills.
status_calc_pc(sd, 0);
status_calc_pc(sd, SCO_NONE);
break;
default: //Unknown flag?
return 0;
@@ -4314,6 +4316,7 @@ int pc_isUseitem(struct map_session_data *sd,int n)
return 0;
if( (item->item_usage.flag&NOUSE_SITTING) && (pc_issit(sd) == 1) && (pc_get_group_level(sd) < item->item_usage.override) ) {
clif_msgtable(sd->fd,ITEM_NOUSE_SITTING);
return 0; // You cannot use this item while sitting.
}
@@ -4478,7 +4481,7 @@ int pc_useitem(struct map_session_data *sd,int n)
nullpo_ret(sd);
if( sd->npc_id ){
if (sd->npc_id) {
#ifdef RENEWAL
clif_msg(sd, USAGE_FAIL); // TODO look for the client date that has this message.
return 0;
@@ -4489,7 +4492,7 @@ int pc_useitem(struct map_session_data *sd,int n)
}
item = sd->status.inventory[n];
id = sd->inventory_data[n];
if (item.nameid <= 0 || item.amount <= 0)
return 0;
@@ -5933,13 +5936,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) {
@@ -5999,7 +6002,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_DEVIL, 1, 0, 0, 0, 1); //Permanent blind effect from SG_DEVIL.
@@ -6336,7 +6339,7 @@ bool pc_statusup(struct map_session_data* sd, int type, int increase)
final_value = pc_setstat(sd, type, current + increase);
sd->status.status_point -= needed_points;
status_calc_pc(sd, 0);
status_calc_pc(sd,SCO_NONE);
// update increase cost indicator
clif_updatestatus(sd, SP_USTR + type-SP_STR);
@@ -6380,7 +6383,7 @@ int pc_statusup2(struct map_session_data* sd, int type, int val)
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) )
@@ -6426,7 +6429,7 @@ int pc_skillup(struct map_session_data *sd,uint16 skill_id)
sd->status.skill[skill_id].lv++;
sd->status.skill_point--;
if( !skill_get_inf(skill_id) )
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 Ranker skills.
else
@@ -6494,7 +6497,7 @@ int pc_allskillup(struct map_session_data *sd)
sd->status.skill[id].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);
@@ -6584,7 +6587,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;
@@ -6649,7 +6652,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;
}
@@ -6760,11 +6763,10 @@ int pc_resetskill(struct map_session_data* sd, int flag)
sd->status.skill_point += skill_point;
if( flag&1 )
{
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;
@@ -7053,7 +7055,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 )
@@ -7450,11 +7452,9 @@ bool 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_NONE);
if(sd->status.party_id)
{
party_send_levelup(sd);
}
break;
case SP_JOBLEVEL:
if ((unsigned int)val >= sd->status.job_level) {
@@ -7900,7 +7900,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);
@@ -8012,12 +8012,12 @@ void 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_status_load(&sd->bl,SI_RIDING,1);
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 && pc_checkskill(sd,RK_DRAGONTRAINING) > 0) )
{ // Dismount
clif_status_load(&sd->bl,SI_RIDING,0);
status_calc_pc(sd,0);
status_calc_pc(sd,SCO_NONE);
}
#ifndef NEW_CARTS
@@ -8025,7 +8025,7 @@ void 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)
@@ -8041,15 +8041,15 @@ void 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_status_load(&sd->bl,SI_WUGRIDER,1);
status_calc_pc(sd,0);
status_calc_pc(sd,SCO_NONE);
} else if( !(type&OPTION_WUGRIDER) && p_type&OPTION_WUGRIDER ) { // Dismount
clif_status_load(&sd->bl,SI_WUGRIDER,0);
status_calc_pc(sd,0);
status_calc_pc(sd,SCO_NONE);
}
}
if( (sd->class_&MAPID_THIRDMASK) == MAPID_MECHANIC ) {
if( type&OPTION_MADOGEAR && !(p_type&OPTION_MADOGEAR) ) {
status_calc_pc(sd, 0);
status_calc_pc(sd,SCO_NONE);
status_change_end(&sd->bl,SC_MAXIMIZEPOWER,INVALID_TIMER);
status_change_end(&sd->bl,SC_OVERTHRUST,INVALID_TIMER);
status_change_end(&sd->bl,SC_WEAPONPERFECTION,INVALID_TIMER);
@@ -8058,7 +8058,7 @@ void pc_setoption(struct map_session_data *sd,int type)
status_change_end(&sd->bl,SC_MELTDOWN,INVALID_TIMER);
status_change_end(&sd->bl,SC_MAXOVERTHRUST,INVALID_TIMER);
} else if( !(type&OPTION_MADOGEAR) && p_type&OPTION_MADOGEAR ) {
status_calc_pc(sd, 0);
status_calc_pc(sd,SCO_NONE);
status_change_end(&sd->bl,SC_SHAPESHIFT,INVALID_TIMER);
status_change_end(&sd->bl,SC_HOVERING,INVALID_TIMER);
status_change_end(&sd->bl,SC_ACCELERATION,INVALID_TIMER);
@@ -8124,7 +8124,7 @@ bool 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;
@@ -8368,15 +8368,12 @@ bool pc_setregistry(struct map_session_data *sd,const char *reg,int val,int type
switch( type )
{
case 3: //Char reg
if( !strcmp(reg,"PC_DIE_COUNTER") && sd->die_counter != val )
{
if( !strcmp(reg,"PC_DIE_COUNTER") && sd->die_counter != val ) {
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.
}
else if( !strcmp(reg,"COOK_MASTERY") && sd->cook_mastery != val )
{
status_calc_pc(sd,SCO_NONE); // Lost the bonus.
} else if( !strcmp(reg,"COOK_MASTERY") && sd->cook_mastery != val ) {
val = cap_value(val, 0, 1999);
sd->cook_mastery = val;
}
@@ -8385,13 +8382,10 @@ bool pc_setregistry(struct map_session_data *sd,const char *reg,int val,int type
regmax = GLOBAL_REG_NUM;
break;
case 2: //Account reg
if( !strcmp(reg,"#CASHPOINTS") && sd->cashPoints != val )
{
if( !strcmp(reg,"#CASHPOINTS") && sd->cashPoints != val ) {
val = cap_value(val, 0, MAX_ZENY);
sd->cashPoints = val;
}
else if( !strcmp(reg,"#KAFRAPOINTS") && sd->kafraPoints != val )
{
} else if( !strcmp(reg,"#KAFRAPOINTS") && sd->kafraPoints != val ) {
val = cap_value(val, 0, MAX_ZENY);
sd->kafraPoints = val;
}
@@ -8995,7 +8989,7 @@ bool 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);
@@ -9169,7 +9163,7 @@ bool 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_SIGNUMCRUCIS] && !battle_check_undead(sd->battle_status.race,sd->battle_status.def_ele))
@@ -9235,10 +9229,8 @@ void 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;
}
/*==========================================
@@ -9536,7 +9528,7 @@ void pc_setsavepoint(struct map_session_data *sd, short mapindex,int x,int y)
}
/*==========================================
* Save 1 player data at autosave intervalle
* Save 1 player data at autosave interval
*------------------------------------------*/
static int pc_autosave(int tid, unsigned int tick, int id, intptr_t data)
{
@@ -10671,7 +10663,7 @@ int pc_bonus_script_timer(int tid, unsigned int tick, int id, intptr_t data) {
}
pc_bonus_script_remove(sd,i);
status_calc_pc(sd,false);
status_calc_pc(sd,SCO_NONE);
return 0;
}
@@ -10718,7 +10710,7 @@ void pc_bonus_script_clear(struct map_session_data *sd, uint16 flag) {
}
}
if (count && !(flag&BONUS_FLAG_REM_ON_LOGOUT)) //Don't need to do this if log out
status_calc_pc(sd,false);
status_calc_pc(sd,SCO_NONE);
}
/** [Cydh]

View File

@@ -207,6 +207,7 @@ struct map_session_data {
unsigned int prevend : 1;//used to flag wheather you've spent 40sp to open the vending or not.
unsigned int warping : 1;//states whether you're in the middle of a warp processing
unsigned int permanent_speed : 1; // When 1, speed cannot be changed through status_calc_pc().
unsigned int hold_recalc : 1;
unsigned int banking : 1; //1 when we using the banking system 0 when closed
unsigned int hpmeter_visible : 1;
bool disable_atcommand_on_npc; //Prevent to use atcommand while talking with NPC [Kichi]
@@ -565,6 +566,8 @@ struct map_session_data {
struct sc_display_entry **sc_display;
unsigned char sc_display_count;
unsigned char delayed_damage; //[Ind]
// temporary debugging of bug #3504
const char* delunit_prevfile;
int delunit_prevline;

View File

@@ -68,7 +68,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)
@@ -225,7 +225,7 @@ static int pet_hungry(int tid, unsigned int 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);
@@ -310,7 +310,7 @@ static 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;
@@ -366,19 +366,24 @@ int pet_data_init(struct map_session_data *sd, struct s_pet *pet)
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 = gettick();
pd->state.skillbonus = 0;
if( battle_config.pet_status_support )
run_script(pet_db[i].pet_script,0,sd->bl.id,0);
if( pd->petDB && pd->petDB->equip_script )
status_calc_pc(sd,0);
if( battle_config.pet_hungry_delay_rate != 100 )
interval = (pd->petDB->hungry_delay*battle_config.pet_hungry_delay_rate)/100;
else
interval = pd->petDB->hungry_delay;
if( pd->petDB ) {
if( pd->petDB->equip_script )
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;
else
interval = pd->petDB->hungry_delay;
}
if( interval <= 0 )
interval = 1;
pd->pet_hungry_timer = add_timer(gettick() + interval, pet_hungry, sd->bl.id, 0);
@@ -717,23 +722,19 @@ static int pet_unequipitem(struct map_session_data *sd, struct pet_data *pd)
clif_additem(sd,0,0,flag);
map_addflooritem(&tmp_item,1,sd->bl.m,sd->bl.x,sd->bl.y,0,0,0,0);
}
if( battle_config.pet_equip_required )
{ // Skotlex: halt support timers if needed
if( pd->state.skillbonus )
{
if( battle_config.pet_equip_required ) { // Skotlex: halt support timers if needed
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 )
{
if( pd->s_skill && pd->s_skill->timer != INVALID_TIMER ) {
if( pd->s_skill->id )
delete_timer(pd->s_skill->timer, pet_skill_support_timer);
else
delete_timer(pd->s_skill->timer, pet_heal_timer);
pd->s_skill->timer = INVALID_TIMER;
}
if( pd->bonus && pd->bonus->timer != INVALID_TIMER )
{
if( pd->bonus && pd->bonus->timer != INVALID_TIMER ) {
delete_timer(pd->bonus->timer, pet_skill_bonus_timer);
pd->bonus->timer = INVALID_TIMER;
}
@@ -746,9 +747,9 @@ static int pet_food(struct map_session_data *sd, struct pet_data *pd)
{
int i,k;
k=pd->petDB->FoodID;
i=pc_search_inventory(sd,k);
if(i < 0) {
k = pd->petDB->FoodID;
i = pc_search_inventory(sd,k);
if( i < 0 ) {
clif_pet_food(sd,k,0);
return 1;
}
@@ -756,29 +757,25 @@ static int pet_food(struct map_session_data *sd, struct pet_data *pd)
if( pd->pet.hungry > 90 )
pet_set_intimate(pd, pd->pet.intimate - pd->petDB->r_full);
else
{
else {
if( battle_config.pet_friendly_rate != 100 )
k = (pd->petDB->r_hungry * battle_config.pet_friendly_rate)/100;
k = (pd->petDB->r_hungry * battle_config.pet_friendly_rate) / 100;
else
k = pd->petDB->r_hungry;
if( pd->pet.hungry > 75 )
{
if( pd->pet.hungry > 75 ) {
k = k >> 1;
if( k <= 0 )
k = 1;
}
pet_set_intimate(pd, pd->pet.intimate + k);
}
if( pd->pet.intimate <= 0 )
{
if( pd->pet.intimate <= 0 ) {
pd->pet.intimate = 0;
pet_stop_attack(pd);
pd->status.speed = pd->db->status.speed;
}
else if( pd->pet.intimate > 1000 )
} 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;
@@ -1087,7 +1084,7 @@ int pet_skill_bonus_timer(int tid, unsigned int 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=add_timer(tick+timer,pet_skill_bonus_timer,sd->bl.id,0);

View File

@@ -10998,7 +10998,6 @@ static void script_detach_rid(struct script_state* st)
}
}
/*=========================================================================
* Attaches a set of RIDs to the current script. [digitalhamster]
* addrid(<type>{,<flag>{,<parameters>}});
@@ -11016,17 +11015,17 @@ static void script_detach_rid(struct script_state* st)
* 0 : Players are always attached. (default)
* 1 : Players currently running another script will not be attached.
*-------------------------------------------------------------------------*/
static int buildin_addrid_sub(struct block_list *bl,va_list ap)
{
int forceflag;
struct map_session_data *sd = (TBL_PC *)bl;
struct script_state* st;
st=va_arg(ap,struct script_state*);
forceflag=va_arg(ap,int);
if(!forceflag||!sd->st)
if(sd->status.account_id!=st->rid)
st = va_arg(ap,struct script_state*);
forceflag = va_arg(ap,int);
if(!forceflag || !sd->st)
if(sd->status.account_id != st->rid)
run_script(st->script,st->pos,sd->status.account_id,st->oid);
return 0;
}
@@ -11036,46 +11035,48 @@ BUILDIN_FUNC(addrid)
struct s_mapiterator* iter;
struct block_list *bl;
TBL_PC *sd;
if(st->rid<1){
if(st->rid < 1) {
st->state = END;
bl=map_id2bl(st->oid);
bl = map_id2bl(st->oid);
} else
bl=map_id2bl(st->rid); //if run without rid it'd error,also oid if npc, else rid for map
bl = map_id2bl(st->rid); //if run without rid it'd error,also oid if npc, else rid for map
iter = mapit_getallusers();
switch(script_getnum(st,2)){
switch(script_getnum(st,2)) {
case 0:
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter)){
if(!script_getnum(st,3)||!sd->st)
if(sd->status.account_id!=st->rid) //attached player already runs.
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter)) {
if(!script_getnum(st,3) || !sd->st)
if(sd->status.account_id != st->rid) //attached player already runs.
run_script(st->script,st->pos,sd->status.account_id,st->oid);
}
break;
case 1:
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter)){
if(!script_getnum(st,3)||!sd->st)
if((sd->bl.m == bl->m)&&(sd->status.account_id!=st->rid))
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter)) {
if(!script_getnum(st,3) || !sd->st)
if((sd->bl.m == bl->m) && (sd->status.account_id != st->rid))
run_script(st->script,st->pos,sd->status.account_id,st->oid);
}
break;
case 2:
if(script_getnum(st,4)==0){
if(script_getnum(st,4) == 0) {
script_pushint(st,0);
return 0;
}
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter)){
if(!script_getnum(st,3)||!sd->st)
if((sd->status.account_id!=st->rid)&&(sd->status.party_id==script_getnum(st,4))) //attached player already runs.
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter)) {
if(!script_getnum(st,3) || !sd->st)
if((sd->status.account_id != st->rid) && (sd->status.party_id == script_getnum(st,4))) //attached player already runs.
run_script(st->script,st->pos,sd->status.account_id,st->oid);
}
break;
case 3:
if(script_getnum(st,4)==0){
if(script_getnum(st,4) == 0) {
script_pushint(st,0);
return 0;
}
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter)){
if(!script_getnum(st,3)||!sd->st)
if((sd->status.account_id!=st->rid)&&(sd->status.guild_id==script_getnum(st,4))) //attached player already runs.
for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter)) {
if(!script_getnum(st,3) || !sd->st)
if((sd->status.account_id != st->rid) && (sd->status.guild_id == script_getnum(st,4))) //attached player already runs.
run_script(st->script,st->pos,sd->status.account_id,st->oid);
}
break;
@@ -11085,11 +11086,11 @@ BUILDIN_FUNC(addrid)
st,script_getnum(st,3));//4-x0 , 5-y0 , 6-x1, 7-y1
break;
default:
if((map_id2sd(script_getnum(st,2)))==NULL){ // Player not found.
if((map_id2sd(script_getnum(st,2))) == NULL) { // Player not found.
script_pushint(st,0);
return 0;
}
if(!script_getnum(st,3)||!map_id2sd(script_getnum(st,2))->st) {
if(!script_getnum(st,3) || !map_id2sd(script_getnum(st,2))->st) {
run_script(st->script,st->pos,script_getnum(st,2),st->oid);
script_pushint(st,1);
}
@@ -13170,11 +13171,11 @@ BUILDIN_FUNC(nude)
}
if( calcflag )
status_calc_pc(sd,0);
status_calc_pc(sd,SCO_NONE);
return SCRIPT_CMD_SUCCESS;
}
int atcommand_sub(struct script_state* st,int type){
int atcommand_sub(struct script_state* st,int type) {
TBL_PC dummy_sd;
TBL_PC* sd;
int fd;
@@ -13627,11 +13628,10 @@ BUILDIN_FUNC(npcwalkto)
y=script_getnum(st,3);
if(nd) {
if (!nd->status.hp) {
status_calc_npc(nd, true);
} else {
status_calc_npc(nd, false);
}
if (!nd->status.hp)
status_calc_npc(nd, SCO_FIRST);
else
status_calc_npc(nd, SCO_NONE);
unit_walktoxy(&nd->bl,x,y,0);
}
return SCRIPT_CMD_SUCCESS;
@@ -18123,17 +18123,16 @@ BUILDIN_FUNC(npcskill)
nd->level = npc_level;
nd->stat_point = stat_point;
if (!nd->status.hp) {
status_calc_npc(nd, true);
} else {
status_calc_npc(nd, false);
}
if (!nd->status.hp)
status_calc_npc(nd, SCO_FIRST);
else
status_calc_npc(nd, SCO_NONE);
if (skill_get_inf(skill_id)&INF_GROUND_SKILL) {
if (skill_get_inf(skill_id)&INF_GROUND_SKILL)
unit_skilluse_pos(&nd->bl, sd->bl.x, sd->bl.y, skill_id, skill_level);
} else {
else
unit_skilluse_id(&nd->bl, sd->bl.id, skill_id, skill_level);
}
return SCRIPT_CMD_SUCCESS;
}
@@ -18723,7 +18722,7 @@ BUILDIN_FUNC(bonus_script) {
if (sd->bonus_script[i].icon != SI_BLANK) //Gives status icon if exist
clif_status_change(&sd->bl,sd->bonus_script[i].icon,1,dur,1,0,0);
status_calc_pc(sd,false);
status_calc_pc(sd,SCO_NONE);
return SCRIPT_CMD_SUCCESS;
}

View File

@@ -2282,17 +2282,17 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev
/** [Skotlex]
* Calculates the initial status for the given mob
* @param md: Mob object
* @param first: Whether or not it is the first calculation
* @param opt: Whether or not it is the first calculation
This will only be false when a mob levels up (Regular and WoE Guardians)
* @return 1 for calculated special statuses or 0 for none
**/
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 *status;
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
@@ -2322,7 +2322,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;
}
@@ -2476,7 +2476,7 @@ 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, status, sizeof(struct status_data));
return 1;
@@ -2485,15 +2485,15 @@ int status_calc_mob_(struct mob_data* md, bool first)
/** [Skotlex]
* Calculates the stats of the given pet
* @param pd: Pet object
* @param first: Whether or not it is the first calculation
* @param opt: Whether or not it is the first calculation
This will only be false when a pet levels up
* @return 1
**/
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.class_ = CLASS_NORMAL;
@@ -2512,10 +2512,11 @@ 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, *status = &pd->status;
pd->pet.level = lv;
if (!first) // Lv Up animation
if (!(opt&SCO_FIRST)) // Lv Up animation
clif_misceffect(&pd->bl, 0);
status->rhw.atk = (bstat->rhw.atk*lv)/pd->db->lv;
status->rhw.atk2 = (bstat->rhw.atk2*lv)/pd->db->lv;
@@ -2537,10 +2538,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;
@@ -2751,7 +2752,7 @@ static unsigned int status_calc_maxhpsp_pc(struct map_session_data* sd, unsigned
uint16 idx, level, job_id;
nullpo_ret(sd);
job_id = pc_mapid2jobid(sd->class_,sd->status.sex);
idx = pc_class2idx(job_id);
level = max(sd->status.base_level,1);
@@ -2774,10 +2775,10 @@ static unsigned int status_calc_maxhpsp_pc(struct map_session_data* sd, unsigned
* Calculates player data from scratch without counting SC adjustments
* Should be invoked whenever players raise stats, learn passive skills or change equipment
* @param sd: Player object
* @param first: Whether it is first calc (login) or not
* @param opt: Whether it is first calc (login) or not
* @return (-1) for too many recursive calls, (1) recursive call, (0) success
**/
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 *status; ///< Pointer to the player's base status
@@ -2799,7 +2800,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
sd->max_weight = job_info[pc_class2idx(sd->status.class_)].max_weight_base+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;
@@ -2961,7 +2962,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
status->def += sd->inventory_data[index]->def;
// Items may be equipped, their effects however are nullified.
if(first && sd->inventory_data[index]->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT)
if (opt&SCO_FIRST && sd->inventory_data[index]->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT)
|| !itemdb_isNoEquip(sd->inventory_data[index],sd->bl.m))) { // Execute equip-script on login
run_script(sd->inventory_data[index]->equip_script,0,sd->bl.id,0);
if (!calculating)
@@ -3112,7 +3113,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
data = itemdb_exists(c);
if(!data)
continue;
if(first && data->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(data,sd->bl.m))) {// Execute equip-script on login
if (opt&SCO_FIRST && data->equip_script && (pc_has_permission(sd,PC_PERM_USE_ALL_EQUIPMENT) || !itemdb_isNoEquip(data,sd->bl.m))) {// Execute equip-script on login
run_script(data->equip_script,0,sd->bl.id,0);
if (!calculating)
return 1;
@@ -3608,15 +3609,15 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
/**
* Calculates Mercenary data
* @param md: Mercenary object
* @param first: Whether it is first calc or not (0 on level up or status)
* @param opt: Whether it is first calc or not (0 on level up or status)
* @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 *status = &md->base_status;
struct s_mercenary *merc = &md->mercenary;
if( first ) {
if (opt&SCO_FIRST) {
memcpy(status, &md->db->status, sizeof(struct status_data));
status->class_ = CLASS_NORMAL;
status->mode = MD_CANMOVE|MD_CANATTACK;
@@ -3637,10 +3638,10 @@ int status_calc_mercenary_(struct mercenary_data *md, bool first)
/**
* Calculates Homunculus data
* @param hd: Homunculus object
* @param first: Whether it is first calc or not (0 on level up or status)
* @param opt: Whether it is first calc or not (0 on level up or status)
* @return 1
**/
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 *status = &hd->base_status;
struct s_homunculus *hom = &hd->homunculus;
@@ -3654,7 +3655,7 @@ int status_calc_homunculus_(struct homun_data *hd, bool first)
status->int_ = hom->int_ / 10;
status->luk = hom->luk / 10;
if (first) {
if (opt&SCO_FIRST) {
const struct s_homunculus_db *db = hd->homunculusDB;
status->def_ele = db->element;
status->ele_lv = 1;
@@ -3710,7 +3711,7 @@ int status_calc_homunculus_(struct homun_data *hd, bool first)
if((skill = hom_checkskill(hd,HLIF_BRAIN)) > 0)
status->max_sp += (1 +skill/2 -skill/4 +skill/5) * status->max_sp / 100 ;
if (first) {
if (opt&SCO_FIRST) {
hd->battle_status.hp = hom->hp ;
hd->battle_status.sp = hom->sp ;
if(hom->class_ == 6052) // Eleanor
@@ -3735,10 +3736,10 @@ int status_calc_homunculus_(struct homun_data *hd, bool first)
/**
* Calculates Elemental data
* @param ed: Elemental object
* @param first: Whether it is first calc or not (0 on status change)
* @param opt: Whether it is first calc or not (0 on status change)
* @return 0
**/
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 *status = &ed->base_status;
struct s_elemental *ele = &ed->elemental;
@@ -3747,7 +3748,7 @@ int status_calc_elemental_(struct elemental_data *ed, bool first)
if( !sd )
return 0;
if( first ) {
if (opt&SCO_FIRST) {
memcpy(status, &ed->db->status, sizeof(struct status_data));
if( !ele->mode )
status->mode = EL_MODE_PASSIVE;
@@ -3785,17 +3786,17 @@ int status_calc_elemental_(struct elemental_data *ed, bool first)
/**
* Calculates NPC data
* @param nd: NPC object
* @param first: Whether it is first calc or not (what?)
* @param opt: Whether it is first calc or not (what?)
* @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 *status = &nd->status;
if (!nd)
return 0;
if (first) {
if (opt&SCO_FIRST) {
status->hp = 1;
status->sp = 1;
status->max_hp = 1;
@@ -4550,38 +4551,47 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
* See [set_sc] [add_sc]
* @param bl: Object whose status has changed [PC|MOB|HOM|MER|ELEM]
* @param flag: Which status has changed on bl
* @param first: If true, will cause status_calc_* functions to run their base status initialization code
* @param opt: 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 b_status; // Previous battle status
struct status_data* status; // Pointer to current battle status
if (bl->type == BL_PC && ((TBL_PC*)bl)->delayed_damage != 0) {
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
status = status_get_status_data(bl);
memcpy(&b_status, status, sizeof(struct status_data));
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( first && bl->type == BL_MOB )
if (opt&SCO_FIRST && bl->type == BL_MOB)
return; // Assume there will be no statuses active
if( bl->type == BL_PET )
return; // Pets are not affected by statuses
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
@@ -10192,8 +10202,11 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
status_calc_state(bl,sc,( enum scs_flag ) StatusChangeStateTable[type],true);
if(sd && sd->pd)
pet_sc_check(sd, type); // Skotlex: Pet Status Effect Healing
if(sd) {
if (sd->pd)
pet_sc_check(sd, type); // Skotlex: Pet Status Effect Healing
status_calc_pc(sd, SCO_NONE);
}
// 1st thing to execute when loading status
switch (type) {

View File

@@ -1725,6 +1725,12 @@ enum scb_flag
SCB_ALL = 0x3FFFFFFF
};
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 */
};
///Enum for bonus_script's flag
enum e_bonus_script_flags {
BONUS_FLAG_REM_ON_DEAD = 0x01, //Remove bonus when dead
@@ -1992,22 +1998,23 @@ int status_change_timer_sub(struct block_list* bl, va_list ap);
int status_change_clear(struct block_list* bl, int type);
void status_change_clear_buffs(struct block_list* bl, int type);
#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)
void status_calc_bl_(struct block_list *bl, enum scb_flag flag, bool first);
int status_calc_mob_(struct mob_data* md, bool first);
int status_calc_pet_(struct pet_data* pd, bool first);
int status_calc_pc_(struct map_session_data* sd, bool first);
int status_calc_homunculus_(struct homun_data *hd, bool first);
int status_calc_mercenary_(struct mercenary_data *md, bool first);
int status_calc_elemental_(struct elemental_data *ed, bool first);
void status_calc_bl_(struct block_list *bl, enum scb_flag flag, enum e_status_calc_opt opt);
int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt);
int status_calc_pet_(struct pet_data* pd, enum e_status_calc_opt opt);
int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt);
int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt);
int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt);
int status_calc_elemental_(struct elemental_data *ed, enum e_status_calc_opt opt);
int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt);
void status_calc_misc(struct block_list *bl, struct status_data *status, int level);
void status_calc_regen(struct block_list *bl, struct status_data *status, struct regen_data *regen);