Jump to content


How is Sacred 2 Weapon Damage Calculated


Recommended Posts

 
 
On 7/31/2024 at 8:56 PM, Maneus said:

Could it be possible that critical hits always use the maximum base damage, and determine the min and max solely from the attribute bonus?

YES! That is it!

I set attrWdam_fact = 0 to remove the dexterity bonus and now all critical hits do the maximum damage!

 

On 7/31/2024 at 11:02 AM, SLD said:

One and a half months of quality science and you're still going. Where do you get that energy?

It is because of you and @idbeholdME giving me all these weird ideas! :friends3:

 

 

The critical hit damage range should be:

Critical Ice damage 79831.58-80887.752

Spoiler

MaxBaseDamage = FLOOR(FLOOR((MaxWeaponDamage + SumFlatBonuses) * (1 + SumPercentageBonuses / 1000)) * (CombatArtMultiplier / 1000)) * (CriticalMultiplier / 1000)
MaxBaseDamage = 7708 * (10000 / 1000)
MaxBaseDamage = 7708 * 10
MaxBaseDamage = 77080

MinCombinedDamage = MaxBaseDamage + MinAttributeBonus
MinCombinedDamage = 77080 + 2751.58
MinCombinedDamage = 79831.58

MaxCombinedDamage = MaxBaseDamage + MaxAttributeBonus
MaxCombinedDamage = 77080 + 3807.752
MaxCombinedDamage = 80887.752

 

Critical Physical damage 532588.012-533131.906

Spoiler

MaxBaseDamage = FLOOR(FLOOR((MaxWeaponDamage + SumFlatBonuses) * (1 + SumPercentageBonuses / 1000)) * (CombatArtMultiplier / 1000)) * (CriticalMultiplier / 1000)
MaxBaseDamage = 50863 * (10000 / 1000)
MaxBaseDamage = 50863 * 10
MaxBaseDamage = 508630

MinCombinedDamage = MaxBaseDamage + MinAttributeBonus
MinCombinedDamage = 508630 + 23958.012
MinCombinedDamage = 532588.012

MaxCombinedDamage = MaxBaseDamage + MaxAttributeBonus
MaxCombinedDamage = 508630 + 24501.906
MaxCombinedDamage = 533131.906

 

Expected total damage 612419-614018

 

Tested in-game

Quote

612999613360, 613880, 613805, 613367, 612921, 613666, 612597

 

Edited by Maneus
  • Appreciation 1
Link to comment
 
5 hours ago, Maneus said:

Looks like they are in the right ballpark :)

Great :)

5 hours ago, Maneus said:

Could it be possible that critical hits always use the maximum base damage, and determine the min and max solely from the attribute bonus?

4 hours ago, Maneus said:

YES! That is it!

I missed that 95 minute window to specaluate on who might find out :(
 

4 hours ago, Maneus said:

It is because of you and @idbeholdME giving me all these weird ideas! :friends3:

Moo? :cow:

  • Appreciation 1
Link to comment
 
On 7/31/2024 at 11:02 AM, SLD said:

Why can't you fix that? I'm not sure where your lvl 200 characters with no or specific skills chosen come from but I would guess it's a character editor. If that editor had the option to set the survival bonus to 100% I assume you'd already have used that option. Survival Bonus increases with time spent in combat obviously changing more quickly at lower values ruining your tests, but afaik the rate can be somehow modified through the easily accessible game files. If that is true you just either set it to increase at an extremely slow rate and test away with 0% or you would set it to increase super fast and test at 99%+. If I'm wrong about the ability to change the rate you'd have to get your test character to a high enough value so that during testing no measurable changes occur. That can always be achieved by letting a wolf chew on you for a while, whith high enough hp regen of course. That works afk and even with the game running in background so it doesn't necessarily create a lot of extra work. Once a high enough value is achieved backup copies of the character would obviously prevent the need for doing that again.

Unfortunately, the character editor doesn't show you the survival bonus or the bonus vs enemy type. So you can't change them. The only way to reset the survival bonus is to kill your character. Also, I think it is very important to have tests that are easily reproducible.

But you're right about something else! In balance.txt there are three parameters related to the survival bonus:

Quote

UBmean = 500,
UBpivot = 21600,
UBquot_attr = 3000,

 

The formula for the survival bonus (%) is:

SurvivalBonus = MIN(100, 0.2 * UBmean * alivetime / (alivetime + UBpivot))

Where:
- alivetime - From the character's stats file. The file can be opened with a plain text editor like notepad.

Example 1:

Spoiler

alivetime = 382425.41 sec
UBmean = 500
UBpivot = 21600

SurvivalBonus = MIN(100, 0.2 * UBmean * alivetime / (alivetime + UBpivot))
SurvivalBonus = MIN(100, 0.2 * 500 * 382425.41 / (382425.41 + 21600))
SurvivalBonus = MIN(100, 38242541 / 404025.41)
SurvivalBonus = MIN(100, 94.65380160124087)
SurvivalBonus = 94.65380160124087 (Reference value is 94.6%)


Example 2: Stalworth Safeguard shield with +18.6% Faster Increase of Survival Bonus

Spoiler

alivetime = 382425.41 * (1 + 0.186)
alivetime = 382425.41 * (1.186)
alivetime = 453556.53626
UBmean = 500
UBpivot = 21600 

SurvivalBonus = MIN(100, 0.2 * UBmean * alivetime / (alivetime + UBpivot))
SurvivalBonus = MIN(100, 0.2 * 500 * 453556.53626 / (453556.53626 + 21600))
SurvivalBonus = MIN(100, 45355653.626 / 475156.53626)
SurvivalBonus = MIN(100, 95.45412967061012)
SurvivalBonus = 95.45412967061012 (Reference value is 95.4%)

 

The formula from the wiki is correct, but it is missing the parameters from balance.txt.
https://www.sacredwiki.org/index.php/Sacred_2:Survival_Bonus

Quote

Explicitly, the Survival Bonus is given by the formula SB = T/(T+6), where T is the total time in combat since the character's last ressurection, measured in hours. This value T can be looked up under the name "Alive Time" in your character's stats file, where it is given in seconds.

 

The formula for the attribute (including the survival bonus) is:

FinalAttribute = FLOOR(BaseAttribute * (1 +  (SurvivalBonus * 1000 / UBquot_attr)))

Example 1:

Spoiler

SurvivalBonus = 0.9465380160124087 (94.6%)
BaseAttribute = 432
UBquot_attr = 3000

FinalAttribute = FLOOR(BaseAttribute * (1 +  (SurvivalBonus * 1000 / UBquot_attr)))
FinalAttribute = FLOOR(432 * (1 +  (0.9465380160124087 * 1000 / 3000)))
FinalAttribute = FLOOR(432 * (1 +  (946.5380160124087 / 3000)))
FinalAttribute = FLOOR(432 * (1 +  0.3155126720041362))
FinalAttribute = FLOOR(432 * 1.3155126720041362)
FinalAttribute = FLOOR(568.3014743057869)
FinalAttribute = 568 (Reference value is 568)

Example 2:

Spoiler

SurvivalBonus = 0.9545412967061012 (95.4%)
BaseAttribute = 432
UBquot_attr = 3000

FinalAttribute = FLOOR(BaseAttribute * (1 +  (SurvivalBonus * 1000 / UBquot_attr)))
FinalAttribute = FLOOR(432 * (1 +  (0.9545412967061012 * 1000 / 3000)))
FinalAttribute = FLOOR(432 * (1 +  (954.5412967061012 / 3000)))
FinalAttribute = FLOOR(432 * (1 +  0.3181804322353671))
FinalAttribute = FLOOR(432 * 1.3181804322353671)
FinalAttribute = FLOOR(569.4539467256786)
FinalAttribute = 569 (Reference value is 569)

 

With the default settings and at 100% survival bonus, all attributes are increased by 33.3333%. Just like the wiki says.

These are rough formulas and there are some special cases, but I think it is good enough for now :)

