Open cbluebdk opened 3 weeks ago
I edited the src/game/Objects/Creature.cpp
and recompiled the core.
When changing line 1752
float const meleeDamageAverage = pCLS->melee_damage * cinfo->damage_multiplier * damageMod;
to
float const meleeDamageAverage = pCLS->melee_damage * cinfo->damage_multiplier * damageMod * 10;
then the creature's melee damage is multiplied by 10, as expected.
However, when I change line 1754
float const rangedDamageAverage = pCLS->ranged_damage * cinfo->damage_multiplier * damageMod;
to
float const rangedDamageAverage = pCLS->ranged_damage * cinfo->damage_multiplier * damageMod * 10;
then the creature's ranged damage does not change.
I would expect it to be multiplied by 10, like with melee damage.
As stated in the OP, the min and max ranged damage is calculated in the function InitStatsForLevel
. From there, they are written into m_weaponDamage
by calling the function SetBaseWeaponDamage
.
These values are read by the function UpdateDamagePhysical
in StatSystem.cpp
by calling GetWeaponDamageRange
. The values are then slightly modified, and written into UNIT_FIELD_MINRANGEDDAMAGE
and UNIT_FIELD_MAXRANGEDDAMAGE
respectively, by calling SetStatFloatValue
.
We can inspect those values in-game by executing .unit statinfo
. I set Rate.Creature.Normal.Damage = 100
in mangosd.conf
and executed .unit statinfo
on a Level 12 Riverpaw Scout. The output was:
Min damage: 1691.77
Max damage: 2242.57
...
Min ranged damage: 1581
Max ranged damage: 2096
The correct damage values are written into the UNIT_FIELD_MINRANGEDDAMAGE
and UNIT_FIELD_MAXRANGEDDAMAGE
. While the enemy indeed does around 2000 melee damage, the actual ranged damage stays at 20.
These values are read by the function CalculateDamage
in Unit.cpp
. This function takes the attack type as an argument. If the attack type is RANGED_ATTACK
, then the UNIT_FIELD_MINRANGEDDAMAGE
and UNIT_FIELD_MAXRANGEDDAMAGE
are read by calling GetFloatValue
. However, this function is not called when an enemy makes a ranged attack!
I print a message into the mangos console every time this function is executed, and it turns out that this function is only called when an enemy makes an attack with either the main-hand (attack type BASE_ATTACK
) or the off-hand (attack type OFF_ATTACK
), but it is not called when an enemy makes a ranged attack.
Now I need to find out how the damage of a ranged attack is actually calculated.
As I noted in the previous comment,
the function CalculateDamage
is not executed on a ranged attack.
Instead, the function SpellCaster::CalculateSpellDamage
is called.
This function differentiates between Weapon Attacks and Magical Attacks.
On a Magical Attack, the function SpellDamageBonusDone
is called,
where the Rate.Creature.*.SpellDamage
modifier from mangosd.conf
is applied.
On a Weapon Attack, the function MeleeDamageBonusDone
is called,
where no modifier from mangosd.conf
is applied.
This makes sense for melee attacks.
The function MeleeDamageBonusDone
is also called in Unit::CalculateMeleeDamage
.
In this case the Rate.Creature.*.Damage
modifier is already applied on the weapon damage itself.
But as I stated in an earlier comment,
the ranged weapon damage seems to be ignored;
here it would make sense to apply the damage modifier in MeleeDamageBonusDone
.
My current solution is this:
In analogy to how the spell damage modifier is applied in SpellDamageBonusDone
,
I applied the physical damage modifier in MeleeDamageBonusDone
;
but only for ranged attacks, to avoid applying the modifier twice on melee attacks.
To apply the fix, insert the following at line 1170 of src/game/Objects/SpellCaster.cpp
:
if (attType == RANGED_ATTACK)
DonePercent *= Creature::_GetDamageMod(((Creature*)this)->GetCreatureInfo()->rank);
I tested this in Westfall with the Riverpaw Scouts and the Defias Pillagers in Moonbrook.
The Rate.Creature.Normal.Damage
modifier is now correctly applied to both melee and physical ranged attacks.
The Rate.Creature.Normal.SpellDamage
modifier is still correctly applied to ranged magic attacks (e.g. Fireball).
Still, I cannot be sure that there aren't any unwanted side-effects;
for now, I consider this a workaround, not a fix.
This solution requires that all ranged attacks ignore the ranged weapon damage set by InitStatsForLevel
.
Otherwise, the modifier could be applied twice.
Are there any magical crossbows that cause fire damage,
where now both the Damage and SpellDamage modifier are applied?
Does this really only affect creatures,
or are some magical ranged attacks of players also affected by this, e.g. some Hunter abilities?
Maybe there are enemy pets that use ranged attacks, where the modifier is still is not applied?
I haven't understood the source code enough to be confident about this.
Maybe there are people around who are more experienced with the codebase who can comment on this solution.
🐛 Bug report
It seems to me that the
Rate.Creature.*.Damage
option inmangosd.conf
does not apply to physical ranged attacks (e.g. bow or crossbow).I compiled vmangos on Arch Linux and used the default mangosd.conf. I play with a client version 1.12.1, build number 5875.
I created a Level 13 Human Warrior, set the Defense skill the 65/65, used only the starting equipment, i.e. I had nearly no armor.
Then I went to Westfall and got attacked by a Level 12 'Riverpaw Scout'. This one attacks with a crossbow, and switches to melee as soon as the player gets in melee range. I set my HP to 100000 and watched the damage. I ignored critical hits, blocked, or crushing damage. The ranged attacks had a strength of 19-25, while the melee attack did 16-21 damage to me.
Now I set
Rate.Creature.Normal.Damage = 0.2
inmangosd.conf
and restarted the server. Same situation as before; melee attacks now between 2-4, but the ranged attacks were still at 19-25. The config option apparently only had an effect on the melee damage, but not on the range damage.Expected behavior
Here is a part of
mangosd.conf
:It says 'Damage' affects melee damage, but it doesn't say it only affects melee damage. So it's not clear to me what is the intended behavior. It would seem strange to me if one could modify melee and spell damage, but not physical range damage.
Look in the source code where the config option is used:
The config option is set in
src/game/World.cpp
and stored in the arraym_configFloatValues
at indexCONFIG_FLOAT_RATE_CREATURE_NORMAL_DAMAGE
. Look where this config option is used:In
src/game/Objects/Creature.cpp
, the function_GetDamageMod
returns this config option value:Let's see where the function
_GetDamageMod
is called:So we have the declaration in the header file, the function header in
Creature.cpp
, and 4 function calls in total: three inCreature.cpp
and one inPet.cpp
.The call in
Pet.cpp
seem to apply to enemy pets, which is not relevant here.Another call is in the function
GetDefaultDamageRange
.This function is only called in some scripts for bosses in mc and zg, so it is not relevant here. The same applies to the function
ResetStats
. Inside this function, the_GetDamageMod
function is called, but theResetStats
function itself is only called in some scripts for zg bosses:That leaves only one call of
_GetDamageMod
inCreature.cpp
. It is in the functionInitStatsForLevel
:This seems to me the right place to look at. I see that the ranged damage is multiplied by
damageMod
. To me this looks how it is supposed to be, however in the game the damage modifier is not applied. This is where I don't know what to do anymore.Why is this important?
I like to play alone locally, and to do dungeons I set the HP and damage of creatures to 0.2. This works fine, but when I encounter an enemy that uses physical range attacks, its damage output is far higher than all the other enemies.
I label this as a bug, because I suspect this is not intended behavior. If it is, I would appreciate if someone can point me to what parts of the code need to be changed to make it work. Then I could at least apply a patch for myself before compiling the core.
Steps to reproduce
Version & Environment
Client Version: 1.12.1.5875
Commit Hash: https://github.com/vmangos/core/tree/9b3b375ef34e92b70e343f057eebea6df75601de
OS Client: Arch Linux OS Server: Arch Linux
Crashlog