Browse Source

Convert to CelSprite

pull/2049/head
obligaron 5 years ago committed by Anders Jenbo
parent
commit
61ba5009ac
  1. 8
      Source/engine/animationinfo.cpp
  2. 12
      Source/engine/animationinfo.h
  3. 6
      Source/items.cpp
  4. 9
      Source/loadsave.cpp
  5. 187
      Source/player.cpp
  6. 38
      Source/player.h
  7. 23
      Source/scrollrt.cpp
  8. 1
      test/writehero_test.cpp

8
Source/engine/animationinfo.cpp

@ -69,7 +69,7 @@ float AnimationInfo::GetAnimationProgress() const
return fAnimationFraction;
}
void AnimationInfo::SetNewAnimation(byte *pData, int numberOfFrames, int delayLen, AnimationDistributionFlags flags /*= AnimationDistributionFlags::None*/, int numSkippedFrames /*= 0*/, int distributeFramesBeforeFrame /*= 0*/)
void AnimationInfo::SetNewAnimation(CelSprite *pCelSprite, int numberOfFrames, int delayLen, AnimationDistributionFlags flags /*= AnimationDistributionFlags::None*/, int numSkippedFrames /*= 0*/, int distributeFramesBeforeFrame /*= 0*/)
{
if ((flags & AnimationDistributionFlags::RepeatedAction) == AnimationDistributionFlags::RepeatedAction && distributeFramesBeforeFrame != 0 && NumberOfFrames == numberOfFrames && CurrentFrame >= distributeFramesBeforeFrame && CurrentFrame != NumberOfFrames) {
// We showed the same Animation (for example a melee attack) before but truncated the Animation.
@ -79,7 +79,7 @@ void AnimationInfo::SetNewAnimation(byte *pData, int numberOfFrames, int delayLe
SkippedFramesFromPreviousAnimation = 0;
}
this->pData = pData;
this->pCelSprite = pCelSprite;
NumberOfFrames = numberOfFrames;
CurrentFrame = 1 + numSkippedFrames;
DelayCounter = 0;
@ -154,7 +154,7 @@ void AnimationInfo::SetNewAnimation(byte *pData, int numberOfFrames, int delayLe
}
}
void AnimationInfo::ChangeAnimationData(byte *pData, int numberOfFrames, int delayLen)
void AnimationInfo::ChangeAnimationData(CelSprite *pCelSprite, int numberOfFrames, int delayLen)
{
if (numberOfFrames != NumberOfFrames || delayLen != DelayLen) {
// Ensure that the CurrentFrame is still valid and that we disable ADL cause the calculcated values (for example TickModifier) could be wrong
@ -166,7 +166,7 @@ void AnimationInfo::ChangeAnimationData(byte *pData, int numberOfFrames, int del
RelevantFramesForDistributing = 0;
TickModifier = 0.0f;
}
this->pData = pData;
this->pCelSprite = pCelSprite;
DelayLen = delayLen;
}

12
Source/engine/animationinfo.h

@ -37,9 +37,9 @@ enum AnimationDistributionFlags : uint8_t {
class AnimationInfo {
public:
/**
* @brief Pointer to Animation Data
* @brief Pointer to Animation Sprite
*/
byte *pData;
CelSprite *pCelSprite;
/**
* @brief Additional delay of each animation in the current animation
*/
@ -70,22 +70,22 @@ public:
/**
* @brief Sets the new Animation with all relevant information for rendering
* @param pData Pointer to Animation Data
* @param pCelSprite Pointer to Animation Sprite
* @param numberOfFrames Number of Frames in Animation
* @param delayLen Delay after each Animation sequence
* @param flags Specifies what special logics are applied to this Animation
* @param numSkippedFrames Number of Frames that will be skipped (for example with modifier "faster attack")
* @param distributeFramesBeforeFrame Distribute the numSkippedFrames only before this frame
*/
void SetNewAnimation(byte *pData, int numberOfFrames, int delayLen, AnimationDistributionFlags flags = AnimationDistributionFlags::None, int numSkippedFrames = 0, int distributeFramesBeforeFrame = 0);
void SetNewAnimation(CelSprite *pCelSprite, int numberOfFrames, int delayLen, AnimationDistributionFlags flags = AnimationDistributionFlags::None, int numSkippedFrames = 0, int distributeFramesBeforeFrame = 0);
/**
* @brief Changes the Animation Data on-the-fly. This is needed if a animation is currently in progress and the player changes his gear.
* @param pData Pointer to Animation Data
* @param pCelSprite Pointer to Animation Sprite
* @param numberOfFrames Number of Frames in Animation
* @param delayLen Delay after each Animation sequence
*/
void ChangeAnimationData(byte *pData, int numberOfFrames, int delayLen);
void ChangeAnimationData(CelSprite *pCelSprite, int numberOfFrames, int delayLen);
/*
* @brief Process the Animation for a game tick (for example advances the frame)

6
Source/items.cpp

@ -888,11 +888,9 @@ void CalcPlrItemVals(int playerId, bool Loadgfx)
SetPlrAnims(player);
LoadPlrGFX(player, static_cast<player_graphic>(PFILE_STAND | PFILE_WALK));
if (player._pmode == PM_STAND) {
player._pAnimWidth = player.GetAnimationWidth(PFILE_STAND);
player.AnimInfo.ChangeAnimationData(player._pNAnim[player._pdir], player._pNFrames, 3);
player.AnimInfo.ChangeAnimationData(&*player._pNAnim[player._pdir], player._pNFrames, 3);
} else {
player._pAnimWidth = player.GetAnimationWidth(PFILE_WALK);
player.AnimInfo.ChangeAnimationData(player._pWAnim[player._pdir], player._pWFrames, 0);
player.AnimInfo.ChangeAnimationData(&*player._pWAnim[player._pdir], player._pWFrames, 0);
}
} else {
player._pgfxnum = g;

9
Source/loadsave.cpp

@ -338,7 +338,8 @@ static void LoadPlayer(LoadHelper *file, int p)
pPlayer->AnimInfo.DelayCounter = file->nextLE<int32_t>();
pPlayer->AnimInfo.NumberOfFrames = file->nextLE<int32_t>();
pPlayer->AnimInfo.CurrentFrame = file->nextLE<int32_t>();
pPlayer->_pAnimWidth = file->nextLE<int32_t>();
// Skip _pAnimWidth
file->skip(4);
// Skip _pAnimWidth2
file->skip(4);
file->skip(4); // Skip _peflag
@ -1333,9 +1334,11 @@ static void SavePlayer(SaveHelper *file, int p)
file->writeLE<int32_t>(pPlayer->AnimInfo.DelayCounter);
file->writeLE<int32_t>(pPlayer->AnimInfo.NumberOfFrames);
file->writeLE<int32_t>(pPlayer->AnimInfo.CurrentFrame);
file->writeLE<int32_t>(pPlayer->_pAnimWidth);
// write _pAnimWidth for vanilla compatibility
int animWidth = pPlayer->AnimInfo.pCelSprite == nullptr ? 96 : pPlayer->AnimInfo.pCelSprite->Width();
file->writeLE<int32_t>(animWidth);
// write _pAnimWidth2 for vanilla compatibility
file->writeLE<int32_t>(CalculateWidth2(pPlayer->_pAnimWidth));
file->writeLE<int32_t>(CalculateWidth2(animWidth));
file->skip(4); // Skip _peflag
file->writeLE<int32_t>(pPlayer->_plid);
file->writeLE<int32_t>(pPlayer->_pvid);

187
Source/player.cpp

@ -420,12 +420,14 @@ int PlayerStruct::GetAnimationWidth(player_graphic graphic)
}
}
void SetPlayerGPtrs(byte *pData, byte **pAnim)
void SetPlayerGPtrs(const char *path, std::unique_ptr<byte[]> &data, std::array<std::optional<CelSprite>, 8> &anim, int width)
{
int i;
data = nullptr;
data = LoadFileInMem(path);
for (i = 0; i < 8; i++) {
pAnim[i] = CelGetFrameStart(pData, i);
for (int i = 0; i < 8; i++) {
byte *pCelStart = CelGetFrameStart(data.get(), i);
anim[i].emplace(pCelStart, width);
}
}
@ -434,8 +436,8 @@ void LoadPlrGFX(PlayerStruct &player, player_graphic gfxflag)
char prefix[16];
char pszName[256];
const char *szCel;
byte *pData;
byte **pAnim;
std::unique_ptr<byte[]> *pData;
std::array<std::optional<CelSprite>, 8> *pAnim;
HeroClass c = player._pClass;
if (c == HeroClass::Bard && hfbard_mpq == nullptr) {
@ -458,64 +460,64 @@ void LoadPlrGFX(PlayerStruct &player, player_graphic gfxflag)
if (leveltype == DTYPE_TOWN) {
szCel = "ST";
}
pData = player._pNData;
pAnim = player._pNAnim;
pData = &player._pNData;
pAnim = &player._pNAnim;
break;
case PFILE_WALK:
szCel = "AW";
if (leveltype == DTYPE_TOWN) {
szCel = "WL";
}
pData = player._pWData;
pAnim = player._pWAnim;
pData = &player._pWData;
pAnim = &player._pWAnim;
break;
case PFILE_ATTACK:
if (leveltype == DTYPE_TOWN) {
continue;
}
szCel = "AT";
pData = player._pAData;
pAnim = player._pAAnim;
pData = &player._pAData;
pAnim = &player._pAAnim;
break;
case PFILE_HIT:
if (leveltype == DTYPE_TOWN) {
continue;
}
szCel = "HT";
pData = player._pHData;
pAnim = player._pHAnim;
pData = &player._pHData;
pAnim = &player._pHAnim;
break;
case PFILE_LIGHTNING:
if (leveltype == DTYPE_TOWN) {
continue;
}
szCel = "LM";
pData = player._pLData;
pAnim = player._pLAnim;
pData = &player._pLData;
pAnim = &player._pLAnim;
break;
case PFILE_FIRE:
if (leveltype == DTYPE_TOWN) {
continue;
}
szCel = "FM";
pData = player._pFData;
pAnim = player._pFAnim;
pData = &player._pFData;
pAnim = &player._pFAnim;
break;
case PFILE_MAGIC:
if (leveltype == DTYPE_TOWN) {
continue;
}
szCel = "QM";
pData = player._pTData;
pAnim = player._pTAnim;
pData = &player._pTData;
pAnim = &player._pTAnim;
break;
case PFILE_DEATH:
if ((player._pgfxnum & 0xF) != 0) {
continue;
}
szCel = "DT";
pData = player._pDData;
pAnim = player._pDAnim;
pData = &player._pDData;
pAnim = &player._pDAnim;
break;
case PFILE_BLOCK:
if (leveltype == DTYPE_TOWN) {
@ -526,16 +528,15 @@ void LoadPlrGFX(PlayerStruct &player, player_graphic gfxflag)
}
szCel = "BL";
pData = player._pBData;
pAnim = player._pBAnim;
pData = &player._pBData;
pAnim = &player._pBAnim;
break;
default:
app_fatal("PLR:2");
}
sprintf(pszName, "PlrGFX\\%s\\%s\\%s%s.CL2", cs, prefix, prefix, szCel);
LoadFileInMem(pszName, pData);
SetPlayerGPtrs(pData, pAnim);
SetPlayerGPtrs(pszName, *pData, *pAnim, player.GetAnimationWidth(static_cast<player_graphic>(i)));
player._pGFXLoad |= i;
}
}
@ -567,101 +568,21 @@ static HeroClass GetPlrGFXClass(HeroClass c)
}
}
static DWORD GetPlrGFXSize(HeroClass c, const char *szCel)
{
const char *a, *w;
DWORD dwSize, dwMaxSize;
HANDLE hsFile;
char pszName[256];
char Type[16];
c = GetPlrGFXClass(c);
dwMaxSize = 0;
const auto hasBlockAnimation = [c](char w) {
return w == 'D' || w == 'U' || w == 'H'
|| (c == HeroClass::Monk && (w == 'S' || w == 'M' || w == 'N' || w == 'T'));
};
for (a = &ArmourChar[0]; *a; a++) {
if (gbIsSpawn && a != &ArmourChar[0])
break;
for (w = &WepChar[0]; *w; w++) {
if (szCel[0] == 'D' && szCel[1] == 'T' && *w != 'N') {
continue; //Death has no weapon
}
if (szCel[0] == 'B' && szCel[1] == 'L' && !hasBlockAnimation(*w)) {
continue; // No block animation
}
sprintf(Type, "%c%c%c", CharChar[static_cast<std::size_t>(c)], *a, *w);
sprintf(pszName, "PlrGFX\\%s\\%s\\%s%s.CL2", ClassPathTbl[static_cast<std::size_t>(c)], Type, Type, szCel);
if (SFileOpenFile(pszName, &hsFile)) {
assert(hsFile);
dwSize = SFileGetFileSize(hsFile);
SFileCloseFileThreadSafe(hsFile);
if (dwMaxSize <= dwSize) {
dwMaxSize = dwSize;
}
}
}
}
return dwMaxSize;
}
void InitPlrGFXMem(PlayerStruct &player)
{
const HeroClass c = player._pClass;
// STAND (ST: TOWN, AS: DUNGEON)
player._pNData = new byte[std::max(GetPlrGFXSize(c, "ST"), GetPlrGFXSize(c, "AS"))];
// WALK (WL: TOWN, AW: DUNGEON)
player._pWData = new byte[std::max(GetPlrGFXSize(c, "WL"), GetPlrGFXSize(c, "AW"))];
// ATTACK
player._pAData = new byte[GetPlrGFXSize(c, "AT")];
// HIT
player._pHData = new byte[GetPlrGFXSize(c, "HT")];
// LIGHTNING
player._pLData = new byte[GetPlrGFXSize(c, "LM")];
// FIRE
player._pFData = new byte[GetPlrGFXSize(c, "FM")];
// MAGIC
player._pTData = new byte[GetPlrGFXSize(c, "QM")];
// DEATH
player._pDData = new byte[GetPlrGFXSize(c, "DT")];
// BLOCK
player._pBData = new byte[GetPlrGFXSize(c, "BL")];
player._pGFXLoad = 0;
FreePlayerGFX(player);
}
void FreePlayerGFX(PlayerStruct &player)
{
delete[] player._pNData;
player._pNData = nullptr;
delete[] player._pWData;
player._pWData = nullptr;
delete[] player._pAData;
player._pAData = nullptr;
delete[] player._pHData;
player._pHData = nullptr;
delete[] player._pLData;
player._pLData = nullptr;
delete[] player._pFData;
player._pFData = nullptr;
delete[] player._pTData;
player._pTData = nullptr;
delete[] player._pDData;
player._pDData = nullptr;
delete[] player._pBData;
player._pBData = nullptr;
player._pGFXLoad = 0;
}
@ -671,43 +592,45 @@ void NewPlrAnim(PlayerStruct &player, player_graphic graphic, Direction dir, int
if ((player._pGFXLoad & graphic) != graphic)
LoadPlrGFX(player, graphic);
int width = player.GetAnimationWidth(graphic);
byte *pData = nullptr;
std::array<std::optional<CelSprite>, 8> *pCelSprites = nullptr;
switch (graphic) {
case PFILE_STAND:
pData = player._pNAnim[dir];
pCelSprites = &player._pNAnim;
break;
case PFILE_WALK:
pData = player._pWAnim[dir];
pCelSprites = &player._pWAnim;
break;
case PFILE_ATTACK:
pData = player._pAAnim[dir];
pCelSprites = &player._pAAnim;
break;
case PFILE_HIT:
pData = player._pHAnim[dir];
pCelSprites = &player._pHAnim;
break;
case PFILE_LIGHTNING:
pData = player._pLAnim[dir];
pCelSprites = &player._pLAnim;
break;
case PFILE_FIRE:
pData = player._pFAnim[dir];
pCelSprites = &player._pFAnim;
break;
case PFILE_MAGIC:
pData = player._pTAnim[dir];
pCelSprites = &player._pTAnim;
break;
case PFILE_DEATH:
pData = player._pDAnim[dir];
pCelSprites = &player._pDAnim;
break;
case PFILE_BLOCK:
pData = player._pBAnim[dir];
pCelSprites = &player._pBAnim;
break;
default:
Log("NewPlrAnim: Unkown graphic {}", graphic);
break;
}
player._pAnimWidth = width;
player.AnimInfo.SetNewAnimation(pData, numberOfFrames, delayLen, flags, numSkippedFrames, distributeFramesBeforeFrame);
CelSprite *pCelSprite = nullptr;
if (pCelSprites != nullptr && (*pCelSprites)[dir])
pCelSprite = &*(*pCelSprites)[dir];
player.AnimInfo.SetNewAnimation(pCelSprite, numberOfFrames, delayLen, flags, numSkippedFrames, distributeFramesBeforeFrame);
}
static void ClearPlrPVars(PlayerStruct &player)
@ -3892,21 +3815,21 @@ void SyncPlrAnim(int pnum)
dir = player._pdir;
switch (player._pmode) {
case PM_STAND:
player.AnimInfo.pData = player._pNAnim[dir];
player.AnimInfo.pCelSprite = &*player._pNAnim[dir];
break;
case PM_WALK:
case PM_WALK2:
case PM_WALK3:
player.AnimInfo.pData = player._pWAnim[dir];
player.AnimInfo.pCelSprite = &*player._pWAnim[dir];
break;
case PM_ATTACK:
player.AnimInfo.pData = player._pAAnim[dir];
player.AnimInfo.pCelSprite = &*player._pAAnim[dir];
break;
case PM_RATTACK:
player.AnimInfo.pData = player._pAAnim[dir];
player.AnimInfo.pCelSprite = &*player._pAAnim[dir];
break;
case PM_BLOCK:
player.AnimInfo.pData = player._pBAnim[dir];
player.AnimInfo.pCelSprite = &*player._pBAnim[dir];
break;
case PM_SPELL:
if (pnum == myplr)
@ -3914,23 +3837,23 @@ void SyncPlrAnim(int pnum)
else
sType = STYPE_FIRE;
if (sType == STYPE_FIRE)
player.AnimInfo.pData = player._pFAnim[dir];
player.AnimInfo.pCelSprite = &*player._pFAnim[dir];
if (sType == STYPE_LIGHTNING)
player.AnimInfo.pData = player._pLAnim[dir];
player.AnimInfo.pCelSprite = &*player._pLAnim[dir];
if (sType == STYPE_MAGIC)
player.AnimInfo.pData = player._pTAnim[dir];
player.AnimInfo.pCelSprite = &*player._pTAnim[dir];
break;
case PM_GOTHIT:
player.AnimInfo.pData = player._pHAnim[dir];
player.AnimInfo.pCelSprite = &*player._pHAnim[dir];
break;
case PM_NEWLVL:
player.AnimInfo.pData = player._pNAnim[dir];
player.AnimInfo.pCelSprite = &*player._pNAnim[dir];
break;
case PM_DEATH:
player.AnimInfo.pData = player._pDAnim[dir];
player.AnimInfo.pCelSprite = &*player._pDAnim[dir];
break;
case PM_QUIT:
player.AnimInfo.pData = player._pNAnim[dir];
player.AnimInfo.pCelSprite = &*player._pNAnim[dir];
break;
default:
app_fatal("SyncPlrAnim");

38
Source/player.h

@ -5,6 +5,7 @@
*/
#pragma once
#include <array>
#include <cstdint>
#include "diablo.h"
@ -169,7 +170,6 @@ struct PlayerStruct {
* @brief Contains Information for current Animation
*/
AnimationInfo AnimInfo;
int _pAnimWidth;
int _plid;
int _pvid;
spell_id _pSpell;
@ -239,23 +239,23 @@ struct PlayerStruct {
bool _pSLvlVisited[NUMLEVELS]; // only 10 used
/** Using player_graphic as bitflags */
int _pGFXLoad;
byte *_pNAnim[8]; // Stand animations
std::array<std::optional<CelSprite>, 8> _pNAnim; // Stand animations
int _pNFrames;
byte *_pWAnim[8]; // Walk animations
std::array<std::optional<CelSprite>, 8> _pWAnim; // Walk animations
int _pWFrames;
byte *_pAAnim[8]; // Attack animations
std::array<std::optional<CelSprite>, 8> _pAAnim; // Attack animations
int _pAFrames;
int _pAFNum;
byte *_pLAnim[8]; // Lightning spell cast animations
byte *_pFAnim[8]; // Fire spell cast animations
byte *_pTAnim[8]; // Generic spell cast animations
std::array<std::optional<CelSprite>, 8> _pLAnim; // Lightning spell cast animations
std::array<std::optional<CelSprite>, 8> _pFAnim; // Fire spell cast animations
std::array<std::optional<CelSprite>, 8> _pTAnim; // Generic spell cast animations
int _pSFrames;
int _pSFNum;
byte *_pHAnim[8]; // Getting hit animations
std::array<std::optional<CelSprite>, 8> _pHAnim; // Getting hit animations
int _pHFrames;
byte *_pDAnim[8]; // Death animations
std::array<std::optional<CelSprite>, 8> _pDAnim; // Death animations
int _pDFrames;
byte *_pBAnim[8]; // Block animations
std::array<std::optional<CelSprite>, 8> _pBAnim; // Block animations
int _pBFrames;
ItemStruct InvBody[NUM_INVLOC];
ItemStruct InvList[NUM_INV_GRID_ELEM];
@ -294,15 +294,15 @@ struct PlayerStruct {
uint8_t pDiabloKillLevel;
_difficulty pDifficulty;
uint32_t pDamAcFlags;
byte *_pNData;
byte *_pWData;
byte *_pAData;
byte *_pLData;
byte *_pFData;
byte *_pTData;
byte *_pHData;
byte *_pDData;
byte *_pBData;
std::unique_ptr<byte[]> _pNData;
std::unique_ptr<byte[]> _pWData;
std::unique_ptr<byte[]> _pAData;
std::unique_ptr<byte[]> _pLData;
std::unique_ptr<byte[]> _pFData;
std::unique_ptr<byte[]> _pTData;
std::unique_ptr<byte[]> _pHData;
std::unique_ptr<byte[]> _pDData;
std::unique_ptr<byte[]> _pBData;
void CalcScrolls();

23
Source/scrollrt.cpp

@ -354,7 +354,7 @@ static void DrawMonster(const CelOutputBuffer &out, int x, int y, int mx, int my
*/
static void DrawPlayerIconHelper(const CelOutputBuffer &out, int pnum, missile_graphic_id missileGraphicId, int x, int y, bool lighting)
{
x += CalculateWidth2(plr[pnum]._pAnimWidth) - misfiledata[missileGraphicId].mAnimWidth2[0];
x += CalculateWidth2(plr[pnum].AnimInfo.pCelSprite->Width()) - misfiledata[missileGraphicId].mAnimWidth2[0];
int width = misfiledata[missileGraphicId].mAnimWidth[0];
byte *pCelBuff = misfiledata[missileGraphicId].mAnimData[0];
@ -410,16 +410,15 @@ static void DrawPlayer(const CelOutputBuffer &out, int pnum, int x, int y, int p
PlayerStruct *pPlayer = &plr[pnum];
byte *pCelBuff = pPlayer->AnimInfo.pData;
auto *pCelSprite = pPlayer->AnimInfo.pCelSprite;
int nCel = pPlayer->AnimInfo.GetFrameToUseForRendering();
if (pCelBuff == nullptr) {
Log("Drawing player {} \"{}\": NULL Cel Buffer", pnum, plr[pnum]._pName);
if (pCelSprite == nullptr) {
Log("Drawing player {} \"{}\": NULL CelSprite", pnum, plr[pnum]._pName);
return;
}
CelSprite cel { pCelBuff, pPlayer->_pAnimWidth };
int frames = SDL_SwapLE32(*reinterpret_cast<const DWORD *>(cel.Data()));
int frames = SDL_SwapLE32(*reinterpret_cast<const DWORD *>(pCelSprite->Data()));
if (nCel < 1 || frames > 50 || nCel > frames) {
const char *szMode = "unknown action";
if (plr[pnum]._pmode <= PM_QUIT)
@ -436,16 +435,16 @@ static void DrawPlayer(const CelOutputBuffer &out, int pnum, int x, int y, int p
}
if (pnum == pcursplr)
Cl2DrawOutline(out, 165, px, py, cel, nCel);
Cl2DrawOutline(out, 165, px, py, *pCelSprite, nCel);
if (pnum == myplr) {
Cl2Draw(out, px, py, cel, nCel);
Cl2Draw(out, px, py, *pCelSprite, nCel);
DrawPlayerIcons(out, pnum, px, py, true);
return;
}
if (!(dFlags[x][y] & BFLAG_LIT) || (plr[myplr]._pInfraFlag && light_table_index > 8)) {
Cl2DrawLightTbl(out, px, py, cel, nCel, 1);
Cl2DrawLightTbl(out, px, py, *pCelSprite, nCel, 1);
DrawPlayerIcons(out, pnum, px, py, true);
return;
}
@ -456,7 +455,7 @@ static void DrawPlayer(const CelOutputBuffer &out, int pnum, int x, int y, int p
else
light_table_index -= 5;
Cl2DrawLight(out, px, py, cel, nCel);
Cl2DrawLight(out, px, py, *pCelSprite, nCel);
DrawPlayerIcons(out, pnum, px, py, false);
light_table_index = l;
@ -481,7 +480,7 @@ void DrawDeadPlayer(const CelOutputBuffer &out, int x, int y, int sx, int sy)
p = &plr[i];
if (p->plractive && p->_pHitPoints == 0 && p->plrlevel == (BYTE)currlevel && p->position.tile.x == x && p->position.tile.y == y) {
dFlags[x][y] |= BFLAG_DEAD_PLAYER;
px = sx + p->position.offset.x - CalculateWidth2(p->_pAnimWidth);
px = sx + p->position.offset.x - CalculateWidth2(p->AnimInfo.pCelSprite == nullptr ? 96 : p->AnimInfo.pCelSprite->Width());
py = sy + p->position.offset.y;
DrawPlayer(out, i, x, y, px, py);
}
@ -718,7 +717,7 @@ static void DrawPlayerHelper(const CelOutputBuffer &out, int x, int y, int sx, i
if (pPlayer->IsWalking()) {
offset = GetOffsetForWalking(pPlayer->AnimInfo, pPlayer->_pdir);
}
int px = sx + offset.x - CalculateWidth2(pPlayer->_pAnimWidth);
int px = sx + offset.x - CalculateWidth2(pPlayer->AnimInfo.pCelSprite == nullptr ? 96 : pPlayer->AnimInfo.pCelSprite->Width());
int py = sy + offset.y;
DrawPlayer(out, p, x, y, px, py);

1
test/writehero_test.cpp

@ -296,7 +296,6 @@ static void AssertPlayer(PlayerStruct *pPlayer)
ASSERT_EQ(pPlayer->AnimInfo.DelayCounter, 1);
ASSERT_EQ(pPlayer->AnimInfo.NumberOfFrames, 20);
ASSERT_EQ(pPlayer->AnimInfo.CurrentFrame, 1);
ASSERT_EQ(pPlayer->_pAnimWidth, 96);
ASSERT_EQ(pPlayer->_pSpell, -1);
ASSERT_EQ(pPlayer->_pSplType, 4);
ASSERT_EQ(pPlayer->_pSplFrom, 0);

Loading…
Cancel
Save