Setting UBquot_attr to 0 makes it so the survival bonus does not increase the attributes at all. So at least this part we can control. Now the question is how can we manipulate the random number generation...

 

Edit: There is one more parameter that looks related to the survival bonus

Quote

UBspawn_fact = 175

 

Edited by Maneus
Link to comment
 
10 hours ago, Maneus said:

In balance.txt there are three parameters related to the survival bonus

10 hours ago, Maneus said:

Setting UBquot_attr to 0 makes it so the survival bonus does not increase the attributes at all. So at least this part we can control.

Another thing that helps with testing. Glad I could point you in the right direction again :)

10 hours ago, Maneus said:

The formula for the attribute (including the survival bonus) is:

FinalAttribute = FLOOR(BaseAttribute * (1 +  (SurvivalBonus * 10) / UBquot_attr))

That one is a bit more sloppy than your usual work and did confuse me for a bit. Your example below shows that for this calculation you treat "SurvivalBonus" as a value between 0 and 100 and then you say:

10 hours ago, Maneus said:

With the default settings and at 100% survival bonus, all attributes are increased by 33.3333%.

So you first dump the "%" and then you miraculously add it back. I think it would make more sense to just change the formula to:

FinalAttribute = FLOOR(BaseAttribute * (1 +  (SurvivalBonus * 1000) / UBquot_attr))

treating S
urvivalBonus as a value between 0 and 1 just like the game client does.

10 hours ago, Maneus said:

These are rough formulas and there are some special cases, but I think it is good enough for now

If you have neither flat attribute bonuses nor other % based attribute bonuses the fomula is good enough. Everything is "good enough for now", I'm just as always hinting there's more to be discovered here :)
 

10 hours ago, Maneus said:

Now the question is how can we manipulate the random number generation...

I'm sure you'll figure it out, so you can move on to more interesting things, like changing the gravitational constant of the universe :) 

How come we have a Spock :spock: but no Q? Fascinating.

Edited by SLD
  • Like! 1
Link to comment
 

More about the survival bonus:

- Setting UBpivot to 0 is the same as setting it to 1 - this is done to avoid division by 0.
- Setting UBmean to 0 removes the survival bonus - it becomes 0.0%.
- Setting UBquot_attr to 0 removes the stat increase from the survival bonus.
- Setting UBspawn_fact to 0 removes the level bonus that enemies receive because of the survival bonus.

The formulas for the attributes appear to be:

AttrSurvivalBonus = FLOOR((AttrBase + AttrPoints) * SurvivalBonus * 1000 / UBquot_attr)

FinalAttribute = FLOOR((AttrBase + AttrPoints + SumFlatBonuses) * (1 + SumPercentageBonuses) + AttrSurvivalBonus)

Where:
- AttrBase - the base value of the attribute (for the character at the current character level).
- AttrPoints - how many attribute points are spent on this attribute.
- AttrSurvivalBonus - the increase from the survival bonus.
- SumFlatBonuses - sum of all flat bonuses from equipment and combat arts.
- SumPercentageBonuses - sum of all percentage bonuses from equipment.

Important note: In-game, the character sheet does not have enough space to show values higher than 9999. For example: You might see that your dexterity is only 9040, but the dexterity tooltip shows Defense Value +609040 (1 Dexterity = 1 Defense Value). I haven't explored what the upper limits are, but they appear to be very high.

 

Example: Shadow Warrior with Grim Resilience and equipment

