Skip to content

Commit 1f842e1

Browse files
authored
[Vanilla Enhancement] Customizable spawn delay of VoxelAnim's TrailerAnim and fix its incorrect position (#1722)
- Fixed the issue of incorrect position of `TrailerAnim` in `VoxelAnim`. --- - You can now customize the generation interval of VoxelAnim's trailer animation In `rulesmd.ini`: ```ini [SOMEVOXELANIM] ; VoxelAnimType Trailer.SpawnDelay=2 ; integer, game frames ```
1 parent f64c5f5 commit 1f842e1

File tree

9 files changed

+69
-21
lines changed

9 files changed

+69
-21
lines changed

CREDITS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,7 @@ This page lists all the individual contributions to the project by their author.
491491
- Exclusive SuperWeapon Sidebar
492492
- Fix an issue that the widespread damage caused by detonation on the bridge/ground cannot affect objects on the ground/bridge who are in the opposite case
493493
- Several new Infotypes, no display in specific status and a new single frame display method
494+
- Customizable spawn delay of `VoxelAnim`'s `TrailerAnim` and fix its incorrect position
494495
- **Ollerus**:
495496
- Build limit group enhancement
496497
- Customizable rocker amplitude

docs/Fixed-or-Improved-Logics.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
233233
- Fixed the issue that the widespread damage caused by detonation on the bridge/ground cannot affect objects on the ground/bridge who are in the opposite case.
234234
- Fixed the bug that `DamageSelf` and `AllowDamageOnSelf` are ineffective on airforce.
235235
- Fixed the bug that damaged particle dont disappear after building has repaired by engineer.
236+
- Fixed the issue of incorrect position of `TrailerAnim` in `VoxelAnim`.
236237

237238
## Fixes / interactions with other extensions
238239

@@ -1793,6 +1794,16 @@ UseWeeds.ReadinessAnimationPercentage=0.9 ; double - when this many weeds
17931794

