Jump to content


How is Sacred 2 Weapon Damage Calculated


Recommended Posts

 

How are the Energy Shield hitpoints calculated?

BaseEnergyShieldHitpoints = SpecialBaseHitpoints * SumBonusShield * 0.001 * (1+ SumBonusShieldRel * 0.001)

Where:
- SpecialBaseHitpoints - Calculated in the same way as BaseHitpoints from my previous post, but with LifeFactor always set to 2500 (concerns the creatures).
- SumBonusShield - Add together the values of all bonuses with the type "BONUS_SHIELD". Such a bonus would usually come from the combat arts.
- SumBonusShieldRel - Add together the values of all bonuses with the type "BONUS_SHIELD_REL". Such a bonus might come from the skill Warding Energy Lore or item modifiers.

WillpowerHitpoints = (10 / (10 + CharacterLevel)) * Willpower * BaseEnergyShieldHitpoints / MAX(LifeAttribut, 1)

TotalEnergyShieldHitpoints = FLOOR(BaseEnergyShieldHitpoints + WillpowerHitpoints)

 

As I already mentioned in my previous post, any character can receive a fully functional Energy Shield. The creatures can, too. But sadly, there is no visual indication whether a creature has an Energy Shield or not. Only the bosses, I think.

For example:

Spoiler

Testing on the usual Wolf.
Removed the Vitality and WIllpower attributes (set them to 0).

CharacterLevel = 200 (The creature level)
LifeBase = 4900
LifeStep = 0
LifeFactor = 1000 (through LifeFactorDiff)

BaseHitpoints = ((1 + CharacterLevel + LifeStep * 2) * CharacterLevel + LifeBase * 2) * LifeFactor * 0.0001
BaseHitpoints = ((1 + 200 + 0 * 2) * 200 + 4900 * 2) * 1000 * 0.0001
BaseHitpoints = (201 * 200 + 9800) * 0.1
BaseHitpoints = (40200 + 9800) * 0.1
BaseHitpoints = 50000 * 0.1
BaseHitpoints = 5000

TotalHitpoints = MAX(ROUND(BaseHitpoints + VitalityHitpoints + ConstitutionHitpoints), 1)
TotalHitpoints = MAX(ROUND(5000 + 0 + 0), 1)
TotalHitpoints = MAX(5000, 1)
TotalHitpoints = 5000

Now we will add an Energy Shield to the wolf.

SumBonusShield = 1000
SumBonusShieldRel = 0
LifeFactor = 2500

SpecialBaseHitpoints = ((1 + CharacterLevel + LifeStep * 2) * CharacterLevel + LifeBase * 2) * LifeFactor * 0.0001
SpecialBaseHitpoints = ((1 + 200 + 0 * 2) * 200 + 4900 * 2) * 2500 * 0.0001
SpecialBaseHitpoints = (201 * 200 + 9800) * 0.25
SpecialBaseHitpoints = (40200 + 9800) * 0.25
SpecialBaseHitpoints = 50000 * 0.25
SpecialBaseHitpoints = 12500

BaseEnergyShieldHitpoints = SpecialBaseHitpoints * SumBonusShield * 0.001 * (1+ SumBonusShieldRel * 0.001)
BaseEnergyShieldHitpoints = 12500 * 1000 * 0.001 * (1+ 0 * 0.001)
BaseEnergyShieldHitpoints = 12500

TotalEnergyShieldHitpoints = FLOOR(BaseEnergyShieldHitpoints + WillpowerHitpoints)
TotalEnergyShieldHitpoints = FLOOR(12500 + 0)
TotalEnergyShieldHitpoints = 12500

So the wolf ends up with 5000 regular hitpoints and 12500 energy shield hitpoints.

We set the BONUS_SHIELDFACTOR to 1000 (Absorption Warding Energy +100.0%).