Spoiler

Shadow Warrior, level 200
We're looking at the willpower attribute
AttrBase = 546
AttrPoints = 454
SurvivalBonus = 100%
UBquot_attr = 500 (Lowered from 3000)

Two rings, each with +1000 willpower and +50% willpower
Grim Resilience, level 98, +1500 willpower

AttrSurvivalBonus = FLOOR((AttrBase + AttrPoints) * SurvivalBonus * 1000 / UBquot_attr)
AttrSurvivalBonus = FLOOR((546 + 454) * 1 * 1000 / 500)
AttrSurvivalBonus = FLOOR(1000 * 2)
AttrSurvivalBonus = 2000

FinalAttribute = FLOOR((AttrBase + AttrPoints + SumFlatBonuses) * (1 + SumPercentageBonuses) + AttrSurvivalBonus)
FinalAttribute = FLOOR((546 + 454 + 1000 + 1000 + 1500) * (1 + 0.5 + 0.5) + 2000)
FinalAttribute = FLOOR(4500 * 2 + 2000)
FinalAttribute = FLOOR(9000 + 2000)
FinalAttribute = 11000 (Reference value is 11000)

Note: The character sheet shows 1000 Willpower, but the tooltip shows Spell Resistance 11000 and 1 Willpower = 1 Spell Resistance.

Without Grim Resilience the Willpower drops to 8000.

 

Edited by Maneus
  • Like! 1
Link to comment
 

How does armor (resistances) work?

First, there is this parameter in balance.txt

Quote

Enemy_armor = {800,900,1000,6000,7200},

These values look like they are multipliers for the enemy armor per difficulty. But after doing a few tests in-game, they appear to have no effect on the damage dealt. I'll keep this parameter in mind - maybe I'm missing something.

 

Second, there is this parameter in balance.txt

Quote

MP_armor = {1000,1100,1210,1330,1460},

These values are multipliers to the enemy armor based on the number of players (?). The first value is applied in single-player or free play (1 player in-game). I've been using this parameter (setting it to 0) for almost all of my tests so far, but now I used it to control a known value and see how the damage changes.

 

Near Sloeford, there are a few wolves patrolling. Wolves are ideal because they have only physical armor. In bronze difficulty, the level 1 wolf has 8 armor and the level 2 wolf has 9 armor (shown in the Last Opponent section). I used a different character to kill them, because I don't want the familiarity bonus to affect the results.

 

I used a level 200 character, which is much higher level than the wolves, so he would receive the level difference bonus. But I found which parameters are related to this bonus:

Quote

DamScaleIncMax = 1250,
DamScaleRatioMin = 200,
DamScaleRatioMax = 350,

Setting DamScaleIncMax to 0 removes the level difference bonus.

 

I also modified Cobalt Strike to have exactly 10000 physical damage. I used a combination of fists and Cobalt Strike for the tests.

The tests went as expected (nothing interesting). I might post some results later.

 

The findings:

FinalArmor = FLOOR(BaseArmor * MP_Armor * 0.001)

Where:
- BaseArmor - the value shown in the Last Opponent section.

 

The formula for the damage reduction (from armor) is:

DamageReduction = FLOOR3(Damage / (FinalArmor + Damage))

Where:
- FLOOR3 - Round down to three decimal places.

 

And the damage dealt becomes:

DamageDealt = Damage * DamageReduction

 

Edit: Some examples

Spoiler

Example 1

Damage = 10000
BaseArmor = 8
MP_Armor = 1000 (first value)

FinalArmor = FLOOR(BaseArmor * MP_Armor * 0.001)
FinalArmor = FLOOR(8 * 1000 * 0.001)
FinalArmor = 8

DamageReduction = FLOOR3(Damage / (FinalArmor + Damage))
DamageReduction = FLOOR3(10000 / (8 + 10000))
DamageReduction = FLOOR3(10000 / 10008)
DamageReduction = FLOOR3(0.9992006394884093)
DamageReduction = 0.999

DamageDealt = Damage * DamageReduction
DamageDealt = 10000 * 0.999
DamageDealt = 9990 (Reference value is 9990)

 

Example 2:

Damage = 10000
BaseArmor = 8
MP_Armor = 1250000 (first value)

FinalArmor = FLOOR(BaseArmor * MP_Armor * 0.001)
FinalArmor = FLOOR(8 * 1250000 * 0.001)
FinalArmor = 10000

DamageReduction = FLOOR3(Damage / (FinalArmor + Damage))
DamageReduction = FLOOR3(10000 / (10000 + 10000))
DamageReduction = FLOOR3(10000 / 20000)
DamageReduction = FLOOR3(0.5)
DamageReduction = 0.5

DamageDealt = Damage * DamageReduction
DamageDealt = 10000 * 0.5
DamageDealt = 5000 (Reference value is 5000)

 

Example 3:

Damage = 10000
BaseArmor = 8
MP_Armor = 3750000 (first value)

FinalArmor = FLOOR(BaseArmor * MP_Armor * 0.001)
FinalArmor = FLOOR(8 * 3750000 * 0.001)
FinalArmor = 30000

DamageReduction = FLOOR3(Damage / (FinalArmor + Damage))
DamageReduction = FLOOR3(10000 / (30000 + 10000))
DamageReduction = FLOOR3(10000 / 40000)
DamageReduction = FLOOR3(0.25)
DamageReduction = 0.25

DamageDealt = Damage * DamageReduction
DamageDealt = 10000 * 0.25
DamageDealt = 2500 (Reference value is 2500)

 

 

On 7/15/2024 at 10:16 AM, idbeholdME said:

