Skip to content

Commit 849838f

Browse files
author
LocalIdentity
committed
Use Characters.ot and Monsters.ot files for many magic numbers
Port of PathOfBuildingCommunity/PathOfBuilding-PoE2#1184 These 2 files contain many constants we had currently hardcoded in various files
1 parent 14a0aae commit 849838f

8 files changed

Lines changed: 269 additions & 69 deletions

File tree

src/Data/Misc.lua

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,153 @@ data.gameConstants = {
5555
["GoldPlusPercentPerAffix"] = 10,
5656
["UniqueBaseGoldCost"] = 2000,
5757
}
58+
-- From Metadata/Characters/Character.ot
59+
data.characterConstants = {
60+
["level"] = 1,
61+
["is_player"] = 1,
62+
["energy_shield_recharge_rate_per_minute_%"] = 2000,
63+
["mana_regeneration_rate_per_minute_%"] = 105,
64+
["base_maximum_all_resistances_%"] = 75,
65+
["maximum_physical_damage_reduction_%"] = 90,
66+
["maximum_block_%"] = 75,
67+
["base_maximum_spell_block_%"] = 75,
68+
["base_attack_speed_+%_per_frenzy_charge"] = 4,
69+
["base_cast_speed_+%_per_frenzy_charge"] = 4,
70+
["object_inherent_damage_+%_final_per_frenzy_charge"] = 4,
71+
["physical_damage_reduction_%_per_endurance_charge"] = 4,
72+
["elemental_damage_reduction_%_per_endurance_charge"] = 4,
73+
["critical_strike_chance_+%_per_power_charge"] = 50,
74+
["max_viper_strike_orbs"] = 4,
75+
["dual_wield_inherent_attack_speed_+%_final"] = 10,
76+
["max_fuse_arrow_orbs"] = 5,
77+
["max_fire_beam_stacks"] = 8,
78+
["base_evasion_rating"] = 15,
79+
["life_per_level"] = 12,
80+
["mana_per_level"] = 6,
81+
["accuracy_rating_per_level"] = 2,
82+
["inherent_block_while_dual_wielding_%"] = 20,
83+
["base_critical_strike_multiplier"] = 150,
84+
["critical_ailment_dot_multiplier_+"] = 50,
85+
["strength_per_level"] = 0,
86+
["dexterity_per_level"] = 0,
87+
["intelligence_per_level"] = 0,
88+
["max_endurance_charges"] = 3,
89+
["max_frenzy_charges"] = 3,
90+
["max_power_charges"] = 3,
91+
["maximum_righteous_charges"] = 5,
92+
["maximum_blood_scythe_charges"] = 5,
93+
["base_number_of_totems_allowed"] = 1,
94+
["base_number_of_traps_allowed"] = 15,
95+
["base_number_of_remote_mines_allowed"] = 15,
96+
["max_charged_attack_stacks"] = 6,
97+
["max_talisman_degen_stacks"] = 20,
98+
["max_frost_nova_stacks"] = 20,
99+
["max_rampage_stacks"] = 1000,
100+
["damage_+%_per_10_rampage_stacks"] = 2,
101+
["movement_velocity_+%_per_10_rampage_stacks"] = 1,
102+
["pvp_shield_damage_+%_final"] = -15,
103+
["maximum_life_leech_rate_%_per_minute"] = 1200,
104+
["maximum_mana_leech_rate_%_per_minute"] = 1200,
105+
["maximum_energy_shield_leech_rate_%_per_minute"] = 600,
106+
["minions_have_labyrinth_trap_degen_effect_+%"] = -90,
107+
["minions_are_immune_to_labyrinth_degen_effect"] = 0,
108+
["minion_damage_taken_+%_from_spike_traps_final"] = -90,
109+
["minion_damage_taken_+%_from_arrow_traps_final"] = 0,
110+
["minion_damage_taken_+%_from_guillotine_traps_final"] = -90,
111+
["minion_global_always_hit"] = 1,
112+
["traps_explode_on_timeout"] = 1,
113+
["maximum_rage"] = 30,
114+
["max_delve_degen_stacks"] = 5000,
115+
["max_azurite_debuff_stacks"] = 10,
116+
["melee_variation"] = 1,
117+
["impaled_debuff_base_duration_ms"] = 8000,
118+
["impaled_debuff_number_of_reflected_hits"] = 5,
119+
["base_total_number_of_sigils_allowed"] = 3,
120+
["maximum_life_leech_amount_per_leech_%_max_life"] = 10,
121+
["maximum_mana_leech_amount_per_leech_%_max_mana"] = 10,
122+
["maximum_energy_shield_leech_amount_per_leech_%_max_energy_shield"] = 10,
123+
["enable_movement_skill_animation_skipping"] = 1,
124+
["melee_hit_damage_stun_multiplier_+%"] = 25,
125+
["non_physical_hit_damage_stun_multiplier_+%"] = -25,
126+
["non_melee_hit_damage_stun_multiplier_+%_final"] = -25,
127+
["object_inherent_melee_hit_stun_duration_+%_final"] = 50,
128+
["additional_insanity_effects_while_delirious"] = 1,
129+
["max_steel_ammo"] = 12,
130+
["chance_to_deal_triple_damage_%_per_brutal_charge"] = 3,
131+
["stun_threshold_+%_per_brutal_charge"] = 10,
132+
["ailment_damage_+%_final_per_affliction_charge"] = 8,
133+
["non_damaging_ailment_effect_+%_final_per_affliction_charge"] = 8,
134+
["elemental_damage_taken_goes_to_energy_shield_over_4_seconds_%_per_absorption_charge"] = 12,
135+
["actor_scale_+%_limit"] = 100,
136+
["mines_invulnerable_for_duration_ms"] = 2000,
137+
["traps_invulnerable_for_duration_ms"] = 2000,
138+
["damage_taken_when_hit_+%_final_per_fortification"] = -1,
139+
["base_max_fortification"] = 20,
140+
["base_presence_radius"] = 80,
141+
["mtx_max_killcounter_stacks"] = 30000,
142+
["soul_eater_maximum_stacks"] = 45,
143+
["rage_loss_delay_ms"] = 2000,
144+
["trigger_attack_graft_each_second_channeling"] = 1,
145+
["base_speed"] = 37,
146+
}
147+
-- From Metadata/Monsters/Monster.ot
148+
data.monsterConstants = {
149+
["item_drop_slots"] = 1,
150+
["energy_shield_recharge_rate_per_minute_%"] = 2000,
151+
["mana_regeneration_rate_per_minute_%"] = 100,
152+
["base_maximum_mana"] = 200,
153+
["maximum_physical_damage_reduction_%"] = 75,
154+
["max_viper_strike_orbs"] = 4,
155+
["base_maximum_all_resistances_%"] = 75,
156+
["max_fuse_arrow_orbs"] = 5,
157+
["max_fire_beam_stacks"] = 8,
158+
["max_charged_attack_stacks"] = 10,
159+
["base_critical_strike_multiplier"] = 130,
160+
["critical_ailment_dot_multiplier_+"] = 30,
161+
["max_endurance_charges"] = 3,
162+
["max_frenzy_charges"] = 3,
163+
["max_power_charges"] = 3,
164+
["base_attack_speed_+%_per_frenzy_charge"] = 4,
165+
["base_attack_speed_+%_per_frenzy_charge_if_not_player_minion"] = 11,
166+
["base_cast_speed_+%_per_frenzy_charge"] = 4,
167+
["base_cast_speed_+%_per_frenzy_charge_if_not_player_minion"] = 11,
168+
["movement_velocity_+%_per_frenzy_charge_if_not_player_minion"] = 5,
169+
["object_inherent_damage_+%_final_per_frenzy_charge"] = 4,
170+
["physical_damage_reduction_%_per_endurance_charge"] = 4,
171+
["physical_damage_reduction_%_per_endurance_charge_if_not_player_minion"] = 11,
172+
["elemental_damage_reduction_%_per_endurance_charge_if_player_minion"] = 4,
173+
["resist_all_elements_%_per_endurance_charge_if_not_player_minion"] = 15,
174+
["critical_strike_chance_+%_per_power_charge"] = 50,
175+
["critical_strike_chance_+%_per_power_charge_if_not_player_minion"] = 150,
176+
["maximum_block_%"] = 75,
177+
["base_maximum_spell_block_%"] = 75,
178+
["base_number_of_totems_allowed"] = 1,
179+
["base_number_of_traps_allowed"] = 3,
180+
["base_number_of_remote_mines_allowed"] = 5,
181+
["movement_velocity_cap"] = 128,
182+
["maximum_life_leech_rate_%_per_minute"] = 1200,
183+
["maximum_mana_leech_rate_%_per_minute"] = 1200,
184+
["maximum_energy_shield_leech_rate_%_per_minute"] = 600,
185+
["monster_ignite_damage_+%_final"] = -72,
186+
["monster_bleeding_damage_+%_final"] = -86,
187+
["monster_poison_damage_+%_final"] = -50,
188+
["bleeding_moving_damage_%_of_base_override"] = 500,
189+
["max_azurite_debuff_stacks"] = 10,
190+
["impaled_debuff_base_duration_ms"] = 8000,
191+
["impaled_debuff_number_of_reflected_hits"] = 5,
192+
["ignore_skill_weapon_restrictions"] = 1,
193+
["base_total_number_of_sigils_allowed"] = 3,
194+
["maximum_life_leech_amount_per_leech_%_max_life"] = 10,
195+
["maximum_mana_leech_amount_per_leech_%_max_mana"] = 10,
196+
["maximum_energy_shield_leech_amount_per_leech_%_max_energy_shield"] = 10,
197+
["object_inherent_melee_hit_stun_duration_+%_final"] = 20,
198+
["scale_melee_range_to_actor_scale"] = 1,
199+
["use_melee_pattern_range"] = 1,
200+
["actor_scale_+%_limit"] = 100,
201+
["damage_taken_when_hit_+%_final_per_fortification"] = -1,
202+
["base_max_fortification"] = 20,
203+
["soul_eater_maximum_stacks"] = 45,
204+
}
58205
-- From MonsterVarieties.dat combined with SkillTotemVariations.dat
59206
data.totemLifeMult = { [1] = 1, [2] = 1, [3] = 1, [4] = 1.2, [5] = 1, [6] = 1.2, [7] = 1.2, [8] = 1.2, [9] = 1, [10] = 1, [11] = 1, [12] = 1, [13] = 1.2, [15] = 1.2, [16] = 7.44, [17] = 1.2, [18] = 1, [19] = 1, [20] = 1.2, [21] = 1.2, }
60207
data.monsterVarietyLifeMult = {

src/Export/Classes/GGPKData.lua

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,10 @@ function GGPKClass:GetNeededFiles()
308308
"Metadata/StatDescriptions/tincture_stat_descriptions.txt",
309309
"Metadata/StatDescriptions/graft_stat_descriptions.txt",
310310
}
311+
local otFiles = {
312+
"Metadata/Characters/Character.ot",
313+
"Metadata/Monsters/Monster.ot",
314+
}
311315
local itFiles = {
312316
"Metadata/Items/Quivers/AbstractQuiver.it",
313317
"Metadata/Items/Rings/AbstractRing.it",
@@ -351,5 +355,5 @@ function GGPKClass:GetNeededFiles()
351355
"Metadata/Items/Tinctures/AbstractTincture.it",
352356
"Metadata/Items/Jewels/AbstractAnimalCharm.it",
353357
}
354-
return datFiles, txtFiles, itFiles
358+
return datFiles, txtFiles, otFiles, itFiles
355359
end