I have modified one of my spells to have 100% leech life from opponents. The spell does 5000 damage per cast (equal to the creature's regular hitpoints). The first two castings do no damage to the wolf (to the regular hitpoints). The third casting leaves the wolf at half hitpoints.

 

Both BONUS_SHIELD and BONUS_SHIELD_REL appear in item tooltips as Max. shield energy +X%, but the one from BONUS_SHIELD has gray text, while the one from BONUS_SHIELD_REL has white text.

Energy Shield on creatures might also be affected by the parameter MP_EShieldHP in balance.txt.

Edited by Maneus
  • Like! 1
Link to comment
 

The skill Warding Energy Lore uses the same formula as Tactics Lore, but has different values for mean_value and advance_mean_value.

Spoiler

--upgrade
--Sera + Temple guardian improve e-shield capacity and absorption
--Advanced:
--upgrade
--Sera/temple guardian improve energy shield

mgr.createSkill {
    skill_name = "skill_energy_shield_lore",
    advance_level = 75,
    min_level = 1,
    mean_value = 150,
    advance_mean_value = 225,
    skillgroup = "SKG_DEFENCE",
    adv_skill_name = "skill_energy_shield_mastery",
}

The formula for the "Shield Energy" bonus for pre-mastery skill levels is:

ShieldEnergy = FLOOR(20 * mean_value * (SkillLevel + SkillPivotPoint * 0.015) / (SkillLevel + SkillPivotPoint)) / 10

Where:
- ShieldEnergy - the value shown in the skill tooltip (as a percentage).
- mean_value - from the skill definition in creatures.txt. Default value is 150.
- SkillLevel - total skill points in the skill.
- SkillPivotPoint - from balance.txt. Default value is 100.

And the formula for post-mastery skill levels is:

ModifiedSkillLevel = SkillLevel - FLOOR((advance_level + 1) / 2.222)

ShieldEnergy = FLOOR(20 * advance_mean_value * (ModifiedSkillLevel + SkillPivotPoint * 0.015) / (ModifiedSkillLevel + SkillPivotPoint)) / 10

Where:
- advance_level - from the skill definition in creatures.txt. Default value is 75.
- advance_mean_value - from the skill definition in creatures.txt. Default value is 225.

In the tooltip, the displayed percentage is subject to precision loss from 32-bit floats. As usual.

The "Shield Energy" is actually a bonus of type "BONUS_SHIELD_REL". See my previous post to learn how it affects the energy shield.

 

The skill also gives "Damage absorption", which is a bonus of type "BONUS_SHIELDBLOCK". It decreases the incoming damage by a flat amount. It is calculated as follows:

DamageAbsorption = FLOOR(10 * ShieldEnergy / balanceShieldAbsorptionSkill)

Where:
- balanceShieldAbsorptionSkill - from balance.txt. Default value is 50.

Setting balanceShieldAbsorptionSkill to 0 makes the "Damage absorption" bonus become 0.

 

At mastery, the skill gives another bonus, which is Shield Regeneration +X%. I don't know how it is calculated yet. Also, this bonus is not reflected in the inventory screen tooltip - the regeneration rate of the Energy Shield doesn't change. But it might be that the tooltip is wrong - will have to test.

 

Examples:

Spoiler

SkillLevel = 74
mean_value = 150
SkillPivotPoint = 100
balanceShieldAbsorptionSkill = 50

ShieldEnergy = FLOOR(20 * mean_value * (SkillLevel + SkillPivotPoint * 0.015) / (SkillLevel + SkillPivotPoint)) / 10
ShieldEnergy = FLOOR(20 * 150 * (74 + 100 * 0.015) / (74 + 100)) / 10
ShieldEnergy = FLOOR(3000 * (74 + 1.5) / 174) / 10
ShieldEnergy = FLOOR(3000 * 75.5 / 174) / 10
ShieldEnergy = FLOOR(1301.724137931034) / 10
ShieldEnergy = 1301 / 10
ShieldEnergy = 130.1 (Reference value is 130.1%)

DamageAbsorption = FLOOR(10 * ShieldEnergy / balanceShieldAbsorptionSkill)
DamageAbsorption = FLOOR(10 * 130.1 / 50)
DamageAbsorption = FLOOR(26.02)
DamageAbsorption = 26 (Reference value is 26)

 

SkillLevel = 75
advance_level = 75
advance_mean_value = 300
SkillPivotPoint = 100
balanceShieldAbsorptionSkill = 50

ModifiedSkillLevel = SkillLevel - FLOOR((advance_level + 1) / 2.222)
ModifiedSkillLevel = 75 - FLOOR((75 + 1) / 2.222)
ModifiedSkillLevel = 75 - FLOOR(76 / 2.222)
ModifiedSkillLevel = 75 - FLOOR(34.2034203420342)
ModifiedSkillLevel = 75 - 34
ModifiedSkillLevel = 41

ShieldEnergy = FLOOR(20 * advance_mean_value * (ModifiedSkillLevel + SkillPivotPoint * 0.015) / (ModifiedSkillLevel + SkillPivotPoint)) / 10
ShieldEnergy = FLOOR(20 * 225 * (41 + 100 * 0.015) / (41 + 100)) / 10
ShieldEnergy = FLOOR(4500 * (41 + 1.5) / 141) / 10
ShieldEnergy = FLOOR(4500 * 42.5 / 141) / 10
ShieldEnergy = FLOOR(1356.382978723404) / 10
ShieldEnergy = 1356 / 10
ShieldEnergy = 135.6 (Reference value is 135.6%)

DamageAbsorption = FLOOR(10 * ShieldEnergy / balanceShieldAbsorptionSkill)
DamageAbsorption = FLOOR(10 * 135.6 / 50)
DamageAbsorption = FLOOR(27.12)
DamageAbsorption = 27 (Reference value is 27)

 

Edited by Maneus
  • Like! 1
Link to comment
 
On 9/19/2024 at 3:16 AM, Maneus said:

The bonus type "BONUS_SHIELD_REGENERATION" represents flat regeneration rate, which works in and out of combat (just like regular flat hitpoint regeneration). That is what the Temple Guardian uses (the modification of the combat art). I think it was affected by the Tactics Lore/Aspect Lore skill, but I will have to check this. I suspect that the Aspect Lore skill only affects bonuses that come from a combat art, and not when given directly to a creature or item.

When given to an item, the item tooltip shows Shield Regeneration +X / s (as a flat amount). But the inventory screen tooltip doesn't reflect this change - the shield regeneration rate remains the same. In combat, the bonus does work and regenerates roughly the stated amount. I say "roughly", because there is some minor variation in the regenerated amount, similarly to how the DOT damage instances vary in damage. Of course, the bonus works out of combat too.

It is not affected by the bonus type "BONUS_SHIELD_RELOAD_REL".

On 9/19/2024 at 3:16 AM, Maneus said:

The bonus type "BONUS_SHIELD_RELOAD_REL" seems to be a percentage bonus to the regeneration rate. I wonder how (or if) it interacts with the flat regeneration bonus.

This is indeed a percentage bonus to the regeneration rate. It is reflected in the inventory screen tooltip, and works as expected.

When given to an item, the item tooltip shows Shield Regeneration +X%.

Edited by Maneus
  • Like! 1
Link to comment
 
 
22 hours ago, SLD said:

Characters with hidden bonuses... how evil :)