Another thing that I've been wondering about: Chance to bypass armor. I always assumed it only worked on weapon attacks and CAs, but not spells. Never actually got around to testing it. Could probably be done by using an item with the stat (preferably unique) and massively increasing the value in blueprint.txt do that it's 100%+ while giving a specific enemy ludicrous amounts of armor and just testing it.

I equipped two rings, each with +50% Chance to disregard armor

The findings: It doesn't work on spells. Only on weapon attacks (left click and combat arts). It stacks additively, meaning that every hit (100%) ignored the target's armor.

 

I'm still exploring this topic. I will post more stuff later. I'm sure SLD has a lot to say :)

Edited by Maneus
  • Like! 1
Link to comment
 
 
On 7/8/2024 at 6:53 AM, Maneus said:

My tests show that Combat Discipline does affect hybrid combat arts. I don't know why the wiki states that it doesn't. https://www.sacredwiki.org/index.php/Sacred_2:Hybrid_Damage_Based_Combat_Arts

On 7/9/2024 at 5:46 AM, SLD said:

Now all that reamins is that someone corrects that entry on the wiki...

just leaving the info here that "someone" now has corrected that. Still not a nice page but at least the most blatantly misleading part is gone.

moohoo :cow:

Link to comment
 
 
 
 
 

I've been revisiting my older posts and updating the examples with the new formulas. It's very time-consuming, but it's so satisfying to see the results match the in-game values. I even corrected a mistake in one of my reference values concerning critical hits, thanks to the formulas. After noticing the discrepancy I redid the exact same tests and the formulas were correct :D

While redoing the tests, I also used the opportunity to learn why some of the enemies in the desert region (near Khorum) gave me inconsistent results. I did do some of my tests there, because that is where level 200 enemies can be found in Niobium. It turns out that the elite Scarabs have 15% physical vulnerability (10000 damage -> 11500 damage) and the non-elite Blade Spiders have the toughness skill (10000 damage -> 9190 damage). But it's odd that the toughness skill provides so little damage mitigation (8.1%). If the skill level is supposed to be equal to the creature level, then even unmastered, the percentage should be higher.

Similarly, some time ago I tried to seek out enemies that have the spell resistance skill. I went to different bosses (in niobium) that looked like they have it at mastery level, but my spell DOT duration or damage wasn't reduced. Very suspicious.

Edited by Maneus
  • Like! 1
Link to comment
 
 
On 8/17/2024 at 6:21 PM, Maneus said:

I've been revisiting my older posts and updating the examples with the new formulas. It's very time-consuming, but it's so satisfying to see the results match the in-game values. I even corrected a mistake in one of my reference values concerning critical hits, thanks to the formulas. After noticing the discrepancy I redid the exact same tests and the formulas were correct :D

Nice to hear that you've managed to find a way to "feel" the progress you've made.
I'm a bit worried about you changing the past though. Meddling with the timeline, turning this into a non linear thread...
Don't forget you had to go to that place to get to this one :)

  • Like! 1
Link to comment
 

How do the entries et_missile_adapt and et_cone_adapt work?

In spells.txt, both entries share the same blueprint bonus:

Quote

mgr.addTokenBonus( {"et_missile_adapt", 419 })  -- 419 = bb_mult_spelldamage_any
mgr.addTokenBonus( {"et_cone_adapt", 419 })  -- 419 = bb_mult_spelldamage_any

Which is:

Spoiler

newBonus = {
--  name = "bb_mult_spelldamage_any",
  rating = 0,
  basedonskill = "SKILL_INVALID",
  type = "BONUS_CA_MULTIPLIER",
  spez = "",
  spez2 = "",
  usagebits = 65535,
  minconstraints = {0,0,0},
  difficultyvaluerange0 = {0,0,0},
  difficultyvaluerange1 = {1,0,0},
  difficultyvaluerange2 = {2,0,0},
  difficultyvaluerange3 = {3,0,0},
  difficultyvaluerange4 = {4,0,0},
}
mgr.createBonus(419, newBonus);

I added this bonus to an item (with a specific value) and the following happened:
- The bonus was not shown in the item tooltip.
- The damage in the combat art tooltip was multiplied by the configured value.
- But the actual damage dealt remained unchanged.

So it appears to be useless as an item modifier (unless it needs more configuration?). Also, when used by a combat art, the combat art itself sets the value of the bonus based on other rules.

As a damage multiplier, it appears to work similarly to et_mult_weapondamage, but for spells. It is applied after the percentage bonuses. The result is rounded down. It goes into the calculation for the intelligence bonus. After that is the critical hit multiplier and so on.

How much does it affect the damage?

Both et_missile_adapt and et_cone_adapt use the same formula for the determining the value of the multiplier. I haven't actually determined what the formula is, but I have the next best thing - a table with all possible values:

Spoiler

