Skip to content

Spawns Enhancement #1349

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ This page lists all the individual contributions to the project by their author.
- Fix the bug where pathfinding issues occur when a building performs undeploy
- Fix amphibious harvesters can not automatically return to refineries with `WaterBound`
- Fix [EIP 004C2C19](https://modenc.renegadeprojects.com/Internal_Error#eip_004C2C19) concerning the electric bolt
- Fixed `DefaultDisguise` showing wrong house colors for different players
- Fix `DefaultDisguise` showing wrong house colors for different players
- **Apollo** - Translucent SHP drawing patches
- **ststl**:
- Customizable `ShowTimer` priority of superweapons
Expand All @@ -374,6 +374,8 @@ This page lists all the individual contributions to the project by their author.
- Customizable rocker amplitude
- Customizable wake anim
- Initial effort on optimization for crates' random distribution
- Customizable spawns queue
- Initial spawns number
- **Fryone**:
- Customizable ElectricBolt Arcs
- Sound entry on unit's creation
Expand Down Expand Up @@ -411,7 +413,7 @@ This page lists all the individual contributions to the project by their author.
- Type select for buildings (doc)
- Enhanced Bombard trajectory
- Shield armor inheritance customization
- Fixed `DefaultDisguise` showing wrong house colors for different players
- Fix `DefaultDisguise` showing wrong house colors for different players
- **NaotoYuuki** - Vertical & meteor trajectory projectile prototypes
- **handama** - AI script action to `16005 Jump Back To Previous Script`
- **TaranDahl (航味麻酱)**:
Expand Down
21 changes: 21 additions & 0 deletions docs/New-or-Enhanced-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,18 @@ OpenTopped.AllowFiringIfDeactivated=true ; boolean
OpenTopped.ShareTransportTarget=true ; boolean
```

### Customizable spawns queue
- It is now possible to spawn multiple types of spawnees from a spawner with `Spawns.Queue`. The order of spawnees in this queue is the order of their respawn.
- `Spawns` still needs to be set to enable the spawner logic and act as a default spawnee.
- `SpawnsNumber` still needs to be set to determine the amount of spawnee slots.
- If the length of the queue is longer than the spawner's `SpawnsNumber`, spawnee after this length will be omitted. If the length is shorter however, the rest of the positions will be filled by the spawnee defined by `Spawns`. Hence, it's recommended to make them the same.

In `rulesmd.ini`:
```ini
[SOMETECHNO] ; TechnoType
Spawns.Queue= ; list of aircrafts in order
```

### Disabling fallback to (Elite)Secondary weapon

- It is now possible to disable the fallback to `(Elite)Secondary` weapon from `(Elite)Primary` weapon if it cannot fire at the chosen target by setting `NoSecondaryWeaponFallback` to true (defaults to false). `NoSecondaryWeaponFallback.AllowAA` controls whether or not fallback because of projectile `AA` setting and target being in air is still allowed. This does not apply to special cases where `(Elite)Secondary` weapon is always chosen, including but not necessarily limited to the following:
Expand Down Expand Up @@ -1336,6 +1348,15 @@ ForceWeapon.Cloaked=-1 ; integer. 0 for primary weapon, 1 for secondary
ForceWeapon.Disguised=-1 ; integer. 0 for primary weapon, 1 for secondary weapon, -1 to disable
```

### Initial spawns number
- It is now possible to set the initial amount of spawnees for a spawner, instead of always being filled. Won't work if it's larger than `SpawnsNumber`.

In `rulesmd.ini`:
```ini
[SOMETECHNO] ; TechnoType
InitialSpawnsNumber= ; integer
```

### Initial strength for TechnoTypes and cloned infantry

![image](_static/images/initialstrength.cloning-01.png)
Expand Down
2 changes: 2 additions & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ New:
- Technos recount current burst index when change the firing weapon (by CrimRecya)
- Shield armor inheritance customization (by Ollerus)
- Damaged unit image changes (by Fryone)
- Customizable spawns queue (by TwinkleStar)
- Initial spawns number (by TwinkleStar)

Vanilla fixes:
- Prevent the units with locomotors that cause problems from entering the tank bunker (by TaranDahl)
Expand Down
53 changes: 53 additions & 0 deletions src/Ext/Techno/Hooks.Misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,59 @@ DEFINE_HOOK(0x6B7600, SpawnManagerClass_AI_InitDestination, 0x6)
return R->Origin() == 0x6B7600 ? SkipGameCode1 : SkipGameCode2;
}