Very Sacred Ascaroney

approved

:devil:

gogo

Link to comment
 
On 9/23/2024 at 12:56 PM, Maneus said:

DamageToEnergyShield = MIN(CurrentEnergyShield,

On 9/23/2024 at 12:56 PM, Maneus said:

DamageToHitpoints = MAX(0,

I guess that's how you spell "common sense" in "math" :4rofl:

Link to comment
 

My tests regarding Absorption warding energy were very shallow. I went back and did more thorough tests this time - there are some important things that I missed.

First, it is not actually possible to set Absorption warding energy to exactly 0.0%. Looking at the blueprint bonus, if we set ValueAt0 and ValueAt200 to 0, then the item tooltip will show Absorption warding energy +0.0%, but the bonus will not be applied and the game will use the default value of 50%. If ValueAt0 and ValueAt200 have a value of at least 1, then, even at 0 intensity, the Absorption warding energy will become 0.1%. That's the lowest it can go. Now this makes me wonder if all bonuses are like that...

At Absorption warding energy +0.1%, if the opponent does exactly 999 damage, then the energy shield will not be damaged. But if the opponent does exactly 1000 damage, then 1 hitpoint will be subtracted from the energy shield. My earlier tests were done with very low damage values.

Second, the formula that I gave above suggests that having over 100% Absorption warding energy is detrimental. That is not the case. While Absorption warding energy can go over 100% in the tooltips, the damage to the energy shield is limited to the actual damage dealt.

In that case, the "MAX(0, ...)" part of the formula is indeed redundant, since the DamageToEnergyShield cannot exceed the DamageDealt. :)

 

Edit: On the topic of blueprint bonuses, there is another mystery that I've yet to solve. It is possible to set the ValueAt0 higher than the ValueAt200 and therefore make the value of the bonus decrease as the item/character level goes up. But the results in-game are strange. For example:

Spoiler

ValueAt0 = 1000
ValueAt200 = 0
Intensity = 1000

At ItemLevel = 1, we expect the result to be 995, but it is 994.
At ItemLevel = 2, we expect the result to be 990, but it is 989.
At ItemLevel = 3, we expect the result to be 985, but it is 984.
At ItemLevel = 4, we expect the result to be 980, but it is 979.
At ItemLevel = 5, we expect the result to be 975, but it is 974.
At ItemLevel = 10, we expect the result to be 950, but it is 949.
At ItemLevel = 100, we expect the result to be 500, but it is 499.
At ItemLevel = 200, we expect the result to be 0, but it is 4294966.

ValueAt0 = 1000
ValueAt200 = 0
ItemLevel = 200

At Intensity = 1000, the result is 4294966
At Intensity = 100, the result is 2147483
At Intensity = 10, the result is 214748
At Intensity = 1, the result is 21474
At Intensity = 0, the result is 1

Regardless, there are no such bonuses to be found in blueprint.txt.

Edited by Maneus
  • Like! 1
Link to comment
 
18 hours ago, Maneus said:

In that case, the "MAX(0, ...)" part of the formula is indeed redundant, since the DamageToEnergyShield cannot exceed the DamageDealt. :)

I just thought it was funny you made sure to exclude the energy shield blocking more damage than it's size and the potential for taking negative damage :)
 

18 hours ago, Maneus said:

At ItemLevel = 200, we expect the result to be 0, but it is 4294966.

18 hours ago, Maneus said:

At Intensity = 1000, the result is 4294966
At Intensity = 100, the result is 2147483

Sacred 2 going out of its way to make the bs number bigger eventually even ditching the sign(+/-) :)

  • Like! 1
Link to comment
 

My previous post about weapon damage: https://darkmatters.org/forums/index.php?/topic/18511-how-is-sacred-2-weapon-damage-calculated/&do=findComment&comment=7145350

 

There are several parameters in balance.txt that additionally affect it:

Quote

AdjustDamageFactor = 1000
DamageFactorDiff = {1000,1050,1200,1350,1500}
MP_damage = {1000,1050,1100,1160,1220}
Enemy_weapondamage = {650,850,1000,3300,3630}
DamageFactorMT = {1000,1200,1400,1400}

Out of these, only AdjustDamageFactor affects both the player's character and the creatures. But the change is not reflected in the inventory screen (at least for the player's character).

AdjustDamageFactor, DamageFactorDiff, Enemy_weapondamage and DamageFactorMT all appear to multiply the BaseDamage in this formula:

On 8/14/2024 at 10:11 PM, Maneus said:

CombinedDamage = BaseDamage + AttributeBonus

They do not affect the AttributeBaseDamage and therefore do not affect the AttributeBonus.

The new formula appears to be:

CombinedDamage = BaseDamage * FLOOR3(AdjustDamageFactor * 0.001 * DamageFactorDiff * 0.001 * Enemy_weapondamage * 0.001 * DamageFactorMT * 0.001) + AttributeBonus

Since they modify the CombinedDamage, that means they also affect the ArmorMultiplier.

Edit: MP_damage is only applied to the damage that goes to the energy shield! The damage to the regular hitpoints is not affected.

MP_damage is a multiplier that is applied after that (does not affect the ArmorMultiplier), similarly to damage mitigation/vulnerability and direct damage. While it definitely does affect the damage dealt, the floating numbers are not affected - they still show the original damage (when MP_damage = 1000)!

