Skip to content

Commit

Permalink
WIP Techno Attachment logic
Browse files Browse the repository at this point in the history
Implement ParentDestructionMission & ParentDetachmentMission


"Fixed" chronowarping children

Add children skip for ChronoWarp

Rewritten and fixed a hook


Loop over attachment AI separately from other AI routines
  • Loading branch information
Metadorius committed Nov 11, 2021
1 parent 3eb18e7 commit cf33e39
Show file tree
Hide file tree
Showing 16 changed files with 799 additions and 7 deletions.
6 changes: 6 additions & 0 deletions Phobos.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
<ClCompile Include="src\New\Type\RadTypeClass.cpp" />
<ClCompile Include="src\New\Type\ShieldTypeClass.cpp" />
<ClCompile Include="src\New\Type\LaserTrailTypeClass.cpp" />
<ClCompile Include="src\New\Type\AttachmentTypeClass.cpp" />
<ClCompile Include="src\New\Entity\LaserTrailClass.cpp" />
<ClCompile Include="src\New\Entity\AttachmentClass.cpp" />
<ClCompile Include="src\Ext\Aircraft\Body.cpp" />
<ClCompile Include="src\Ext\Aircraft\Hooks.cpp" />
<ClCompile Include="src\Ext\AnimType\Body.cpp" />
Expand Down Expand Up @@ -66,6 +68,7 @@
<ClCompile Include="src\Ext\TechnoType\Hooks.cpp" />
<ClCompile Include="src\Ext\Techno\Body.cpp" />
<ClCompile Include="src\Ext\Techno\Hooks.cpp" />
<ClCompile Include="src\Ext\Techno\Hooks.TechnoAttachment.cpp" />
<ClCompile Include="src\Ext\TerrainType\Body.cpp" />
<ClCompile Include="src\Ext\TerrainType\Hooks.cpp" />
<ClCompile Include="src\Ext\Unit\Hooks.DisallowMoving.cpp" />
Expand All @@ -75,6 +78,7 @@
<ClCompile Include="src\Ext\WeaponType\Hook.EBolt.cpp" />
<ClCompile Include="src\Ext\WeaponType\Hooks.cpp" />
<ClCompile Include="src\Ext\WeaponType\Hooks.DiskLaserRadius.cpp" />
<ClCompile Include="src\Misc\Hooks.AI.cpp" />
<ClCompile Include="src\Misc\Hooks.Blowfish.cpp" />
<ClCompile Include="src\Misc\Hooks.INIClass.cpp" />
<ClCompile Include="src\Misc\Hooks.Savegame.cpp" />
Expand Down Expand Up @@ -117,7 +121,9 @@
<ClInclude Include="src\New\Type\RadTypeClass.h" />
<ClInclude Include="src\New\Type\ShieldTypeClass.h" />
<ClInclude Include="src\New\Type\LaserTrailTypeClass.h" />
<ClInclude Include="src\New\Type\AttachmentTypeClass.h" />
<ClInclude Include="src\New\Entity\LaserTrailClass.h" />
<ClInclude Include="src\New\Entity\AttachmentClass.h" />
<ClInclude Include="src\Utilities\Enumerable.h" />
<ClInclude Include="src\ExtraHeaders\ArmorType.h" />
<ClInclude Include="src\Ext\Aircraft\Body.h" />
Expand Down
2 changes: 2 additions & 0 deletions src/Ext/Rules/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <New/Type/RadTypeClass.h>
#include <New/Type/ShieldTypeClass.h>
#include <New/Type/LaserTrailTypeClass.h>
#include <New/Type/AttachmentTypeClass.h>

template<> const DWORD Extension<RulesClass>::Canary = 0x12341234;
std::unique_ptr<RulesExt::ExtData> RulesExt::Data = nullptr;
Expand All @@ -32,6 +33,7 @@ void RulesExt::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
{
RadTypeClass::LoadFromINIList(pINI);
ShieldTypeClass::LoadFromINIList(pINI);
AttachmentTypeClass::LoadFromINIList(pINI);

Data->LoadBeforeTypeData(pThis, pINI);
}
Expand Down
97 changes: 96 additions & 1 deletion src/Ext/Techno/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <Unsorted.h>

#include <Ext/BulletType/Body.h>
#include <Ext/WeaponType/Body.h>

