From aab67a3cf6eebe47480024bf8e84486782f74117 Mon Sep 17 00:00:00 2001 From: Starkku Date: Wed, 9 Mar 2022 17:24:54 +0200 Subject: [PATCH] TerrainType & ore minimap color customization --- Phobos.vcxproj | 3 + README.md | 2 +- docs/Fixed-or-Improved-Logics.md | 23 ++++++ docs/Whats-New.md | 1 + src/Ext/TerrainType/Body.cpp | 6 ++ src/Ext/TerrainType/Body.h | 2 + src/Ext/TerrainType/Hooks.cpp | 45 +++++++++++- src/Ext/Tiberium/Body.cpp | 117 +++++++++++++++++++++++++++++++ src/Ext/Tiberium/Body.h | 49 +++++++++++++ src/Ext/Tiberium/Hooks.cpp | 45 ++++++++++++ src/Phobos.Ext.cpp | 2 + 11 files changed, 292 insertions(+), 3 deletions(-) create mode 100644 src/Ext/Tiberium/Body.cpp create mode 100644 src/Ext/Tiberium/Body.h create mode 100644 src/Ext/Tiberium/Hooks.cpp 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,