/** * @file dead.cpp * * Implementation of functions for placing dead monsters. */ #include "dead.h" #include #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; } void MoveLightToCorpse(Monster &monster) { 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 }); return; } } } AddUnLight(monster.lightId); } } // 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(*GetMissileSpriteData(MissileGraphicID::StoneCurseShatter).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(nd) <= MaxCorpses); } void AddCorpse(Point tilePosition, int8_t dv, Direction ddir) { dCorpse[tilePosition.x][tilePosition.y] = (dv & 0x1F) + (static_cast(ddir) << 5); } void MoveLightsToCorpses() { for (size_t i = 0; i < ActiveMonsterCount; i++) { auto &monster = Monsters[ActiveMonsters[i]]; if (!monster.isUnique()) continue; MoveLightToCorpse(monster); } } } // namespace devilution