-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPhysicalProjectile.cs
186 lines (138 loc) · 6.21 KB
/
PhysicalProjectile.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
using System;
using System.Text;
using System.Diagnostics;
namespace PFW.Damage
{
public static class PhysicalProjectile
{
public float FrictionFactor = 1.0f;
public float Energy2Pierce = 1.0f;
public struct Kinetic
{
public float Pierce;
public float ArmorKineticFactor;
public float HealthKineticFactor;
}
public struct Heat
{
public float Pierce;
public float ArmorHeatFactor;
public float HealthHeatFactor;
}
public struct Vehicle
{
public float Armor;
public float Health;
}
public struct ERA
{
public int Plates;
public float Bonus;
public float PiercingFactor;
public float ExplosiveFactor;
}
/// <summary>
/// Returns how much armor and health is left, possibly if the target has died.
/// Returns are the following: 0 is Remaining AV, 1 is Remaining HP
/// </summary>
public static float[] GetTargetDamage(Kinetic kinetic, Heat heat, Vehicle vehicle, ERA era, float distance)
{
float armorPiercingDamage = 0f;
float heatPiercingDamage = 0f;
//bool ERABlocksShot = false;
// Apply KE attenuation
kinetic.Pierce = CalculateKEAttenuationSimple(kinetic.Pierce,distance, FrictionFactor);
// Kinetic Armor Degradation
if (era.Plates < 1 && vehicle.Armor > 0)
{
armorPiercingDamage = (kinetic.Pierce / vehicle.Armor) * kinetic.ArmorKineticFactor;
Debug.WriteLine($"Armor Piercing Damage: {armorPiercingDamage}");
}
if (era.Plates > 0)
{
armorPiercingDamage = (kinetic.Pierce / era.Bonus) * kinetic.ArmorKineticFactor;
float eraArmor = era.Bonus - (armorPiercingDamage * era.PiercingFactor);
if (eraArmor > 0)
armorPiercingDamage = 0;
else if (vehicle.Armor > 0)
armorPiercingDamage = ((eraArmor * -1) / vehicle.Armor) * kinetic.ArmorKineticFactor;
}
Debug.WriteLine($"Armor Piercing Damage: {armorPiercingDamage}");
// Heat Armor Degradation
/*heatPiercingDamage = (era.Plates < 1 && vehicle.Armor > 0) ?
(heat.Piercing / vehicle.Armor) * heat.ArmorHeatFactor :
heatPiercingDamage;*/
if (era.Plates < 1 && vehicle.Armor > 0)
{
heatPiercingDamage = (heat.Pierce / vehicle.Armor) * heat.ArmorHeatFactor;
Debug.WriteLine($"Heat Piercing Damage: {heatPiercingDamage}");
}
if (era.Plates > 0)
{
heatPiercingDamage = (heat.Pierce / era.Bonus) * heat.HealthHeatFactor;
float eraArmor = era.Bonus - (heatPiercingDamage * era.ExplosiveFactor);
if (era.Bonus > 0)
{
heatPiercingDamage = 0;
}
else if (vehicle.Armor > 0)
{
heatPiercingDamage = ((eraArmor * -1) / vehicle.Armor) * heat.ArmorHeatFactor;
}
}
Debug.WriteLine($"Heat Piercing Damage: {heatPiercingDamage}");
// Total armor degradation
var totalDegradation = armorPiercingDamage + heatPiercingDamage;
vehicle.Armor -= totalDegradation;
if (vehicle.Armor < 0) vehicle.Armor = 0;
Debug.WriteLine($"Total Degradation: {totalDegradation}");
Debug.WriteLine($"Vehicle Armor: {vehicle.Armor}");
// AP -> HP damage
float kineticHealthDamage = (kinetic.Pierce - vehicle.Armor) * kinetic.HealthKineticFactor;
if (kineticHealthDamage < 0) kineticHealthDamage = 0;
Debug.WriteLine($"Kinetic Health Damage: {kineticHealthDamage}");
// HE -> HP damage
float heatHealthDamage = (heat.Pierce - vehicle.Armor) * heat.HealthHeatFactor;
if (heatHealthDamage < 0) kineticHealthDamage = 0;
if (vehicle.Armor == 0 && era.Plates > 0)
{
kineticHealthDamage -= era.Bonus;
heatHealthDamage -= era.Bonus;
}
era.Plates = era.Plates - 1;
Debug.WriteLine($"ERA Plates: {era.Plates}");
// Total health reduction
vehicle.Health = vehicle.Health - (kineticHealthDamage + heatHealthDamage);
// just to prevent any bugs, i'm resetting any negative values
if (era.Plates < 0)
era.Plates = 0;
if (vehicle.Armor < 0)
vehicle.Armor = 0;
if (vehicle.Health < 0)
vehicle.Health = 0;
Math.Round(vehicle.Armor, 2);
Math.Round(vehicle.Health, 2);
return new float[] { vehicle.Armor, vehicle.Health, era.Plates };
}
public static float CalculateKEAttenuationSimple(float pierce, float distance, float frictionFactor)
{
float finalEnergy = Math.Exp(-frictionFactor*distance)*pierce;
return finalEnergy;
}
public static float CalculateKEAttenuationRealistic(float pierce, float distance, float frictionK, float mass, float initialVelocity)
{
float finalEnergy = Math.Exp(-2*frictionK*distance/mass)*pierce;
return finalEnergy;
}
/// <summary>
/// Given the mass and initial velocity of a particular projectile,
/// calculate its initial kinetic energy then convert to in-game piercing power value
/// </summary>
public static float CalculateInitialEnergy(float mass, float initialVelocity)
{
float energy = 0.5*mass*initialVelocity*initialVelocity; // KE = 1/2 mv^2
float pierce = energy*Energy2Pierce;
return pierce;
}
}
}