src/Export/Scripts/miscdata.lua

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,48 @@ for row in dat("GameConstants"):Rows() do
4848
end
4949
out:write('}\n')
5050

51+
out:write('-- From Metadata/Characters/Character.ot\n')
52+
out:write('data.characterConstants = {\n')
53+
local file = getFile("Metadata/Characters/Character.ot")
54+
if not file then return nil end
55+
local text = convertUTF16to8(file)
56+
local inWantedBlock = false
57+
for line in text:gmatch("[^\r\n]+") do
58+
-- Detect start of a block
59+
if line:match("^Stats") or line:match("^Pathfinding") then
60+
inWantedBlock = true
61+
elseif inWantedBlock and line:match("^}") then
62+
inWantedBlock = false
63+
elseif inWantedBlock and line:find("=") then
64+
local key, value = line:gsub("%s+",""):match("^(.-)=(.+)$")
65+
if key and value then
66+
out:write('\t["' .. key .. '"] = ' .. value .. ',\n')
67+
end
68+
end
69+
end
70+
out:write('}\n')
71+
72+
out:write('-- From Metadata/Monsters/Monster.ot\n')
73+
out:write('data.monsterConstants = {\n')
74+
local file = getFile("Metadata/Monsters/Monster.ot")
75+
if not file then return nil end
76+
local text = convertUTF16to8(file)
77+
local inWantedBlock = false
78+
for line in text:gmatch("[^\r\n]+") do
79+
-- Detect start of a block
80+
if line:match("^Stats") then
81+
inWantedBlock = true
82+
elseif inWantedBlock and line:match("^}") then
83+
inWantedBlock = false
84+
elseif inWantedBlock and line:find("=") then
85+
local key, value = line:gsub("%s+",""):match("^(.-)=(.+)$")
86+
if key and value then
87+
out:write('\t["' .. key .. '"] = ' .. value .. ',\n')
88+
end
89+
end
90+
end
91+
out:write('}\n')
92+
5193
local totemMult = ""
5294
local keys = { }
5395
for var in dat("SkillTotemVariations"):Rows() do

