From 2e04ca98b0efb3973e880dc16da57e737d57281a Mon Sep 17 00:00:00 2001 From: Jittapan Pluemsumran Date: Wed, 1 Jul 2020 04:39:40 +0700 Subject: [PATCH] Random options update (#3993) * Implemented additional random options from official server Fixed #3988 Thanks to @Stolao @cydh @aleos89 --- db/const.txt | 68 ++++++++++++++++++++++++------------ db/re/item_randomopt_db.txt | 55 ++++++++++++++++++++--------- doc/atcommands.txt | 2 +- doc/item_bonus.txt | 3 ++ src/map/battle.cpp | 55 +++++++++++++++++++++++++---- src/map/map.hpp | 2 +- src/map/pc.cpp | 61 +++++++++++++++++++++++++++++++- src/map/pc.hpp | 10 ++++++ src/map/script_constants.hpp | 3 ++ src/map/status.cpp | 2 ++ 10 files changed, 214 insertions(+), 47 deletions(-) diff --git a/db/const.txt b/db/const.txt index 83a9102b518..fe7f6d75b15 100644 --- a/db/const.txt +++ b/db/const.txt @@ -48,7 +48,7 @@ RDMOPT_ATTR_TOLERACE_SAINT 31 RDMOPT_ATTR_TOLERACE_DARKNESS 32 RDMOPT_ATTR_TOLERACE_TELEKINESIS 33 RDMOPT_ATTR_TOLERACE_UNDEAD 34 -RDMOPT_ATTR_TOLERACE_ALL 35 +RDMOPT_ATTR_TOLERACE_ALLBUTNOTHING 35 RDMOPT_DAMAGE_PROPERTY_NOTHING_USER 36 RDMOPT_DAMAGE_PROPERTY_NOTHING_TARGET 37 RDMOPT_DAMAGE_PROPERTY_WATER_USER 38 @@ -186,27 +186,51 @@ RDMOPT_HEAL_MODIFY_PERCENT 169 RDMOPT_DEC_SPELL_CAST_TIME 170 RDMOPT_DEC_SPELL_DELAY_TIME 171 RDMOPT_DEC_SP_CONSUMPTION 172 -RDMOPT_HP_DRAIN 173 -RDMOPT_SP_DRAIN 174 -RDMOPT_WEAPON_ATTR_NOTHING 175 -RDMOPT_WEAPON_ATTR_WATER 176 -RDMOPT_WEAPON_ATTR_GROUND 177 -RDMOPT_WEAPON_ATTR_FIRE 178 -RDMOPT_WEAPON_ATTR_WIND 179 -RDMOPT_WEAPON_ATTR_POISON 180 -RDMOPT_WEAPON_ATTR_SAINT 181 -RDMOPT_WEAPON_ATTR_DARKNESS 182 -RDMOPT_WEAPON_ATTR_TELEKINESIS 183 -RDMOPT_WEAPON_ATTR_UNDEAD 184 -RDMOPT_WEAPON_INDESTRUCTIBLE 185 -RDMOPT_BODY_INDESTRUCTIBLE 186 -RDMOPT_MDAMAGE_SIZE_SMALL_TARGET 187 -RDMOPT_MDAMAGE_SIZE_MIDIUM_TARGET 188 -RDMOPT_MDAMAGE_SIZE_LARGE_TARGET 189 -RDMOPT_MDAMAGE_SIZE_SMALL_USER 190 -RDMOPT_MDAMAGE_SIZE_MIDIUM_USER 191 -RDMOPT_MDAMAGE_SIZE_LARGE_USER 192 -//RDMOPT_ATTR_TOLERACE_ALL 193 +RDMOPT_WEAPON_ATTR_NOTHING 173 +RDMOPT_WEAPON_ATTR_WATER 174 +RDMOPT_WEAPON_ATTR_GROUND 175 +RDMOPT_WEAPON_ATTR_FIRE 176 +RDMOPT_WEAPON_ATTR_WIND 177 +RDMOPT_WEAPON_ATTR_POISON 178 +RDMOPT_WEAPON_ATTR_SAINT 179 +RDMOPT_WEAPON_ATTR_DARKNESS 180 +RDMOPT_WEAPON_ATTR_TELEKINESIS 181 +RDMOPT_WEAPON_ATTR_UNDEAD 182 +RDMOPT_WEAPON_INDESTRUCTIBLE 183 +RDMOPT_BODY_INDESTRUCTIBLE 184 +RDMOPT_MDAMAGE_SIZE_SMALL_TARGET 185 +RDMOPT_MDAMAGE_SIZE_MIDIUM_TARGET 186 +RDMOPT_MDAMAGE_SIZE_LARGE_TARGET 187 +RDMOPT_MDAMAGE_SIZE_SMALL_USER 188 +RDMOPT_MDAMAGE_SIZE_MIDIUM_USER 189 +RDMOPT_MDAMAGE_SIZE_LARGE_USER 190 +RDMOPT_ATTR_TOLERACE_ALL 191 +RDMOPT_RACE_WEAPON_TOLERACE_NOTHING 192 +RDMOPT_RACE_WEAPON_TOLERACE_UNDEAD 193 +RDMOPT_RACE_WEAPON_TOLERACE_ANIMAL 194 +RDMOPT_RACE_WEAPON_TOLERACE_PLANT 195 +RDMOPT_RACE_WEAPON_TOLERACE_INSECT 196 +RDMOPT_RACE_WEAPON_TOLERACE_FISHS 197 +RDMOPT_RACE_WEAPON_TOLERACE_DEVIL 198 +RDMOPT_RACE_WEAPON_TOLERACE_HUMAN 199 +RDMOPT_RACE_WEAPON_TOLERACE_ANGEL 200 +RDMOPT_RACE_WEAPON_TOLERACE_DRAGON 201 +RDMOPT_RANGE_WEAPON_ATTACK_DAMAGE_TARGET 202 +RDMOPT_RANGE_WEAPON_ATTACK_DAMAGE_USER 203 +RDMOPT_RACE_TOLERACE_PLAYER_DORAM 204 +RDMOPT_RACE_DAMAGE_PLAYER_HUMAN 205 +RDMOPT_RACE_DAMAGE_PLAYER_DORAM 206 +RDMOPT_RACE_MDAMAGE_PLAYER_HUMAN 207 +RDMOPT_RACE_MDAMAGE_PLAYER_DORAM 208 +RDMOPT_RACE_CRI_PERCENT_PLAYER_HUMAN 209 +RDMOPT_RACE_CRI_PERCENT_PLAYER_DORAM 210 +RDMOPT_RACE_IGNORE_DEF_PERCENT_PLAYER_HUMAN 211 +RDMOPT_RACE_IGNORE_DEF_PERCENT_PLAYER_DORAM 212 +RDMOPT_RACE_IGNORE_MDEF_PERCENT_PLAYER_HUMAN 213 +RDMOPT_RACE_IGNORE_MDEF_PERCENT_PLAYER_DORAM 214 +RDMOPT_REFLECT_DAMAGE_PERCENT 215 +RDMOPT_MELEE_ATTACK_DAMAGE_TARGET 216 +RDMOPT_MELEE_ATTACK_DAMAGE_USER 217 SWORDCLAN 1 ARCWANDCLAN 2 diff --git a/db/re/item_randomopt_db.txt b/db/re/item_randomopt_db.txt index 502c2fa661e..0be2b8d4015 100644 --- a/db/re/item_randomopt_db.txt +++ b/db/re/item_randomopt_db.txt @@ -36,9 +36,7 @@ RDMOPT_ATTR_TOLERACE_SAINT,{ bonus2 bSubEle,Ele_Holy,getrandomoptinfo(ROA_VALUE) RDMOPT_ATTR_TOLERACE_DARKNESS,{ bonus2 bSubEle,Ele_Dark,getrandomoptinfo(ROA_VALUE); } RDMOPT_ATTR_TOLERACE_TELEKINESIS,{ bonus2 bSubEle,Ele_Ghost,getrandomoptinfo(ROA_VALUE); } RDMOPT_ATTR_TOLERACE_UNDEAD,{ bonus2 bSubEle,Ele_Undead,getrandomoptinfo(ROA_VALUE); } -RDMOPT_ATTR_TOLERACE_ALL,{ bonus2 bSubEle,Ele_All,getrandomoptinfo(ROA_VALUE); } -// TODO: Confirm if damage reduction is implemented correctly. -// kRO desc : 몬스터로부터 받는 물리 데미지 %d%% 감소. +RDMOPT_ATTR_TOLERACE_ALLBUTNOTHING,{ for(.@i = Ele_Water; .@i < Ele_Undead; ++.@i) bonus2 bSubEle,.@i,getrandomoptinfo(ROA_VALUE); } RDMOPT_DAMAGE_PROPERTY_NOTHING_USER,{ bonus2 bSubDefEle,Ele_Neutral,getrandomoptinfo(ROA_VALUE); } RDMOPT_DAMAGE_PROPERTY_NOTHING_TARGET,{ bonus2 bAddEle,Ele_Neutral,getrandomoptinfo(ROA_VALUE); } RDMOPT_DAMAGE_PROPERTY_WATER_USER,{ bonus2 bSubDefEle,Ele_Water,getrandomoptinfo(ROA_VALUE); } @@ -89,7 +87,7 @@ RDMOPT_BODY_ATTR_SAINT,{ bonus bDefEle,Ele_Holy; } RDMOPT_BODY_ATTR_DARKNESS,{ bonus bDefEle,Ele_Dark; } RDMOPT_BODY_ATTR_TELEKINESIS,{ bonus bDefEle,Ele_Ghost; } RDMOPT_BODY_ATTR_UNDEAD,{ bonus bDefEle,Ele_Undead; } -//RDMOPT_BODY_ATTR_ALL,{ /* Needs more info */ } +//RDMOPT_BODY_ATTR_ALL,{} RDMOPT_RACE_TOLERACE_NOTHING,{ bonus2 bSubRace,RC_Formless,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_TOLERACE_UNDEAD,{ bonus2 bSubRace,RC_Undead,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_TOLERACE_ANIMAL,{ bonus2 bSubRace,RC_Brute,getrandomoptinfo(ROA_VALUE); } @@ -97,7 +95,7 @@ RDMOPT_RACE_TOLERACE_PLANT,{ bonus2 bSubRace,RC_Plant,getrandomoptinfo(ROA_VALUE RDMOPT_RACE_TOLERACE_INSECT,{ bonus2 bSubRace,RC_Insect,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_TOLERACE_FISHS,{ bonus2 bSubRace,RC_Fish,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_TOLERACE_DEVIL,{ bonus2 bSubRace,RC_Demon,getrandomoptinfo(ROA_VALUE); } -RDMOPT_RACE_TOLERACE_HUMAN,{ bonus2 bSubRace,RC_DemiHuman,getrandomoptinfo(ROA_VALUE); bonus2 bSubRace,RC_Player_Human,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_TOLERACE_HUMAN,{ bonus2 bSubRace,RC_DemiHuman,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_TOLERACE_ANGEL,{ bonus2 bSubRace,RC_Angel,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_TOLERACE_DRAGON,{ bonus2 bSubRace,RC_Dragon,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_DAMAGE_NOTHING,{ bonus2 bAddRace,RC_Formless,getrandomoptinfo(ROA_VALUE); } @@ -107,7 +105,7 @@ RDMOPT_RACE_DAMAGE_PLANT,{ bonus2 bAddRace,RC_Plant,getrandomoptinfo(ROA_VALUE); RDMOPT_RACE_DAMAGE_INSECT,{ bonus2 bAddRace,RC_Insect,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_DAMAGE_FISHS,{ bonus2 bAddRace,RC_Fish,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_DAMAGE_DEVIL,{ bonus2 bAddRace,RC_Demon,getrandomoptinfo(ROA_VALUE); } -RDMOPT_RACE_DAMAGE_HUMAN,{ bonus2 bAddRace,RC_DemiHuman,getrandomoptinfo(ROA_VALUE); bonus2 bAddRace,RC_Player_Human,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_DAMAGE_HUMAN,{ bonus2 bAddRace,RC_DemiHuman,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_DAMAGE_ANGEL,{ bonus2 bAddRace,RC_Angel,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_DAMAGE_DRAGON,{ bonus2 bAddRace,RC_Dragon,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_MDAMAGE_NOTHING,{ bonus2 bMagicAddRace,RC_Formless,getrandomoptinfo(ROA_VALUE); } @@ -117,7 +115,7 @@ RDMOPT_RACE_MDAMAGE_PLANT,{ bonus2 bMagicAddRace,RC_Plant,getrandomoptinfo(ROA_V RDMOPT_RACE_MDAMAGE_INSECT,{ bonus2 bMagicAddRace,RC_Insect,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_MDAMAGE_FISHS,{ bonus2 bMagicAddRace,RC_Fish,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_MDAMAGE_DEVIL,{ bonus2 bMagicAddRace,RC_Demon,getrandomoptinfo(ROA_VALUE); } -RDMOPT_RACE_MDAMAGE_HUMAN,{ bonus2 bMagicAddRace,RC_DemiHuman,getrandomoptinfo(ROA_VALUE); bonus2 bMagicAddRace,RC_Player_Human,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_MDAMAGE_HUMAN,{ bonus2 bMagicAddRace,RC_DemiHuman,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_MDAMAGE_ANGEL,{ bonus2 bMagicAddRace,RC_Angel,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_MDAMAGE_DRAGON,{ bonus2 bMagicAddRace,RC_Dragon,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_CRI_PERCENT_NOTHING,{ bonus2 bCriticalAddRace,RC_Formless,getrandomoptinfo(ROA_VALUE)/10; } @@ -127,7 +125,7 @@ RDMOPT_RACE_CRI_PERCENT_PLANT,{ bonus2 bCriticalAddRace,RC_Plant,getrandomoptinf RDMOPT_RACE_CRI_PERCENT_INSECT,{ bonus2 bCriticalAddRace,RC_Insect,getrandomoptinfo(ROA_VALUE)/10; } RDMOPT_RACE_CRI_PERCENT_FISHS,{ bonus2 bCriticalAddRace,RC_Fish,getrandomoptinfo(ROA_VALUE)/10; } RDMOPT_RACE_CRI_PERCENT_DEVIL,{ bonus2 bCriticalAddRace,RC_Demon,getrandomoptinfo(ROA_VALUE)/10; } -RDMOPT_RACE_CRI_PERCENT_HUMAN,{ bonus2 bCriticalAddRace,RC_DemiHuman,getrandomoptinfo(ROA_VALUE)/10; bonus2 bCriticalAddRace,RC_Player_Human,getrandomoptinfo(ROA_VALUE)/10; } +RDMOPT_RACE_CRI_PERCENT_HUMAN,{ bonus2 bCriticalAddRace,RC_DemiHuman,getrandomoptinfo(ROA_VALUE)/10; } RDMOPT_RACE_CRI_PERCENT_ANGEL,{ bonus2 bCriticalAddRace,RC_Angel,getrandomoptinfo(ROA_VALUE)/10; } RDMOPT_RACE_CRI_PERCENT_DRAGON,{ bonus2 bCriticalAddRace,RC_Dragon,getrandomoptinfo(ROA_VALUE)/10; } RDMOPT_RACE_IGNORE_DEF_PERCENT_NOTHING,{ bonus2 bIgnoreDefRaceRate,RC_Formless,getrandomoptinfo(ROA_VALUE); } @@ -137,7 +135,7 @@ RDMOPT_RACE_IGNORE_DEF_PERCENT_PLANT,{ bonus2 bIgnoreDefRaceRate,RC_Plant,getran RDMOPT_RACE_IGNORE_DEF_PERCENT_INSECT,{ bonus2 bIgnoreDefRaceRate,RC_Insect,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_IGNORE_DEF_PERCENT_FISHS,{ bonus2 bIgnoreDefRaceRate,RC_Fish,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_IGNORE_DEF_PERCENT_DEVIL,{ bonus2 bIgnoreDefRaceRate,RC_Demon,getrandomoptinfo(ROA_VALUE); } -RDMOPT_RACE_IGNORE_DEF_PERCENT_HUMAN,{ bonus2 bIgnoreDefRaceRate,RC_DemiHuman,getrandomoptinfo(ROA_VALUE); bonus2 bIgnoreDefRaceRate,RC_Player_Human,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_IGNORE_DEF_PERCENT_HUMAN,{ bonus2 bIgnoreDefRaceRate,RC_DemiHuman,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_IGNORE_DEF_PERCENT_ANGEL,{ bonus2 bIgnoreDefRaceRate,RC_Angel,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_IGNORE_DEF_PERCENT_DRAGON,{ bonus2 bIgnoreDefRaceRate,RC_Dragon,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_IGNORE_MDEF_PERCENT_NOTHING,{ bonus2 bIgnoreMdefRaceRate,RC_Formless,getrandomoptinfo(ROA_VALUE); } @@ -147,7 +145,7 @@ RDMOPT_RACE_IGNORE_MDEF_PERCENT_PLANT,{ bonus2 bIgnoreMdefRaceRate,RC_Plant,getr RDMOPT_RACE_IGNORE_MDEF_PERCENT_INSECT,{ bonus2 bIgnoreMdefRaceRate,RC_Insect,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_IGNORE_MDEF_PERCENT_FISHS,{ bonus2 bIgnoreMdefRaceRate,RC_Fish,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_IGNORE_MDEF_PERCENT_DEVIL,{ bonus2 bIgnoreMdefRaceRate,RC_Demon,getrandomoptinfo(ROA_VALUE); } -RDMOPT_RACE_IGNORE_MDEF_PERCENT_HUMAN,{ bonus2 bIgnoreMdefRaceRate,RC_DemiHuman,getrandomoptinfo(ROA_VALUE); bonus2 bIgnoreMdefRaceRate,RC_Player_Human,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_IGNORE_MDEF_PERCENT_HUMAN,{ bonus2 bIgnoreMdefRaceRate,RC_DemiHuman,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_IGNORE_MDEF_PERCENT_ANGEL,{ bonus2 bIgnoreMdefRaceRate,RC_Angel,getrandomoptinfo(ROA_VALUE); } RDMOPT_RACE_IGNORE_MDEF_PERCENT_DRAGON,{ bonus2 bIgnoreMdefRaceRate,RC_Dragon,getrandomoptinfo(ROA_VALUE); } RDMOPT_CLASS_DAMAGE_NORMAL_TARGET,{ bonus2 bAddClass,Class_Normal,getrandomoptinfo(ROA_VALUE); } @@ -168,7 +166,7 @@ RDMOPT_DAMAGE_SIZE_MIDIUM_USER,{ bonus2 bSubSize,Size_Medium,getrandomoptinfo(RO RDMOPT_DAMAGE_SIZE_LARGE_USER,{ bonus2 bSubSize,Size_Large,getrandomoptinfo(ROA_VALUE); } RDMOPT_DAMAGE_SIZE_PERFECT,{ bonus bNoSizeFix,1; } RDMOPT_DAMAGE_CRI_TARGET,{ bonus bCritAtkRate,getrandomoptinfo(ROA_VALUE); } -RDMOPT_DAMAGE_CRI_USER,{ bonus bCriticalDef,getrandomoptinfo(ROA_VALUE); } +RDMOPT_DAMAGE_CRI_USER,{ bonus bCritDefRate,getrandomoptinfo(ROA_VALUE); } RDMOPT_RANGE_ATTACK_DAMAGE_TARGET,{ bonus bLongAtkRate,getrandomoptinfo(ROA_VALUE); } RDMOPT_RANGE_ATTACK_DAMAGE_USER,{ bonus bLongAtkDef,getrandomoptinfo(ROA_VALUE); } RDMOPT_HEAL_VALUE,{ bonus bHealPower,getrandomoptinfo(ROA_VALUE); } @@ -193,8 +191,33 @@ RDMOPT_BODY_INDESTRUCTIBLE,{ bonus bUnbreakableArmor,1; } RDMOPT_MDAMAGE_SIZE_SMALL_TARGET,{ bonus2 bMagicAddSize,Size_Small,getrandomoptinfo(ROA_VALUE); } RDMOPT_MDAMAGE_SIZE_MIDIUM_TARGET,{ bonus2 bMagicAddSize,Size_Medium,getrandomoptinfo(ROA_VALUE); } RDMOPT_MDAMAGE_SIZE_LARGE_TARGET,{ bonus2 bMagicAddSize,Size_Large,getrandomoptinfo(ROA_VALUE); } -//RDMOPT_MDAMAGE_SIZE_SMALL_USER,{} -//RDMOPT_MDAMAGE_SIZE_MIDIUM_USER,{} -//RDMOPT_MDAMAGE_SIZE_LARGE_USER,{} -//redefined? -//RDMOPT_ATTR_TOLERACE_ALL,{} +RDMOPT_MDAMAGE_SIZE_SMALL_USER,{ bonus2 bMagicSubSize,Size_Small,getrandomoptinfo(ROA_VALUE); } +RDMOPT_MDAMAGE_SIZE_MIDIUM_USER,{ bonus2 bMagicSubSize,Size_Medium,getrandomoptinfo(ROA_VALUE); } +RDMOPT_MDAMAGE_SIZE_LARGE_USER,{ bonus2 bMagicSubSize,Size_Large,getrandomoptinfo(ROA_VALUE); } +RDMOPT_ATTR_TOLERACE_ALL,{ bonus2 bSubEle,Ele_All,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_WEAPON_TOLERACE_NOTHING,{ bonus3 bSubRace,RC_Formless,getrandomoptinfo(ROA_VALUE),BF_WEAPON; } +RDMOPT_RACE_WEAPON_TOLERACE_UNDEAD,{ bonus3 bSubRace,RC_Undead,getrandomoptinfo(ROA_VALUE),BF_WEAPON; } +RDMOPT_RACE_WEAPON_TOLERACE_ANIMAL,{ bonus3 bSubRace,RC_Brute,getrandomoptinfo(ROA_VALUE),BF_WEAPON; } +RDMOPT_RACE_WEAPON_TOLERACE_PLANT,{ bonus3 bSubRace,RC_Plant,getrandomoptinfo(ROA_VALUE),BF_WEAPON; } +RDMOPT_RACE_WEAPON_TOLERACE_INSECT,{ bonus3 bSubRace,RC_Insect,getrandomoptinfo(ROA_VALUE),BF_WEAPON; } +RDMOPT_RACE_WEAPON_TOLERACE_FISHS,{ bonus3 bSubRace,RC_Fish,getrandomoptinfo(ROA_VALUE),BF_WEAPON; } +RDMOPT_RACE_WEAPON_TOLERACE_DEVIL,{ bonus3 bSubRace,RC_Demon,getrandomoptinfo(ROA_VALUE),BF_WEAPON; } +RDMOPT_RACE_WEAPON_TOLERACE_HUMAN,{ bonus3 bSubRace,RC_DemiHuman,getrandomoptinfo(ROA_VALUE),BF_WEAPON; } +RDMOPT_RACE_WEAPON_TOLERACE_ANGEL,{ bonus3 bSubRace,RC_Angel,getrandomoptinfo(ROA_VALUE),BF_WEAPON; } +RDMOPT_RACE_WEAPON_TOLERACE_DRAGON,{ bonus3 bSubRace,RC_Dragon,getrandomoptinfo(ROA_VALUE),BF_WEAPON; } +// RDMOPT_RANGE_WEAPON_ATTACK_DAMAGE_TARGET,{} +// RDMOPT_RANGE_WEAPON_ATTACK_DAMAGE_USER,{} +RDMOPT_RACE_TOLERACE_PLAYER_DORAM,{ bonus2 bSubRace,RC_Player_Doram,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_DAMAGE_PLAYER_HUMAN,{ bonus2 bAddRace,RC_Player_Human,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_DAMAGE_PLAYER_DORAM,{ bonus2 bAddRace,RC_Player_Doram,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_MDAMAGE_PLAYER_HUMAN,{ bonus2 bMagicAddRace,RC_Player_Human,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_MDAMAGE_PLAYER_DORAM,{ bonus2 bMagicAddRace,RC_Player_Doram,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_CRI_PERCENT_PLAYER_HUMAN,{ bonus2 bCriticalAddRace,RC_Player_Human,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_CRI_PERCENT_PLAYER_DORAM,{ bonus2 bCriticalAddRace,RC_Player_Doram,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_IGNORE_DEF_PERCENT_PLAYER_HUMAN,{ bonus2 bIgnoreDefRaceRate,RC_Player_Human,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_IGNORE_DEF_PERCENT_PLAYER_DORAM,{ bonus2 bIgnoreDefRaceRate,RC_Player_Doram,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_IGNORE_MDEF_PERCENT_PLAYER_HUMAN,{ bonus2 bIgnoreMdefRaceRate,RC_Player_Human,getrandomoptinfo(ROA_VALUE); } +RDMOPT_RACE_IGNORE_MDEF_PERCENT_PLAYER_DORAM,{ bonus2 bIgnoreMdefRaceRate,RC_Player_Doram,getrandomoptinfo(ROA_VALUE); } +// RDMOPT_REFLECT_DAMAGE_PERCENT,{} +RDMOPT_MELEE_ATTACK_DAMAGE_TARGET,{ bonus bShortAtkRate,getrandomoptinfo(ROA_VALUE); } +RDMOPT_MELEE_ATTACK_DAMAGE_USER,{ bonus bNearAtkDef,getrandomoptinfo(ROA_VALUE); } diff --git a/doc/atcommands.txt b/doc/atcommands.txt index 54c2bcae13f..0fb5008b478 100644 --- a/doc/atcommands.txt +++ b/doc/atcommands.txt @@ -1360,7 +1360,7 @@ Affected files: -- atcommand: atcommand_athena.conf, groups.conf -- battleconf: battle_athena.conf, battle_conf.txt -- instancedb: instance_db.txt --- itemdb: item_db.txt, item_group_db.txt, item_trade.txt, item_noequip.txt, item_nouse.txt, item_combo_db.txt, item_avail.txt, item_stack.txt, item_delay.txt, item_buyingstore.txt, item_flag.txt +-- itemdb: item_db.txt, item_group_db.txt, item_trade.txt, item_noequip.txt, item_nouse.txt, item_combo_db.txt, item_avail.txt, item_stack.txt, item_delay.txt, item_buyingstore.txt, item_flag.txt, item_randomopt_db.txt, item_randomopt_group.txt -- mobdb: mob_db.txt, mob_item_ratio.txt, mob_chat_db.txt, mob_avail.txt, mob_race2_db.txt, mob_branch.txt, mob_poring.txt, mob_boss.txt, mob_pouch.txt, mob_classchange.txt, pet_db.yml, homunculus_db.txt, homun_skill_tree.txt, exp_homun.txt, mercenary_db.txt, mercenary_skill_db.txt, elemental_db.txt, elemental_skill_db.txt -- motd: motd.txt -- msgconf: atcommand_athena.conf diff --git a/doc/item_bonus.txt b/doc/item_bonus.txt index dde95ca7734..89c5a809a86 100644 --- a/doc/item_bonus.txt +++ b/doc/item_bonus.txt @@ -171,6 +171,7 @@ bonus2 bSkillAtk,sk,n; Increases damage of skill sk by n% bonus bShortAtkRate,n; Increases damage of short ranged attacks by n% bonus bLongAtkRate,n; Increases damage of long ranged attacks by n% bonus bCritAtkRate,n; Increases critical damage by +n% +bonus bCritDefRate,n; Decreases critical damage received by n% bonus bCriticalDef,n; Decreases the chance of being hit by critical hits by n% bonus2 bWeaponAtk,w,n; Adds n ATK when weapon of type w is equipped bonus2 bWeaponDamageRate,w,n; Adds n% damage to normal attacks when weapon of type w is equipped @@ -232,6 +233,7 @@ bonus2 bSubDefEle,e,x; +x% damage reduction from enemy with defense element bonus2 bAddRace,r,x; +x% physical damage against race r bonus2 bMagicAddRace,r,x; +x% magical damage against race r bonus2 bSubRace,r,x; +x% damage reduction against race r +bonus3 bSubRace,r,x,bf; +x% damage reduction against race r with trigger criteria bf bonus2 bAddClass,c,x; +x% physical damage against class c bonus2 bMagicAddClass,c,x; +x% magical damage against class c @@ -240,6 +242,7 @@ bonus2 bSubClass,c,x; +x% damage reduction against class c bonus2 bAddSize,s,x; +x% physical damage against size s bonus2 bMagicAddSize,s,x; +x% magical damage against size s bonus2 bSubSize,s,x; +x% damage reduction against size s +bonus2 bMagicSubSize,s,x; +x% magic damage reduction against size s bonus bNoSizeFix; Ignores the size modifier when calculating damage bonus2 bAddDamageClass,mid,x; +x% physical damage against monster mid diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 8539406e6d2..59bba863e78 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -698,8 +698,19 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li cardfix = cardfix * (100 - ele_fix) / 100; } cardfix = cardfix * (100 - tsd->subsize[sstatus->size] - tsd->subsize[SZ_ALL]) / 100; + cardfix = cardfix * (100 - tsd->magic_subsize[sstatus->size] - tsd->magic_subsize[SZ_ALL]) / 100; cardfix = cardfix * (100 - tsd->subrace2[s_race2]) / 100; - cardfix = cardfix * (100 - tsd->subrace[sstatus->race] - tsd->subrace[RC_ALL]) / 100; + int race_fix = tsd->subrace[sstatus->race] - tsd->subrace[RC_ALL]; + for (const auto &it : tsd->subrace3) { + if (it.race != sstatus->race) + continue; + if (!(((it.flag)&flag)&BF_WEAPONMASK && + ((it.flag)&flag)&BF_RANGEMASK && + ((it.flag)&flag)&BF_SKILLMASK)) + continue; + race_fix += it.rate; + } + cardfix = cardfix * (100 - race_fix) / 100; cardfix = cardfix * (100 - tsd->subclass[sstatus->class_] - tsd->subclass[CLASS_ALL]) / 100; for (const auto &it : tsd->add_mdef) { @@ -898,7 +909,17 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li } cardfix = cardfix * (100 - tsd->subsize[sstatus->size] - tsd->subsize[SZ_ALL]) / 100; cardfix = cardfix * (100 - tsd->subrace2[s_race2]) / 100; - cardfix = cardfix * (100 - tsd->subrace[sstatus->race] - tsd->subrace[RC_ALL]) / 100; + int race_fix = tsd->subrace[sstatus->race] - tsd->subrace[RC_ALL]; + for (const auto &it : tsd->subrace3) { + if (it.race != sstatus->race) + continue; + if (!(((it.flag)&flag)&BF_WEAPONMASK && + ((it.flag)&flag)&BF_RANGEMASK && + ((it.flag)&flag)&BF_SKILLMASK)) + continue; + race_fix += it.rate; + } + cardfix = cardfix * (100 - race_fix) / 100; cardfix = cardfix * (100 - tsd->subclass[sstatus->class_] - tsd->subclass[CLASS_ALL]) / 100; for (const auto &it : tsd->add_def) { if (it.id == s_class) { @@ -935,9 +956,20 @@ int battle_calc_cardfix(int attack_type, struct block_list *src, struct block_li ele_fix += tsd->subdefele[s_defele] + tsd->subdefele[ELE_ALL]; cardfix = cardfix * (100 - ele_fix) / 100; } + int race_fix = tsd->subrace[sstatus->race] - tsd->subrace[RC_ALL]; + for (const auto &it : tsd->subrace3) { + if (it.race != sstatus->race) + continue; + if (!(((it.flag)&flag)&BF_WEAPONMASK && + ((it.flag)&flag)&BF_RANGEMASK && + ((it.flag)&flag)&BF_SKILLMASK)) + continue; + race_fix += it.rate; + } + cardfix = cardfix * (100 - race_fix) / 100; + cardfix = cardfix * (100 - tsd->subsize[sstatus->size] - tsd->subsize[SZ_ALL]) / 100; cardfix = cardfix * (100 - tsd->subrace2[s_race2]) / 100; - cardfix = cardfix * (100 - tsd->subrace[sstatus->race] - tsd->subrace[RC_ALL]) / 100; cardfix = cardfix * (100 - tsd->subclass[sstatus->class_] - tsd->subclass[CLASS_ALL]) / 100; cardfix = cardfix * (100 - tsd->bonus.misc_def_rate) / 100; if( flag&BF_SHORT ) @@ -3257,6 +3289,8 @@ static void battle_calc_skill_base_damage(struct Damage* wd, struct block_list * struct status_data *sstatus = status_get_status_data(src); struct status_data *tstatus = status_get_status_data(target); struct map_session_data *sd = BL_CAST(BL_PC, src); + struct map_session_data *tsd = BL_CAST(BL_PC, target); + uint16 i; std::bitset nk = battle_skill_get_damage_properties(skill_id, wd->miscflag); @@ -3467,6 +3501,11 @@ static void battle_calc_skill_base_damage(struct Damage* wd, struct block_list * } } } +#ifndef RENEWAL + if(tsd != nullptr & tsd->bonus.crit_def_rate != 0 && !skill_id && is_attack_critical(wd, src, target, skill_id, skill_lv, false)) { + ATK_ADDRATE(wd->damage, wd->damage2, -tsd->bonus.crit_def_rate); + } +#endif break; } //End switch(skill_id) } @@ -5795,11 +5834,15 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl #ifdef RENEWAL if (is_attack_critical(&wd, src, target, skill_id, skill_lv, false)) { if (sd) { //Check for player so we don't crash out, monsters don't have bonus crit rates [helvetica] - wd.damage = (int)floor((float)((wd.damage * 140) / 100 * (100 + sd->bonus.crit_atk_rate)) / 100); + wd.damage = (int64)floor((float)((wd.damage * 140) / 100 * (100 + sd->bonus.crit_atk_rate)) / 100); if (is_attack_left_handed(src, skill_id)) - wd.damage2 = (int)floor((float)((wd.damage2 * 140) / 100 * (100 + sd->bonus.crit_atk_rate)) / 100); + wd.damage2 = (int64)floor((float)((wd.damage2 * 140) / 100 * (100 + sd->bonus.crit_atk_rate)) / 100); } else - wd.damage = (int)floor((float)(wd.damage * 140) / 100); + wd.damage = (int64)floor((float)(wd.damage * 140) / 100); + + if (tsd && tsd->bonus.crit_def_rate != 0) { + ATK_ADDRATE(wd.damage, wd.damage2, -tsd->bonus.crit_def_rate); + } } #endif diff --git a/src/map/map.hpp b/src/map/map.hpp index 9f7a2c92095..2e49a0ccec8 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -505,7 +505,7 @@ enum _sp { SP_STATE_NORECOVER_RACE, SP_CRITICAL_RANGEATK, SP_MAGIC_ADDRACE2, SP_IGNORE_MDEF_RACE2_RATE, // 2079-2082 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-2093 - SP_LONG_SP_GAIN_VALUE, SP_LONG_HP_GAIN_VALUE, SP_SHORT_ATK_RATE // 2094-2096 + SP_LONG_SP_GAIN_VALUE, SP_LONG_HP_GAIN_VALUE, SP_SHORT_ATK_RATE, SP_MAGIC_SUBSIZE, SP_CRIT_DEF_RATE // 2094-2098 }; enum _look { diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 423242ea447..e580779dec6 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -2890,6 +2890,49 @@ static void pc_bonus_subele(struct map_session_data* sd, unsigned char ele, shor sd->subele2.push_back(entry); } +/** + * Adjust race damage to target when attacking + * @param sd: Player data + * @param race: Race to adjust + * @param rate: Success chance + * @param flag: Battle flag +*/ +static void pc_bonus_subrace(struct map_session_data* sd, unsigned char race, short rate, short flag) +{ + if (sd->subrace3.size() == MAX_PC_BONUS) { + ShowWarning("pc_bonus_subrace: Reached max (%d) number of resist race damage bonuses per character!\n", MAX_PC_BONUS); + return; + } + + 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 : sd->subrace3) { + if (it.race == race && it.flag == flag) { + it.rate = cap_value(it.rate + rate, -10000, 10000); + return; + } + } + + struct s_addrace2 entry = {}; + + if (rate < -10000 || rate > 10000) + ShowWarning("pc_bonus_subrace: Item bonus rate %d exceeds -10000~10000 range, capping.\n", rate); + + entry.race = race; + entry.rate = cap_value(rate, -10000, 10000); + entry.flag = flag; + + sd->subrace3.push_back(entry); +} /** * General item bonus for player * @param bonus: Bonus array @@ -3469,6 +3512,10 @@ void pc_bonus(struct map_session_data *sd,int type,int val) if(sd->state.lr_flag != 2) sd->bonus.crit_atk_rate += val; break; + case SP_CRIT_DEF_RATE: + if(sd->state.lr_flag != 2) + sd->bonus.crit_def_rate += val; + break; case SP_NO_REGEN: if(sd->state.lr_flag != 2) sd->regen.state.block|=val; @@ -3924,6 +3971,11 @@ void pc_bonus2(struct map_session_data *sd,int type,int type2,int val) if(sd->state.lr_flag != 2) sd->subsize[type2]+=val; break; + case SP_MAGIC_SUBSIZE: // bonus2 bMagicSubSize,s,x; + PC_BONUS_CHK_SIZE(type2,SP_MAGIC_SUBSIZE); + if(sd->state.lr_flag != 2) + sd->magic_subsize[type2]+=val; + break; case SP_SUBRACE2: // bonus2 bSubRace2,mr,x; PC_BONUS_CHK_RACE2(type2,SP_SUBRACE2); if(sd->state.lr_flag != 2) @@ -4281,7 +4333,13 @@ void pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val) if (sd->state.lr_flag != 2) pc_bonus_subele(sd, (unsigned char)type2, type3, val); break; - + + case SP_SUBRACE: // bonus3 bSubRace,r,x,bf; + PC_BONUS_CHK_RACE(type2, SP_SUBRACE); + if (sd->state.lr_flag != 2) + pc_bonus_subrace(sd, (unsigned char)type2, type3, val); + break; + case SP_SP_VANISH_RACE_RATE: // bonus3 bSPVanishRaceRate,r,x,n; PC_BONUS_CHK_RACE(type2,SP_SP_VANISH_RACE_RATE); if(sd->state.lr_flag != 2) { @@ -8731,6 +8789,7 @@ int64 pc_readparam(struct map_session_data* sd,int64 type) #else val = sd->castrate; break; #endif + case SP_CRIT_DEF_RATE: val = sd->bonus.crit_def_rate; break; default: ShowError("pc_readparam: Attempt to read unknown parameter '%lld'.\n", type); return -1; diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 261141c0f97..fe05b221cdb 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -151,6 +151,12 @@ struct s_addele2 { unsigned char ele; }; +/// AddRace bonus struct +struct s_addrace2 { + short flag, rate; + unsigned char race; +}; + struct weapon_data { int atkmods[SZ_ALL]; // all the variables except atkmods get zero'ed in each call of status_calc_pc @@ -181,6 +187,7 @@ struct weapon_data { std::vector add_dmg; std::vector addele2; + std::vector addrace3; }; /// AutoSpell bonus struct @@ -440,6 +447,7 @@ struct map_session_data { int magic_addclass[CLASS_MAX]; int magic_addsize[SZ_MAX]; int magic_atk_ele[ELE_MAX]; + int magic_subsize[SZ_MAX]; int critaddrace[RC_MAX]; int expaddrace[RC_MAX]; int expaddclass[CLASS_MAX]; @@ -462,6 +470,7 @@ struct map_session_data { std::vector add_drop; 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 // zeroed structures start here @@ -502,6 +511,7 @@ struct map_session_data { int magic_damage_return; // AppleGirl Was Here int break_weapon_rate,break_armor_rate; int crit_atk_rate; + int crit_def_rate; int classchange; // [Valaris] int speed_rate, speed_add_rate, aspd_add; int itemhealrate2; // [Epoque] Increase heal rate of all healing items. diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index b1394c0774b..bb702d269d4 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -753,6 +753,9 @@ export_constant2("bNoWalkDelay",SP_NO_WALK_DELAY); export_constant2("bLongSPGainValue",SP_LONG_SP_GAIN_VALUE); export_constant2("bLongHPGainValue",SP_LONG_HP_GAIN_VALUE); + export_constant2("bMagicSubSize",SP_MAGIC_SUBSIZE); + export_constant2("bCritDefRate",SP_CRIT_DEF_RATE); + /* equip indices */ export_constant(EQI_COMPOUND_ON); diff --git a/src/map/status.cpp b/src/map/status.cpp index c15cc6f9195..27d22006267 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -3832,6 +3832,7 @@ int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt) + sizeof(sd->magic_addclass) + sizeof(sd->magic_addsize) + sizeof(sd->magic_atk_ele) + + sizeof(sd->magic_subsize) + sizeof(sd->critaddrace) + sizeof(sd->expaddrace) + sizeof(sd->expaddclass) @@ -3914,6 +3915,7 @@ int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt) sd->add_drop.clear(); sd->itemhealrate.clear(); sd->subele2.clear(); + sd->subrace3.clear(); sd->skilldelay.clear(); sd->sp_vanish.clear(); sd->hp_vanish.clear();