Skip to content
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
3 changes: 3 additions & 0 deletions Phobos.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
<ClCompile Include="src\Ext\WarheadType\Detonate.cpp" />
<ClCompile Include="src\Ext\Techno\Hooks.Shield.cpp" />
<ClCompile Include="src\Ext\Techno\Hooks.Grinding.cpp" />
<ClCompile Include="src\Ext\Tiberium\Body.cpp" />
<ClCompile Include="src\Ext\Tiberium\Hooks.cpp" />
<ClCompile Include="src\Ext\VoxelAnimType\Body.cpp" />
<ClCompile Include="src\Ext\VoxelAnim\Body.cpp" />
<ClCompile Include="src\Ext\VoxelAnim\Hooks.cpp" />
Expand Down Expand Up @@ -144,6 +146,7 @@
<ClInclude Include="src\Ext\TechnoType\Body.h" />
<ClInclude Include="src\Ext\Techno\Body.h" />
<ClInclude Include="src\Ext\TerrainType\Body.h" />
<ClInclude Include="src\Ext\Tiberium\Body.h" />
<ClInclude Include="src\Ext\VoxelAnimType\Body.h" />
<ClInclude Include="src\Ext\VoxelAnim\Body.h" />
<ClInclude Include="src\Ext\WeaponType\Body.h" />
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ Credits
- **ChrisLv_CN** - interceptor logic, LaserTrails, laser fixes, general assistance (work relicensed under [following permission](images/ChrisLv-relicense.png))
- **Xkein** - general assistance, YRpp edits
- **thomassneddon** - general assistance
- **Starkku** - Warhead shield penetration & breaking, strafing aircraft weapon customization, vehicle DeployFire fixes/improvements, stationary VehicleTypes, Burst logic improvements, TechnoType auto-firing weapons, Secondary weapon fallback customization, weapon target type filtering, AreaFire targeting customization, CreateUnit improvements, Attached animation & jumpjet unit layer customization, IsSimpleDeployer improvements, Shield modification warheads, Warhead decloaking toggle, Warp(In/Out)Weapon, Grinder improvements / additions, Attached animation position customization, Critical hit logic additions, Aircraft & jumpjet speed modifiers fix, Local warhead screen shaking, Vehicle custom palette fix, Weapon owner detachment, Feedback weapon
- **Starkku** - Warhead shield penetration & breaking, strafing aircraft weapon customization, vehicle DeployFire fixes/improvements, stationary VehicleTypes, Burst logic improvements, TechnoType auto-firing weapons, Secondary weapon fallback customization, weapon target type filtering, AreaFire targeting customization, CreateUnit improvements, Attached animation & jumpjet unit layer customization, IsSimpleDeployer improvements, Shield modification warheads, Warhead decloaking toggle, Warp(In/Out)Weapon, Grinder improvements / additions, Attached animation position customization, Critical hit logic additions, Aircraft & jumpjet speed modifiers fix, Local warhead screen shaking, Vehicle custom palette fix, Weapon owner detachment, Feedback weapon, TerrainType & ore minimap color customization
- **SukaHati (Erzoid)** - Minimum interceptor guard range
- **Morton (MortonPL)** - XDrawOffset, Shield passthrough & absorption, building LimboDelivery, fix for Image in art rules, power delta counter
- **mevitar** - honorary shield tester *triple* award
Expand Down
23 changes: 23 additions & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Aircraft & jumpjet units are now affected by speed modifiers such as `SpeedAircraft/Infantry/UnitsMult` on `Countries`, `VeteranSpeed` and Crates / AttachEffect (Ares feature).
- Both voxel and SHP vehicle units should now correctly respect custom palette set through `Palette`.
- Weapons fired by EMPulse superweapons without `EMPulse.TargetSelf=true` *(Ares feature)* can now create radiation.
- Setting `RadarInvisible` to true on TerrainTypes now hides them from minimap display.

## Animations