17941795
- The INI keys and behaviour is mostly identical to the [equivalent behaviour available to regular animations](#customizable-debris--meteor-impact-and-warhead-detonation-behaviour). Main difference is that the keys must be listed in the VoxelAnim's entry in `rulesmd.ini`, not `artmd.ini`.
17951796

1797+
### Customizable debris trailer anim spawn delay
1798+
1799+
- You can now customize the generation interval of VoxelAnim's trailer animation
1800+
1801+
In `rulesmd.ini`:
1802+
```ini
1803+
[SOMEVOXELANIM] ; VoxelAnimType
1804+
Trailer.SpawnDelay=2 ; integer, game frames
1805+
```
1806+
17961807
## Warheads
17971808

17981809
### Allowing damage dealt to firer

docs/Whats-New.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ New:
394394
- Targeting limitation for berzerk technos (by TaranDahl)
395395
- Allowed faking digital display for `InfoType=Health` at disguise (by Ollerus)
396396
- [Customize limit and sound when engineer repair a building](New-or-Enhanced-Logics.md#engineer-repair-customization) (by NetsuNegi)
397+
- Customizable debris trailer anim spawn delay (by CrimRecya)
397398
398399
Vanilla fixes:
399400
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)
@@ -420,6 +421,7 @@ Vanilla fixes:
420421
- Fixed the issue that the widespread damage caused by detonation on the bridge/ground cannot affect objects on the ground/bridge who are in the opposite case (by CrimRecya)
421422
- Fixed the bug that `DamageSelf` and `AllowDamageOnSelf` are ineffective on airforce (by NetsuNegi)
422423
- Fixed the bug that damaged particle dont disappear after building has repaired by engineer (by NetsuNegi)
424+
- Fixed the issue of incorrect position of `TrailerAnim` in `VoxelAnim` (by CrimRecya)
423425
424426
Phobos fixes:
425427
- Fixed the bug that `AllowAirstrike=no` cannot completely prevent air strikes from being launched against it (by NetsuNegi)

src/Ext/VoxelAnim/Body.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ template <typename T>
2929
void VoxelAnimExt::ExtData::Serialize(T& Stm)
3030
{
3131
Stm
32-
.Process(LaserTrails)
32+
.Process(this->LaserTrails)
33+
.Process(this->TrailerSpawnTimer)
3334
;
3435
}
3536

src/Ext/VoxelAnim/Body.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ class VoxelAnimExt
2525
public:
2626

2727
std::vector<LaserTrailClass> LaserTrails;
28+
CDTimerClass TrailerSpawnTimer;
2829

2930
ExtData(VoxelAnimClass* OwnerObject) : Extension<VoxelAnimClass>(OwnerObject)
3031
, LaserTrails()
32+
, TrailerSpawnTimer()
3133
{ }
3234

3335
virtual ~ExtData() = default;

src/Ext/VoxelAnim/Hooks.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,6 @@ DEFINE_HOOK(0x74A027, VoxelAnimClass_AI_Expired, 0x6)
4141
GET(int, flag, EAX);
4242

4343
bool heightFlag = flag & 0xFF;
44-
45-
if (!pThis || !pThis->Type)
46-
return SkipGameCode;
47-
4844
auto const pType = pThis->Type;
4945
auto const pTypeExt = VoxelAnimTypeExt::ExtMap.Find(pType);
5046
auto const splashAnims = pTypeExt->SplashAnims.GetElements(RulesClass::Instance->SplashList);
@@ -54,3 +50,26 @@ DEFINE_HOOK(0x74A027, VoxelAnimClass_AI_Expired, 0x6)
5450

5551
return SkipGameCode;
5652
}
53+
54+
DEFINE_HOOK(0x74A70E, VoxelAnimClass_AI_Trailer, 0x6)
55+
{
56+
enum { SkipGameCode = 0x74A7AB };
57+
58+
GET(VoxelAnimClass* const, pThis, EBX);
59+
60+
const auto pType = pThis->Type;
61+
62+
if (const auto pAnimType = pType->TrailerAnim)
63+
{
64+
auto pExt = VoxelAnimExt::ExtMap.Find(pThis);
65+
66+
if (pExt->TrailerSpawnTimer.Expired())
67+
{
68+
pExt->TrailerSpawnTimer.Start(VoxelAnimTypeExt::ExtMap.Find(pType)->Trailer_SpawnDelay.Get());
69+
auto const pTrailerAnim = GameCreate<AnimClass>(pAnimType, pThis->Location, 1, 1);
70+
AnimExt::SetAnimOwnerHouseKind(pTrailerAnim, pThis->OwnerHouse, nullptr, false, true);
71+
}
72+
}
73+
74+
return SkipGameCode;
75+
}

src/Ext/VoxelAnimType/Body.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ void VoxelAnimTypeExt::ExtData::LoadFromINIFile(CCINIClass* pINI)
1616
this->WakeAnim.Read(exINI, pID, "WakeAnim");
1717
this->SplashAnims.Read(exINI, pID, "SplashAnims");
1818
this->SplashAnims_PickRandom.Read(exINI, pID, "SplashAnims.PickRandom");
19+
this->Trailer_SpawnDelay.Read(exINI, pID, "Trailer.SpawnDelay");
1920
}
2021

2122
// =============================
@@ -30,6 +31,7 @@ void VoxelAnimTypeExt::ExtData::Serialize(T& Stm)
3031
.Process(this->WakeAnim)
3132
.Process(this->SplashAnims)
3233
.Process(this->SplashAnims_PickRandom)
34+
.Process(this->Trailer_SpawnDelay)
3335
;
3436
}
3537

src/Ext/VoxelAnimType/Body.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class VoxelAnimTypeExt
2828
Valueable<AnimTypeClass*> WakeAnim;
2929
NullableVector<AnimTypeClass*> SplashAnims;
3030
Valueable<bool> SplashAnims_PickRandom;
31+
Valueable<int> Trailer_SpawnDelay;
3132

3233
ExtData(VoxelAnimTypeClass* OwnerObject) : Extension<VoxelAnimTypeClass>(OwnerObject)
3334
, LaserTrail_Types()
@@ -36,6 +37,7 @@ class VoxelAnimTypeExt
3637
, WakeAnim {}
3738
, SplashAnims {}
3839
, SplashAnims_PickRandom { false }
40+
, Trailer_SpawnDelay { 2 }
3941
{ }
4042

