Skip to content

Commit de5de8c

Browse files
ImmotephSimonLocalIdentity
andauthored
Add Stun, Pin, Freeze and Electrocute buildup calculations (#1378)
* Add parsing/support for buildup mechanics Add poise from data Add poise to ConfigOptions * Add pin buildup Add data table Clean up code * Add breakdown for buildup Add breakdown support in CalcOffense * Add all damage types to stun in data * Fix Poise Threshold + Misc.lua * Redo removed export * Fix misc and add poise number * Update breakdown * Fix parsing for proj pin + remove pin damage type * Add Bone Cage pin mods * Undo duplicated electrocute-change Simplify base_all_damage_can_pin * Tree / Gear mods for builup * Fix breakdown * Add support for a lot of skills with buildups * Fix Lightning damage innately affection electrocution * Innate Melee / Phys damage Stun bonuses * Adds support for buildup from: Rime Chaotic Freeze Leap Slam Shield Charge Freezing Mark * Fix Pin support not disabling Stun * Fix Melee Damage buildup not working * Fix Enemy Poise multiplier The base value in MonsterVarieties is 100 so we need to take away 100 when applying it as a more multiplier * Add stat name to config mods * Use enemy damage taken instead of pre hit mitigation * Fix Quality on Overwhelming Presence not affecting threshold mods The stat was not being applied as a AuraDebuff so wasn't being properly scaled by the Aura effect quality mod --------- Co-authored-by: LocalIdentity <localidentity2@gmail.com>
1 parent 449b497 commit de5de8c

21 files changed

Lines changed: 690 additions & 309 deletions

src/Data/Misc.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ data.monsterDamageTable = { 9.1599998474121, 10.260000228882, 11.390000343323, 1
1010
data.monsterAllyDamageTable = { 3.1099998950958, 4.4200000762939, 5.8200001716614, 7.3099999427795, 8.9200000762939, 10.630000114441, 12.460000038147, 14.420000076294, 16.510000228882, 18.729999542236, 21.10000038147, 23.620000839233, 26.309999465942, 29.159999847412, 32.189998626709, 35.419998168945, 38.830001831055, 42.459999084473, 46.310001373291, 50.389999389648, 54.709999084473, 59.290000915527, 64.139999389648, 69.269996643066, 74.690002441406, 80.430000305176, 86.5, 92.910003662109, 99.690002441406, 106.83999633789, 114.40000152588, 122.37000274658, 130.78999328613, 139.66999816895, 149.03999328613, 158.91000366211, 169.32000732422, 180.28999328613, 191.86000061035, 204.03999328613, 216.86000061035, 230.36999511719, 244.60000610352, 259.57000732422, 275.32000732422, 291.89999389648, 309.33999633789, 327.69000244141, 346.98001098633, 367.26998901367, 388.58999633789, 411.01000976563, 434.57000732422, 459.32000732422, 485.32998657227, 512.65997314453, 541.34997558594, 571.48999023438, 603.14001464844, 636.36999511719, 671.26000976563, 707.86999511719, 746.29998779297, 786.63000488281, 828.94000244141, 873.34002685547, 919.90997314453, 968.76000976563, 1019.9899902344, 1073.7199707031, 1130.0600585938, 1189.1300048828, 1251.0600585938, 1315.9799804688, 1384.0300292969, 1455.3399658203, 1530.0799560547, 1608.4000244141, 1690.4599609375, 1776.4300537109, 1866.5, 1960.8399658203, 2059.6599121094, 2163.1599121094, 2271.5600585938, 2385.0600585938, 2503.9099121094, 2628.3601074219, 2758.6398925781, 2895.0300292969, 3037.8000488281, 3187.2399902344, 3343.6599121094, 3507.3500976563, 3678.6599121094, 3857.9299316406, 4045.5100097656, 4241.7700195313, 4447.1098632813, 4661.9301757813, }
1111
data.monsterArmourTable = { 3, 6, 8, 10, 13, 16, 19, 22, 26, 30, 34, 39, 43, 49, 54, 60, 67, 73, 81, 89, 97, 106, 116, 126, 137, 149, 161, 174, 189, 204, 220, 237, 255, 274, 295, 317, 340, 364, 391, 418, 448, 479, 512, 547, 585, 624, 666, 711, 758, 808, 861, 917, 976, 1039, 1105, 1176, 1250, 1329, 1412, 1500, 1594, 1692, 1796, 1906, 2023, 2146, 2276, 2413, 2558, 2712, 2874, 3044, 3225, 3416, 3617, 3829, 4053, 4290, 4540, 4803, 5081, 5375, 5684, 6011, 6355, 6718, 7101, 7505, 7930, 8379, 8852, 9351, 9877, 10431, 11015, 11630, 12279, 12962, 13682, 14441, }
1212
data.monsterAilmentThresholdTable = { 15, 20, 24, 28, 34, 39, 46, 52, 60, 70, 81, 95, 110, 126, 144, 171, 193, 218, 245, 275, 306, 340, 376, 413, 455, 497, 543, 590, 641, 695, 752, 812, 874, 950, 1033, 1123, 1220, 1326, 1442, 1568, 1705, 1854, 2015, 2192, 2384, 2564, 2757, 2966, 3188, 3426, 3681, 3955, 4247, 4560, 4895, 5254, 5638, 6049, 6489, 6959, 7462, 8001, 8576, 9193, 9723, 10382, 11085, 11837, 12639, 13497, 14413, 15390, 16435, 17549, 18742, 20013, 21372, 22824, 24373, 26029, 27796, 29684, 31700, 33852, 36153, 38608, 41230, 44033, 47023, 50219, 53630, 57272, 61164, 65318, 69757, 74494, 79554, 84958, 90729, 96892, }
13+
data.monsterPoiseThresholdTable = { 30, 40, 48, 57, 67, 79, 93, 106, 122, 142, 165, 192, 220, 254, 290, 344, 390, 437, 488, 542, 599, 659, 724, 791, 862, 937, 1015, 1097, 1183, 1273, 1367, 1464, 1567, 1660, 1758, 1864, 1976, 2093, 2219, 2352, 2494, 2644, 2804, 2971, 3150, 3369, 3598, 3846, 4109, 4387, 4685, 5002, 5338, 5697, 6078, 6485, 6915, 7377, 7866, 8386, 8940, 9528, 10153, 10819, 11376, 12648, 14061, 15634, 17382, 19326, 21492, 23897, 26573, 29553, 32864, 36550, 40649, 45211, 50282, 55927, 62209, 69197, 76969, 85615, 95241, 105954, 117866, 131122, 145878, 162291, 180568, 200887, 223518, 248690, 276705, 307880, 342574, 381187, 424158, 471974, }
1314

1415
-- From MinionGemLevelScaling.dat
1516
data.minionLevelTable = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, }

src/Data/ModCache.lua

100755100644
Lines changed: 292 additions & 245 deletions
Large diffs are not rendered by default.

src/Data/SkillStatMap.lua

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,10 @@ return {
11581158
},
11591159
-- Ailments
11601160
["skill_overwhelming_pressure_aura_enemy_ailment_threshold_+%"] = {
1161-
mod("AilmentThreshold", "INC", nil, 0, 0, { type = "GlobalEffect", effectType = "Debuff", effectName = "Overwhelming Presence"}),
1161+
mod("EnemyAilmentThreshold", "INC", nil, 0, 0, { type = "GlobalEffect", effectType = "AuraDebuff", effectName = "Overwhelming Presence"}),
1162+
},
1163+
["skill_overwhelming_pressure_aura_enemy_stun_threshold_+%"] = {
1164+
mod("EnemyStunThreshold", "INC", nil, 0, 0, { type = "GlobalEffect", effectType = "AuraDebuff", effectName = "Overwhelming Presence"}),
11621165
},
11631166
["bleed_on_hit_with_attacks_%"] = {
11641167
mod("BleedChance", "BASE", nil, ModFlag.Attack),
@@ -1297,10 +1300,13 @@ return {
12971300
["active_skill_shock_effect_+%_final"] = {
12981301
mod("EnemyShockMagnitude", "MORE", nil),
12991302
},
1303+
["active_skill_electrocutes_as_though_dealt_damage_+%_final"] = {
1304+
mod("EnemyElectrocuteBuildup", "MORE", nil),
1305+
},
13001306
["non_damaging_ailment_effect_+%"] = {
13011307
mod("EnemyChillMagnitude", "INC", nil),
13021308
mod("EnemyShockMagnitude", "INC", nil),
1303-
mod("EnemyFreezeEffect", "INC", nil),
1309+
mod("EnemyFreezeBuildup", "INC", nil),
13041310
},
13051311
["lightning_ailment_effect_+%"] = {
13061312
mod("EnemyShockMagnitude", "INC", nil),
@@ -1315,10 +1321,16 @@ return {
13151321
},
13161322
["cold_ailment_effect_+%"] = {
13171323
mod("EnemyChillMagnitude", "INC", nil),
1318-
mod("EnemyFreezeEffect", "INC", nil),
1324+
mod("EnemyFreezeBuildup", "INC", nil),
1325+
},
1326+
["hit_damage_freeze_multiplier_+%"] = {
1327+
mod("EnemyFreezeBuildup", "INC", nil),
13191328
},
13201329
["active_skill_hit_damage_freeze_multiplier_+%_final"] = {
1321-
mod("EnemyFreezeEffect", "MORE", nil),
1330+
mod("EnemyFreezeBuildup", "MORE", nil),
1331+
},
1332+
["support_hypothermia_hit_damage_freeze_multiplier_+%_final"] = {
1333+
mod("EnemyFreezeBuildup", "MORE", nil),
13221334
},
13231335
["base_poison_effect_+%"] = {
13241336
mod("AilmentEffect", "INC", nil),
@@ -1425,6 +1437,10 @@ return {
14251437
["shock_minimum_damage_taken_increase_%+"] = {
14261438
mod("ShockMinimum", "BASE", nil),
14271439
},
1440+
["active_skill_pins_as_though_dealt_damage_+%_final"] = {
1441+
mod("EnemyPinBuildup", "MORE", nil),
1442+
},
1443+
14281444
-- Global flags
14291445
["never_ignite"] = {
14301446
flag("CannotIgnite"),
@@ -1442,6 +1458,13 @@ return {
14421458
["never_chill"] = {
14431459
flag("CannotChill"),
14441460
},
1461+
["cannot_pin"] = {
1462+
flag("CannotPin"),
1463+
},
1464+
["cannot_stun"] = {
1465+
flag("CannotHeavyStun"),
1466+
flag("CannotStun"),
1467+
},
14451468
["cannot_cause_bleeding"] = {
14461469
flag("CannotBleed"),
14471470
},
@@ -1494,12 +1517,29 @@ return {
14941517
flag("FireCanShock"),
14951518
flag("ChaosCanShock"),
14961519
},
1520+
["chaos_damage_can_freeze"] = {
1521+
flag("ChaosCanFreeze"),
1522+
},
14971523
["base_chaos_damage_can_ignite"] = {
14981524
flag("ChaosCanIgnite"),
14991525
},
15001526
["base_lightning_damage_can_electrocute"] = {
15011527
flag("LightningCanElectrocute"),
15021528
},
1529+
["base_all_damage_can_pin"] = {
1530+
flag("CanPin"),
1531+
},
1532+
["support_pin_physical_damage_can_pin"] = {
1533+
flag("PhysicalCanPin"),
1534+
},
1535+
["support_pin_buildup_pin_instead_of_stun"] = {
1536+
flag("PinBuildupInsteadOfHeavyStunBuildup"),
1537+
flag("CannotStun"),
1538+
flag("CannotHeavyStun"),
1539+
},
1540+
["support_pin_pin_buildup_+%_final"] = {
1541+
mod("EnemyPinBuildup", "MORE", nil),
1542+
},
15031543
["is_hazard"] = {
15041544
flag("CanCreateHazards"),
15051545
},
@@ -1516,6 +1556,15 @@ return {
15161556
mod("EnemyImpalePhysicalDamageReduction", "BASE", nil),
15171557
mult = -1,
15181558
},
1559+
["support_brink_hit_damage_stun_multiplier_+%_final"] = {
1560+
mod("EnemyHeavyStunBuildup", "MORE", nil),
1561+
},
1562+
["active_skill_hit_damage_stun_multiplier_+%_final"] = {
1563+
mod("EnemyHeavyStunBuildup", "MORE", nil),
1564+
},
1565+
["active_skill_minion_hit_damage_stun_multiplier_+%_final"] = {
1566+
mod("MinionModifier", "LIST", { mod = mod("EnemyHeavyStunBuildup", "MORE", nil) }),
1567+
},
15191568
["base_stun_duration_+%"] = {
15201569
mod("EnemyStunDuration", "INC", nil),
15211570
},
@@ -2840,4 +2889,10 @@ return {
28402889
["quality_display_supercharged_slam_is_gem"] = {
28412890
-- Display Only
28422891
},
2892+
["quality_display_active_skill_pins_as_though_dealt_damage_+%_final_is_gem"] = {
2893+
-- Display Only
2894+
},
2895+
["quality_display_freezing_mark_is_gem"] = {
2896+
-- Display Only
2897+
},
28432898
}

src/Data/Skills/act_int.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8530,6 +8530,9 @@ skills["FreezingMarkPlayer"] = {
85308530
["freezing_mark_damage_buff_damage_%_to_gain_as_cold"] = {
85318531
mod("DamageGainAsCold", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Buff" }),
85328532
},
8533+
["freezing_mark_hit_damage_freeze_multiplier_+%_final"] = {
8534+
mod("FreezeBuildup", "MORE", nil, 0, 0, { type = "GlobalEffect", effectType = "Curse" }),
8535+
},
85338536
},
85348537
baseFlags = {
85358538
area = true,

src/Data/Skills/act_str.lua

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7957,6 +7957,11 @@ skills["LeapSlamPlayer"] = {
79577957
baseEffectiveness = 0,
79587958
incrementalEffectiveness = 0.092720001935959,
79597959
statDescriptionScope = "leap_slam",
7960+
statMap = {
7961+
["active_skill_consume_enemy_fully_broken_armour_to_gain_hit_damage_stun_multiplier_+%"] = {
7962+
mod("EnemyHeavyStunBuildup", "MORE", nil, 0, 0, { type = "ActorCondition", actor = "enemy", var = "ArmourFullyBroken" }),
7963+
},
7964+
},
79607965
baseFlags = {
79617966
attack = true,
79627967
area = true,
@@ -16303,16 +16308,28 @@ skills["ShieldChargePlayer"] = {
1630316308
[39] = { attackTime = 600, baseMultiplier = 2.36, critChance = 5, levelRequirement = 90, cost = { ManaPerMinute = 10702, }, },
1630416309
[40] = { attackTime = 600, baseMultiplier = 2.48, critChance = 5, levelRequirement = 90, cost = { ManaPerMinute = 11389, }, },
1630516310
},
16311+
preDamageFunc = function(activeSkill, output)
16312+
activeSkill.skillData.hitTimeMultiplier = 1
16313+
activeSkill.skillData.channelTimeMultiplier = 1
16314+
end,
1630616315
statSets = {
1630716316
[1] = {
1630816317
label = "Area of Effect",
1630916318
incrementalEffectiveness = 0.27349999547005,
1631016319
statDescriptionScope = "channel_shield_charge",
16320+
statMap = {
16321+
["shield_charge_hit_damage_stun_multiplier_when_fully_charged_+%_final"] = {
16322+
mod("EnemyHeavyStunBuildup", "MORE", nil),
16323+
},
16324+
["base_skill_show_average_damage_instead_of_dps"] = {
16325+
},
16326+
},
1631116327
baseFlags = {
1631216328
attack = true,
1631316329
area = true,
1631416330
melee = true,
1631516331
shieldAttack = true,
16332+
channelRelease = true,
1631616333
},
1631716334
constantStats = {
1631816335
{ "active_skill_base_area_of_effect_radius", 24 },
@@ -16391,11 +16408,22 @@ skills["ShieldChargePlayer"] = {
1639116408
label = "Collision",
1639216409
incrementalEffectiveness = 0.054999999701977,
1639316410
statDescriptionScope = "channel_shield_charge",
16411+
statMap = {
16412+
["shield_charge_hit_damage_stun_multiplier_when_fully_charged_+%_final"] = {
16413+
mod("EnemyHeavyStunBuildup", "MORE", nil),
16414+
},
16415+
["base_skill_show_average_damage_instead_of_dps"] = {
16416+
},
16417+
},
1639416418
baseFlags = {
1639516419
attack = true,
1639616420
area = true,
1639716421
melee = true,
1639816422
shieldAttack = true,
16423+
channelRelease = true,
16424+
},
16425+
baseMods = {
16426+
skill("minChannelTime", 1.3),
1639916427
},
1640016428
constantStats = {
1640116429
{ "active_skill_base_area_of_effect_radius", 24 },

src/Data/Skills/sup_dex.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,8 +1435,8 @@ skills["SupportCommiseratePlayer"] = {
14351435
mod("AilmentMagnitude", "MORE", nil, 0, KeywordFlag.Poison, { type = "Condition", var = "Poisoned" }),
14361436
mod("EnemyShockMagnitude", "MORE", nil, 0, 0, { type = "Condition", var = "Shocked" }),
14371437
mod("EnemyChillMagnitude", "MORE", nil, 0, 0, { type = "Condition", var = "Chilled" }),
1438-
mod("EnemyFreezeEffect", "MORE", nil, 0, 0, { type = "Condition", var = "Frozen" }),
1439-
mod("EnemyElectrocuteEffect", "MORE", nil, 0, 0, { type = "Condition", var = "Electrocuted" }),
1438+
mod("EnemyFreezeBuildup", "MORE", nil, 0, 0, { type = "Condition", var = "Frozen" }),
1439+
mod("EnemyElectrocuteBuildup", "MORE", nil, 0, 0, { type = "Condition", var = "Electrocuted" }),
14401440
},
14411441
},
14421442
baseFlags = {

src/Data/Skills/sup_int.lua

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,6 +1796,11 @@ skills["SupportChaoticFreezePlayer"] = {
17961796
label = "Chaotic Freeze",
17971797
incrementalEffectiveness = 0.054999999701977,
17981798
statDescriptionScope = "gem_stat_descriptions",
1799+
statMap = {
1800+
["support_chaotic_freeze_dots_allow_enemies_to_be_frozen_by_chaos_damage"] = {
1801+
flag("ChaosCanFreeze", { type = "GlobalEffect", effectType = "Buff", effectName = "Chaotic Freeze" }),
1802+
},
1803+
},
17991804
baseFlags = {
18001805
},
18011806
stats = {
@@ -6701,6 +6706,14 @@ skills["SupportRimePlayer"] = {
67016706
label = "Rime",
67026707
incrementalEffectiveness = 0.054999999701977,
67036708
statDescriptionScope = "gem_stat_descriptions",
6709+
statMap = {
6710+
["chilled_ground_applies_%_freeze_multiplier_taken"] = {
6711+
mod("EnemyFreezeBuildup", "MORE", nil, 0, 0, { type = "GlobalEffect", effectType = "Buff", effectName = "Rime" }, { type = "ActorCondition", actor = "enemy", var = "OnChilledGround" }),
6712+
},
6713+
["support_winterblast_chill_effect_+%_final"] = {
6714+
mod("EnemyChillMagnitude", "MORE", nil),
6715+
},
6716+
},
67046717
baseFlags = {
67056718
},
67066719
constantStats = {

src/Data/Skills/sup_str.lua

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6101,6 +6101,14 @@ skills["RuthlessSupportPlayer"] = {
61016101
label = "Ruthless",
61026102
incrementalEffectiveness = 0.092720001935959,
61036103
statDescriptionScope = "gem_stat_descriptions",
6104+
statMap = {
6105+
["support_ruthless_big_hit_max_count"] = {
6106+
mod("RuthlessBlowMaxCount", "BASE", nil),
6107+
},
6108+
["support_ruthless_big_hit_stun_damage_+%_final"] = {
6109+
mod("RuthlessBlowStunMultiplier", "BASE", nil),
6110+
},
6111+
},
61046112
baseFlags = {
61056113
},
61066114
constantStats = {
@@ -6799,7 +6807,7 @@ skills["SupportStunPlayer"] = {
67996807
statDescriptionScope = "gem_stat_descriptions",
68006808
statMap = {
68016809
["support_overpower_hit_damage_stun_multiplier_+%_final"] = {
6802-
mod("StunBuildup", "MORE", nil),
6810+
mod("EnemyHeavyStunBuildup", "MORE", nil),
68036811
},
68046812
},
68056813
baseFlags = {
@@ -6834,7 +6842,7 @@ skills["SupportStunPlayerTwo"] = {
68346842
statDescriptionScope = "gem_stat_descriptions",
68356843
statMap = {
68366844
["support_overpower_hit_damage_stun_multiplier_+%_final"] = {
6837-
mod("StunBuildup", "MORE", nil),
6845+
mod("EnemyHeavyStunBuildup", "MORE", nil),
68386846
},
68396847
},
68406848
baseFlags = {
@@ -6869,7 +6877,7 @@ skills["SupportStunPlayerThree"] = {
68696877
statDescriptionScope = "gem_stat_descriptions",
68706878
statMap = {
68716879
["support_overpower_hit_damage_stun_multiplier_+%_final"] = {
6872-
mod("StunBuildup", "MORE", nil),
6880+
mod("EnemyHeavyStunBuildup", "MORE", nil),
68736881
},
68746882
["support_overpower_damage_+%_final"] = {
68756883
mod("Damage", "MORE", nil),

src/Export/Scripts/miscdata.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ local allyDamage = ""
99
local damage = ""
1010
local armour = ""
1111
local ailmentThreshold = ""
12+
local poiseThreshold = ""
1213
local minionLevel = ""
1314
for stats in dat("DefaultMonsterStats"):Rows() do
1415
evasion = evasion .. stats.Evasion .. ", "
@@ -19,6 +20,7 @@ for stats in dat("DefaultMonsterStats"):Rows() do
1920
allyDamage = allyDamage .. stats.MinionDamage .. ", "
2021
armour = armour .. stats.Armour .. ", "
2122
ailmentThreshold = ailmentThreshold .. stats.AilmentThreshold .. ", "
23+
poiseThreshold = poiseThreshold .. stats.PoiseThreshold .. ", "
2224
end
2325
-- Table was incorrect is PoE 1 but seems to be correct for PoE 2. Keeping here just in case
2426
--for i = 1, 100 do
@@ -33,6 +35,7 @@ out:write('data.monsterDamageTable = { '..damage..'}\n')
3335
out:write('data.monsterAllyDamageTable = { '..allyDamage..'}\n')
3436
out:write('data.monsterArmourTable = { '..armour..'}\n')
3537
out:write('data.monsterAilmentThresholdTable = { '..ailmentThreshold..'}\n')
38+
out:write('data.monsterPoiseThresholdTable = { '..poiseThreshold..'}\n')
3639
out:write('\n')
3740

3841
out:write('-- From MinionGemLevelScaling.dat\n')

src/Export/Skills/act_int.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,9 @@ statMap = {
561561
["freezing_mark_damage_buff_damage_%_to_gain_as_cold"] = {
562562
mod("DamageGainAsCold", "BASE", nil, 0, 0, { type = "GlobalEffect", effectType = "Buff" }),
563563
},
564+
["freezing_mark_hit_damage_freeze_multiplier_+%_final"] = {
565+
mod("FreezeBuildup", "MORE", nil, 0, 0, { type = "GlobalEffect", effectType = "Curse" }),
566+
},
564567
},
565568
#mods
566569
#skillEnd

0 commit comments

Comments
 (0)