src/Modules/CalcOffence.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3198,7 +3198,7 @@ function calcs.offence(env, actor, activeSkill)
31983198
if skillModList:Flag(cfg, "IgnoreEnemyPhysicalDamageReduction") or ChanceToIgnoreEnemyPhysicalDamageReduction >= 100 then
31993199
resist = 0
32003200
else
3201-
resist = m_min(m_max(0, enemyDB:Sum("BASE", nil, "PhysicalDamageReduction") + skillModList:Sum("BASE", cfg, "EnemyPhysicalDamageReduction") + armourReduction), data.misc.DamageReductionCap)
3201+
resist = m_min(m_max(0, enemyDB:Sum("BASE", nil, "PhysicalDamageReduction") + skillModList:Sum("BASE", cfg, "EnemyPhysicalDamageReduction") + armourReduction), data.misc.EnemyPhysicalDamageReductionCap)
32023202
resist = resist > 0 and resist * (1 - (skillModList:Sum("BASE", nil, "PartialIgnoreEnemyPhysicalDamageReduction") / 100 + ChanceToIgnoreEnemyPhysicalDamageReduction / 100)) or resist
32033203
end
32043204
else
@@ -4204,7 +4204,7 @@ function calcs.offence(env, actor, activeSkill)
42044204
skillFlags.duration = true
42054205
local effMult = 1
42064206
if env.mode_effective then
4207-
local resist = m_min(m_max(0, enemyDB:Sum("BASE", nil, "PhysicalDamageReduction")), data.misc.DamageReductionCap)
4207+
local resist = m_min(m_max(0, enemyDB:Sum("BASE", nil, "PhysicalDamageReduction")), data.misc.EnemyPhysicalDamageReductionCap)
42084208
local takenInc = enemyDB:Sum("INC", dotCfg, "DamageTaken", "DamageTakenOverTime", "PhysicalDamageTaken", "PhysicalDamageTakenOverTime")
42094209
local takenMore = enemyDB:More(dotCfg, "DamageTaken", "DamageTakenOverTime", "PhysicalDamageTaken", "PhysicalDamageTakenOverTime")
42104210
effMult = (1 - resist / 100) * (1 + takenInc / 100) * takenMore
@@ -5209,7 +5209,7 @@ function calcs.offence(env, actor, activeSkill)
52095209