template<> const DWORD Extension<TechnoClass>::Canary = 0x55555555;
TechnoExt::ExtContainer TechnoExt::ExtMap;
Expand Down Expand Up @@ -214,7 +215,7 @@ void TechnoExt::InitializeLaserTrails(TechnoClass* pThis)
{
for (auto const& entry: pTypeExt->LaserTrailData)
{
if (auto const pLaserType = LaserTrailTypeClass::Array[entry.idxType].get())
if (auto const pLaserType = LaserTrailTypeClass::Array[entry.Type].get())
{
pExt->LaserTrails.push_back(std::make_unique<LaserTrailClass>(
pLaserType, pThis->Owner, entry.FLH, entry.IsOnTurret));
Expand Down Expand Up @@ -371,6 +372,100 @@ void TechnoExt::EatPassengers(TechnoClass* pThis)
}
}

bool TechnoExt::AttachmentAI(TechnoClass* pThis)
{
auto const pExt = TechnoExt::ExtMap.Find(pThis);
// auto const pTypeExt = TechnoTypeExt::ExtMap.Find(pThis->GetTechnoType());

if (pExt && pExt->ParentAttachment)
{
pExt->ParentAttachment->AI();
return true;
}

return false;
}

// Attaches this techno in a first available attachment "slot".
// Returns true if the attachment is successful.
bool TechnoExt::AttachTo(TechnoClass* pThis, TechnoClass* pParent)
{
auto const pParentExt = TechnoExt::ExtMap.Find(pParent);

for (auto const& pAttachment: pParentExt->ChildAttachments)
{
if (pAttachment->AttachChild(pThis))
return true;
}

return false;
}

bool TechnoExt::DetachFromParent(TechnoClass* pThis, bool isForceDetachment)
{
auto const pExt = TechnoExt::ExtMap.Find(pThis);
return pExt->ParentAttachment->DetachChild(isForceDetachment);
}

void TechnoExt::InitializeAttachments(TechnoClass* pThis)
{
auto const pExt = TechnoExt::ExtMap.Find(pThis);
auto const pType = pThis->GetTechnoType();
auto const pTypeExt = TechnoTypeExt::ExtMap.Find(pType);

for (auto& entry : pTypeExt->AttachmentData)
{
pExt->ChildAttachments.push_back(std::make_unique<AttachmentClass>(&entry, pThis, nullptr));
pExt->ChildAttachments.back()->Initialize();
}
}

void TechnoExt::HandleHostDestruction(TechnoClass* pThis)
{
auto const pExt = TechnoExt::ExtMap.Find(pThis);
for (auto const& pAttachment: pExt->ChildAttachments)
pAttachment->Uninitialize();
}

void TechnoExt::UnlimboAttachments(TechnoClass* pThis)
{
auto const pExt = TechnoExt::ExtMap.Find(pThis);
for (auto const& pAttachment: pExt->ChildAttachments)
pAttachment->Unlimbo();
}

void TechnoExt::LimboAttachments(TechnoClass* pThis)
{
auto const pExt = TechnoExt::ExtMap.Find(pThis);
for (auto const& pAttachment: pExt->ChildAttachments)
pAttachment->Limbo();
}

bool TechnoExt::IsParentOf(TechnoClass* pThis, TechnoClass* pOtherTechno)
{
auto const pExt = TechnoExt::ExtMap.Find(pThis);

if (!pOtherTechno)
return false;

for (auto const& pAttachment: pExt->ChildAttachments)
{
if (pAttachment->Child &&
(pAttachment->Child == pOtherTechno ||
TechnoExt::IsParentOf(pAttachment->Child, pOtherTechno)))
{
return true;
}
}

return false;
}

void TechnoExt::FireWeaponAtSelf(TechnoClass* pThis, WeaponTypeClass* pWeaponType)
{
WeaponTypeExt::DetonateAt(pWeaponType, pThis, pThis);
}

// =============================
// load / save

Expand Down
19 changes: 19 additions & 0 deletions src/Ext/Techno/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <New/Entity/ShieldClass.h>
#include <New/Entity/LaserTrailClass.h>
#include <New/Entity/AttachmentClass.h>

class BulletClass;

Expand All @@ -25,13 +26,18 @@ class TechnoExt
Valueable<bool> LastKillWasTeamTarget;
TimerStruct PassengerDeletionTimer;

AttachmentClass* ParentAttachment;
ValueableVector<std::unique_ptr<AttachmentClass>> ChildAttachments;

ExtData(TechnoClass* OwnerObject) : Extension<TechnoClass>(OwnerObject)
, InterceptedBullet(nullptr)
, Shield()
, LaserTrails()
, ReceiveDamage(false)
, LastKillWasTeamTarget(false)
, PassengerDeletionTimer(-1)
, ParentAttachment()
, ChildAttachments()
{ }

virtual ~ExtData() = default;
Expand Down Expand Up @@ -73,6 +79,19 @@ class TechnoExt

static CoordStruct GetBurstFLH(TechnoClass* pThis, int weaponIndex, bool& FLHFound);

static bool AttachmentAI(TechnoClass* pThis);
static bool AttachTo(TechnoClass* pThis, TechnoClass* pParent);
static bool DetachFromParent(TechnoClass* pThis, bool force = false);

static void InitializeAttachments(TechnoClass* pThis);
static void HandleHostDestruction(TechnoClass* pThis);
static void UnlimboAttachments(TechnoClass* pThis);
static void LimboAttachments(TechnoClass* pThis);

static bool IsParentOf(TechnoClass* pThis, TechnoClass* pOtherTechno);

static void FireWeaponAtSelf(TechnoClass* pThis, WeaponTypeClass* pWeaponType);

static void TransferMindControlOnDeploy(TechnoClass* pTechnoFrom, TechnoClass* pTechnoTo);

static void ApplyMindControlRangeLimit(TechnoClass* pThis);
Expand Down
2 changes: 2 additions & 0 deletions src/Ext/Techno/Hooks.Shield.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ DEFINE_HOOK(0x6F9E50, TechnoClass_AI_Shield, 0x5)
DEFINE_HOOK(0x71A88D, TemporalClass_AI_Shield, 0x0)
{
GET(TemporalClass*, pThis, ESI);

// Shield logic
if (auto const pTarget = pThis->Target)
{
const auto pExt = TechnoExt::ExtMap.Find(pTarget);
Expand Down
102 changes: 102 additions & 0 deletions src/Ext/Techno/Hooks.TechnoAttachment.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "Body.h"

#include <Ext/TechnoType/Body.h>

DEFINE_HOOK(0x4DA86E, FootClass_AI_UpdateAttachedLocomotion, 0x0)
{
GET(FootClass* const, pThis, ESI);
auto const pExt = TechnoExt::ExtMap.Find(pThis);

if (!pExt->ParentAttachment)
pThis->Locomotor->Process();

return 0x4DA87A;
}

DEFINE_HOOK(0x710460, TechnoClass_Destroy_HandleAttachments, 0x6)
{
GET(TechnoClass*, pThis, ECX);

TechnoExt::HandleHostDestruction(pThis);

auto const pExt = TechnoExt::ExtMap.Find(pThis);
if (pExt->ParentAttachment)
pExt->ParentAttachment->ChildDestroyed();

pExt->ParentAttachment = nullptr;

return 0;
}

DEFINE_HOOK(0x6F6F20, TechnoClass_Unlimbo_UnlimboAttachments, 0x6)
{
GET(TechnoClass*, pThis, ESI);

TechnoExt::UnlimboAttachments(pThis);

return 0;
}

DEFINE_HOOK(0x6F6B1C, TechnoClass_Limbo_LimboAttachments, 0x6)
{
GET(TechnoClass*, pThis, ESI);

TechnoExt::LimboAttachments(pThis);

return 0;
}

DEFINE_HOOK(0x73F528, UnitClass_CanEnterCell_SkipChildren, 0x0)
{
enum { IgnoreOccupier = 0x73FC10, Continue = 0x73F530 };

GET(UnitClass*, pThis, EBX);
GET(TechnoClass*, pOccupier, ESI);

if (pThis == pOccupier || TechnoExt::IsParentOf(pThis, pOccupier))
return IgnoreOccupier;

return Continue;
}

DEFINE_HOOK(0x51C251, InfantryClass_CanEnterCell_SkipChildren, 0x0)
{
enum { IgnoreOccupier = 0x51C70F, Continue = 0x51C259 };

GET(InfantryClass*, pThis, EBP);
GET(TechnoClass*, pOccupier, ESI);

if ((TechnoClass*)pThis == pOccupier || TechnoExt::IsParentOf((TechnoClass*)pThis, pOccupier))
return IgnoreOccupier;

return Continue;
}

DEFINE_HOOK(0x6CC763, SuperClass_Place_ChronoWarp_SkipChildren, 0x6)
{
enum { Skip = 0x6CCCCA, Continue = 0 };

GET(FootClass* const, pFoot, ESI);
auto const pExt = TechnoExt::ExtMap.Find(pFoot);

return pExt->ParentAttachment ? Skip : Continue;
}

// DEFINE_HOOK(0x6CCCCA, SuperClass_Place_ChronoWarp_HandleAttachment, 0x0)
// {
// enum { Loop = 0x6CC742, Break = 0x6CCCD5 };
//
// GET(FootClass*, pFoot, ESI)
//
// pFoot = abstract_cast<FootClass*>(pFoot->NextObject);
//
// return pFoot ? Loop : Break;
// }

// TODO
// 0x4DEAE0 IC for footclass
// 0x457C90 IC (forceshield) for buildings
// 0x6CCCCA Chrono Warp
// 0x4694BB Temporal warhead
// 0x4696FB Locomotor warhead
// ...
3 changes: 2 additions & 1 deletion src/Ext/Techno/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ DEFINE_HOOK(0x6F9E50, TechnoClass_AI, 0x5)
}


DEFINE_HOOK(0x6F42F7, TechnoClass_Init_SetLaserTrails, 0x2)
DEFINE_HOOK(0x6F42F7, TechnoClass_Init, 0x2)
{
GET(TechnoClass*, pThis, ESI);

TechnoExt::InitializeLaserTrails(pThis);
TechnoExt::InitializeAttachments(pThis);

return 0;
}
Expand Down
Loading

0 comments on commit cf33e39

Please sign in to comment.