Creatures do receive an AttributeBonus, just like the player's character. It appears to be affected by the same parameters from balance.txt (at least attrWdam_fact does). The parameter NPC_attrWdam_fact doesn't appear to change anything.

 

For DamageFactorDiff, in niobium difficulty, the last value of the tuple is used. I assume that the previous values are for the lower difficulties.

For MP_damage, I believe the number of players determines which value to use, which, in my case, is always the first one.

For Enemy_weapondamage, things are a bit odd. In niobium difficulty, the fourth value is the one that is used (instead of the fifth one).

For DamageFactorMT, in niobium difficulty, the first value of the tuple is used. I don't know when the other values are used.

 

There is also a strange interaction with energy shields, where the floating number will correctly show a high damage number, but the actual damage to the energy shield is greatly reduced. MP_damage also behaves strangely when the character has an energy shield. I'll be investigating... :)

 

Edited by Maneus
  • Like! 1
Link to comment
 
On 9/28/2024 at 12:00 AM, Maneus said:

MP_damage also behaves strangely when the character has an energy shield.

When the player's character has an energy shield, MP_damage is applied only to the damage to the energy shield. For example:

Character's hitpoints = 220000
Character's energy shield hitpoints = 20000
Character's absorption warding energy = 50.0%
Opponent's damage = 100
MP_damage = 10000 (x10)

The opponent hits the character. The floating number shows 100. The tooltips do not update immediately. After a short time the hitpoints become 219950 and the energy shield hitpoints become 19500. So the damage to the regular hitpoints is 50, and the damage to the energy shield hitpoints is 500. At 100% absorption warding energy, the energy shield receives 1000 damage (and 0 to regular hitpoints). At 99.9% absorption warding energy, the energy shield receives 990 damage (and 1 to regular hitpoints). All of this suggests that MP_damage is applied after the absorption warding energy is applied.

If the energy shield gets depleted, then 100 damage will be done to the regular hitpoints from that point on.

If the character has no energy shield to begin with, then 1000 damage is done to the regular hitpoints always.

 

On 9/28/2024 at 12:00 AM, Maneus said:

There is also a strange interaction with energy shields, where the floating number will correctly show a high damage number, but the actual damage to the energy shield is greatly reduced.

This appears to be because of direct damage. I am using 900% or 9900% to check the decimal part of the damage. At 9900% it works against regular hitpoints just fine. Against the energy shield, the floating number correctly shows the damage value, but the actual damage to the energy shield hitpoints is much much lower. For example:

Character's hitpoints = 220000
Character's energy shield hitpoints = 20000
Character's absorption warding energy = 100.0%
Opponent's damage = 123
Opponent's direct damage = 9900%

The opponent hits the character. The floating number shows 12300. The energy shield hitpoints become 16289. So the damage to the energy shield hitpoints is 3711. This continues on until the energy shield is about to become depleted, at which point the damage jumps to 12300. I haven't done too much testing here. Decreasing the direct damage to 900% seems to avoid this problem. I don't know if I want to explore this further. I don't think 9900% direct damage is a natural occurence :)

 

But it is sad to learn that the floating numbers are not entirely trustworthy. From now on I'll need to test the reduction in the hitpoints too.

Edited by Maneus
  • Like! 1
Link to comment
 
41 minutes ago, Maneus said:

If the energy shield gets depleted, then 100 damage will be done to the regular hitpoints from that point on.

If the character has no energy shield to begin with, then 1000 damage is done to the regular hitpoints always.

So in multiplayer you should always have an Energy shield. Nice find :)

42 minutes ago, Maneus said:

I don't know if I want to explore this further. I don't think 9900% direct damage is a natural occurence :)

"Not a natural occurrence"...
When has that ever stopped you before?
Did you think dexterity values of "609040" where occuring naturally? :)
Oh boy, did I have to search for that one... It's on page 4. :4rofl:

41 minutes ago, Maneus said:

But it is sad to learn that the floating numbers are not entirely trustworthy. From now on I'll need to test the reduction in the hitpoints too.

With your track record, I'm sure you'll soon find out that death doesn't always occur at 0 life. :)

No, don't worry, that was just a joke, not another hint by the infallible nose :connie_xmas-moose:.
Though there was a bug like that in Sacred 1 where enemy healthbars didn't show their actual health and could show "empty" long before the enemy was dead...

  • Like! 1
Link to comment
 

It appears that I'm wrong about MP_damage. My newest tests show that it is never applied to the damage against the regular hitpoints. The energy shield has nothing to do with it. I was so convinced that it was applied...

And I guess this makes some sense. The floating number is actually correct when it comes to damage to the regular hitpoints. But it doesn't account for the energy shield absorption and damage, where MP_damage is applied.

And for all of my previous tests, where I was setting MP_damage to 0 - I think MP_combatvalue was the parameter that actually helped me. Because when I got hit, which happened occasionally, I got hit pretty hard.

1 hour ago, SLD said:

So in multiplayer you should always have an Energy shield. Nice find :)