4143
virtual ~ExtData() = default;

src/Misc/Hooks.BugFixes.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -125,45 +125,53 @@ DEFINE_HOOK(0x702299, TechnoClass_ReceiveDamage_DebrisMaximumsFix, 0xA)
125125
{
126126
GET(TechnoClass* const, pThis, ESI);
127127

128-
auto pType = pThis->GetTechnoType();
128+
const auto pType = pThis->GetTechnoType();
129129

130-
// If DebrisMaximums has one value, then legacy behavior is used
130+
// Jun12,2025 - CrimRecya : I think there is no need to return to the unreasonable vanilla logic
131+
// Otherwise, they should be in a parallel relationship rather than a sequential relationship
132+
/* // If DebrisMaximums has one value, then legacy behavior is used
131133
if (pType->DebrisMaximums.Count == 1 &&
132134
pType->DebrisMaximums.GetItem(0) > 0 &&
133135
pType->DebrisTypes.Count > 0)
134136
{
135137
return 0;
136-
}
138+
}*/
139+
140+
// Removed -1 from the MaxDebris
141+
int totalSpawnAmount = ScenarioClass::Instance->Random.RandomRanged(pType->MinDebris, pType->MaxDebris);
137142

138-
auto totalSpawnAmount = ScenarioClass::Instance->Random.RandomRanged(
139-
pType->MinDebris, pType->MaxDebris);
143+
const auto& debrisTypes = pType->DebrisTypes;
144+
const auto& debrisMaximums = pType->DebrisMaximums;
140145

141-
if (pType->DebrisTypes.Count > 0 && pType->DebrisMaximums.Count > 0)
146+
// Make DebrisTypes generate completely in accordance with DebrisMaximums,
147+
// without continuously looping until it exceeds totalSpawnAmount
148+
if (debrisTypes.Count > 0 && debrisMaximums.Count > 0)
142149
{
143-
auto cord = pThis->GetCoords();
144-
for (int currentIndex = 0; currentIndex < pType->DebrisTypes.Count; ++currentIndex)
150+
auto coord = pThis->GetCoords();
151+
152+
for (int currentIndex = 0; currentIndex < debrisMaximums.Count; ++currentIndex)
145153
{
146-
if (pType->DebrisMaximums.GetItem(currentIndex) > 0)
154+
const int currentMaxDebris = debrisMaximums.GetItem(currentIndex);
155+
156+
if (currentMaxDebris > 0)
147157
{
148-
int adjustedMaximum = Math::min(pType->DebrisMaximums.GetItem(currentIndex), pType->MaxDebris);
149-
int amountToSpawn = abs(ScenarioClass::Instance->Random.Random()) % (adjustedMaximum + 1); //0x702337
158+
const int adjustedMaximum = Math::min(currentMaxDebris, pType->MaxDebris);
159+
int amountToSpawn = std::abs(ScenarioClass::Instance->Random.Random()) % (adjustedMaximum + 1); // 0x702337
150160
amountToSpawn = Math::min(amountToSpawn, totalSpawnAmount);
151161
totalSpawnAmount -= amountToSpawn;
152162

153-
for (; amountToSpawn > 0; --amountToSpawn)
163+
for ( ; amountToSpawn > 0; --amountToSpawn)
154164
{
155-
GameCreate<VoxelAnimClass>(pType->DebrisTypes.GetItem(currentIndex),
156-
&cord, pThis->Owner);
165+
GameCreate<VoxelAnimClass>(debrisTypes.GetItem(currentIndex), &coord, pThis->Owner);
157166
}
158167

159-
if (totalSpawnAmount < 1)
168+
if (totalSpawnAmount <= 0)
160169
break;
161170
}
162171
}
163172
}
164173

165174
R->EBX(totalSpawnAmount);
166-
167175
return 0x7023E5;
168176
}
169177

0 commit comments

Comments
 (0)