Skip to content

Commit

Permalink
Custom palette
Browse files Browse the repository at this point in the history
  • Loading branch information
Starkku committed May 2, 2024
1 parent ba9226a commit 25ad3b9
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 15 deletions.
11 changes: 11 additions & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,17 @@ SpawnsTiberium.GrowthStage=3 ; integer - single or comma-sep. range
SpawnsTiberium.CellsPerAnim=1 ; integer - single or comma-sep. range
```

### Custom palette

- You can now specify custom palette for TerrainTypes in similar manner as TechnoTypes can.
- Note that this palette behaves like an object palette and does not use tint etc. that have been applied to the tile the TerrainType resides on like a TerrainType using tile palette would.

In `artmd.ini`:
```ini
[SOMETERRAINTYPE] ; TerrainType
Palette= ; filename - excluding .pal extension and three-character theater-specific suffix
```

### Damaged frames and crumbling animation

- By default game shows damage frame only for TerrainTypes alive at only 1 point of health left. Because none of the original game TerrainType assets were made with this in mind, the logic is now locked behind a new key `HasDamagedFrames`.
Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ New:
- Toggle for `Explodes=true` BuildingTypes to not explode during buildup or being sold (by Starkku)
- Toggleable height-based shadow scaling for voxel air units (by Trsdy & Starkku)
- Customizable damage & 'crumbling' (destruction) frames for TerrainTypes (by Starkku)
- Custom object palettes for TerrainTypes (by Starkku)
Vanilla fixes:
- Allow AI to repair structures built from base nodes/trigger action 125/SW delivery in single player missions (by Trsdy)
Expand Down
16 changes: 2 additions & 14 deletions src/Ext/OverlayType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,14 @@ void OverlayTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
auto pArtSection = pThis->ImageFile;

this->PaletteFile.Read(pArtINI, pArtSection, "Palette");

BuildPalette();
}

void OverlayTypeExt::ExtData::BuildPalette()
{
if (GeneralUtils::IsValidString(this->PaletteFile))
{
char pFilename[0x20];
strcpy_s(pFilename, this->PaletteFile.data());

this->Palette = ColorScheme::GeneratePalette(pFilename);
}
this->Palette = GeneralUtils::BuildPalette(this->PaletteFile);
}

void OverlayTypeExt::ExtData::LoadFromStream(PhobosStreamReader& Stm)
{
Extension<OverlayTypeClass>::LoadFromStream(Stm);
this->Serialize(Stm);
this->BuildPalette();
this->Palette = GeneralUtils::BuildPalette(this->PaletteFile);
}

void OverlayTypeExt::ExtData::SaveToStream(PhobosStreamWriter& Stm)
Expand Down
1 change: 0 additions & 1 deletion src/Ext/OverlayType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ class OverlayTypeExt
private:
template <typename T>
void Serialize(T& Stm);
void BuildPalette();
};

class ExtContainer final : public Container<OverlayTypeExt>
Expand Down
8 changes: 8 additions & 0 deletions src/Ext/TerrainType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ void TerrainTypeExt::ExtData::Serialize(T& Stm)
.Process(this->HasCrumblingFrames)
.Process(this->CrumblingSound)
.Process(this->AnimationLength)
.Process(this->PaletteFile)
;
}

Expand Down Expand Up @@ -91,12 +92,19 @@ void TerrainTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)

//Strength is already part of ObjecTypeClass::ReadIni Duh!
//this->TerrainStrength.Read(exINI, pSection, "Strength");

auto const pArtINI = &CCINIClass::INI_Art();
auto pArtSection = pThis->ImageFile;

this->PaletteFile.Read(pArtINI, pArtSection, "Palette");
this->Palette = GeneralUtils::BuildPalette(this->PaletteFile);
}

void TerrainTypeExt::ExtData::LoadFromStream(PhobosStreamReader& Stm)
{
Extension<TerrainTypeClass>::LoadFromStream(Stm);
this->Serialize(Stm);
this->Palette = GeneralUtils::BuildPalette(this->PaletteFile);
}

void TerrainTypeExt::ExtData::SaveToStream(PhobosStreamWriter& Stm)
Expand Down
5 changes: 5 additions & 0 deletions src/Ext/TerrainType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class TerrainTypeExt
NullableIdx<VocClass> CrumblingSound;
Nullable<int> AnimationLength;

PhobosFixedString<32u> PaletteFile;
DynamicVectorClass<ColorScheme*>* Palette; // Intentionally not serialized - rebuilt from the palette file on load.

ExtData(TerrainTypeClass* OwnerObject) : Extension<TerrainTypeClass>(OwnerObject)
, SpawnsTiberium_Type { 0 }
, SpawnsTiberium_Range { 1 }
Expand All @@ -45,6 +48,8 @@ class TerrainTypeExt
, HasCrumblingFrames { false }
, CrumblingSound {}
, AnimationLength {}
, PaletteFile {}
, Palette {}
{ }

virtual ~ExtData() = default;
Expand Down
23 changes: 23 additions & 0 deletions src/Ext/TerrainType/Hooks.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "Body.h"

#include <HouseClass.h>
#include <ScenarioClass.h>
#include <SpecificStructures.h>
#include <TacticalClass.h>
Expand Down Expand Up @@ -116,6 +117,28 @@ DEFINE_HOOK(0x71C1FE, TerrainClass_Draw_PickFrame, 0x6)
return SkipGameCode;
}

DEFINE_HOOK(0x71C2BC, TerrainClass_Draw_Palette, 0x6)
{
GET(TerrainClass*, pThis, ESI);

auto const pCell = pThis->GetCell();
int wallOwnerIndex = pCell->WallOwnerIndex;
int colorSchemeIndex = HouseClass::CurrentPlayer->ColorSchemeIndex;

if (wallOwnerIndex >= 0)
colorSchemeIndex = HouseClass::Array->GetItem(wallOwnerIndex)->ColorSchemeIndex;

auto const pTypeExt = TerrainTypeExt::ExtMap.Find(pThis->Type);

if (pTypeExt->Palette)
{
R->EDX(pTypeExt->Palette->GetItem(colorSchemeIndex)->LightConvert);
R->EBP(pCell->Intensity_Normal);
}

return 0;
}

// Overrides Ares hook at 0x5F4FF9, required for animated terrain cause game & Ares check SpawnsTiberium instead of IsAnimated
DEFINE_HOOK(0x5F4FEF, ObjectClass_Unlimbo_UpdateTerrain, 0x6)
{
Expand Down
14 changes: 14 additions & 0 deletions src/Utilities/GeneralUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <BitFont.h>

#include <Misc/FlyingStrings.h>
#include <Utilities/Constructs.h>

bool GeneralUtils::IsValidString(const char* str)
{
Expand Down Expand Up @@ -215,3 +216,16 @@ void GeneralUtils::DisplayDamageNumberString(int damage, DamageDisplayType type,

offset = offset + width;
}

DynamicVectorClass<ColorScheme*>* GeneralUtils::BuildPalette(const char* paletteFileName)
{
if (GeneralUtils::IsValidString(paletteFileName))
{
char pFilename[0x20];
strcpy_s(pFilename, paletteFileName);

return ColorScheme::GeneratePalette(pFilename);
}

return nullptr;
}
1 change: 1 addition & 0 deletions src/Utilities/GeneralUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class GeneralUtils
static int CountDigitsInNumber(int number);
static CoordStruct CalculateCoordsFromDistance(CoordStruct currentCoords, CoordStruct targetCoords, int distance);
static void DisplayDamageNumberString(int damage, DamageDisplayType type, CoordStruct coords, int& offset);
static DynamicVectorClass<ColorScheme*>* BuildPalette(const char* paletteFileName);

template<typename T>
static constexpr T FastPow(T x, size_t n)
Expand Down

0 comments on commit 25ad3b9

Please sign in to comment.