X    Multiplier
0    1000
1    1000
2    707
3    577
4    500
5    447
6    408
7    377
8    353
9    333
10    316
11    301
12    288
13    277
14    267
15    258
16    250
17    242
18    235
19    229
20    223
21    218
22    213
23    208
24    204
25    200
26    196
27    192
28    188
29    185
30    182
31    179
32    176
33    174
34    171
35    169
36    166
37    164
38    162
39    160
40    158
41    156
42    154
43    152
44    150
45    149
46    147
47    145
48    144
49    142
50    141
51    140
52    138
53    137
54    136
55    134
56    133
57    132
58    131
59    130
60    129
61    128
62    127
63    125
64    125
65    124
66    123
67    122
68    121
69    120
70    119
71    118
72    117
73    117
74    116
75    115
76    114
77    113
78    113
79    112
80    111
81    111
82    110
83    109
84    109
85    108
86    107
87    107
88    106
89    105
90    105
91    104
92    104
93    103
94    103
95    102
96    102
97    101
98    101
99    100
100    100
101    99
102    99
103    98
104    98
105    97
106    97
107    96
108    96
109    95
110    95
111    94
112    94
113    94
114    93
115    93
116    92
117    92
118    92
119    91
120    91
121    90
122    90
123    90
124    89
125    89
126    89
127    88
128    88
129    88
130    87
131    87
132    87
133    86
134    86
135    86
136    85
137    85
138    85
139    84
140    84
141    84
142    83
143    83
144    83
145    83
146    82
147    82
148    82
149    81
150    81
151    81
152    81
153    80
154    80
155    80
156    80
157    79
158    79
159    79
160    79
161    78
162    78
163    78
164    78
165    77
166    77
167    77
168    77
169    76
170    76
171    76
172    76
173    76
174    75
175    75
176    75
177    75
178    74
179    74
180    74
181    74
182    74
183    73
184    73
185    73
186    73
187    73
188    72
189    72
190    72
191    72
192    72
193    71
194    71
195    71
196    71
197    71
198    71
199    70
200    70
201    70
202    70
203    70
204    70
205    69
206    69
207    69
208    69
209    69
210    69
211    68
212    68
213    68
214    68
215    68
216    68
217    67
218    67
219    67
220    67
221    67
222    67
223    66
224    66
225    66
226    66
227    66
228    66
229    66
230    65
231    65
232    65
233    65
234    65
235    65
236    65
237    64
238    64
239    64
240    64
241    64
242    64
243    64
244    64
245    63
246    63
247    63
248    63
249    63
250    63
251    63
252    62
253    62
254    62
255    62
256    62
257    62
258    62
259    62
260    62
261    61
262    61
263    61
264    61
265    61
266    61
267    61
268    61
269    60
270    60
271    60
272    60
273    60
274    60
275    60
276    60
277    60
278    59
279    59
280    59
281    59
282    59
283    59
284    59
285    59
286    59
287    59
288    58
289    58
290    58
291    58
292    58
293    58
294    58
295    58
296    58
297    58
298    57
299    57
300    57
301    57
302    57
303    57
304    57
305    57
306    57
307    57
308    56
309    56
310    56
311    56
312    56
313    56
314    56
315    56
316    56
317    56
318    56
319    55
320    55
321    55
322    55
323    55
324    55
325    55
326    55
327    55
328    55
329    55
330    55
331    54
332    54
333    54
334    54
335    54
336    54
337    54
338    54
339    54
340    54
341    54
342    54
343    53
344    53
345    53
346    53
347    53
348    53
349    53
350    53
351    53
352    53
353    53
354    53
355    53
356    52
357    52
358    52
359    52

You apply the multiplier this way:

Damage  = FLOOR(Damage * Multiplier * 0.001)

 

What is X?

It depends on the entry (et_missile_adapt or et_cone_adapt).

For et_missile_adapt it appears to be the number of "projectiles". In the case of Glacial Thorns, a single "projectile" counts as 5 Thorns in the tooltip. When casting the spell, a single "projectile" is visually represented as a group of 6 distinct ice shards that travel in the same direction. Even though there are 6 of them, they act as a group. If one stops, then all stop. If one hits, then all hit. Only one damage instance is dealt for the whole group. The damage per "projectile" (ice shard group) is what you see in the combat art tooltip.

The number of "projectiles" is determined by the following formula (using the entry):

Projectiles = FLOOR((InitialValue + ValuePerLevel * FinalCombatArtLevel) / (300 + FinalCombatArtLevel * 10))

Example 1: Glacial Thorns, no modifications

Spoiler

entry3 = {"et_missile_adapt", 2900, 315, 0, 9 },

InitialValue = 2900
ValuePerLevel = 315
FinalCombatArtLevel = 90

Projectiles = FLOOR((InitialValue + ValuePerLevel * FinalCombatArtLevel) / (300 + FinalCombatArtLevel * 10))
Projectiles = FLOOR((2900 + 315 * 90) / (300 + 90 * 10))
Projectiles = FLOOR((2900 + 28350) / (300 + 900))
Projectiles = FLOOR(31250 / 1200)
Projectiles = FLOOR(26.04166666666667)
Projectiles = 26

Thorns = Projectiles * 5
Thorns = 26 * 5
Thorns = 130 (Reference value is 130)

CombatArtMultiplier = 196 (From the table)

Example 2: Glacial Thorns, with both modifications that increase the number of ice shards

Spoiler

entry3 = {"et_missile_adapt", 2900, 315, 0, 9 },
entry4 = {"et_missile_adapt", 470, 27, 1, 9 },
entry8 = {"et_missile_adapt", 470, 27, 5, 9 },

InitialValue = 3840 (Combined)
ValuePerLevel = 369 (Combined)
FinalCombatArtLevel = 90

Projectiles = FLOOR((InitialValue + ValuePerLevel * FinalCombatArtLevel) / (300 + FinalCombatArtLevel * 10))
Projectiles = FLOOR((3840 + 369 * 90) / (300 + 90 * 10))
Projectiles = FLOOR((3840 + 33210) / (300 + 900))
Projectiles = FLOOR(37050 / 1200)
Projectiles = FLOOR(30.875)
Projectiles = 30

Thorns = Projectiles * 5
Thorns = 30 * 5
Thorns = 150 (Reference value is 150)

CombatArtMultiplier = 182 (From the table)

Important note: The maximum possible value for Projectiles is 255. Past that it overflows and starts counting from zero, so 256 = 0, 257 = 1 and so on.

 

For et_cone_adapt I don't really know what X is supposed to represent. But it is calculated as follows:

X = FLOOR(MIN(359, AngleValue) / MAX(AdaptValue, 1))