It turns out it is the opposite. :(

 

1 hour ago, SLD said:

With your track record, I'm sure you'll soon find out that death doesn't always occur at 0 life. :)

No, don't worry, that was just a joke, not another hint by the infallible nose :connie_xmas-moose:.

This reminds me of a rare phenomenon, where those pesky kobolds would rise up again after being killed, just like a skeleton would. I've always been curious about that.

  • Like! 1
Link to comment
 

Giving your character 100000 willpower appears to be a bad idea. My energy shield of 3829523 hitpoints instantly evaporates whenever I get hit (even when it's just for 1 damage). MP_damage does not have anything to do with this - it happens even at MP_damage set to 0. At 10000 willpower (and therefore less energy shield hitpoints) everything works as expected. Will have to investigate.

 

The "freeze" secondary damage effect appears to do only one thing: it lowers the movement speed by 20% (relative). It does not affect attack speed at all. So if you have 100% movement speed, it will become 80%. And if you have 150% movement speed, it will become 120%.

Movement speed is capped at 150%. But the reduction is not applied to the capped movement speed, but to the uncapped movement speed. So if you have 175% movement speed, it will become 140%. At least, when the movement speed bonus comes from an item modifier.

Spell Resistance Mastery appears to decrease this penalty. At level 75 the tooltip states Reduction of Detrimental Effects +35.6%. If you have 100% movement speed, then it becomes 91.8%. And if you have 150% movement speed, it becomes 137.7%. But these numbers don't make sense to me right now. I will need to do more tests.

 

The "weaken" secondary damage effect appears to lower all attributes by 16.6666...%. I don't know how many decimal places there are, but if the attribute is at 100000, then it becomes 83333. The result appears to be rounded down. Spell Resistance Mastery decreases this penalty too. At level 75, 100000 becomes 93370. But there are many questions still.

 

I'm posting preliminary findings because I don't have as much time as before to make more complete posts. I'm also planning to go on vacation soon, so I'll be away for some time. And I don't want to forget what I was doing. :)

Hopefully, this will give the power cow more time to recharge :cow:

  • Like! 1
Link to comment
 
7 hours ago, Maneus said:

Giving your character 100000 willpower appears to be a bad idea. My energy shield of 3829523 hitpoints instantly evaporates whenever I get hit (even when it's just for 1 damage).

Lemme guess, the number shown is unsigned but the one used overflows to the negative as Sacred 2 dumps the other 3 digits behind the decimal point? And when you get hit it checks the current value sees <=0 and removes the shield. The "nose" is at it again...
 

7 hours ago, Maneus said:

Hopefully, this will give the power cow more time to recharge :cow:

That :cow: is the normal cow.
The power-cow is this one :connie_xmas-moose:.
Blame Gogo for it :)

  • Like! 1
Link to comment
 
21 hours ago, SLD said:

Lemme guess, the number shown is unsigned but the one used overflows to the negative as Sacred 2 dumps the other 3 digits behind the decimal point? And when you get hit it checks the current value sees <=0 and removes the shield. The "nose" is at it again...

And once again you are correct. The energy shield, being a product of T-Energy, becomes highly unstable past a certain point. That limit, where it will still work, appears to be exactly 2147483 hitpoints. At 2147484 hitpoints, even the slightest puff from a wolf (0 damage) will overload it and it will dissipate completely.

My immense willpower has nothing to do with it. It is simply the nature of (T-)energy shields.

The power-cow has spoken the truth again. :bow:

21 hours ago, SLD said:

That :cow: is the normal cow.
The power-cow is this one :connie_xmas-moose:.

Legend has it that the appearance of the power-cow is heralded by the normal dancing cows. And, if the power-cow is in good spirits, it will present itself to share it's ancient knowledge with those who are willing to listen.

 

 

Edit: If the wolf misses (MP_combatvalue = 0), then the energy shield remains intact.

If the wolf does exactly 1 damage, then the shield will remain intact at 2147484 hitpoints, but dissipate at 2147485 hitpoints.

If the wolf does exactly 2250 damage (1000 base + 125% from level difference bonus), then the shield will remain intact at 2149733 hitpoints, but dissipate at 2149734 hitpoints.

The maximum value of a 32-bit signed integer is 2147483647. If, as SLD says, we remove the last 3 digits, that leaves us with 2147483. If we add the damage done to this number, we get the limit at which the shield remains stable.

If the maximum hitpoints are above the safe limit, but the current hitpoins are below or at the limit, then the energy shield will remain stable. It is the current hitpoints (after taking damage) that matter.

Edited by Maneus
  • Thanks! 1
Link to comment
 
 
6 hours ago, Maneus said:

If the maximum hitpoints are above the safe limit, but the current hitpoins are below or at the limit, then the energy shield will remain stable. It is the current hitpoints (after taking damage) that matter.

Can it then regenerate into the unsafe zone and turn itself off? Does it only regenerate to the safe maximum? Or is this stuff really only ever checked after a hit?
 

21 minutes ago, chattius said:

I supposed an overflow bug at the Burgfräulein D2F paladin build of my daughter. Sadly I had no time to investigate any further. Thanks for clarification.

You have an amazing memory :)

  • Like! 1
Link to comment
 
10 hours ago, SLD said:

Can it then regenerate into the unsafe zone and turn itself off? Does it only regenerate to the safe maximum? Or is this stuff really only ever checked after a hit?

It regenerates up to the maximum hitpoints as normal. And the maximum hitpoints can be much higher - I tried with 20 million.

Being (successfully) hit is what triggers this behavior.

Edited by Maneus
  • Like! 1
Link to comment
 
 

Regarding the following parameters:

Quote

SpellAttackFactorMT = {1000,1330,2000,2000},
SpellDefenseFactorMT = {1000,1750,2500,2500},
HitFactorMT = {1000,1500,2000,2000},
DamageFactorMT = {1000,1200,1400,1400},
LifeQuotientMT = {2500,800,125,125},

MT appears to stand for "monster type". In creatures.txt, each creature is assigned a "monstertype". Regular creatures have "monstertype = 0", elite have "monstertype = 1" and bosses have "monstertype = 2".

For "monstertype = 0" we need to use the first value of each tuple. For "monstertype = 1" - the second. And for "monstertype = 2" - the third. The fourth value - no idea.

 

LifeQuotientMT is used in the formula for the BaseHitpoints like so:

BaseHitpoints = ((1 + CharacterLevel + LifeStep * 2) * CharacterLevel + LifeBase * 2) * LifeFactor * 0.0001 * 2500 * (1 / LifeQuotientMT)

 

I haven't tested if it also affects the energy shield hitpoints yet.

 

Let's calculate the hitpoints of the boss Gar'Colossus.

The creature:

Spoiler

mgr.createCreature {
    id = 76,
    itemtype_id = 1705,
    name = "Boss_tenerg_steingolem",
    behaviour = "Enemy_boss_golem",
    dangerclass = 9,
    groupmaxcount = 1,
    elite_creature_id = 76,
    probabilityforelite = 0.000000,
    rank = 0,
    tenergy_creature_id = 76,
    livesremaining = 0,
    unconscioustime = 5,
    palettebits = "1111111111111111",
    monstertype = 2,
    faction_id = 27,
    modelscale = 1.000000,
    rise_from_ground = 0,
    has_corpse = 0,
    has_soul = 0,
    can_strafe = 0,
    spells = {
        entry0 = { "boss_golem_erdbeben" },
        entry1 = { "boss_golem_steinwurf" },
        entry2 = { "boss_golem_splitterschuss" },
        entry3 = { "boss_golem_rage" },
        entry4 = { "boss_golem_schockwelle" },
        entry5 = { "boss_golem_energieschild" },
    },
}

He is given a vitality bonus.

Spoiler

mgr.addCreatureBonus( 76, {
    intensity = 1250,
    bonus = 24,
})

The bonus in blueprint.txt

Spoiler

newBonus = {
--  name = "crbonus_attr_vit_npc",
  rating = 0,
  basedonskill = "SKILL_INVALID",
  type = "BONUS_STATS",
  spez = "STAT_VIT",
  spez2 = "",
  usagebits = 65535,
  minconstraints = {1,0,0},
  difficultyvaluerange0 = {0,23,525},
  difficultyvaluerange1 = {1,32,700},
  difficultyvaluerange2 = {2,41,875},
  difficultyvaluerange3 = {3,50,1050},
  difficultyvaluerange4 = {4,62,1300},
}
mgr.createBonus(24, newBonus);

At level 200 he has 1625 vitality.

Spoiler

CreatureLevel = 200
ValueAt0 = 62
ValueAt200 = 1300
Intensity = 1250

ValueOfBonus = FLOOR((FLOOR((ValueAt200 - ValueAt0) * (1 / 200) * CreatureOrItemLevel) + ValueAt0) * Intensity * 0.001)
ValueOfBonus = FLOOR((FLOOR((1300 - 62) * (1 / 200) * 200) + 62) * 1250 * 0.001)
ValueOfBonus = FLOOR((FLOOR(1238) + 62) * 1.25)
ValueOfBonus = FLOOR((1238 + 62) * 1.25)
ValueOfBonus = FLOOR(1300 * 1.25)
ValueOfBonus = FLOOR(1625)
ValueOfBonus = 1625

Vitality = ValueOfBonus
Vitality = 1625

We can calculate that his total hitpoints are 1574537.

Spoiler

CharacterLevel = 200
LifeStep = 19
LifeBase = 130
LifeQuotientMT = 125
LifeFactor = 4000 (Niobium difficulty)

BaseHitpoints = ((1 + CharacterLevel + LifeStep * 2) * CharacterLevel + LifeBase * 2) * LifeFactor * 0.0001 * 2500 * (1 / LifeQuotientMT)
BaseHitpoints = ((1 + 200 + 19 * 2) * 200 + 130 * 2) * 4000 * 0.0001 * 2500 * (1 / 125)
BaseHitpoints = ((201 + 38) * 200 + 260) * 8
BaseHitpoints = (239 * 200 + 260) * 8
BaseHitpoints = (47800 + 260) * 8
BaseHitpoints = 48060 * 8
BaseHitpoints = 384480

Vitality = 1625
LifeAttribut = 25

VitalityHitpoints = (10 / (10 + CharacterLevel)) * Vitality * BaseHitpoints / MAX(LifeAttribut, 1)
VitalityHitpoints = (10 / (10 + 200)) * 1625 * 384480 / MAX(25, 1)
VitalityHitpoints = (10 / 210) * 1625 * 384480 / 25
VitalityHitpoints = 1190057.142857143

TotalHitpoints = MAX(ROUND(BaseHitpoints + VitalityHitpoints + ConstitutionHitpoints), 1)
TotalHitpoints = MAX(ROUND(384480 + 1190057.142857143 + 0), 1)
TotalHitpoints = MAX(ROUND(1574537.142857143), 1)
TotalHitpoints = MAX(1574537, 1)
TotalHitpoints = 1574537

By hitting the boss with a modified spell that has 100% leech life from opponents (and nothing else), I do exactly 1574537 damage.

Note: In niobium difficulty, the maximum level of Gar'Colossus is 194. I have modified the parameter Spawn_OffsetHigh (175 -> 181) to allow him to reach level 200, which is my character level.

Edited by Maneus
Link to comment
 

Gar'Colossus is given willpower:

Spoiler

mgr.addCreatureBonus( 76, {
    intensity = 1500,
    bonus = 25,
})

The bonus in blueprint.txt

Spoiler

newBonus = {
--  name = "crbonus_attr_wil_npc",
  rating = 0,
  basedonskill = "SKILL_INVALID",
  type = "BONUS_STATS",
  spez = "STAT_WIL",
  spez2 = "",
  usagebits = 65535,
  minconstraints = {1,0,0},
  difficultyvaluerange0 = {0,23,525},
  difficultyvaluerange1 = {1,32,700},
  difficultyvaluerange2 = {2,41,875},
  difficultyvaluerange3 = {3,50,1050},
  difficultyvaluerange4 = {4,62,1300},
}
mgr.createBonus(25, newBonus);

At level 200 he has 1950 willpower.

Spoiler

CreatureLevel = 200
ValueAt0 = 62
ValueAt200 = 1300
Intensity = 1500

ValueOfBonus = FLOOR((FLOOR((ValueAt200 - ValueAt0) * (1 / 200) * CreatureOrItemLevel) + ValueAt0) * Intensity * 0.001)
ValueOfBonus = FLOOR((FLOOR((1300 - 62) * (1 / 200) * 200) + 62) * 1500 * 0.001)
ValueOfBonus = FLOOR((FLOOR(1238) + 62) * 1.5)
ValueOfBonus = FLOOR((1238 + 62) * 1.5)
ValueOfBonus = FLOOR(1300 * 1.5)
ValueOfBonus = FLOOR(1950)
ValueOfBonus = 1950

Willpower = ValueOfBonus
Willpower = 1950

The combat art that gives him the energy shield:

Spoiler

mgr.defineSpell( "boss_golem_energieschild", {
    eiStateName = "cSpellCast",
    fxTypeCast = "",
    fxTypeSpell = "",
    duration = 0.000000,
    animType = "ANIM_TYPE_ATTACKA",
    animTypeApproach = "",
    animTypeRide = "",
    animTypeSpecial = "",
    causesSpellDamage = 1,
    tokens = {
        entry0 = {"et_shieldstrength", 2000, 0, 0, 5 },
        entry1 = {"et_shieldblock", 15, 5, 0, 5 },
        entry2 = {"et_damping_any", 700, 0, 0, 41 },
        entry3 = {"et_shieldfactor", 1000, 10, 0, 37 },
    },
    fightDistance = 0.000000,
    aspect = "EA_ENEMY_ANY",
    cooldown = 0.000000,
    soundProfile = 0,
    cost_level = 300,
    cost_base = 300,
    focus_skill_name = "skill__enemy_focus",
    lore_skill_name = "skill__enemy_lore",
    spellClass = "cSpellSeEnergieschild",
    spellcontroltype = "eCAtype_t_buff",
    sorting_rank = 0,
})

mgr.addTokenBonus( {"et_shieldstrength", 409 })  -- 409 = bb_shieldstrength

At all combat art levels, the value of the bonus (BONUS_SHIELD) is 2000.

We can calculate that his total energy shield hitpoints are 113284.

Spoiler

CharacterLevel = 200
LifeStep = 19
LifeBase = 130
LifeFactor = 2500 (Always use this value for energy shields)
SumBonusShield = 2000
SumBonusShieldRel = 0
LifeAttribut = 25
Willpower = 1950

SpecialBaseHitpoints = ((1 + CharacterLevel + LifeStep * 2) * CharacterLevel + LifeBase * 2) * LifeFactor * 0.0001
SpecialBaseHitpoints = ((1 + 200 + 19 * 2) * 200 + 130 * 2) * 2500 * 0.0001
SpecialBaseHitpoints = ((201 + 38) * 200 + 260) * 0.25
SpecialBaseHitpoints = (239 * 200 + 260) * 0.25
SpecialBaseHitpoints = (47800 + 260) * 0.25
SpecialBaseHitpoints = 48060 * 0.25
SpecialBaseHitpoints = 12015

BaseEnergyShieldHitpoints = SpecialBaseHitpoints * SumBonusShield * 0.001 * (1+ SumBonusShieldRel * 0.001)
BaseEnergyShieldHitpoints = 12015 * 2000 * 0.001 * (1+ 0 * 0.001)
BaseEnergyShieldHitpoints = 24030

WillpowerHitpoints = (10 / (10 + CharacterLevel)) * Willpower * BaseEnergyShieldHitpoints / MAX(LifeAttribut, 1)
WillpowerHitpoints = (10 / (10 + 200)) * 1950 * 24030 / MAX(25, 1)
WillpowerHitpoints = (10 / 210) * 1950 * 24030 / 25
WillpowerHitpoints = 89254.28571428571

TotalEnergyShieldHitpoints = FLOOR(BaseEnergyShieldHitpoints + WillpowerHitpoints)
TotalEnergyShieldHitpoints = FLOOR(24030 + 89254.28571428571)
TotalEnergyShieldHitpoints = FLOOR(113284.2857142857)
TotalEnergyShieldHitpoints = 113284

I modified my spell to do exactly 113284 damage via flat life leech. A single spell cast completely depletes his energy shield. If I lower the life leech by 1, then the energy shield remains.

In conclusion: LifeQuotientMT does not affect energy shield hitpoints.

 

gar colossus 2.jpg

gar colossus 1.jpg

Edited by Maneus
  • Like! 1
Link to comment
 
13 hours ago, SLD said:

Interesting. Sounds like testing ~3 million "life" for similar behaviour would make sense now :connie_xmas-moose:

179838208 hitpoints seems to work fine.

Note to self: My in-combat regeneration is 79928.0 / s (without constitution mastery).

Another note to self: Test for damage overflows. I know that "leech life from opponents" overflows at some point.

Edited by Maneus
  • Like! 1
Link to comment
 
1 hour ago, Maneus said:

179838208 hitpoints seems to work fine.

So they either thought they needed to allocate more space for life than for shields or they thought they needed fractional shield values? Nah... they probably just forgot to change the shields away from the "normal" 3 decimals system. 
We need 2.2 billion life to confirm. 179838208 is not enough :)

