diff --git a/src/include/unittype.h b/src/include/unittype.h index d7ae21724..057f17115 100644 --- a/src/include/unittype.h +++ b/src/include/unittype.h @@ -525,6 +525,7 @@ public: std::string Name; /// Pretty name shown from the engine int Slot; /// Type as number std::string File; /// Sprite files + std::string AltFile; /// Alternative sprite files std::string ShadowFile; /// Shadow file int Width; /// Sprite width @@ -665,6 +666,7 @@ public: CUnitStats Stats[PlayerMax]; /// Unit status for each player CPlayerColorGraphic *Sprite; /// Sprite images + CPlayerColorGraphic *AltSprite; /// Alternative sprite images CGraphic *ShadowSprite; /// Shadow sprite image }; diff --git a/src/unit/script_unittype.cpp b/src/unit/script_unittype.cpp index 2f5cac46f..d79dfdcfa 100644 --- a/src/unit/script_unittype.cpp +++ b/src/unit/script_unittype.cpp @@ -512,6 +512,8 @@ static int CclDefineUnitType(lua_State *l) if (!strcmp(value, "file")) { type->File = LuaToString(l, -1, k + 1); + } else if (!strcmp(value, "alt-file")) { + type->AltFile = LuaToString(l, -1, k + 1); } else if (!strcmp(value, "size")) { lua_rawgeti(l, -1, k + 1); CclGetPos(l, &type->Width, &type->Height); @@ -520,9 +522,15 @@ static int CclDefineUnitType(lua_State *l) LuaError(l, "Unsupported image tag: %s" _C_ value); } } - if (redefine && type->Sprite) { - CGraphic::Free(type->Sprite); - type->Sprite = NULL; + if (redefine) { + if (type->Sprite && type->Sprite->File != type->File) { + CGraphic::Free(type->Sprite); + type->Sprite = NULL; + } + if (type->AltSprite && type->AltSprite->File != type->AltFile) { + CGraphic::Free(type->AltSprite); + type->AltSprite = NULL; + } } if (type->ShadowFile == shadowMarker) { type->ShadowFile = type->File; @@ -1239,12 +1247,17 @@ static int CclCopyUnitType(lua_State *l) to->Flip = from->Flip; to->Name = toName; to->File = from->File; + to->AltFile = from->AltFile; to->Width = from->Width; to->Height = from->Height; if (to->Sprite) { CGraphic::Free(to->Sprite); to->Sprite = NULL; } + if (to->AltSprite) { + CGraphic::Free(to->AltSprite); + to->AltSprite = NULL; + } to->ShadowFile = from->ShadowFile; to->ShadowWidth = from->ShadowWidth; to->ShadowHeight = from->ShadowHeight; diff --git a/src/unit/unit_draw.cpp b/src/unit/unit_draw.cpp index 523acd53c..789a565b2 100644 --- a/src/unit/unit_draw.cpp +++ b/src/unit/unit_draw.cpp @@ -1000,6 +1000,9 @@ void CUnit::Draw(const CViewport &vp) const sprite = resinfo->SpriteWhenEmpty; } } + } else if (type->AltSprite && this->Variable[HP_INDEX].Value < (this->Variable[HP_INDEX].Max >> 1)) { + // TODO: (timfel) do we need more configurability? This at least is pretty fast to check + sprite = type->AltSprite; } // diff --git a/src/unit/unittype.cpp b/src/unit/unittype.cpp index e85974871..1282cdcb7 100644 --- a/src/unit/unittype.cpp +++ b/src/unit/unittype.cpp @@ -536,7 +536,7 @@ CUnitType::CUnitType() : CanAttack(0), Neutral(0), GivesResource(0), PoisonDrain(0), FieldFlags(0), MovementMask(0), - Sprite(NULL), ShadowSprite(NULL), ShadowSpriteFrame(0), ShadowScale(1) + Sprite(NULL), AltSprite(NULL), ShadowSprite(NULL), ShadowSpriteFrame(0), ShadowScale(1) { #ifdef USE_MNG memset(&Portrait, 0, sizeof(Portrait)); @@ -588,6 +588,7 @@ CUnitType::~CUnitType() } CGraphic::Free(Sprite); + CGraphic::Free(AltSprite); CGraphic::Free(ShadowSprite); #ifdef USE_MNG if (this->Portrait.Num) { @@ -1030,6 +1031,14 @@ void LoadUnitTypeSprite(CUnitType &type) } } + if (!type.AltFile.empty()) { + type.AltSprite = CPlayerColorGraphic::New(type.AltFile, type.Width, type.Height); + type.AltSprite->Load(); + if (type.Flip) { + type.AltSprite->Flip(); + } + } + #ifdef USE_MNG if (type.Portrait.Num) { for (int i = 0; i < type.Portrait.Num; ++i) {