Where:
- AngleValue - calculated from the entry et_maxangle_cone
- AdaptValue - calculated from the entry et_cone_adapt

Example: Blazing Tempest

Spoiler

entry0 = {"et_maxangle_cone", 270, 0, 0, 8 },
entry4 = {"et_cone_adapt", 30, 0, 0, 5 },

AngleValue = 270
AdaptValue = 30

X = FLOOR(MIN(359, AngleValue) / MAX(AdaptValue, 1))
X = FLOOR(MIN(359, 270) / MAX(30, 1))
X = FLOOR(270 / 30)
X = FLOOR(9)
X = 9

CombatArtMultiplier = 333 (From the table)

This is how the damage is determined in the tooltip. But for the actual damage dealt it is slightly different. The angle of the cone depends how far away you click. So the angle is dynamic, and therefore the multiplier is dynamic too.

For example:

Spoiler

entry0 = {"et_maxangle_cone", 360, 0, 0, 8 },
entry4 = {"et_cone_adapt", 0, 0, 0, 5 },

AngleValue = 360
AdaptValue = 0

X = FLOOR(MIN(359, AngleValue) / MAX(AdaptValue, 1))
X = FLOOR(MIN(359, 360) / MAX(0, 1))
X = FLOOR(359 / 1)
X = FLOOR(359)
X = 359

CombatArtMultiplier = 52 (From the table)

In the combat art tooltip, that is how much the damage is multiplied by.

I've configured Blazing Tempest to have a base damage of 10000. I've also turned off the intelligence bonus.
The damage in the tooltip is 520.
The lowest damage I could deal (by clicking as close to the character as possible) is 530.
The highest damage I could deal (by clicking as far away from the character as possible) is 3160.
Both of these values seem like they are taken from the multiplier table. My current theory is that there is a minimum and maximum angle that the spell can be cast at, and that angle is used in the formula for X. I'll have to think about it.

 

Enough for now :)

Edited by Maneus
  • Appreciation 1
Link to comment
 
13 hours ago, Maneus said:

My current theory is that there is a minimum and maximum angle that the spell can be cast at, and that angle is used in the formula for X.

This appears to be the case. But finding these angle limits is difficult (unreliable) to do.

The minimum angle appears to be 10, regardless of what the value of et_maxangle_cone is. So a max angle of less than 10 doesn't do anything.

The maximum angle is slightly less than et_maxangle_cone. I suspect it is a relative decrease. For example 360 -> 356. In practice, you will either do the stated damage in the tooltip (X is the same) or higher (X-1). Usually the latter.

In one of my previous posts I stated that given 3330 damage in the tooltip, the lowest I could get (wide angle) is 3340, but that appears to be incorrect. I don't remember how or where I got this value, but I did a new set of tests and the lowest is actually 3530.

3330 is when X = 9
3530 is when X = 8

To get 3340 damage, the multiplier must be 334, but such a multiplier does not exist in the table. It must be a mistake.

Edit: I found a document with some tests from way back when I was looking into DOT damage. There is no mention of 3340 there. The results match my findings here.

So, as a summary, lets look at Blazing Tempest again:

Spoiler

entry0 = {"et_maxangle_cone", 270, 0, 0, 8 },
entry4 = {"et_cone_adapt", 30, 0, 0, 5 },

AngleValue = 270
AdaptValue = 30

X = FLOOR(MIN(359, AngleValue) / MAX(AdaptValue, 1))
X = FLOOR(MIN(359, 270) / MAX(30, 1))
X = FLOOR(270 / 30)
X = FLOOR(9)
X = 9

CombatArtMultiplier = 333 (From the table)

Given a base damage of 10000, the tooltip shows 3330.

Here is how the damage dealt varies based on the angle (from wide to narrow):
3530 (X = 8)
3770 (X = 7)
4080 (X = 6)
4470 (X = 5)
5000 (X = 4)
5770 (X = 3)
7070 (X = 2)
10000 (X <= 1)

These numbers are exactly what you see in-game.

 

Edited by Maneus
  • Appreciation 1
Link to comment
 

Great, so Glacial Thorns does less damage per projectile when you take the extra projectiles mod? interesting.

Oh boy did that factor<=1 confuse me. Until I realised that the ingame tooltip is just the opposite perspective. In game the cone would look like you could do up to ~3 times the tooltip damage.

I love chewing on your science until finally white smoke comes out of my ears :)

  • Haha 1
Link to comment
 
11 minutes ago, SLD said:

Great, so Glacial Thorns does less damage per projectile when you take the extra projectiles mod? interesting.

All combat arts that use the entry et_missile_adapt are like that. It's not because of the mods specifically, but how the extra projectiles work in general. Aside from Glacial Thorns, there are:

Flaring Nova

Spoiler

entry4 = {"et_missile_adapt", 300, 10, 0, 9 },
entry6 = {"et_missile_adapt", 300, 10, 2, 9 },

The first entry means the number of "projectiles" is always 1 at any combat art level.
The second entry is for the modification that adds another "projectile" (pulse?). So the number of "projectiles" becomes 2 at any combat art level.

With 1 projectile, the damage multiplier is equal to 1000, so the damage is unchanged.
With 2 projectiles, the damage multiplier is equal to 707,  so each projectile individually does less damage (70.7% of the original), but the total is still higher. One thing to consider is that armor is more effective against low damage hits.

Archangel's Wrath

Spoiler

entry4 = {"et_missile_adapt", 300, 10, 0, 9 },
entry6 = {"et_missile_adapt", 300, 10, 2, 9 },

Same explanation as Flaring Nova.

Ancestral Fireball

Spoiler

