Author Topic: Weapon Damage  (Read 2402 times)

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Weapon Damage
« on: January 21, 2007, 09:31:38 PM »
Well, since someone recently asked about this, and I've been rather curious about it for a while, here's a bit about how weapon damage is calculated.


The function of interest can be found at address 004A3690. I've referred to it in my comments as Unit:Weapon.DoDamage().

The majority of the start of this function is conerned with the blast radius. It setups up a range on the x and y coordinates that fall within the damage zone. Note that this zone is square. It checks the destinations x and y coordinates (in pixels) and converts them to tiles. Then it converts the weaponBlastRadius (in pixels) to tiles (rounding up to the next full tile). The area of interest when calculating damage is then TileX/Y-TileRadius to TileX/Y+TileRadius. It then clips the Y values. The X values are not clipped as they may wrap around the world in an around the world type map. That behavior is handled later.

It then plays the explosion sound at the destination location.

It then loops through the tiles in that regions and checks the 11 unitIndex bits of each tile to see if there is a unit there that needs to be damaged. If no unit is present (these bits are all 0), then it will check for walls to damage.

If a unit is found, then it does some basic checking to ensure the unit is still alive/valid. It then checks to see if the unit is a building or not.

If the unit is not a building, then it calculates the absolute value of the distance between the unit (at it's center) and the weapons fire destination (all done in pixels).

If the unit was a building, then some different code executes first (relating to distance), and then the program flow rejoins units at this point.

There is some clipping like code done at this point for the x direction based on the map width (in pixels).
Code: [Select]
If mapPixelWidth/2 >= absPixelXDiff then pixelXDiff = mapPixelWidth/2 - absPixelXDiff else pixelXDiff = mapPixelWidth - absPixelXDiff
The y difference is simply taken as the absolute value of the difference in y coordinates. A special distance measure is calculated. It is:
Code: [Select]
dist = Min(pixelXDiff, pixelYDiff)/2 + Max(pixelXDiff, pixelYDiff)

If this dist >= weaponBlastRadius, then no damage is done. The code continues checking for the next unit in the damage zone.

It then loads the unit's armor, and the weapons penetration and concussion damage. It calculates a base damage value as follows:
Code: [Select]
damage = armor * concussionDamage / 256 + pentrationDamage


It then checks a flag, which is probably set for weapons fire from a GuardPost connected to a CC that increases the damage to 150% (damage = damage + damage/2). Right after this is checks a hidden flag, probably used for some kind of debug mode, that increases damage by 4x (global to the whole game). I'd come across a way to set this flag previously, but it didn't seem to have much use, so I won't discuss it here.


If the unit is a building, then the final damage will be calculated from the above damage based on the average DIRT damage prevention. If the unit is not a building than the final damage is calculated based on the above distance measure:
Code: [Select]
FinalDamage = damage * (weaponBlastRadius - dist) / weaponBlastRadius


If the FinalDamage <= 0 then the code continues checking for the next unit in the damage zone. Otherwise it applies the damage and checks if the player needs to hear an alert about being attacked.



So in short, if the target unit is a vehicle, than damage is:
Code: [Select]
FinalDamage = (armor * concussionDamage / 256 + penetrationDamage) * (weaponBlastRadius - dist) / weaponBlastRadius

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Weapon Damage
« Reply #1 on: March 08, 2007, 02:07:06 PM »
A small update in regards to Unit:Weapon:EMP.DoDamage.

The duration is either 16 game ticks if an Ally caused the EMP, and 32 game ticks when an Enemy caused the EMP.

The vehicle armor, and random numbers are used to determine whether or not the vehicle gets EMPed, but there is no change in the duration based on the armor. The distance, as calculated in the above post is also checked to see if the vehicle was within range of the EMP blast. It is checked in a simple Yes/No manner, so again, no impact on the EMP time.


This function then calls a function on the unit getting EMPed, which I've dubbed Unit.EMPed(short empTime). In the case of vehicles, the empTime is copied into the unit object, and the IsEMPed flag is set. The headlights are also turned off. When the unit recovers from EMP, the headlights will be turned on. (It would appear to forget the headlight state, and not leave them off if they were off to begin with).


I have not really checked into how the building class behaves under EMP. I know it's been suggested that DIRTs decrease the EMP time, but I haven't looked into this claim at this time. There is more code involved with buildings getting EMPed.

Edit: Headlights are indeed turned off for vehicles.
I haven't seen any evidence of DIRTs decreasing EMP time at all so far. Maybe some code is still hiding though.
 
« Last Edit: March 08, 2007, 11:57:02 PM by Hooman »

Offline Brazilian Fan

  • Sr. Member
  • ****
  • Posts: 302
Weapon Damage
« Reply #2 on: March 09, 2007, 05:16:14 PM »
Amazing   :o  

Offline Savant 231-A

  • Sr. Member
  • ****
  • Posts: 486
    • https://www.outpost2.net
Weapon Damage
« Reply #3 on: March 10, 2007, 10:41:45 AM »
Amazed too :o ...
But the only problem is that i don't understand everything you wrote... never mind...

Good job understanding op2 language... dude.... i wouldn't understand this....
Gordon Freeman, and mr. Crowbar would own Master Chief in any part of the day.
"Come here citizen."

"From the ashes of the collapse we seek to build a better world for all."