DEFINE_HOOK(0x6B6D44, SpawnManagerClass_Init_Spawns, 0x5)
{
enum { Jump = 0x6B6DF0, Change = 0x6B6D53, Continue = 0 };
GET(SpawnManagerClass*, pThis, ESI);
GET_STACK(size_t, i, STACK_OFFSET(0x1C, 0x4));

auto const pTypeExt = TechnoTypeExt::ExtMap.Find(pThis->Owner->GetTechnoType());

if ((int) i >= pTypeExt->InitialSpawnsNumber.Get(pThis->SpawnCount))
{
GET(SpawnControl*, pControl, EBP);
pControl->Unit = nullptr;
pControl->SpawnTimer.Start(pThis->RegenRate);
pControl->Status = SpawnNodeStatus::Dead;
pThis->SpawnedNodes.AddItem(pControl);
return Jump;
}

if (pTypeExt->Spawns_Queue.size() <= i || !pTypeExt->Spawns_Queue[i])
return Continue;

R->EAX(pTypeExt->Spawns_Queue[i]->CreateObject(pThis->Owner->GetOwningHouse()));
return Change;
}

DEFINE_HOOK(0x6B78D3, SpawnManagerClass_Update_Spawns, 0x6)
{
GET(SpawnManagerClass*, pThis, ESI);

auto const pTypeExt = TechnoTypeExt::ExtMap.Find(pThis->Owner->GetTechnoType());

if (pTypeExt->Spawns_Queue.empty())
return 0;

std::vector<AircraftTypeClass*> vec = pTypeExt->Spawns_Queue;

for (auto pNode : pThis->SpawnedNodes)
{
if (pNode->Unit)
{
auto it = std::find_if(vec.begin(), vec.end(), [=](auto pType) { return pType == pNode->Unit->GetTechnoType(); });
if (it != vec.end())
vec.erase(it);
}
}

if (vec.empty() || !vec[0])
return 0;

R->EAX(vec[0]->CreateObject(pThis->Owner->GetOwningHouse()));
return 0x6B78EA;
}

DEFINE_HOOK(0x6B7282, SpawnManagerClass_AI_PromoteSpawns, 0x5)
{
GET(SpawnManagerClass*, pThis, ESI);
Expand Down
8 changes: 7 additions & 1 deletion src/Ext/TechnoType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,9 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
this->WaterImage_ConditionYellow.Read(exINI, pSection, "WaterImage.ConditionYellow");
this->WaterImage_ConditionRed.Read(exINI, pSection, "WaterImage.ConditionRed");

this->InitialSpawnsNumber.Read(exINI, pSection, "InitialSpawnsNumber");
this->Spawns_Queue.Read(exINI, pSection, "Spawns.Queue");

// Ares 0.2
this->RadarJamRadius.Read(exINI, pSection, "RadarJamRadius");

Expand Down Expand Up @@ -884,10 +887,13 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm)

.Process(this->Power)

.Process(this->Image_ConditionYellow)
.Process(this->Image_ConditionYellow)
.Process(this->Image_ConditionRed)
.Process(this->WaterImage_ConditionYellow)
.Process(this->WaterImage_ConditionRed)

.Process(this->InitialSpawnsNumber)
.Process(this->Spawns_Queue)
;
}
void TechnoTypeExt::ExtData::LoadFromStream(PhobosStreamReader& Stm)
Expand Down
10 changes: 8 additions & 2 deletions src/Ext/TechnoType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,11 +256,14 @@ class TechnoTypeExt

Valueable<int> Power;

Nullable<UnitTypeClass*> Image_ConditionYellow;
Nullable<UnitTypeClass*> Image_ConditionYellow;
Nullable<UnitTypeClass*> Image_ConditionRed;
Nullable<UnitTypeClass*> WaterImage_ConditionYellow;
Nullable<UnitTypeClass*> WaterImage_ConditionRed;

Nullable<int> InitialSpawnsNumber;
ValueableVector<AircraftTypeClass*> Spawns_Queue;

struct LaserTrailDataEntry
{
ValueableIdx<LaserTrailTypeClass> idxType;
Expand Down Expand Up @@ -510,10 +513,13 @@ class TechnoTypeExt

, Power { }

, Image_ConditionYellow { }
, Image_ConditionYellow { }
, Image_ConditionRed { }
, WaterImage_ConditionYellow { }
, WaterImage_ConditionRed { }

, InitialSpawnsNumber { }
, Spawns_Queue { }
{ }

virtual ~ExtData() = default;
Expand Down