Nice pictures of your High Elf dating the Gar'Colossus! :cow:

  • Like! 1
Link to comment
 

The formula for Attack vs Defense is:

ChanceToHit = FLOOR2(AttackValue / (AttackValue + FLOOR(DefenseValue * DefenseFactorDiff * 0.001)))

Where:
ChanceToHit - The percentage shown in the Last Opponent section.
DefenseFactorDiff - from balance.txt.

Quote

DefenseFactorDiff = {650,1000,1500,2500,4500},

 

Examples:

Spoiler

AttackValue = 500
DefenseValue = 1000
DefenseFactorDiff = 4500 (Niobium)

ChanceToHit = FLOOR2(AttackValue / (AttackValue + FLOOR(DefenseValue * DefenseFactorDiff * 0.001)))
ChanceToHit = FLOOR2(500 / (500 + FLOOR(1000 * 4500 * 0.001)))
ChanceToHit = FLOOR2(500 / (500 + FLOOR(4500)))
ChanceToHit = FLOOR2(500 / (500 + 4500))
ChanceToHit = FLOOR2(500 / 5000)
ChanceToHit = FLOOR2(0.1)
ChanceToHit = 0.1 (Reference value is 10%)

AttackValue = 1000
DefenseValue = 1000
DefenseFactorDiff = 4500 (Niobium)

