diff --git a/Phobos.vcxproj b/Phobos.vcxproj
index 39706373fa..2db8816257 100644
--- a/Phobos.vcxproj
+++ b/Phobos.vcxproj
@@ -76,6 +76,8 @@
+
+
@@ -144,6 +146,7 @@
+
diff --git a/README.md b/README.md
index aa18d06935..33a1ad7c21 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md
index 52d95db6ac..73b70be74d 100644
--- a/docs/Fixed-or-Improved-Logics.md
+++ b/docs/Fixed-or-Improved-Logics.md
@@ -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
@@ -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
diff --git a/docs/Whats-New.md b/docs/Whats-New.md
index 67a3335290..9fe125d68c 100644
--- a/docs/Whats-New.md
+++ b/docs/Whats-New.md
@@ -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)
diff --git a/src/Ext/TerrainType/Body.cpp b/src/Ext/TerrainType/Body.cpp
index e118b2063d..96b6009ca8 100644
--- a/src/Ext/TerrainType/Body.cpp
+++ b/src/Ext/TerrainType/Body.cpp
@@ -29,6 +29,7 @@ void TerrainTypeExt::ExtData::Serialize(T& Stm)
.Process(this->SpawnsTiberium_CellsPerAnim)
.Process(this->DestroyAnim)
.Process(this->DestroySound)
+ .Process(this->MinimapColor)
;
}
@@ -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");
}
@@ -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;
}
diff --git a/src/Ext/TerrainType/Body.h b/src/Ext/TerrainType/Body.h
index 716da1887d..16a2cf971b 100644
--- a/src/Ext/TerrainType/Body.h
+++ b/src/Ext/TerrainType/Body.h
@@ -20,6 +20,7 @@ class TerrainTypeExt
Valueable SpawnsTiberium_CellsPerAnim;
Nullable DestroyAnim;
NullableIdx DestroySound;
+ Nullable MinimapColor;
ExtData(TerrainTypeClass* OwnerObject) : Extension(OwnerObject)
, SpawnsTiberium_Type { 0 }
@@ -28,6 +29,7 @@ class TerrainTypeExt
, SpawnsTiberium_CellsPerAnim { { 1, 0 } }
, DestroyAnim {}
, DestroySound {}
+ , MinimapColor {}
{ }
virtual ~ExtData() = default;
diff --git a/src/Ext/TerrainType/Hooks.cpp b/src/Ext/TerrainType/Hooks.cpp
index 998f730f6e..dfbadcd24b 100644
--- a/src/Ext/TerrainType/Hooks.cpp
+++ b/src/Ext/TerrainType/Hooks.cpp
@@ -2,7 +2,6 @@
#include
#include
-#include
#include
#include
#include
@@ -111,4 +110,46 @@ DEFINE_HOOK(0x71BB2C, TerrainClass_TakeDamage_NowDead_Add, 0x6)
}
return 0;
-}
\ No newline at end of file
+}
+
+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;
+}
diff --git a/src/Ext/Tiberium/Body.cpp b/src/Ext/Tiberium/Body.cpp
new file mode 100644
index 0000000000..7364de892a
--- /dev/null
+++ b/src/Ext/Tiberium/Body.cpp
@@ -0,0 +1,117 @@
+#include "Body.h"
+
+template<> const DWORD Extension::Canary = 0xAABBCCDD;
+TiberiumExt::ExtContainer TiberiumExt::ExtMap;
+
+// =============================
+// load / save
+
+template
+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::LoadFromStream(Stm);
+ this->Serialize(Stm);
+}
+
+void TiberiumExt::ExtData::SaveToStream(PhobosStreamWriter& Stm)
+{
+ Extension::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;
+}
+
diff --git a/src/Ext/Tiberium/Body.h b/src/Ext/Tiberium/Body.h
new file mode 100644
index 0000000000..15cc04d5c3
--- /dev/null
+++ b/src/Ext/Tiberium/Body.h
@@ -0,0 +1,49 @@
+#pragma once
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+class TiberiumExt
+{
+public:
+ using base_type = TiberiumClass;
+
+ class ExtData final : public Extension
+ {
+ public:
+ Nullable MinimapColor;
+
+ ExtData(TiberiumClass* OwnerObject) : Extension(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
+ void Serialize(T& Stm);
+ };
+
+ class ExtContainer final : public Container
+ {
+ public:
+ ExtContainer();
+ ~ExtContainer();
+ };
+
+ static ExtContainer ExtMap;
+
+ static bool LoadGlobals(PhobosStreamReader& Stm);
+ static bool SaveGlobals(PhobosStreamWriter& Stm);
+};
\ No newline at end of file
diff --git a/src/Ext/Tiberium/Hooks.cpp b/src/Ext/Tiberium/Hooks.cpp
new file mode 100644
index 0000000000..d66c276044
--- /dev/null
+++ b/src/Ext/Tiberium/Hooks.cpp
@@ -0,0 +1,45 @@
+#include "Body.h"
+
+#include
+#include
+
+#include
+
+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;
+}
\ No newline at end of file
diff --git a/src/Phobos.Ext.cpp b/src/Phobos.Ext.cpp
index 3906dc33b8..3e979e0eb1 100644
--- a/src/Phobos.Ext.cpp
+++ b/src/Phobos.Ext.cpp
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -242,6 +243,7 @@ auto MassActions = MassAction <
TechnoExt,
TechnoTypeExt,
TerrainTypeExt,
+ TiberiumExt,
VoxelAnimExt,
VoxelAnimTypeExt,
WarheadTypeExt,