From eb88f0ce4f52fe998757ecc90ab0d93b9b440cdb Mon Sep 17 00:00:00 2001 From: Cydh Ramdh Date: Sun, 31 Mar 2019 16:19:57 +0700 Subject: [PATCH] Fixes #4034 (#4036) * Move HP/SP Vanish bonuses to vector * Corrected the BF flags usage * Immaterial Swords, Mental Destroyer, and Dark Priest trigger SPVanish by any attack types Co-Authored-By: cydh --- db/re/item_db.txt | 8 ++++---- src/map/battle.cpp | 33 +++++++++++++++++++++--------- src/map/pc.cpp | 51 +++++++++++++++++++++++++++++++++++----------- src/map/pc.hpp | 10 ++++++--- src/map/status.cpp | 2 ++ 5 files changed, 75 insertions(+), 29 deletions(-) diff --git a/db/re/item_db.txt b/db/re/item_db.txt index 7087045a0b..72042f1caf 100644 --- a/db/re/item_db.txt +++ b/db/re/item_db.txt @@ -494,7 +494,7 @@ 1138,Mysteltainn_,Mysteltainn,5,20,,1000,170,,1,0,0x000654E2,63,2,2,4,40,1,2,{ bonus bAtkEle,Ele_Dark; bonus2 bAddEle,Ele_Ghost,15; bonus3 bAutoSpell,"MG_STONECURSE",3,100; bonus2 bAddEff,Eff_Stone,10; bonus bDex,3; },{},{} 1139,Tale_Fing_,Tirfing,5,20,,1000,200,,1,0,0x000654E2,63,2,2,4,40,1,2,{ bonus bAtkEle,Ele_Dark; bonus2 bHPLossRate,35,10000; },{},{} 1140,Byeorrun_Gum,Byeollungum,5,20,,900,150,,1,0,0x000654E2,63,2,2,4,40,1,2,{ bonus2 bSubClass,Class_Normal,-10; bonus2 bAddClass,Class_Boss,50; bonus bAllStats,2; },{},{} -1141,Immaterial_Sword,Immaterial Sword,5,20,,900,140,,1,0,0x000654E2,63,2,2,4,40,1,2,{ bonus bAtkEle,Ele_Ghost; bonus2 bSPVanishRate,30,30; bonus bSPDrainValue,-1; bonus bUnbreakableWeapon; },{},{} +1141,Immaterial_Sword,Immaterial Sword,5,20,,900,140,,1,0,0x000654E2,63,2,2,4,40,1,2,{ bonus bAtkEle,Ele_Ghost; bonus3 bSPVanishRate,30,30,BF_WEAPON|BF_MAGIC|BF_MISC; bonus bSPDrainValue,-1; bonus bUnbreakableWeapon; },{},{} 1142,Jewel_Sword,Jeweled Sword,5,20,,2200,104,,1,0,0x000654E2,63,2,2,3,68,1,2,{ bonus2 bAddMonsterDropItemGroup,IG_Jewel,100; },{},{} 1143,Gaia_Sword,Gaia Sword,5,20,,2500,140,,1,0,0x000654E2,63,2,2,3,74,1,2,{ bonus2 bAddMonsterDropItemGroup,IG_Ore,30; },{},{} 1144,Sasimi,Sashimi,5,20,,1400,75,,1,0,0x000654E2,63,2,2,3,48,1,2,{ bonus bAtkEle,Ele_Wind; bonus3 bAddMonsterDropItem,544,RC_Fish,4000; },{},{} @@ -1012,7 +1012,7 @@ 1658,P_Staff3,Eden Staff III,5,0,,0,60:170,,1,0,0x00818314,63,2,2,3,60,0,10,{ bonus bInt,4; },{},{} 1659,Recovery_Light,Light of Recovery,5,56000,,400,30:160,,1,1,0x00000100,63,2,2,4,110,1,10,{ bonus bAtkEle,Ele_Holy; bonus bUnbreakableWeapon; .@r = getrefine(); bonus bHealPower,(.@r*6); bonus2 bSkillUseSP,"AL_HEAL",-(.@r*10); bonus2 bSkillUseSP,"AB_CHEAL",-(.@r*12); bonus2 bSkillUseSP,"AB_HIGHNESSHEAL",-(.@r*14); },{},{} 1660,Wand_Of_Affection2,Empowered Wand Of Affection,5,20,,500,30:180,,1,1,0x00000100,63,2,2,3,130,1,10,{ bonus bAtkEle,Ele_Holy; bonus bInt,4; bonus bHealPower,20; },{},{} -1661,Mental_Destroyer,Mental Destroyer,5,20,,1400,100:50,,1,0,0x00000200,63,2,2,4,95,1,10,{ .@r = getrefine(); bonus bInt,10; bonus bUnbreakableWeapon; bonus bUseSPrate,100; bonus bMdef,20; bonus3 bSPVanishRate,1000,5+(.@r>5?3:0),BF_NORMAL|BF_SKILL; },{},{} +1661,Mental_Destroyer,Mental Destroyer,5,20,,1400,100:50,,1,0,0x00000200,63,2,2,4,95,1,10,{ .@r = getrefine(); bonus bInt,10; bonus bUnbreakableWeapon; bonus bUseSPrate,100; bonus bMdef,20; bonus3 bSPVanishRate,1000,5+(.@r>5?3:0),BF_WEAPON|BF_MAGIC|BF_MISC; },{},{} 1662,Bone_Wand_,Evil Bone Wand,5,20,,700,40:110,,1,2,0x00818314,63,2,2,3,24,1,10,{ bonus bInt,4; bonus bAtkEle,Ele_Undead; },{},{} 1663,Staff_Of_Bordeaux_,Staff Of Bordeaux,5,20,,500,30:180,,1,2,0x00010200,18,2,2,4,50,1,10,{ bonus bInt,2; bonus bDex,1; if(getskilllv("SA_DRAGONOLOGY") == 5) { bonus bUseSPrate,-15; bonus bInt,3; } },{},{} 1664,Thorn_Staff_,Thorn Staff of Darkness,5,10,,700,60:160,,,1,0x14,50,2,2,4,75,1,8,{ bonus bInt,3; bonus bDex,3; bonus bVariableCastrate,-getrefine(); bonus bAtkEle,Ele_Dark; },{},{} @@ -2361,7 +2361,7 @@ 4168,Dark_Lord_Card,Dark Lord Card,6,20,,10,,,,,,,,64,,,,,{ bonus3 bAutoSpellWhenHit,"WZ_METEOR",5,100; },{},{} 4169,Dark_Illusion_Card,Dark Illusion Card,6,20,,10,,,,,,,,769,,,,,{ bonus bMaxHPrate,-10; bonus bMaxSPrate,-10; bonus bVariableCastrate,-10; },{},{} 4170,Dark_Frame_Card,Dark Frame Card,6,20,,10,,,,,,,,16,,,,,{ bonus2 bAddEffWhenHit,Eff_Stone,600; },{},{} -4171,Dark_Priest_Card,Dark Priest Card,6,20,,10,,,,,,,,2,,,,,{ bonus2 bSPVanishRate,50,10; if(BaseJob==Job_Sage) bonus bSPDrainValue,1; },{},{} +4171,Dark_Priest_Card,Dark Priest Card,6,20,,10,,,,,,,,2,,,,,{ bonus3 bSPVanishRate,50,10,BF_WEAPON|BF_MAGIC|BF_MISC; if(BaseJob==Job_Sage) bonus bSPDrainValue,1; },{},{} 4172,The_Paper_Card,The Paper Card,6,20,,10,,,,,,,,2,,,,,{ bonus bCritAtkRate,20; bonus bSPDrainValue,-1; },{},{} 4173,Demon_Pungus_Card,Demon Pungus Card,6,20,,10,,,,,,,,16,,,,,{ bonus2 bAddEffWhenHit,Eff_Sleep,600; },{},{} 4174,Deviling_Card,Deviling Card,6,20,,10,,,,,,,,4,,,,,{ bonus2 bSubEle,Ele_Neutral,50; bonus2 bSubEle,Ele_Water,-50; bonus2 bSubEle,Ele_Earth,-50; bonus2 bSubEle,Ele_Fire,-50; bonus2 bSubEle,Ele_Wind,-50; bonus2 bSubEle,Ele_Poison,-50; bonus2 bSubEle,Ele_Holy,-50; bonus2 bSubEle,Ele_Dark,-50; bonus2 bSubEle,Ele_Ghost,-50; bonus2 bSubEle,Ele_Undead,-50; },{},{} @@ -7571,7 +7571,7 @@ 13406,Edger,Edger,5,20,,0,120,,1,0,0x000654E2,63,2,2,1,0,0,2,{ bonus2 bAddClass,Class_All,50; },{},{} 13407,Nagan_C,Refined Nagan,5,1,,0,148,,1,0,0x000654E2,63,2,2,4,0,0,2,{ skill "TF_DOUBLE",5; bonus bDoubleRate,25; bonus2 bAddRace,RC_DemiHuman,40; bonus2 bAddRace,RC_Player,40; },{},{} 13408,Fire_Brand_C,Refined Fireblend,5,1,,0,120,,1,0,0x000654E2,63,2,2,4,0,0,2,{ bonus bAtkEle,Ele_Fire; bonus bInt,2; skill "MG_FIREBOLT",5; bonus3 bAutoSpell,"MG_FIREBOLT",5,100; },{},{} -13409,Immaterial_Sword_C,Refined Immaterial Sword,5,1,,0,160,,1,0,0x000654E2,63,2,2,4,0,0,2,{ bonus bAtkEle,Ele_Ghost; bonus2 bSPVanishRate,80,45; bonus bUnbreakableWeapon; },{},{} +13409,Immaterial_Sword_C,Refined Immaterial Sword,5,1,,0,160,,1,0,0x000654E2,63,2,2,4,0,0,2,{ bonus bAtkEle,Ele_Ghost; bonus3 bSPVanishRate,80,45,BF_WEAPON|BF_MAGIC|BF_MISC; bonus bUnbreakableWeapon; },{},{} 13410,BF_Sword1,Valorous Gladiator Blade,5,20,,0,115,,1,0,0x000654E3,63,2,2,3,80,1,2,{ bonus bStr,1; bonus bDex,1; bonus2 bAddRace,RC_DemiHuman,75; bonus2 bAddRace,RC_Player,75; bonus2 bIgnoreDefRaceRate,RC_DemiHuman,20; bonus2 bIgnoreDefRaceRate,RC_Player,20; bonus bUnbreakableWeapon; },{},{} 13411,BF_Sword2,Brave Gladiator Blade,5,20,,0,115:74,,1,0,0x000654E3,63,2,2,3,80,1,2,{ bonus bStr,1; bonus bDex,1; bonus2 bAddRace,RC_DemiHuman,75; bonus2 bAddRace,RC_Player,75; bonus bMatkRate,10; bonus bUnbreakableWeapon; },{},{} 13412,Twin_Edge_B,Twin Edge of Naght Sieger,5,20,,1500,150,,1,3,0x000654E2,18,2,2,4,75,1,2,{ bonus bAtkEle,Ele_Water; skill "MG_FROSTDIVER",5; autobonus "{ bonus bIgnoreDefClass,Class_Normal; }",50,5000; },{},{} diff --git a/src/map/battle.cpp b/src/map/battle.cpp index ebce77f960..59dbb7c41e 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -6811,17 +6811,30 @@ void battle_vanish_damage(struct map_session_data *sd, struct block_list *target nullpo_retv(target); // bHPVanishRate - int16 vanish_rate_hp = cap_value(sd->bonus.hp_vanish_rate, 0, INT16_MAX); - int8 vanish_hp = cap_value(sd->bonus.hp_vanish_per, INT8_MIN, INT8_MAX); + int16 vanish_hp = 0; + if (!sd->hp_vanish.empty()) { + for (auto &it : sd->hp_vanish) { + if (!(((it.flag)&flag)&BF_WEAPONMASK && + ((it.flag)&flag)&BF_RANGEMASK && + ((it.flag)&flag)&BF_SKILLMASK)) + continue; + if (it.rate && (it.rate >= 1000 || rnd() % 1000 < it.rate)) + vanish_hp += it.per; + } + } + // bSPVanishRate - int16 vanish_rate_sp = cap_value(sd->bonus.sp_vanish_rate, 0, INT16_MAX); - int8 vanish_sp = cap_value(sd->bonus.sp_vanish_per, INT8_MIN, INT8_MAX); - - if (vanish_hp && !(vanish_rate_hp && sd->bonus.hp_vanish_flag & flag && (vanish_rate_hp >= 1000 || rnd() % 1000 < vanish_rate_hp))) - vanish_hp = 0; - - if (vanish_sp && !(vanish_rate_sp && sd->bonus.sp_vanish_flag & flag && (vanish_rate_sp >= 1000 || rnd() % 1000 < vanish_rate_sp))) - vanish_sp = 0; + int16 vanish_sp = 0; + if (!sd->sp_vanish.empty()) { + for (auto &it : sd->sp_vanish) { + if (!(((it.flag)&flag)&BF_WEAPONMASK && + ((it.flag)&flag)&BF_RANGEMASK && + ((it.flag)&flag)&BF_SKILLMASK)) + continue; + if (it.rate && (it.rate >= 1000 || rnd() % 1000 < it.rate)) + vanish_sp += it.per; + } + } if (vanish_hp > 0 || vanish_sp > 0) status_percent_damage(&sd->bl, target, -vanish_hp, -vanish_sp, false); // Damage HP/SP applied once diff --git a/src/map/pc.cpp b/src/map/pc.cpp index d80c384763..d7ba29e806 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -2758,6 +2758,41 @@ static void pc_bonus_itembonus(std::vector &bonus, uint16 id, int bonus.push_back(entry); } +/** + * Remove HP/SP to player when attacking + * @param bonus: Bonus array + * @param rate: Success chance + * @param per: Percentage of HP/SP to vanish + * @param flag: Battle flag + */ +static void pc_bonus_addvanish(std::vector &bonus, int16 rate, int16 per, int flag) { + if (!(flag&BF_RANGEMASK)) + flag |= BF_SHORT | BF_LONG; + if (!(flag&BF_WEAPONMASK)) + flag |= BF_WEAPON; + if (!(flag&BF_SKILLMASK)) { + if (flag&(BF_MAGIC | BF_MISC)) + flag |= BF_SKILL; + if (flag&BF_WEAPON) + flag |= BF_NORMAL | BF_SKILL; + } + + for (auto &it : bonus) { + if (it.flag == flag) { + it.rate += rate; + it.per += per; + return; + } + } + + struct s_vanish_bonus entry = {}; + + entry.rate = rate; + entry.per = per; + entry.flag = flag; + + bonus.push_back(entry); +} /*========================================== * Add a bonus(type) to player sd @@ -3576,16 +3611,12 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val) break; case SP_SP_VANISH_RATE: // bonus2 bSPVanishRate,x,n; if(sd->state.lr_flag != 2) { - sd->bonus.sp_vanish_rate += type2; - sd->bonus.sp_vanish_per += val; - sd->bonus.sp_vanish_flag = BF_WEAPON; + pc_bonus_addvanish(sd->sp_vanish, type2, val, BF_NORMAL); } break; case SP_HP_VANISH_RATE: // bonus2 bHPVanishRate,x,n; if(sd->state.lr_flag != 2) { - sd->bonus.hp_vanish_rate += type2; - sd->bonus.hp_vanish_per += val; - sd->bonus.hp_vanish_flag = BF_WEAPON; + pc_bonus_addvanish(sd->hp_vanish, type2, val, BF_NORMAL); } break; case SP_GET_ZENY_NUM: // bonus2 bGetZenyNum,x,n; @@ -4095,17 +4126,13 @@ void pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) case SP_SP_VANISH_RATE: // bonus3 bSPVanishRate,x,n,bf; if(sd->state.lr_flag != 2) { - sd->bonus.sp_vanish_rate += type2; - sd->bonus.sp_vanish_per += type3; - sd->bonus.sp_vanish_flag |= val; + pc_bonus_addvanish(sd->sp_vanish, type2, type3, val); } break; case SP_HP_VANISH_RATE: // bonus3 bHPVanishRate,x,n,bf; if(sd->state.lr_flag != 2) { - sd->bonus.hp_vanish_rate += type2; - sd->bonus.hp_vanish_per += type3; - sd->bonus.hp_vanish_flag |= val; + pc_bonus_addvanish(sd->hp_vanish, type2, type3, val); } break; diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 1f038745ac..78d0345326 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -193,6 +193,12 @@ struct s_add_drop { unsigned short class_; ///Target Class, bitwise value of 1< add_drop; std::vector subele2; + std::vector sp_vanish, hp_vanish; std::vector autobonus, autobonus2, autobonus3; //Auto script on attack, when attacked, on skill usage // zeroed structures start here @@ -478,9 +485,6 @@ struct map_session_data { short add_steal_rate; int add_heal_rate, add_heal2_rate; int sp_gain_value, hp_gain_value, magic_sp_gain_value, magic_hp_gain_value; - int sp_vanish_rate, hp_vanish_rate; - int sp_vanish_per, hp_vanish_per; - int sp_vanish_flag, hp_vanish_flag; unsigned short unbreakable; // chance to prevent ANY equipment breaking [celest] unsigned short unbreakable_equip; //100% break resistance on certain equipment unsigned short unstripable_equip; diff --git a/src/map/status.cpp b/src/map/status.cpp index 19c99296e1..36b84c22c1 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -3551,6 +3551,8 @@ int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt) sd->itemhealrate.clear(); sd->subele2.clear(); sd->skilldelay.clear(); + sd->sp_vanish.clear(); + sd->hp_vanish.clear(); // Zero up structures... memset(&sd->hp_loss, 0, sizeof(sd->hp_loss)