entry4 = {"et_missile_adapt", 300, 10, 0, 9 },
entry7 = {"et_missile_adapt", 300, 10, 3, 9 },
entry9 = {"et_missile_adapt", 300, 10, 5, 9 },

The last two entries are the modifications that increase the number of projectiles (fireballs). You can have a total of 3 fireballs. At 3 fireballs the multiplier is 577, so each individual fireball does 57.7% of the original damage.

 

 

31 minutes ago, SLD said:

In game the cone would look like you could do up to ~3 times the tooltip damage.

Yes, that is the case with the original (untampered) Blazing Tempest. But, depending on the AdaptValue, the maximum damage (at angle of 10) could also become lower.

For example:

Spoiler

AngleValue = 10
AdaptValue =  5

X = FLOOR(MIN(359, AngleValue) / MAX(AdaptValue, 1))
X = FLOOR(MIN(359, 10) / MAX(5, 1))
X = FLOOR(10 / 5)
X = FLOOR(2)
X = 2

CombatArtMultiplier = 707 (From the table)

And:

Spoiler

AngleValue = 10
AdaptValue =  2

X = FLOOR(MIN(359, AngleValue) / MAX(AdaptValue, 1))
X = FLOOR(MIN(359, 10) / MAX(2, 1))
X = FLOOR(10 / 2)
X = FLOOR(5)
X = 5

CombatArtMultiplier = 447 (From the table)

 

  • Thanks! 1
Link to comment
 
47 minutes ago, Maneus said:

All combat arts that use the entry et_missile_adapt are like that. It's not because of the mods specifically, but how the extra projectiles work in general. Aside from Glacial Thorns, there are:

Yes, I understand more now. But I just meant from an ingame perspective, taking one of the mods increasing the projectile count would at the same time directly reduce the tooltip damage. That felt odd because those mods don't say that they do, while the mods from Ancestral Fireball, Archangel's Wrath and Flaring Nova all say they do reduce damage per hit. (Used the descriptions from the Wiki here, might not be the same as vanilla game).
 

55 minutes ago, Maneus said:

Flaring Nova

I would have never guessed that Flaring Nova would be considered a "missile" :)

But I do understand the "et_missile_adapt"
system is just a balancing tool used for spells that can hit the same opponent multiple times.
 

1 hour ago, Maneus said:

Yes, that is the case with the original (untampered) Blazing Tempest. But, depending on the AdaptValue, the maximum damage (at angle of 10) could also become lower.

Thanks for all the details and of course for always being so perfectly precise :)

I just look at it from my naive "player" point of view: "What does it look like in the game"
while many of the things you post here have already gone far past that toward the "modder" point of view, linking the values from the game files to what is happening in game.
I always end up looking at the things you discover and then trying to revert that "modder knowledge" into "how does it affect my gameplay". For example you just found: "
The maximum possible value for Projectiles is 255. Past that it overflows". And I would be thinking "without modding the game there's no way to ever reach that->discard information"... :)
I look at you finding out that critical hits don't affect the attribute based damage on attacks, so I learn: for builds mostly based on attribute damage scaling crits is a dumb idea.


Don't know why I wrote this paragraph. Probably to explain how my dumbed down versions of your science might end up missing a screw a modder might turn.
Oh and before it gets misunderstood, this is not a critique of your accurate answer. I'm happy you pointed out the parts I may have overlooked and I'm sure others reading through this stuff in the future will be happy about that as well :)

  • Appreciation 1
Link to comment
 

How does damage conversion work?

Let's look at the following blueprint bonus:

Spoiler

newBonus = {
--  name = "sb_off_physical_to_fire",
  rating = 25,
  basedonskill = "SKILL_INVALID",
  type = "BONUS_CHANNELDAMAGE_CONVERSION",
  spez = "DMG_PHYS",
  spez2 = "DMG_FIRE",
  usagebits = 65535,
  minconstraints = {1,5,0},
  difficultyvaluerange0 = {0,334,1000},
  difficultyvaluerange1 = {1,408,1220},
  difficultyvaluerange2 = {2,492,1500},
  difficultyvaluerange3 = {3,562,2334},
  difficultyvaluerange4 = {4,667,4000},
}
mgr.createBonus(455, newBonus);

As the name suggests, this bonus represents the item modifier Conversion damage to Fire +X%.

In niobium difficulty, at item level 200, the value of this bonus is 4000. This value can be further modified by the blueprint, but let's assume that it isn't. The conversion multiplier is calculated as follows:

ConversionMultiplier = ValueOfBonus / (ValueOfBonus + 1000)
ConversionMultiplier = 4000 / (4000 + 1000)
ConversionMultiplier = 4000 / 5000
ConversionMultiplier = 0.8

This means that we convert 80% of all physical damage to fire damage. This is what you will see on a Chunk of Lava, level 200, in niobium difficulty.

"All physical damage" also includes any flat damage bonuses (from rings or otherwise).

In addition, we convert 100% of all non-physical damage to fire damage.

For example:

Spoiler

