Skip to content

Commit

Permalink
DropPod properties per InfantryType (Phobos-developers#1196)
Browse files Browse the repository at this point in the history
  • Loading branch information
chaserli authored Mar 2, 2024
1 parent e1e0178 commit 230b774
Show file tree
Hide file tree
Showing 15 changed files with 333 additions and 22 deletions.
1 change: 1 addition & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ This page lists all the individual contributions to the project by their author.
- Teleport timer reset after load game fix
- Teleport and Tunnel loco visual tilt fix
- Skip units' turret rotation and jumpjets' wobbling under EMP
- Droppod properties dehardcode
- Misc code refactor & maintenance, CN doc fixes, bugfixes
- **FlyStar**
- Campaign load screen PCX support
Expand Down
2 changes: 2 additions & 0 deletions Phobos.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
<ClCompile Include="src\Misc\TextInput.cpp" />
<ClCompile Include="src\New\Entity\ShieldClass.cpp" />
<ClCompile Include="src\Misc\RetryDialog.cpp" />
<ClCompile Include="src\New\Type\Affiliated\DroppodTypeClass.cpp" />
<ClCompile Include="src\New\Type\DigitalDisplayTypeClass.cpp" />
<ClCompile Include="src\New\Type\RadTypeClass.cpp" />
<ClCompile Include="src\New\Type\ShieldTypeClass.cpp" />
Expand Down Expand Up @@ -200,6 +201,7 @@
<ClInclude Include="src\Misc\PhobosToolTip.h" />
<ClInclude Include="src\Misc\SyncLogging.h" />
<ClInclude Include="src\New\Type\Affiliated\TypeConvertGroup.h" />
<ClInclude Include="src\New\Type\Affiliated\DroppodTypeClass.h" />
<ClInclude Include="src\New\Type\DigitalDisplayTypeClass.h" />
<ClInclude Include="src\New\Type\RadTypeClass.h" />
<ClInclude Include="src\New\Type\ShieldTypeClass.h" />
Expand Down
27 changes: 27 additions & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -1038,3 +1038,30 @@ In `rulesmd.ini`:
[AudioVisual]
SelectionFlashDuration=0 ; integer, number of frames
```

## DropPod

DropPod properties can now be customized on a per-InfantryType basis.
- Note that the DropPod is actually the infantry itself with a different shp image.
- If you want to attach the trailer animation to the pod, set `DropPod.Trailer.Attached` to yes.
- By default LaserTrails that are attached to the infantry will not be drawn if it's on DropPod.
- If you really want to use it, set `DropPodOnly` on the LaserTrail's type entry in art.
- If you want `DropPod.Weapon` to be fired only upon hard landing, set `DropPod.Weapon.HitLandOnly` to true.
- The landing speed is not smaller than it's current height /10 + 2 for unknown reason. A small `DropPod.Speed` value therefore results in exponential deceleration.

In `rulesmd.ini`
```ini
[SOMEINFANTRY]
DropPod.Angle = ; double, default to [General]->DropPodAngle, measured in radians
DropPod.AtmosphereEntry = ; anim, default to [AudioVisual]->AtmosphereEntry
DropPod.GroundAnim = ; 2 anims, default to [General]->DropPod
DropPod.AirImage = ; SHP file, the pod's shape, default to POD
DropPod.Height = ; int, default to [General]->DropPodHeight
DropPod.Puff = ; anim, default to [General]->DropPodPuff
DropPod.Speed = ; int, default to [General]->DropPodSpeed
DropPod.Trailer = ; anim, default to [General]->DropPodTrailer, which by default is SMOKEY
DropPod.Trailer.Attached = ; boolean, default to no
DropPod.Trailer.SpawnDelay = ; int, number of frames between each spawn of DropPod.Trailer, default to 6
DropPod.Weapon = ; weapon, default to [General]->DropPodWeapon
DropPod.Weapon.HitLandOnly = ; boolean, default to no
```
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ New:
- Allow toggling whether or not fire particle systems adjust target coordinates when firer rotates (by Starkku)
- `AmbientDamage` warhead & main target ignore customization (by Starkku)
- Flashing Technos on selecting (by Fryone)
- Customizable DropPod properties on a per-InfantryType basis (by Trsdy)
- Projectile return weapon (by Starkku)
- Allow customizing aircraft landing direction per aircraft or per dock (by Starkku)
Expand Down
9 changes: 9 additions & 0 deletions src/Ext/Rules/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
this->IsVoiceCreatedGlobal.Read(exINI, GameStrings::AudioVisual, "IsVoiceCreatedGlobal");
this->SelectionFlashDuration.Read(exINI, GameStrings::AudioVisual, "SelectionFlashDuration");

Nullable<AnimTypeClass*> droppod_trailer {};
droppod_trailer.Read(exINI, GameStrings::General, "DropPodTrailer");
droppod_trailer = droppod_trailer.Get(AnimTypeClass::Find("SMOKEY")); // Ares convention
if (!droppod_trailer.Get())
this->DropPodTrailer = droppod_trailer.Get();
this->PodImage = FileSystem::LoadSHPFile("POD.SHP");

this->Buildings_DefaultDigitalDisplayTypes.Read(exINI, GameStrings::AudioVisual, "Buildings.DefaultDigitalDisplayTypes");
this->Infantry_DefaultDigitalDisplayTypes.Read(exINI, GameStrings::AudioVisual, "Infantry.DefaultDigitalDisplayTypes");
this->Vehicles_DefaultDigitalDisplayTypes.Read(exINI, GameStrings::AudioVisual, "Vehicles.DefaultDigitalDisplayTypes");
Expand Down Expand Up @@ -277,6 +284,8 @@ void RulesExt::ExtData::Serialize(T& Stm)
.Process(this->Vehicles_DefaultDigitalDisplayTypes)
.Process(this->Aircraft_DefaultDigitalDisplayTypes)
.Process(this->ShowDesignatorRange)
.Process(this->DropPodTrailer)
.Process(this->PodImage)
;
}

Expand Down
4 changes: 4 additions & 0 deletions src/Ext/Rules/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ class RulesExt
Valueable<bool> ShowDesignatorRange;
Valueable<bool> IsVoiceCreatedGlobal;
Valueable<int> SelectionFlashDuration;
AnimTypeClass* DropPodTrailer;
SHPStruct* PodImage;

ExtData(RulesClass* OwnerObject) : Extension<RulesClass>(OwnerObject)
, Storage_TiberiumIndex { -1 }
Expand Down Expand Up @@ -178,6 +180,8 @@ class RulesExt
, Vehicles_DefaultDigitalDisplayTypes {}
, Aircraft_DefaultDigitalDisplayTypes {}
, ShowDesignatorRange { true }
, DropPodTrailer { }
, PodImage { }
{ }

virtual ~ExtData() = default;
Expand Down
39 changes: 35 additions & 4 deletions src/Ext/Techno/Body.Update.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// methods used in TechnoClass_AI hooks or anything similar
#include "Body.h"

#include <SpawnManagerClass.h>
Expand All @@ -9,7 +10,31 @@
#include <Utilities/EnumFunctions.h>
#include <Utilities/AresFunctions.h>

// methods used in TechnoClass_AI hooks or anything similar

// TechnoClass_AI_0x6F9E50
// It's not recommended to do anything more here it could have a better place for performance consideration
void TechnoExt::ExtData::OnEarlyUpdate()
{
auto pType = this->OwnerObject()->GetTechnoType();

// Set only if unset or type is changed
// Notice that Ares may handle type conversion in the same hook here, which is executed right before this one thankfully
if (!this->TypeExtData || this->TypeExtData->OwnerObject() != pType)
this->UpdateTypeData(pType);

this->IsInTunnel = false; // TechnoClass::AI is only called when not in tunnel.

if (this->CheckDeathConditions())
return;

this->ApplyInterceptor();
this->EatPassengers();
this->UpdateShield();
this->ApplySpawnLimitRange();
this->UpdateLaserTrails();
this->DepletedAmmoActions();
}


void TechnoExt::ExtData::ApplyInterceptor()
{
Expand Down Expand Up @@ -454,12 +479,18 @@ void TechnoExt::ExtData::UpdateTypeData(TechnoTypeClass* pCurrentType)

void TechnoExt::ExtData::UpdateLaserTrails()
{
auto const pThis = this->OwnerObject();
auto const pThis = generic_cast<FootClass*>(this->OwnerObject());
if (!pThis)
return;

// LaserTrails update routine is in TechnoClass::AI hook because TechnoClass::Draw
// doesn't run when the object is off-screen which leads to visual bugs - Kerbiter
// LaserTrails update routine is in TechnoClass::AI hook because LaserDrawClass-es are updated in LogicClass::AI
for (auto& trail : this->LaserTrails)
{
// @Kerbiter if you want to limit it to certain locos you do it here
// with vtable check you can avoid the tedious process of Query IPersit/IUnknown Interface, GetClassID, compare with loco GUID, which is omnipresent in vanilla code
if (VTable::Get(pThis->Locomotor.GetInterfacePtr()) != 0x7E8278 && trail.Type->DroppodOnly)
continue;

if (pThis->CloakState == CloakState::Cloaked && !trail.Type->CloakVisible)
continue;

Expand Down
2 changes: 2 additions & 0 deletions src/Ext/Techno/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class TechnoExt
, WHAnimRemainingCreationInterval { 0 }
{ }

void OnEarlyUpdate();

void ApplyInterceptor();
bool CheckDeathConditions(bool isInLimbo = false);
void DepletedAmmoActions();
Expand Down
19 changes: 1 addition & 18 deletions src/Ext/Techno/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,7 @@ DEFINE_HOOK(0x6F9E50, TechnoClass_AI, 0x5)

// Do not search this up again in any functions called here because it is costly for performance - Starkku
auto pExt = TechnoExt::ExtMap.Find(pThis);
auto pType = pThis->GetTechnoType();

// Set only if unset or type is changed
// Notice that Ares may handle type conversion in the same hook here, which is executed right before this one thankfully
if (!pExt->TypeExtData || pExt->TypeExtData->OwnerObject() != pType)
pExt->UpdateTypeData(pType);

pExt->IsInTunnel = false; // TechnoClass::AI is only called when not in tunnel.

if (pExt->CheckDeathConditions())
return 0;

pExt->ApplyInterceptor();
pExt->EatPassengers();
pExt->UpdateShield();
pExt->ApplySpawnLimitRange();
pExt->UpdateLaserTrails();
pExt->DepletedAmmoActions();
pExt->OnEarlyUpdate();

TechnoExt::ApplyMindControlRangeLimit(pThis);

Expand Down
12 changes: 12 additions & 0 deletions src/Ext/TechnoType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,17 @@ void TechnoTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
{
this->InterceptorType.reset();
}

if (this->OwnerObject()->WhatAmI() == AbstractType::InfantryType)
{
if (this->DroppodType == nullptr)
this->DroppodType = std::make_unique<DroppodTypeClass>();
this->DroppodType->LoadFromINI(pINI, pSection);
}
else
{
this->DroppodType.reset();
}
}

template <typename T>
Expand Down Expand Up @@ -571,6 +582,7 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm)
.Process(this->SpawnDistanceFromTarget)
.Process(this->SpawnHeight)
.Process(this->LandingDir)
.Process(this->DroppodType)
;
}
void TechnoTypeExt::ExtData::LoadFromStream(PhobosStreamReader& Stm)
Expand Down
3 changes: 3 additions & 0 deletions src/Ext/TechnoType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <New/Type/Affiliated/InterceptorTypeClass.h>
#include <New/Type/Affiliated/PassengerDeletionTypeClass.h>
#include <New/Type/DigitalDisplayTypeClass.h>
#include <New/Type/Affiliated/DroppodTypeClass.h>

class Matrix3D;

Expand Down Expand Up @@ -52,6 +53,7 @@ class TechnoTypeExt

Valueable<ShieldTypeClass*> ShieldType;
std::unique_ptr<PassengerDeletionTypeClass> PassengerDeletionType;
std::unique_ptr<DroppodTypeClass> DroppodType;

Nullable<int> Ammo_AddOnDeploy;
Valueable<int> Ammo_AutoDeployMinimumAmount;
Expand Down Expand Up @@ -361,6 +363,7 @@ class TechnoTypeExt
, SpawnDistanceFromTarget {}
, SpawnHeight {}
, LandingDir {}
, DroppodType {}
{ }

virtual ~ExtData() = default;
Expand Down
Loading

0 comments on commit 230b774

Please sign in to comment.