support alternative spritesheet for units below 50% health

This commit is contained in:
Tim Felgentreff 2022-04-12 09:24:20 +02:00
parent 86f08104dc
commit e8735b04a0
4 changed files with 31 additions and 4 deletions

View file

@ -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
};

View file

@ -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;

View file

@ -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;
}
//

View file

@ -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) {