Files
devilutionX/Source/dead.cpp
T
Gleb Mazovetskiy 961866e1c4 CLX: A new graphics format
The format is almost identical to CL2, except it uses the frame header
to store frame width and height instead of 5 32-line offsets.

This means we always have access to frame dimensions, so we can use it
as an on-disk format for our graphics as well.

Additionally, we may be able to optimize the rendering even more
in the future now that we have guaranteed knowledge of frame dimensions.
2022-08-03 02:38:55 +02:00

98 lines
2.2 KiB
C++

/**
* @file dead.cpp
*
* Implementation of functions for placing dead monsters.
*/
#include "dead.h"
#include "diablo.h"
#include "levels/gendung.h"
#include "lighting.h"
#include "misdat.h"
#include "monster.h"
namespace devilution {
Corpse Corpses[MaxCorpses];
int8_t stonendx;
namespace {
void InitDeadAnimationFromMonster(Corpse &corpse, const CMonster &mon)
{
const AnimStruct &animData = mon.getAnimData(MonsterGraphic::Death);
if (animData.sprites) {
corpse.sprites.emplace(*animData.sprites);
} else {
corpse.sprites = std::nullopt;
}
corpse.frame = animData.frames - 1;
corpse.width = animData.width;
}
} // namespace
void InitCorpses()
{
int8_t mtypes[MaxMonsters] = {};
int8_t nd = 0;
for (size_t i = 0; i < LevelMonsterTypeCount; i++) {
CMonster &monsterType = LevelMonsterTypes[i];
if (mtypes[monsterType.type] != 0)
continue;
InitDeadAnimationFromMonster(Corpses[nd], monsterType);
Corpses[nd].translationPaletteIndex = 0;
nd++;
monsterType.corpseId = nd;
mtypes[monsterType.type] = nd;
}
nd++; // Unused blood spatter
if (!HeadlessMode)
Corpses[nd].sprites.emplace(*MissileSpriteData[MFILE_SHATTER1].sprites);
Corpses[nd].frame = 11;
Corpses[nd].width = 128;
Corpses[nd].translationPaletteIndex = 0;
nd++;
stonendx = nd;
for (size_t i = 0; i < ActiveMonsterCount; i++) {
auto &monster = Monsters[ActiveMonsters[i]];
if (monster.isUnique()) {
InitDeadAnimationFromMonster(Corpses[nd], monster.type());
Corpses[nd].translationPaletteIndex = ActiveMonsters[i] + 1;
nd++;
monster.corpseId = nd;
}
}
assert(static_cast<unsigned>(nd) <= MaxCorpses);
}
void AddCorpse(Point tilePosition, int8_t dv, Direction ddir)
{
dCorpse[tilePosition.x][tilePosition.y] = (dv & 0x1F) + (static_cast<int>(ddir) << 5);
}
void SyncUniqDead()
{
for (size_t i = 0; i < ActiveMonsterCount; i++) {
auto &monster = Monsters[ActiveMonsters[i]];
if (!monster.isUnique())
continue;
for (int dx = 0; dx < MAXDUNX; dx++) {
for (int dy = 0; dy < MAXDUNY; dy++) {
if ((dCorpse[dx][dy] & 0x1F) == monster.corpseId)
ChangeLightXY(monster.lightId, { dx, dy });
}
}
}
}
} // namespace devilution