diff --git a/doc/item_bonus.txt b/doc/item_bonus.txt index c79d8bd720..d9173d4b7d 100644 --- a/doc/item_bonus.txt +++ b/doc/item_bonus.txt @@ -187,13 +187,16 @@ bonus bNoMiscDamage,n; Adds n% reduction to received misc damage Healing ------- -bonus bHealPower,n; Increases heal amount of all heal skills by n% -bonus bHealPower2,n; Increases heal amount if you are healed by any skills by n% -bonus2 bSkillHeal,sk,n; Increases heal amount of skill sk by n% -bonus2 bSkillHeal2,sk,n; Increases heal amount if you are healed by skill sk by n% -bonus bAddItemHealRate,n; Increases HP recovered by n% for healing items -bonus2 bAddItemHealRate,iid,n; Increases HP recovered by n% for item iid -bonus2 bAddItemGroupHealRate,ig,n; Increases HP recovered by n% for items of item group ig +bonus bHealPower,n; Increases heal amount of all heal skills by n% +bonus bHealPower2,n; Increases heal amount if you are healed by any skills by n% +bonus2 bSkillHeal,sk,n; Increases heal amount of skill sk by n% +bonus2 bSkillHeal2,sk,n; Increases heal amount if you are healed by skill sk by n% +bonus bAddItemHealRate,n; Increases HP recovered by n% for healing items +bonus2 bAddItemHealRate,iid,n; Increases HP recovered by n% for item iid +bonus2 bAddItemGroupHealRate,ig,n; Increases HP recovered by n% for items of item group ig +bonus bAddItemSPHealRate,n; Increases SP recovered by n% for healing items +bonus2 bAddItemSPHealRate,iid,n; Increases SP recovered by n% for item iid +bonus2 bAddItemGroupSPHealRate,ig,n; Increases SP recovered by n% for items of item group ig Cast time/delay --------------- diff --git a/src/map/map.hpp b/src/map/map.hpp index 8d4d687839..fdb2c4f647 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -515,7 +515,7 @@ enum _sp { SP_WEAPON_ATK_RATE, SP_WEAPON_MATK_RATE, SP_DROP_ADDRACE, SP_DROP_ADDCLASS, SP_NO_MADO_FUEL, // 2083-2087 SP_IGNORE_DEF_CLASS_RATE, SP_REGEN_PERCENT_HP, SP_REGEN_PERCENT_SP, SP_SKILL_DELAY, SP_NO_WALK_DELAY, //2088-2092 SP_LONG_SP_GAIN_VALUE, SP_LONG_HP_GAIN_VALUE, SP_SHORT_ATK_RATE, SP_MAGIC_SUBSIZE, SP_CRIT_DEF_RATE, // 2093-2097 - SP_MAGIC_SUBDEF_ELE, SP_REDUCE_DAMAGE_RETURN // 2098-2099 + SP_MAGIC_SUBDEF_ELE, SP_REDUCE_DAMAGE_RETURN, SP_ADD_ITEM_SPHEAL_RATE, SP_ADD_ITEMGROUP_SPHEAL_RATE, // 2098-2101 }; enum _look { diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 6d5b55a4a9..746a1b76e7 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -3780,6 +3780,10 @@ void pc_bonus(struct map_session_data *sd,int type,int val) if (sd->state.lr_flag != 2) sd->special_state.no_walk_delay = 1; break; + case SP_ADD_ITEM_SPHEAL_RATE: + if(sd->state.lr_flag != 2) + sd->bonus.itemsphealrate2 += val; + break; default: if (current_equip_combo_pos > 0) { ShowWarning("pc_bonus: unknown bonus type %d %d in a combo with item #%u\n", type, val, sd->inventory_data[pc_checkequip( sd, current_equip_combo_pos )]->nameid); @@ -4112,7 +4116,7 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val) case SP_ADD_ITEM_HEAL_RATE: // bonus2 bAddItemHealRate,iid,n; if(sd->state.lr_flag == 2) break; - if (!itemdb_exists(type2)) { + if( !item_db.exists( type2 ) ){ ShowWarning("pc_bonus2: SP_ADD_ITEM_HEAL_RATE Invalid item with id %d\n", type2); break; } @@ -4130,7 +4134,7 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val) ShowWarning("pc_bonus2: SP_ADD_ITEMGROUP_HEAL_RATE: Invalid item group with id %d\n", type2); break; } - if (sd->itemhealrate.size() == MAX_PC_BONUS) { + if (sd->itemgrouphealrate.size() == MAX_PC_BONUS) { ShowWarning("pc_bonus2: SP_ADD_ITEMGROUP_HEAL_RATE: Reached max (%d) number of item heal bonuses per character!\n", MAX_PC_BONUS); break; } @@ -4373,6 +4377,40 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val) PC_BONUS_CHK_ELEMENT(type2, SP_MAGIC_SUBDEF_ELE); sd->indexed_bonus.magic_subdefele[type2] += val; break; + case SP_ADD_ITEM_SPHEAL_RATE: // bonus2 bAddItemSPHealRate,iid,n; + if( sd->state.lr_flag == 2 ){ + break; + } + + if( !item_db.exists( type2 ) ){ + ShowWarning( "pc_bonus2: SP_ADD_ITEM_SPHEAL_RATE Invalid item with id %d\n", type2 ); + break; + } + + if( sd->itemsphealrate.size() == MAX_PC_BONUS ){ + ShowWarning( "pc_bonus2: SP_ADD_ITEM_SPHEAL_RATE: Reached max (%d) number of item SP heal bonuses per character!\n", MAX_PC_BONUS ); + break; + } + + pc_bonus_itembonus( sd->itemsphealrate, type2, val, false ); + break; + case SP_ADD_ITEMGROUP_SPHEAL_RATE: // bonus2 bAddItemGroupSPHealRate,ig,n; + if( sd->state.lr_flag == 2 ){ + break; + } + + if( !type2 || !itemdb_group.exists( type2 ) ){ + ShowWarning( "pc_bonus2: SP_ADD_ITEMGROUP_SPHEAL_RATE: Invalid item group with id %d\n", type2 ); + break; + } + + if( sd->itemgroupsphealrate.size() == MAX_PC_BONUS ){ + ShowWarning( "pc_bonus2: SP_ADD_ITEMGROUP_SPHEAL_RATE: Reached max (%d) number of item SP heal bonuses per character!\n", MAX_PC_BONUS ); + break; + } + + pc_bonus_itembonus( sd->itemgroupsphealrate, type2, val, false ); + break; default: if (current_equip_combo_pos > 0) { ShowWarning("pc_bonus2: unknown bonus type %d %d %d in a combo with item #%u\n", type, type2, val, sd->inventory_data[pc_checkequip( sd, current_equip_combo_pos )]->nameid); @@ -8947,6 +8985,7 @@ int64 pc_readparam(struct map_session_data* sd,int64 type) val = sd->castrate; break; #endif case SP_CRIT_DEF_RATE: val = sd->bonus.crit_def_rate; break; + case SP_ADD_ITEM_SPHEAL_RATE: val = sd->bonus.itemsphealrate2; break; default: ShowError("pc_readparam: Attempt to read unknown parameter '%lld'.\n", type); return -1; @@ -9219,7 +9258,7 @@ int pc_itemheal(struct map_session_data *sd, t_itemid itemid, int hp, int sp) //All item bonuses. bonus += sd->bonus.itemhealrate2; //Item Group bonuses - bonus += bonus * pc_get_itemgroup_bonus(sd, itemid) / 100; + bonus += bonus * pc_get_itemgroup_bonus(sd, itemid, sd->itemgrouphealrate) / 100; //Individual item bonuses. for(const auto &it : sd->itemhealrate) { if (it.id == itemid) { @@ -9248,6 +9287,18 @@ int pc_itemheal(struct map_session_data *sd, t_itemid itemid, int hp, int sp) if (potion_flag == 2) bonus += bonus * 50 / 100; + // All item bonuses. + bonus += sd->bonus.itemsphealrate2; + // Item Group bonuses + bonus += bonus * pc_get_itemgroup_bonus( sd, itemid, sd->itemgroupsphealrate ) / 100; + // Individual item bonuses. + for( const auto &it : sd->itemsphealrate ){ + if( it.id == itemid ){ + bonus += bonus * it.val / 100; + break; + } + } + tmp = sp * bonus / 100; // Overflow check if (bonus != 100 && tmp > sp) sp = tmp; @@ -13246,13 +13297,13 @@ short pc_maxaspd(struct map_session_data *sd) { * @param nameid Item ID * @return Heal rate **/ -short pc_get_itemgroup_bonus(struct map_session_data* sd, t_itemid nameid) { - if (sd->itemgrouphealrate.empty()) +short pc_get_itemgroup_bonus(struct map_session_data* sd, t_itemid nameid, std::vector& bonuses) { + if (bonuses.empty()) return 0; short bonus = 0; - for (const auto &it : sd->itemgrouphealrate) { + for (const auto &it : bonuses) { uint16 group_id = it.id; if (group_id == 0) continue; @@ -13269,14 +13320,15 @@ short pc_get_itemgroup_bonus(struct map_session_data* sd, t_itemid nameid) { * @param group_id Item Group ID * @return Heal rate **/ -short pc_get_itemgroup_bonus_group(struct map_session_data* sd, uint16 group_id) { - if (sd->itemgrouphealrate.empty()) +short pc_get_itemgroup_bonus_group(struct map_session_data* sd, uint16 group_id, std::vector& bonuses) { + if (bonuses.empty()) return 0; - for (const auto &it : sd->itemgrouphealrate) { + for (const auto &it : bonuses) { if (it.id == group_id) return it.val; } + return 0; } diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 3d10c3bfcf..936b891107 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -487,7 +487,7 @@ struct map_session_data { std::vector addeff, addeff_atked; std::vector addeff_onskill; std::vector skillatk, skillusesprate, skillusesp, skillheal, skillheal2, skillblown, skillcastrate, skillfixcastrate, subskill, skillcooldown, skillfixcast, - skillvarcast, skilldelay, itemhealrate, add_def, add_mdef, add_mdmg, reseff, itemgrouphealrate; + skillvarcast, skilldelay, itemhealrate, add_def, add_mdef, add_mdmg, reseff, itemgrouphealrate, itemsphealrate, itemgroupsphealrate; std::vector add_drop; std::vector subele2; std::vector sp_vanish, hp_vanish; @@ -536,6 +536,7 @@ struct map_session_data { int classchange; // [Valaris] int speed_rate, speed_add_rate, aspd_add; int itemhealrate2; // [Epoque] Increase heal rate of all healing items. + int itemsphealrate2; int shieldmdef;//royal guard's unsigned int setitem_hash, setitem_hash2; //Split in 2 because shift operations only work on int ranges. [Skotlex] @@ -1469,8 +1470,8 @@ void pc_bonus_script_clear(struct map_session_data *sd, uint16 flag); void pc_cell_basilica(struct map_session_data *sd); -short pc_get_itemgroup_bonus(struct map_session_data* sd, t_itemid nameid); -short pc_get_itemgroup_bonus_group(struct map_session_data* sd, uint16 group_id); +short pc_get_itemgroup_bonus(struct map_session_data* sd, t_itemid nameid, std::vector& bonuses); +short pc_get_itemgroup_bonus_group(struct map_session_data* sd, uint16 group_id, std::vector& bonuses); bool pc_is_same_equip_index(enum equip_index eqi, short *equip_index, short index); /// Check if player is Taekwon Ranker and the level is >= 90 (battle_config.taekwon_ranker_min_lv) diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index 17c4f9232f..4389ad352b 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -765,6 +765,8 @@ export_constant2("bCritDefRate",SP_CRIT_DEF_RATE); export_constant2("bMagicSubDefEle", SP_MAGIC_SUBDEF_ELE); export_constant2("bReduceDamageReturn",SP_REDUCE_DAMAGE_RETURN); + export_constant2("bAddItemSPHealRate", SP_ADD_ITEM_SPHEAL_RATE); + export_constant2("bAddItemGroupSPHealRate", SP_ADD_ITEMGROUP_SPHEAL_RATE); /* equip indices */ export_constant(EQI_COMPOUND_ON); diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 05f84963fa..e69099d5cb 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -8240,8 +8240,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui } } - if ((bonus = pc_get_itemgroup_bonus_group(sd, IG_POTION))) { + if ((bonus = pc_get_itemgroup_bonus_group(sd, IG_POTION, sd->itemgrouphealrate))) { hp += hp * bonus / 100; + } + + if( ( bonus = pc_get_itemgroup_bonus_group( sd, IG_POTION, sd->itemgroupsphealrate ) ) ){ sp += sp * bonus / 100; } diff --git a/src/map/status.cpp b/src/map/status.cpp index 083c3a8025..ca2815e984 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -4251,6 +4251,8 @@ int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt) sd->skilldelay.clear(); sd->sp_vanish.clear(); sd->hp_vanish.clear(); + sd->itemsphealrate.clear(); + sd->itemgroupsphealrate.clear(); // Zero up structures... memset(&sd->hp_loss, 0, sizeof(sd->hp_loss)