Expand Down Expand Up @@ -259,6 +260,28 @@ SpawnsTiberium.GrowthStage=3 ; single int / comma-sep. range
SpawnsTiberium.CellsPerAnim=1 ; single int / comma-sep. range
```

### Minimap color customization

- TerrainTypes can now be made to display on minimap with different colors by setting `MinimapColor`.

In `rulesmd.ini`:
```ini
[SOMETERRAINTYPE] ; TerrainType
MinimapColor= ; integer - Red,Green,Blue
```

## Tiberiums (ores)

### Minimap color customization

- Ore can now be made to display on minimap with different colors by setting `MinimapColor` on Tiberiums.

In `rulesmd.ini`:
```ini
[SOMEORE] ; Tiberium
MinimapColor= ; integer - Red,Green,Blue
```

## Weapons

### Customizable disk laser radius
Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ New:
- Local warhead screen shaking (by Starkku)
- Weapon owner detachment (by Starkku)
- Feedback weapon (by Starkku)
- TerrainType & ore minimap color customization (by Starkku)

Vanilla fixes:
- Fixed laser drawing code to allow for thicker lasers in house color draw mode (by Kerbiter, ChrisLv_CN)
Expand Down
6 changes: 6 additions & 0 deletions src/Ext/TerrainType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ void TerrainTypeExt::ExtData::Serialize(T& Stm)
.Process(this->SpawnsTiberium_CellsPerAnim)
.Process(this->DestroyAnim)
.Process(this->DestroySound)
.Process(this->MinimapColor)
;
}

Expand All @@ -49,6 +50,8 @@ void TerrainTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
this->DestroyAnim.Read(exINI, pSection, "DestroyAnim");
this->DestroySound.Read(exINI, pSection, "DestroySound");

this->MinimapColor.Read(exINI, pSection, "MinimapColor");

//Strength is already part of ObjecTypeClass::ReadIni Duh!
//this->TerrainStrength.Read(exINI, pSection, "Strength");
}
Expand Down Expand Up @@ -92,6 +95,9 @@ DEFINE_HOOK(0x71DBC0, TerrainTypeClass_CTOR, 0x7)

TerrainTypeExt::ExtMap.FindOrAllocate(pItem);

// Override the default value (true) from game constructor.
pItem->RadarInvisible = false;

return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions src/Ext/TerrainType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class TerrainTypeExt
Valueable<Point2D> SpawnsTiberium_CellsPerAnim;
Nullable<AnimTypeClass*> DestroyAnim;
NullableIdx<VocClass> DestroySound;
Nullable<ColorStruct> MinimapColor;

ExtData(TerrainTypeClass* OwnerObject) : Extension<TerrainTypeClass>(OwnerObject)
, SpawnsTiberium_Type { 0 }
Expand All @@ -28,6 +29,7 @@ class TerrainTypeExt
, SpawnsTiberium_CellsPerAnim { { 1, 0 } }
, DestroyAnim {}
, DestroySound {}
, MinimapColor {}
{ }

virtual ~ExtData() = default;
Expand Down
45 changes: 43 additions & 2 deletions src/Ext/TerrainType/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

#include <ScenarioClass.h>
#include <TiberiumClass.h>
#include <OverlayTypeClass.h>
#include <TerrainClass.h>
#include <SpecificStructures.h>
#include <AnimClass.h>
Expand Down Expand Up @@ -111,4 +110,46 @@ DEFINE_HOOK(0x71BB2C, TerrainClass_TakeDamage_NowDead_Add, 0x6)
}

return 0;
}
}

DEFINE_HOOK(0x47C065, CellClass_CellColor_TerrainRadarColor, 0x6)
{
enum { SkipTerrainColor = 0x47C0AE, ReturnFromFunction = 0x47C0A3 };

GET(CellClass*, pThis, ECX);
GET_STACK(ColorStruct*, arg0, STACK_OFFS(0x14, -0x4));
GET_STACK(ColorStruct*, arg4, STACK_OFFS(0x14, -0x8));

auto pTerrain = pThis->GetTerrain(false);

if (pTerrain)
{
if (pTerrain->Type->RadarInvisible)
{
R->ESI(pThis);
return SkipTerrainColor;
}
else if (auto const pTerrainExt = TerrainTypeExt::ExtMap.Find(pTerrain->Type))
{
if (pTerrainExt->MinimapColor.isset())
{
auto& color = pTerrainExt->MinimapColor.Get();

arg0->R = color.R;
arg0->G = color.G;
arg0->B = color.B;

arg4->R = color.R;
arg4->G = color.G;
arg4->B = color.B;

R->ECX(arg4);
R->AL(color.B);

return ReturnFromFunction;
}
}
}

return 0;
}
117 changes: 117 additions & 0 deletions src/Ext/Tiberium/Body.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#include "Body.h"

template<> const DWORD Extension<TiberiumClass>::Canary = 0xAABBCCDD;
TiberiumExt::ExtContainer TiberiumExt::ExtMap;

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

template <typename T>
void TiberiumExt::ExtData::Serialize(T& Stm)
{
Stm
.Process(this->MinimapColor)
;
}

void TiberiumExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
{
auto pThis = this->OwnerObject();
const char* pSection = pThis->ID;

if (!pINI->GetSection(pSection))
return;

INI_EX exINI(pINI);

this->MinimapColor.Read(exINI, pSection, "MinimapColor");
}

void TiberiumExt::ExtData::LoadFromStream(PhobosStreamReader& Stm)
{
Extension<TiberiumClass>::LoadFromStream(Stm);
this->Serialize(Stm);
}

void TiberiumExt::ExtData::SaveToStream(PhobosStreamWriter& Stm)
{
Extension<TiberiumClass>::SaveToStream(Stm);
this->Serialize(Stm);
}

bool TiberiumExt::LoadGlobals(PhobosStreamReader& Stm)
{
return Stm
.Success();
}

bool TiberiumExt::SaveGlobals(PhobosStreamWriter& Stm)
{
return Stm
.Success();
}

// =============================
// container

TiberiumExt::ExtContainer::ExtContainer() : Container("TiberiumClass") { }
TiberiumExt::ExtContainer::~ExtContainer() = default;

// =============================
// container hooks

DEFINE_HOOK(0x721876, TiberiumClass_CTOR, 0x5)
{
GET(TiberiumClass*, pItem, ESI);

TiberiumExt::ExtMap.FindOrAllocate(pItem);

return 0;
}

DEFINE_HOOK(0x721888, TiberiumClass_DTOR, 0x6)
{
GET(TiberiumClass*, pItem, ECX);

TiberiumExt::ExtMap.Remove(pItem);

return 0;
}

DEFINE_HOOK_AGAIN(0x721E80, TiberiumClass_SaveLoad_Prefix, 0x7)
DEFINE_HOOK(0x7220D0, TiberiumClass_SaveLoad_Prefix, 0x5)
{
GET_STACK(TiberiumClass*, pItem, 0x4);
GET_STACK(IStream*, pStm, 0x8);

TiberiumExt::ExtMap.PrepareStream(pItem, pStm);

return 0;
}

DEFINE_HOOK(0x72208C, TiberiumClass_Load_Suffix, 0x7)
{
TiberiumExt::ExtMap.LoadStatic();

return 0;
}

DEFINE_HOOK(0x72212C, TiberiumClass_Save_Suffix, 0x5)
{
TiberiumExt::ExtMap.SaveStatic();

return 0;
}

DEFINE_HOOK_AGAIN(0x721CDC, TiberiumClass_LoadFromINI, 0xA)
DEFINE_HOOK_AGAIN(0x721CE9, TiberiumClass_LoadFromINI, 0xA)
DEFINE_HOOK(0x721C7B, TiberiumClass_LoadFromINI, 0xA)
{
GET(TiberiumClass*, pItem, ESI);
GET_STACK(CCINIClass*, pINI, STACK_OFFS(0xC4, -0x4));

TiberiumExt::ExtMap.LoadFromINI(pItem, pINI);

return 0;
}

49 changes: 49 additions & 0 deletions src/Ext/Tiberium/Body.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once
#include <TiberiumClass.h>

#include <Helpers/Macro.h>
#include <Utilities/Container.h>
#include <Utilities/TemplateDef.h>
#include <Utilities/Macro.h>
#include <Utilities/GeneralUtils.h>

class TiberiumExt
{
public:
using base_type = TiberiumClass;

class ExtData final : public Extension<TiberiumClass>
{
public:
Nullable<ColorStruct> MinimapColor;

ExtData(TiberiumClass* OwnerObject) : Extension<TiberiumClass>(OwnerObject)
, MinimapColor {}
{ }

virtual ~ExtData() = default;

virtual void LoadFromINIFile(CCINIClass* pINI) override;

virtual void InvalidatePointer(void* ptr, bool bRemoved) override { }

virtual void LoadFromStream(PhobosStreamReader& Stm) override;
virtual void SaveToStream(PhobosStreamWriter& Stm) override;

private:
template <typename T>
void Serialize(T& Stm);
};

class ExtContainer final : public Container<TiberiumExt>
{
public:
ExtContainer();
~ExtContainer();
};

static ExtContainer ExtMap;

static bool LoadGlobals(PhobosStreamReader& Stm);
static bool SaveGlobals(PhobosStreamWriter& Stm);
};
45 changes: 45 additions & 0 deletions src/Ext/Tiberium/Hooks.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "Body.h"

#include <CellClass.h>
#include <OverlayClass.h>

#include <Utilities/GeneralUtils.h>

DEFINE_HOOK(0x47C210, CellClass_CellColor_TiberiumRadarColor, 0x6)
{
enum { ReturnFromFunction = 0x47C23F };

GET(CellClass*, pThis, ESI);
GET_STACK(ColorStruct*, arg0, STACK_OFFS(0x14, -0x4));
GET_STACK(ColorStruct*, arg4, STACK_OFFS(0x14, -0x8));

int tiberiumType = OverlayClass::GetTiberiumType(pThis->OverlayTypeIndex);

if (tiberiumType < 0)
return 0;

auto pTiberium = TiberiumClass::Array->GetItem(tiberiumType);

if (const auto pTiberiumExt = TiberiumExt::ExtMap.Find(pTiberium))
{
if (pTiberiumExt->MinimapColor.isset())
{
auto& color = pTiberiumExt->MinimapColor.Get();

arg0->R = color.R;
arg0->G = color.G;
arg0->B = color.B;

arg4->R = color.R;
arg4->G = color.G;
arg4->B = color.B;

R->ECX(arg4);
R->AL(color.B);

return ReturnFromFunction;
}
}

return 0;
}
Loading