We have a weapon with 5000 physical damage and 5000 ice damage.
We have an item modifier (doesn't matter from where) that states Conversion damage to Fire +80.0%.
We have turned off the attribute bonus.

The inventory screen shows 1000 physical and 9000 fire damage. That is also the damage you do in combat.

All sources of damage conversion, except for Dedicated Blow, work as stated above.

 

The new damage is calculated as follows:

NewElementDamage = CEIL(PhysicalDamage * ConversionMultiplier) + SumNonPhysicalDamage

NewPhysicalDamage = FLOOR(PhysicalDamage * (1 - ConversionMultiplier))

I haven't done tests to see what exactly happens when there is a damage range (min and max) involved.

 

What happens when there are multiple sources of damage conversion?

They are applied in order. For equipped items you can look at the bonus overview to see the order of the item modifiers. The order looks something like this (from lowest priority to highest priority):
- Armor
- Weapon
- Combat Art

Multiple item modifiers on the same item are applied in the order you see them in (which is the order of the bonusgroups in the blueprint).

In the end, you will end up with two elements - physical and the element of the last conversion. Actually, if the weapon doesn't have physical damage to begin with (from allotments) and you don't have any flat physical damage bonuses, then you will end up with only one element.

Interesting note: If you have two rings, each with a different conversion element, you will notice that the order of the conversions is different based on which ring is in the first inventory slot, and which ring is in the second inventory slot. It is not the order in which you equp the rings, but the order of the inventory slots that determines the order of the item modifiers and therefore conversions.

Edit: I wanted to add a funny example:

Spoiler

We have a weapon with 10000 ice damage.
We also have an item modifier that states Conversion damage to Fire +0.0%. (The blueprint bonus is configured to have a value of 1).
We have turned off the attribute bonus.

The inventory screen shows 10000 fire damage. That is also the damage you do in combat.

 

What happens when the attribute bonus is involved?

In the inventory screen, the attribute bonus is not converted at all and you will continue to see its original damage values, which are solely based on the weapon stats.

In actual combat, the attribute bonus IS converted. But it is more appropriate to say, that the attribute bonus is calculated based on the (already) converted damage.

 

What is different about Dedicated Blow? How does the entry et_physical_to_best work?

There are two differences:

1. The conversion element is not predetermined. It is assigned based on what mitigation/vulnerability/armor your opponent has.

2. It only converts the physical damage to the "best" element. It does not touch whatever magic/fire/poison/ice damage you already have.

How the "best" element is determined is not very straightforward. I wanted to include it here, but I will need to do more in-depth tests.

 

 

Additional notes:
- Percentage bonuses to damage are applied after the conversions take place, and not before like some older posts claim - I assume that they are from a time before Ice&Blood.

 

Edited by Maneus
  • Like! 1
Link to comment
 

Secondary damage poison DOT vs spell poison DOT

I'm testing with a Seraphim, level 200, on a wolf, level 177, in niobium difficulty.

I've turned off the weapon/spell attribute bonuses. I'm also editing the creature bonuses of the wolf to make the tests.

Both DOTs do five instances of damage. We assume that each DOT lasts 5 seconds and does one instance of damage per second.

Spell DOT
- The total damage is calculated from the spell entry. We've already gone through this in my previous posts.
- Is not affected by armor. I can now confirm this :)
- Is affected by mitigation and vulnerability.

Secondary damage DOT
- The total damage of the DOT is the same as the total damage of the initial hit that caused it (all elements combined).
- The initial hit is, of course, affected by armor, mitigation and vulnerability.
- The DOT damage itself is not affected by armor.
- It is, however, affected by mitigation and vulnerability, just like the spell DOT.

In practice, it looks like secondary damage DOT is affected twice by mitigation/vulnerability. First, by affecting the initial hit, and then by affecting the DOT damage itself.

Here is an example:

Weapon with 10000 physical damage and 10000 poison damage.
The opponent has 50% poison vulnerability.
The initial hit does 25000 damage (10000 physical + 15000 poison).
The total DOT damage done afterwards is 37500. That is exactly 25000 + 50%.

 

Edited by Maneus
  • Like! 1
Link to comment
 

The base chance to inflict a secondary damage DOT from a weapon attack or spell is determined by the parameters EffectWeaponChance and EffectCombatArtChance in balance.txt.

Quote

EffectWeaponChance = 2
EffectCombatArtChance = 4

The formula appears to be:

ChanceForEffect = (ElementDamage / TotalDamage) / EffectChance

Example:

Spoiler

We have a weapon with 10000 physical damage and 10000 poison damage

ChanceForPoison = (ElementDamage / TotalDamage) / EffectWeaponChance
ChanceForPoison = (10000 / 20000) / 2
ChanceForPoison = 0.5 / 2
ChanceForPoison = 0.25 (Reference value is 25%)

I assume that the result is rounded down to three decimal places. If the chance is lower than 0.001 (0.1%), then the tooltip does not show the bonus at all.

Item modifiers, like Chance for Poison +X%, stack additively with the base chance. But these item modifiers don't do anything on their own. You need to have at least 1 damage of the respective element in order for the item modifier to apply.

For example:

Spoiler

We have a weapon with 10000 physical damage
We have a ring with Chance for Poison +100.0%
In the inventory screen, when hovering over the weapon damage, there is no mention of secondary damage effects.
Hitting an opponent also doesn't poison him.

We modify the weapon to also have exactly 1 poison damage, in addition to the physical damage.

Now, in the inventory screen, we see Chance for Secondary Damage Effects Poison +100.0%, and each time we hit an opponent, we poison him.

 

Edit: Here is an interesting case

We have a weapon with 10000 physical damage and 1000 poison damage.
The attribute bonus (in the inventory) is 9000 physical damage and 900 poison damage.
The damage in the inventory screen in 19000 physical and 1900 poison.
Chance for Poison 4.5%

We equip something that has the item modifier Conversion damage to Ice +50.0%.
Now the damage in the inventory screen is 14000 physical, 900 poison and 6000 ice.
Chance for Poison 2.0% (This should actually be 2.1%. Will have to investigate. It could be due to precision loss).

We equip something that has the item modifier Chance for Poison +100.0%.
Chance for Poison is now 102.0%

This is, of course, misleading. In actual combat, we don't do any poison damage and therefore it is impossible to poison our opponent.

 

Edit: The item modifier Chance for Poison +X% does not work on spells.

Edited by Maneus
  • Like! 1
Link to comment
 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...