diff --git a/src/map/pc.cpp b/src/map/pc.cpp index f03e8de2ac..74ca30901c 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -2789,11 +2789,11 @@ s_autobonus::~s_autobonus(){ * @param onskill: Skill used to trigger autobonus * @return True on success or false otherwise */ -bool pc_addautobonus(std::vector &bonus, const char *script, short rate, unsigned int dur, uint16 flag, const char *other_script, unsigned int pos, bool onskill){ +bool pc_addautobonus(std::vector> &bonus, const char *script, short rate, unsigned int dur, uint16 flag, const char *other_script, unsigned int pos, bool onskill){ // Check if the same bonus already exists - for( s_autobonus& autobonus : bonus ){ + for( std::shared_ptr autobonus : bonus ){ // Compare based on position and bonus script - if( autobonus.pos == pos && strcmp( script, autobonus.bonus_script ) == 0 ){ + if( autobonus->pos == pos && strcmp( script, autobonus->bonus_script ) == 0 ){ return false; } } @@ -2816,18 +2816,18 @@ bool pc_addautobonus(std::vector &bonus, const char *script, short } } - struct s_autobonus entry = {}; + std::shared_ptr entry = std::make_shared(); if (rate < -10000 || rate > 10000) ShowWarning("pc_addautobonus: Item bonus rate %d exceeds -10000~10000 range, capping.\n", rate); - entry.rate = cap_value(rate, -10000, 10000); - entry.duration = dur; - entry.active = INVALID_TIMER; - entry.atk_type = flag; - entry.pos = pos; - entry.bonus_script = aStrdup(script); - entry.other_script = (other_script ? aStrdup(other_script) : NULL); + entry->rate = cap_value(rate, -10000, 10000); + entry->duration = dur; + entry->active = INVALID_TIMER; + entry->atk_type = flag; + entry->pos = pos; + entry->bonus_script = aStrdup(script); + entry->other_script = (other_script ? aStrdup(other_script) : NULL); bonus.push_back(entry); @@ -2840,26 +2840,23 @@ bool pc_addautobonus(std::vector &bonus, const char *script, short * @param bonus: Autobonus array * @param restore: Run script on clearing or not */ -void pc_delautobonus(struct map_session_data* sd, std::vector &bonus, bool restore) -{ - nullpo_retv(sd); - - std::vector::iterator it = bonus.begin(); +void pc_delautobonus(struct map_session_data &sd, std::vector> &bonus, bool restore){ + std::vector>::iterator it = bonus.begin(); while( it != bonus.end() ){ - s_autobonus b = *it; + std::shared_ptr b = *it; - if( b.active != INVALID_TIMER && restore && b.bonus_script != nullptr ){ + if( b->active != INVALID_TIMER && restore && b->bonus_script != nullptr ){ unsigned int equip_pos_idx = 0; // Create a list of all equipped positions to see if all items needed for the autobonus are still present [Playtester] for (uint8 j = 0; j < EQI_MAX; j++) { - if (sd->equip_index[j] >= 0) - equip_pos_idx |= sd->inventory.u.items_inventory[sd->equip_index[j]].equip; + if (sd.equip_index[j] >= 0) + equip_pos_idx |= sd.inventory.u.items_inventory[sd.equip_index[j]].equip; } - if( ( equip_pos_idx&b.pos ) == b.pos ){ - script_run_autobonus(b.bonus_script, sd, b.pos); + if( ( equip_pos_idx&b->pos ) == b->pos ){ + script_run_autobonus(b->bonus_script, &sd, b->pos); }else{ // Not all required items equipped anymore restore = false; @@ -2880,11 +2877,8 @@ void pc_delautobonus(struct map_session_data* sd, std::vector &bonu * @param sd: Player data * @param autobonus: Autobonus to run */ -void pc_exeautobonus(struct map_session_data *sd, std::vector *bonus, struct s_autobonus *autobonus) +void pc_exeautobonus(struct map_session_data &sd, std::vector> *bonus, std::shared_ptr autobonus) { - nullpo_retv(sd); - nullpo_retv(autobonus); - if (autobonus->active != INVALID_TIMER) delete_timer(autobonus->active, pc_endautobonus); @@ -2894,15 +2888,15 @@ void pc_exeautobonus(struct map_session_data *sd, std::vector *bonu unsigned int equip_pos_idx = 0; //Create a list of all equipped positions to see if all items needed for the autobonus are still present [Playtester] for(j = 0; j < EQI_MAX; j++) { - if(sd->equip_index[j] >= 0) - equip_pos_idx |= sd->inventory.u.items_inventory[sd->equip_index[j]].equip; + if(sd.equip_index[j] >= 0) + equip_pos_idx |= sd.inventory.u.items_inventory[sd.equip_index[j]].equip; } if((equip_pos_idx&autobonus->pos) == autobonus->pos) - script_run_autobonus(autobonus->other_script,sd,autobonus->pos); + script_run_autobonus(autobonus->other_script,&sd,autobonus->pos); } - autobonus->active = add_timer(gettick()+autobonus->duration, pc_endautobonus, sd->bl.id, (intptr_t)bonus); - status_calc_pc(sd,SCO_FORCE); + autobonus->active = add_timer(gettick()+autobonus->duration, pc_endautobonus, sd.bl.id, (intptr_t)bonus); + status_calc_pc(&sd,SCO_FORCE); } /** @@ -2910,14 +2904,14 @@ void pc_exeautobonus(struct map_session_data *sd, std::vector *bonu */ TIMER_FUNC(pc_endautobonus){ struct map_session_data *sd = map_id2sd(id); - std::vector *bonus = (std::vector *)data; + std::vector> *bonus = (std::vector> *)data; nullpo_ret(sd); nullpo_ret(bonus); - for( struct s_autobonus& autobonus : *bonus ){ - if( autobonus.active == tid ){ - autobonus.active = INVALID_TIMER; + for( std::shared_ptr autobonus : *bonus ){ + if( autobonus->active == tid ){ + autobonus->active = INVALID_TIMER; break; } } @@ -10800,13 +10794,13 @@ bool pc_equipitem(struct map_session_data *sd,short n,int req_pos,bool equipswit return true; } -static void pc_deleteautobonus( std::vector& bonus, int position ){ - std::vector::iterator it = bonus.begin(); +static void pc_deleteautobonus( std::vector>& bonus, int position ){ + std::vector>::iterator it = bonus.begin(); while( it != bonus.end() ){ - s_autobonus b = *it; + std::shared_ptr b = *it; - if( ( b.pos & position ) != b.pos ){ + if( ( b->pos & position ) != b->pos ){ it++; continue; } diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 42a56ef566..f9846fcccf 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -492,7 +492,7 @@ struct map_session_data { std::vector subele2; std::vector sp_vanish, hp_vanish; std::vector subrace3; - std::vector autobonus, autobonus2, autobonus3; //Auto script on attack, when attacked, on skill usage + std::vector> autobonus, autobonus2, autobonus3; //Auto script on attack, when attacked, on skill usage // zeroed structures start here struct s_regen { @@ -1240,10 +1240,10 @@ bool pc_adoption(struct map_session_data *p1_sd, struct map_session_data *p2_sd, void pc_updateweightstatus(struct map_session_data *sd); -bool pc_addautobonus(std::vector &bonus, const char *script, short rate, unsigned int dur, uint16 atk_type, const char *o_script, unsigned int pos, bool onskill); -void pc_exeautobonus(struct map_session_data* sd, std::vector *bonus, struct s_autobonus *autobonus); +bool pc_addautobonus(std::vector> &bonus, const char *script, short rate, unsigned int dur, uint16 atk_type, const char *o_script, unsigned int pos, bool onskill); +void pc_exeautobonus(struct map_session_data &sd, std::vector> *bonus, std::shared_ptr autobonus); TIMER_FUNC(pc_endautobonus); -void pc_delautobonus(struct map_session_data* sd, std::vector &bonus, bool restore); +void pc_delautobonus(struct map_session_data &sd, std::vector> &bonus, bool restore); void pc_bonus(struct map_session_data *sd, int type, int val); void pc_bonus2(struct map_session_data *sd, int type, int type2, int val); diff --git a/src/map/skill.cpp b/src/map/skill.cpp index b58a023162..9f4ef287d0 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -2246,13 +2246,13 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1 if( sd && !sd->autobonus.empty() ) { for(auto &it : sd->autobonus) { - if (rnd()%1000 >= it.rate) + if (rnd()%1000 >= it->rate) continue; - if (!(((it.atk_type)&attack_type)&BF_WEAPONMASK && - ((it.atk_type)&attack_type)&BF_RANGEMASK && - ((it.atk_type)&attack_type)&BF_SKILLMASK)) + if (!(((it->atk_type)&attack_type)&BF_WEAPONMASK && + ((it->atk_type)&attack_type)&BF_RANGEMASK && + ((it->atk_type)&attack_type)&BF_SKILLMASK)) continue; // one or more trigger conditions were not fulfilled - pc_exeautobonus(sd, &sd->autobonus, &it); + pc_exeautobonus(*sd, &sd->autobonus, it); } } @@ -2330,11 +2330,11 @@ int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint1 if( sd && !sd->autobonus3.empty() ) { for (auto &it : sd->autobonus3) { - if (rnd()%1000 >= it.rate) + if (rnd()%1000 >= it->rate) continue; - if (it.atk_type != skill_id) + if (it->atk_type != skill_id) continue; - pc_exeautobonus(sd, &sd->autobonus3, &it); + pc_exeautobonus(*sd, &sd->autobonus3, it); } } @@ -2552,13 +2552,13 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * //Autobonus when attacked if( dstsd && !status_isdead(bl) && !dstsd->autobonus2.empty() && !(skill_id && skill_get_nk(skill_id, NK_NODAMAGE)) ) { for (auto &it : dstsd->autobonus2) { - if (rnd()%1000 >= it.rate) + if (rnd()%1000 >= it->rate) continue; - if (!(((it.atk_type)&attack_type)&BF_WEAPONMASK && - ((it.atk_type)&attack_type)&BF_RANGEMASK && - ((it.atk_type)&attack_type)&BF_SKILLMASK)) + if (!(((it->atk_type)&attack_type)&BF_WEAPONMASK && + ((it->atk_type)&attack_type)&BF_RANGEMASK && + ((it->atk_type)&attack_type)&BF_SKILLMASK)) continue; // one or more trigger conditions were not fulfilled - pc_exeautobonus(dstsd, &dstsd->autobonus2, &it); + pc_exeautobonus(*dstsd, &dstsd->autobonus2, it); } } diff --git a/src/map/status.cpp b/src/map/status.cpp index badf030b3a..faacc5759a 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -4271,9 +4271,9 @@ int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt) memset(&sd->bonus, 0, sizeof(sd->bonus)); // Autobonus - pc_delautobonus(sd, sd->autobonus, true); - pc_delautobonus(sd, sd->autobonus2, true); - pc_delautobonus(sd, sd->autobonus3, true); + pc_delautobonus(*sd, sd->autobonus, true); + pc_delautobonus(*sd, sd->autobonus2, true); + pc_delautobonus(*sd, sd->autobonus3, true); // Parse equipment for (i = 0; i < EQI_MAX; i++) { diff --git a/src/map/unit.cpp b/src/map/unit.cpp index 98cd5e7c43..750b86769e 100644 --- a/src/map/unit.cpp +++ b/src/map/unit.cpp @@ -3369,9 +3369,9 @@ int unit_free(struct block_list *bl, clr_type clrtype) pc_delinvincibletimer(sd); - pc_delautobonus(sd, sd->autobonus, false); - pc_delautobonus(sd, sd->autobonus2, false); - pc_delautobonus(sd, sd->autobonus3, false); + pc_delautobonus(*sd, sd->autobonus, false); + pc_delautobonus(*sd, sd->autobonus2, false); + pc_delautobonus(*sd, sd->autobonus3, false); if( sd->followtimer != INVALID_TIMER ) pc_stop_following(sd);