52105210
local enemyArmour = m_max(calcLib.val(enemyDB, "Armour"), 0)
52115211
local impaleArmourReduction = calcs.armourReductionF(enemyArmour, impaleHitDamageMod * output.impaleStoredHitAvg)
5212-
local impaleResist = m_min(m_max(0, enemyDB:Sum("BASE", nil, "PhysicalDamageReduction") + skillModList:Sum("BASE", cfg, "EnemyImpalePhysicalDamageReduction") + impaleArmourReduction), data.misc.DamageReductionCap)
5212+
local impaleResist = m_min(m_max(0, enemyDB:Sum("BASE", nil, "PhysicalDamageReduction") + skillModList:Sum("BASE", cfg, "EnemyImpalePhysicalDamageReduction") + impaleArmourReduction), data.misc.EnemyPhysicalDamageReductionCap)
52135213
if skillModList:Flag(cfg, "IgnoreEnemyImpalePhysicalDamageReduction") then
52145214
impaleResist = 0
52155215
end
@@ -5422,7 +5422,7 @@ function calcs.offence(env, actor, activeSkill)
54225422
local takenInc = enemyDB:Sum("INC", dotTakenCfg, "DamageTaken", "DamageTakenOverTime", damageType.."DamageTaken", damageType.."DamageTakenOverTime") + (isElemental[damageType] and enemyDB:Sum("INC", dotTakenCfg, "ElementalDamageTaken") or 0)
54235423
local takenMore = enemyDB:More(dotTakenCfg, "DamageTaken", "DamageTakenOverTime", damageType.."DamageTaken", damageType.."DamageTakenOverTime") * (isElemental[damageType] and enemyDB:More(dotTakenCfg, "ElementalDamageTaken") or 1)
54245424
if damageType == "Physical" then
5425-
resist = m_max(0, m_min(enemyDB:Sum("BASE", nil, "PhysicalDamageReduction"), data.misc.DamageReductionCap))
5425+
resist = m_max(0, m_min(enemyDB:Sum("BASE", nil, "PhysicalDamageReduction"), data.misc.EnemyPhysicalDamageReductionCap))
54265426
else
54275427
resist = calcResistForType(damageType, dotTypeCfg)
54285428
end

