Skip to content

Commit ad7a130

Browse files
committed
Implement per-type damage modifiers
1 parent 19a5f44 commit ad7a130

File tree

6 files changed

+114
-6
lines changed

6 files changed

+114
-6
lines changed

CREDITS.md

+1
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,4 @@ This page lists all the individual contributions to the project by their author.
221221
- Implement `CellSpread` and `PercentAtMax`.
222222
- Implement `ScorchChance`, `CraterChance` and `CellAnimChance`.
223223
- Implement `Explosive` for animations.
224+
- Implement `InfantryMultiplier`, `VehicleMultiplier`, `AircraftMultiplier`, `BuildingMultiplier`, `TerrainMultiplier`.

docs/New-Features-and-Enhancements.md

+14
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,20 @@ CellAnimChance=0 ; % or float, the chance that an affected cell will contain a
12211221
CellAnim= ; list of AnimTypes, the list of animation to pick from when a random animation is spawned. Defaults to `[AudioVisual]->OnFire`.
12221222
```
12231223

1224+
### Damage Modifier against types of objects
1225+
1226+
- Vinifera allows specified a broad multiplier to damage against infantry, vehicles, aircraft, buildings and terrain objects.
1227+
1228+
In `RULES.INI`:
1229+
```ini
1230+
[SOMEWARHEAD] ; WarheadType
1231+
InfantryMultiplier=100% ; % or float, modifier applied to damage dealt to infantry by this warhead.
1232+
VehicleMultiplier=100% ; % or float, modifier applied to damage dealt to vehicles by this warhead.
1233+
AircraftMultiplier=100% ; % or float, modifier applied to damage dealt to aircraft by this warhead.
1234+
BuildingMultiplier=100% ; % or float, modifier applied to damage dealt to buildings by this warhead.
1235+
TerrainMultiplier=100% ; % or float, modifier applied to damage dealt to terrain objects by this warhead.
1236+
```
1237+
12241238
### MinDamage
12251239

12261240
- Vinifera allows customizing the minimum damage dealt using a specific warhead.

docs/Whats-New.md

+1
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ New:
172172
- Implement `CellSpread` and `PercentAtMax` (by ZivDero)
173173
- Implement `ScorchChance`, `CraterChance` and `CellAnimChance` (by ZivDero)
174174
- Implement `Explosive` for animations (by ZivDero, Rampastring)
175+
- Implement `InfantryMultiplier`, `VehicleMultiplier`, `AircraftMultiplier`, `BuildingMultiplier`, `TerrainMultiplier` (by ZivDero)
175176

176177

177178
Vanilla fixes:

src/extensions/combat/combatext_hooks.cpp

+68-5
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,12 @@
7373
* 01/01/1995 JLB - Takes into account distance from damage source.
7474
* 04/11/1996 JLB - Changed damage fall-off formula for less damage fall-off.
7575
* ZivDero : Adjustments for Tiberian Sun
76+
*
77+
* @note: Originally, the function took `ArmorType armor` instead of `ObjectClass * target`.
78+
* The single vanilla call site has been patched to take this into account.
79+
*
7680
*/
77-
int Vinifera_Modify_Damage(int damage, WarheadTypeClass* warhead, ArmorType armor, int distance)
81+
int Vinifera_Modify_Damage(int damage, WarheadTypeClass* warhead, ObjectClass * target, int distance)
7882
{
7983
/**
8084
* If there is no raw damage value to start with, then
@@ -83,6 +87,8 @@ int Vinifera_Modify_Damage(int damage, WarheadTypeClass* warhead, ArmorType armo
8387
if (!damage || Scen->SpecialFlags.IsInert || warhead == nullptr)
8488
return 0;
8589

90+
ArmorType armor = target->Class_Of()->Armor;
91+
8692
/**
8793
* Negative damage (i.e., heal) is always applied full strength, but only if the heal
8894
* effect is close enough.
@@ -104,15 +110,42 @@ int Vinifera_Modify_Damage(int damage, WarheadTypeClass* warhead, ArmorType armo
104110
*/
105111
if (warhead_ext->CellSpread < 0.0)
106112
{
107-
108113
/**
109-
* Apply the warhead's modifier to the damage and ensure it's at least MinDamage.
114+
* Apply the warhead's modifier to the damage.
110115
*/
111116
damage *= Verses::Get_Modifier(armor, warhead);
117+
118+
/**
119+
* Apply an extra modifier based on the object's type.
120+
*/
121+
switch (target->RTTI)
122+
{
123+
case RTTI_INFANTRY:
124+
damage *= warhead_ext->InfantryMultiplier;
125+
break;
126+
case RTTI_UNIT:
127+
damage *= warhead_ext->VehicleMultiplier;
128+
break;
129+
case RTTI_AIRCRAFT:
130+
damage *= warhead_ext->AircraftMultiplier;
131+
break;
132+
case RTTI_BUILDING:
133+
damage *= warhead_ext->BuildingMultiplier;
134+
break;
135+
case RTTI_TERRAIN:
136+
damage *= warhead_ext->TerrainMultiplier;
137+
break;
138+
default:
139+
break;
140+
}
141+
142+
/**
143+
* Ensure that the damage is at least MinDamage.
144+
*/
112145
damage = std::max(min_damage, damage);
113146

114147
/**
115-
* Reduce damage according to the distance from the impact point.
148+
* Reduce damage according to the distance from the impact point.
116149
*/
117150
if (damage)
118151
{
@@ -164,9 +197,37 @@ int Vinifera_Modify_Damage(int damage, WarheadTypeClass* warhead, ArmorType armo
164197
damage = std::max(0, damage);
165198

166199
/**
167-
* Apply the warhead's modifier to the damage and ensure it's at least MinDamage.
200+
* Apply the warhead's modifier to the damage.
168201
*/
169202
damage *= Verses::Get_Modifier(armor, warhead);
203+
204+
/**
205+
* Apply an extra modifier based on the object's type.
206+
*/
207+
switch (target->RTTI)
208+
{
209+
case RTTI_INFANTRY:
210+
damage *= warhead_ext->InfantryMultiplier;
211+
break;
212+
case RTTI_UNIT:
213+
damage *= warhead_ext->VehicleMultiplier;
214+
break;
215+
case RTTI_AIRCRAFT:
216+
damage *= warhead_ext->AircraftMultiplier;
217+
break;
218+
case RTTI_BUILDING:
219+
damage *= warhead_ext->BuildingMultiplier;
220+
break;
221+
case RTTI_TERRAIN:
222+
damage *= warhead_ext->TerrainMultiplier;
223+
break;
224+
default:
225+
break;
226+
}
227+
228+
/**
229+
* Ensure that the damage is at least MinDamage.
230+
*/
170231
damage = std::max(min_damage, damage);
171232
}
172233

@@ -717,6 +778,8 @@ DECLARE_PATCH(_Do_Flash_CombatLightSize_Patch)
717778
*/
718779
void CombatExtension_Hooks()
719780
{
781+
Patch_Byte(0x0058604A, 0x56); // push eax -> push esi; Modify_Damage originally takes ArmorType as its argument, we instead pass the target object
782+
720783
Patch_Jump(0x00460477, &_Do_Flash_CombatLightSize_Patch);
721784
Patch_Jump(0x0045EB60, &Vinifera_Modify_Damage);
722785
Patch_Jump(0x0045EEB0, &Vinifera_Explosion_Damage);

src/extensions/warheadtype/warheadtypeext.cpp

+21-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,12 @@ WarheadTypeClassExtension::WarheadTypeClassExtension(const WarheadTypeClass *thi
6161
ScorchChance(0.0f),
6262
CraterChance(0.0f),
6363
CellAnimChance(0.0f),
64-
CellAnim()
64+
CellAnim(),
65+
InfantryMultiplier(1.0f),
66+
VehicleMultiplier(1.0f),
67+
AircraftMultiplier(1.0f),
68+
BuildingMultiplier(1.0f),
69+
TerrainMultiplier(1.0f)
6570
{
6671
//if (this_ptr) EXT_DEBUG_TRACE("WarheadTypeClassExtension::WarheadTypeClassExtension - Name: %s (0x%08X)\n", Name(), (uintptr_t)(This()));
6772

@@ -202,6 +207,15 @@ void WarheadTypeClassExtension::Compute_CRC(WWCRCEngine &crc) const
202207
crc(ShakePixelXLo);
203208
crc(CellSpread);
204209
crc(PercentAtMax);
210+
crc(ScorchChance);
211+
crc(CraterChance);
212+
crc(CellAnimChance);
213+
crc(CellAnim.Count());
214+
crc(InfantryMultiplier);
215+
crc(VehicleMultiplier);
216+
crc(AircraftMultiplier);
217+
crc(BuildingMultiplier);
218+
crc(TerrainMultiplier);
205219
}
206220

207221

@@ -318,6 +332,12 @@ bool WarheadTypeClassExtension::Read_INI(CCINIClass &ini)
318332
CellAnimChance = std::clamp(CellAnimChance, 0.0f, 1.0f);
319333
CellAnim = ini.Get_Anims(ini_name, "CellAnim", CellAnim);
320334

335+
InfantryMultiplier = ini.Get_Float(ini_name, "InfantryMultiplier", InfantryMultiplier);
336+
VehicleMultiplier = ini.Get_Float(ini_name, "VehicleMultiplier", VehicleMultiplier);
337+
AircraftMultiplier = ini.Get_Float(ini_name, "AircraftMultiplier", AircraftMultiplier);
338+
BuildingMultiplier = ini.Get_Float(ini_name, "BuildingMultiplier", BuildingMultiplier);
339+
TerrainMultiplier = ini.Get_Float(ini_name, "TerrainMultiplier", TerrainMultiplier);
340+
321341
IsInitialized = true;
322342

323343
return true;

src/extensions/warheadtype/warheadtypeext.h

+9
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,13 @@ WarheadTypeClassExtension final : public AbstractTypeClassExtension
119119
* The list of anims to pick from when CellAnimChance is triggered.
120120
*/
121121
TypeList<AnimTypeClass*> CellAnim;
122+
123+
/**
124+
* Damage multipliers against various object types.
125+
*/
126+
float InfantryMultiplier;
127+
float VehicleMultiplier;
128+
float AircraftMultiplier;
129+
float BuildingMultiplier;
130+
float TerrainMultiplier;
122131
};

0 commit comments

Comments
 (0)