ChanceToHit = FLOOR2(AttackValue / (AttackValue + FLOOR(DefenseValue * DefenseFactorDiff * 0.001)))
ChanceToHit = FLOOR2(1000 / (1000 + FLOOR(1000 * 4500 * 0.001)))
ChanceToHit = FLOOR2(1000 / (1000 + FLOOR(4500)))
ChanceToHit = FLOOR2(1000 / (1000 + 4500))
ChanceToHit = FLOOR2(1000 / 5500)
ChanceToHit = FLOOR2(0.1818181818181818)
ChanceToHit = 0.18 (Reference value is 18%)

AttackValue = 1500
DefenseValue = 1000
DefenseFactorDiff = 4500 (Niobium)

ChanceToHit = FLOOR2(AttackValue / (AttackValue + FLOOR(DefenseValue * DefenseFactorDiff * 0.001)))
ChanceToHit = FLOOR2(1500 / (1500 + FLOOR(1000 * 4500 * 0.001)))
ChanceToHit = FLOOR2(1500 / (1500 + FLOOR(4500)))
ChanceToHit = FLOOR2(1500 / (1500 + 4500))
ChanceToHit = FLOOR2(1500 / 6000)
ChanceToHit = FLOOR2(0.25)
ChanceToHit = 0.25 (Reference value is 25%)