src/Modules/CalcPerform.lua

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,22 +1098,21 @@ function calcs.perform(env, skipEHP)
10981098
-- Minion Attacks now inherently always hit (Patch 3.27)
10991099
env.minion.modDB:NewMod("CannotBeEvaded", "FLAG", 1, "Minion Attacks always hit")
11001100
end
1101-
env.minion.modDB:NewMod("CritMultiplier", "BASE", 30, "Base")
1102-
env.minion.modDB:NewMod("CritDegenMultiplier", "BASE", 30, "Base")
1101+
env.minion.modDB:NewMod("CritMultiplier", "BASE", env.data.monsterConstants["base_critical_strike_multiplier"] - 100, "Base")
1102+
env.minion.modDB:NewMod("DotMultiplier", "BASE", env.data.monsterConstants["critical_ailment_dot_multiplier_+"], "Base", { type = "Condition", var = "CriticalStrike" })
11031103
env.minion.modDB:NewMod("FireResist", "BASE", env.minion.minionData.fireResist, "Base")
11041104
env.minion.modDB:NewMod("ColdResist", "BASE", env.minion.minionData.coldResist, "Base")
11051105
env.minion.modDB:NewMod("LightningResist", "BASE", env.minion.minionData.lightningResist, "Base")
11061106
env.minion.modDB:NewMod("ChaosResist", "BASE", env.minion.minionData.chaosResist, "Base")
1107-
env.minion.modDB:NewMod("CritChance", "INC", 50, "Base", { type = "Multiplier", var = "PowerCharge" })
1108-
env.minion.modDB:NewMod("Speed", "INC", 4, "Base", ModFlag.Attack, { type = "Multiplier", var = "FrenzyCharge" })
1109-
env.minion.modDB:NewMod("Speed", "INC", 4, "Base", ModFlag.Cast, { type = "Multiplier", var = "FrenzyCharge" })
1110-
env.minion.modDB:NewMod("Damage", "MORE", 4, "Base", { type = "Multiplier", var = "FrenzyCharge" })
1111-
env.minion.modDB:NewMod("PhysicalDamageReduction", "BASE", 4, "Base", { type = "Multiplier", var = "EnduranceCharge" })
1112-
env.minion.modDB:NewMod("ElementalDamageReduction", "BASE", 4, "Base", { type = "Multiplier", var = "EnduranceCharge" })
1107+
env.minion.modDB:NewMod("CritChance", "INC", env.data.monsterConstants["critical_strike_chance_+%_per_power_charge"], "Base", { type = "Multiplier", var = "PowerCharge" })
1108+
env.minion.modDB:NewMod("Speed", "INC", env.data.monsterConstants["base_attack_speed_+%_per_frenzy_charge"], "Base", ModFlag.Attack, { type = "Multiplier", var = "FrenzyCharge" })
1109+
env.minion.modDB:NewMod("Speed", "INC", env.data.monsterConstants["base_cast_speed_+%_per_frenzy_charge"], "Base", ModFlag.Cast, { type = "Multiplier", var = "FrenzyCharge" })
1110+
env.minion.modDB:NewMod("Damage", "MORE", env.data.monsterConstants["object_inherent_damage_+%_final_per_frenzy_charge"], "Base", { type = "Multiplier", var = "FrenzyCharge" })
1111+
env.minion.modDB:NewMod("PhysicalDamageReduction", "BASE", env.data.monsterConstants["physical_damage_reduction_%_per_endurance_charge"], "Base", { type = "Multiplier", var = "EnduranceCharge" })
1112+
env.minion.modDB:NewMod("ElementalDamageReduction", "BASE", env.data.monsterConstants["elemental_damage_reduction_%_per_endurance_charge_if_player_minion"], "Base", { type = "Multiplier", var = "EnduranceCharge" })
11131113
env.minion.modDB:NewMod("ProjectileCount", "BASE", 1, "Base")
1114-
env.minion.modDB:NewMod("MaximumFortification", "BASE", 20, "Base")
1114+
env.minion.modDB:NewMod("MaximumFortification", "BASE", env.data.monsterConstants["base_max_fortification"], "Base")
11151115
env.minion.modDB:NewMod("Damage", "MORE", 200, "Base", 0, KeywordFlag.Bleed, { type = "ActorCondition", actor = "enemy", var = "Moving" })
1116-
env.minion.modDB:NewMod("DotMultiplier", "BASE", 30, "Base", { type = "Condition", var = "CriticalStrike" })
11171116
for _, mod in ipairs(env.minion.minionData.modList) do
11181117
env.minion.modDB:AddMod(mod)
11191118
end

0 commit comments

Comments
 (0)