AttackValue = 2000
DefenseValue = 1000
DefenseFactorDiff = 4500 (Niobium)

ChanceToHit = FLOOR2(AttackValue / (AttackValue + FLOOR(DefenseValue * DefenseFactorDiff * 0.001)))
ChanceToHit = FLOOR2(2000 / (2000 + FLOOR(1000 * 4500 * 0.001)))
ChanceToHit = FLOOR2(2000 / (2000 + FLOOR(4500)))
ChanceToHit = FLOOR2(2000 / (2000 + 4500))
ChanceToHit = FLOOR2(2000 / 6500)
ChanceToHit = FLOOR2(0.3076923076923077)
ChanceToHit = 0.30 (Reference value is 30%)

AttackValue = 5000
DefenseValue = 1000
DefenseFactorDiff = 4500 (Niobium)

ChanceToHit = FLOOR2(AttackValue / (AttackValue + FLOOR(DefenseValue * DefenseFactorDiff * 0.001)))
ChanceToHit = FLOOR2(5000 / (5000 + FLOOR(1000 * 4500 * 0.001)))
ChanceToHit = FLOOR2(5000 / (5000 + FLOOR(4500)))
ChanceToHit = FLOOR2(5000 / (5000 + 4500))
ChanceToHit = FLOOR2(5000 / 9500)
ChanceToHit = FLOOR2(0.5263157894736842)
ChanceToHit = 0.52 (Reference value is 52%)

AttackValue = 10000
DefenseValue = 1000
DefenseFactorDiff = 4500 (Niobium)

ChanceToHit = FLOOR2(AttackValue / (AttackValue + FLOOR(DefenseValue * DefenseFactorDiff * 0.001)))
ChanceToHit = FLOOR2(10000 / (10000 + FLOOR(1000 * 4500 * 0.001)))
ChanceToHit = FLOOR2(10000 / (10000 + FLOOR(4500)))
ChanceToHit = FLOOR2(10000 / (10000 + 4500))
ChanceToHit = FLOOR2(10000 / 14500)
ChanceToHit = FLOOR2(0.6896551724137931)
ChanceToHit = 0.68 (Reference value is 68%)

 

There is an exception when AttackValue and DefenseValue are both 0 - in that case, the chance to hit will be 50%. But it is unknown if this percentage is the one that is used in practice. Tooltips tend to be misleading.

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...