Browse Source

Optimize `MissileData`: 32 bytes -> 24

23 bytes used, 1 spare byte in the padding.
pull/5766/head^2
Gleb Mazovetskiy 3 years ago committed by Anders Jenbo
parent
commit
98294e0ad5
  1. 2
      Source/engine/render/scrollrt.cpp
  2. 2
      Source/loadsave.cpp
  3. 352
      Source/misdat.cpp
  4. 47
      Source/misdat.h
  5. 58
      Source/missiles.cpp
  6. 2
      Source/missiles.h
  7. 4
      Source/monster.cpp

2
Source/engine/render/scrollrt.cpp

@ -122,7 +122,7 @@ void UpdateMissileRendererData(Missile &m)
m.position.tileForRendering = m.position.tile;
m.position.offsetForRendering = m.position.offset;
const MissileMovementDistribution missileMovement = GetMissileData(m._mitype).MovementDistribution;
const MissileMovementDistribution missileMovement = GetMissileData(m._mitype).movementDistribution;
// don't calculate missile position if they don't move
if (missileMovement == MissileMovementDistribution::Disabled || m.position.velocity == Displacement {})
return;

2
Source/loadsave.cpp

@ -706,7 +706,7 @@ void LoadMissile(LoadHelper *file)
missile._miDelFlag = file->NextBool32();
missile._miAnimType = static_cast<MissileGraphicID>(file->NextLE<uint8_t>());
file->Skip(3); // Alignment
missile._miAnimFlags = static_cast<MissileDataFlags>(file->NextLE<int32_t>());
missile._miAnimFlags = static_cast<MissileGraphicsFlags>(file->NextLE<int32_t>());
file->Skip(4); // Skip pointer _miAnimData
missile._miAnimDelay = file->NextLE<int32_t>();
missile._miAnimLen = file->NextLE<int32_t>();

352
Source/misdat.cpp

@ -13,118 +13,128 @@
namespace devilution {
namespace {
constexpr auto Physical = MissileDataFlags::Physical;
constexpr auto Fire = MissileDataFlags::Fire;
constexpr auto Lightning = MissileDataFlags::Lightning;
constexpr auto Magic = MissileDataFlags::Magic;
constexpr auto Acid = MissileDataFlags::Acid;
constexpr auto Arrow = MissileDataFlags::Arrow;
constexpr auto Invisible = MissileDataFlags::Invisible;
} // namespace
/** Data related to each missile ID. */
MissileData MissilesData[] = {
// clang-format off
// id mAddProc, mProc, mDraw, mType, damageType, mFileNum, mlSFX, miSFX, MovementDistribution;
/*Arrow*/ { &AddArrow, &ProcessArrow, true, 0, DamageType::Physical, MissileGraphicID::Arrow, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable },
/*Firebolt*/ { &AddFirebolt, &ProcessGenericProjectile, true, 1, DamageType::Fire, MissileGraphicID::Fireball, LS_FBOLT1, LS_FIRIMP2, MissileMovementDistribution::Blockable },
/*Guardian*/ { &AddGuardian, &ProcessGuardian, true, 1, DamageType::Physical, MissileGraphicID::Guardian, LS_GUARD, LS_GUARDLAN, MissileMovementDistribution::Disabled },
/*Phasing*/ { &AddPhasing, &ProcessTeleport, false, 1, DamageType::Physical, MissileGraphicID::None, LS_TELEPORT, SFX_NONE, MissileMovementDistribution::Disabled },
/*NovaBall*/ { &AddNovaBall, &ProcessNovaBall, true, 1, DamageType::Lightning, MissileGraphicID::Lightning, SFX_NONE, SFX_NONE, MissileMovementDistribution::Unblockable },
/*FireWall*/ { &AddFireWall, &ProcessFireWall, true, 1, DamageType::Fire, MissileGraphicID::FireWall, LS_WALLLOOP, LS_FIRIMP2, MissileMovementDistribution::Disabled },
/*Fireball*/ { &AddFireball, &ProcessFireball, true, 1, DamageType::Fire, MissileGraphicID::Fireball, LS_FBOLT1, LS_FIRIMP2, MissileMovementDistribution::Blockable },
/*LightningControl*/ { &AddLightningControl, &ProcessLightningControl, false, 1, DamageType::Lightning, MissileGraphicID::Lightning, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Lightning*/ { &AddLightning, &ProcessLightning, true, 1, DamageType::Lightning, MissileGraphicID::Lightning, LS_LNING1, LS_ELECIMP1, MissileMovementDistribution::Disabled },
/*MagmaBallExplosion*/ { &AddMissileExplosion, &ProcessMissileExplosion, true, 2, DamageType::Physical, MissileGraphicID::MagmaBallExplosion, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*TownPortal*/ { &AddTownPortal, &ProcessTownPortal, true, 1, DamageType::Magic, MissileGraphicID::TownPortal, LS_SENTINEL, LS_ELEMENTL, MissileMovementDistribution::Disabled },
/*FlashBottom*/ { &AddFlashBottom, &ProcessFlashBottom, true, 1, DamageType::Magic, MissileGraphicID::FlashBottom, LS_NOVA, LS_ELECIMP1, MissileMovementDistribution::Disabled },
/*FlashTop*/ { &AddFlashTop, &ProcessFlashTop, true, 1, DamageType::Magic, MissileGraphicID::FlashTop, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*ManaShield*/ { &AddManaShield, nullptr, false, 1, DamageType::Magic, MissileGraphicID::ManaShield, LS_MSHIELD, SFX_NONE, MissileMovementDistribution::Disabled },
/*FlameWave*/ { &AddFlameWave, &ProcessFlameWave, true, 1, DamageType::Fire, MissileGraphicID::FireWall, SFX_NONE, SFX_NONE, MissileMovementDistribution::Unblockable },
/*ChainLightning*/ { &AddChainLightning, &ProcessChainLightning, true, 1, DamageType::Lightning, MissileGraphicID::Lightning, LS_LNING1, LS_ELECIMP1, MissileMovementDistribution::Disabled },
/*ChainBall*/ { nullptr, nullptr, true, 1, DamageType::Lightning, MissileGraphicID::Lightning, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*BloodHit*/ { nullptr, nullptr, true, 2, DamageType::Physical, MissileGraphicID::BloodHit, LS_BLODSTAR, LS_BLSIMPT, MissileMovementDistribution::Disabled },
/*BoneHit*/ { nullptr, nullptr, true, 2, DamageType::Physical, MissileGraphicID::BoneHit, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*MetalHit*/ { nullptr, nullptr, true, 2, DamageType::Physical, MissileGraphicID::MetalHit, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Rhino*/ { &AddRhino, &ProcessRhino, true, 2, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable },
/*MagmaBall*/ { &AddMagmaBall, &ProcessGenericProjectile, true, 1, DamageType::Fire, MissileGraphicID::MagmaBall, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable },
/*ThinLightningControl*/ { &AddLightningControl, &ProcessLightningControl, false, 1, DamageType::Lightning, MissileGraphicID::ThinLightning, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*ThinLightning*/ { &AddLightning, &ProcessLightning, true, 1, DamageType::Lightning, MissileGraphicID::ThinLightning, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*BloodStar*/ { &AddGenericMagicMissile, &ProcessGenericProjectile, true, 1, DamageType::Magic, MissileGraphicID::BloodStar, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable },
/*BloodStarExplosion*/ { &AddMissileExplosion, &ProcessMissileExplosion, true, 2, DamageType::Magic, MissileGraphicID::BloodStarExplosion, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Teleport*/ { &AddTeleport, &ProcessTeleport, false, 1, DamageType::Physical, MissileGraphicID::None, LS_ELEMENTL, SFX_NONE, MissileMovementDistribution::Disabled },
/*FireArrow*/ { &AddElementalArrow, &ProcessElementalArrow, true, 0, DamageType::Fire, MissileGraphicID::FireArrow, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable },
/*DoomSerpents*/ { nullptr, nullptr, false, 1, DamageType::Magic, MissileGraphicID::DoomSerpents, LS_DSERP, SFX_NONE, MissileMovementDistribution::Disabled },
/*FireOnly*/ { nullptr, nullptr, true, 2, DamageType::Fire, MissileGraphicID::FireWall, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*StoneCurse*/ { &AddStoneCurse, &ProcessStoneCurse, false, 1, DamageType::Magic, MissileGraphicID::None, LS_SCURIMP, SFX_NONE, MissileMovementDistribution::Disabled },
/*BloodRitual*/ { nullptr, nullptr, true, 1, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Invisibility*/ { nullptr, nullptr, false, 1, DamageType::Physical, MissileGraphicID::None, LS_INVISIBL, SFX_NONE, MissileMovementDistribution::Disabled },
/*Golem*/ { &AddGolem, nullptr, false, 1, DamageType::Physical, MissileGraphicID::None, LS_GOLUM, SFX_NONE, MissileMovementDistribution::Disabled },
/*Etherealize*/ { nullptr, nullptr, true, 1, DamageType::Physical, MissileGraphicID::Etherealize, LS_ETHEREAL, SFX_NONE, MissileMovementDistribution::Disabled },
/*Spurt*/ { nullptr, nullptr, true, 2, DamageType::Physical, MissileGraphicID::Spurt, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*ApocalypseBoom*/ { &AddApocalypseBoom, &ProcessApocalypseBoom, true, 2, DamageType::Physical, MissileGraphicID::ApocalypseBoom, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Healing*/ { &AddHealing, nullptr, false, 1, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*FireWallControl*/ { &AddFireWallControl, &ProcessFireWallControl, false, 1, DamageType::Fire, MissileGraphicID::FireWall, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Infravision*/ { &AddInfravision, &ProcessInfravision, false, 1, DamageType::Physical, MissileGraphicID::None, LS_INFRAVIS, SFX_NONE, MissileMovementDistribution::Disabled },
/*Identify*/ { &AddIdentify, nullptr, false, 1, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*FlameWaveControl*/ { &AddFlameWaveControl, &ProcessFlameWaveControl, true, 1, DamageType::Fire, MissileGraphicID::FireWall, LS_FLAMWAVE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Nova*/ { &AddNova, &ProcessNova, true, 1, DamageType::Lightning, MissileGraphicID::Lightning, LS_NOVA, SFX_NONE, MissileMovementDistribution::Disabled },
/*Rage*/ { &AddRage, &ProcessRage, false, 1, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Apocalypse*/ { &AddApocalypse, &ProcessApocalypse, true, 1, DamageType::Magic, MissileGraphicID::ApocalypseBoom, LS_APOC, SFX_NONE, MissileMovementDistribution::Disabled },
/*ItemRepair*/ { &AddItemRepair, nullptr, false, 2, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*StaffRecharge*/ { &AddStaffRecharge, nullptr, false, 2, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*TrapDisarm*/ { &AddTrapDisarm, nullptr, false, 2, DamageType::Physical, MissileGraphicID::None, LS_TRAPDIS, SFX_NONE, MissileMovementDistribution::Disabled },
/*Inferno*/ { &AddInferno, &ProcessInferno, true, 1, DamageType::Fire, MissileGraphicID::Inferno, LS_SPOUTSTR, SFX_NONE, MissileMovementDistribution::Disabled },
/*InfernoControl*/ { &AddInfernoControl, &ProcessInfernoControl, false, 1, DamageType::Fire, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*FireMan*/ { nullptr, nullptr, true, 2, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable },
/*Krull*/ { nullptr, nullptr, true, 0, DamageType::Fire, MissileGraphicID::Krull, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable },
/*ChargedBolt*/ { &AddChargedBolt, &ProcessChargedBolt, true, 1, DamageType::Lightning, MissileGraphicID::ChargedBolt, LS_CBOLT, SFX_NONE, MissileMovementDistribution::Blockable },
/*HolyBolt*/ { &AddHolyBolt, &ProcessHolyBolt, true, 1, DamageType::Physical, MissileGraphicID::HolyBolt, LS_HOLYBOLT, LS_ELECIMP1, MissileMovementDistribution::Blockable },
/*Resurrect*/ { &AddResurrect, nullptr, false, 1, DamageType::Magic, MissileGraphicID::None, SFX_NONE, LS_RESUR, MissileMovementDistribution::Disabled },
/*Telekinesis*/ { &AddTelekinesis, nullptr, false, 1, DamageType::Physical, MissileGraphicID::None, LS_ETHEREAL, SFX_NONE, MissileMovementDistribution::Disabled },
/*LightningArrow*/ { &AddElementalArrow, &ProcessElementalArrow, true, 0, DamageType::Lightning, MissileGraphicID::LightningArrow, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable },
/*Acid*/ { &AddAcid, &ProcessGenericProjectile, true, 1, DamageType::Acid, MissileGraphicID::Acid, LS_ACID, SFX_NONE, MissileMovementDistribution::Blockable },
/*AcidSplat*/ { &AddMissileExplosion, &ProcessAcidSplate, true, 2, DamageType::Acid, MissileGraphicID::AcidSplat, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*AcidPuddle*/ { &AddAcidPuddle, &ProcessAcidPuddle, true, 2, DamageType::Acid, MissileGraphicID::AcidPuddle, LS_PUDDLE, SFX_NONE, MissileMovementDistribution::Disabled },
/*HealOther*/ { &AddHealOther, nullptr, false, 1, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Elemental*/ { &AddElemental, &ProcessElemental, true, 1, DamageType::Fire, MissileGraphicID::Elemental, LS_ELEMENTL, SFX_NONE, MissileMovementDistribution::Unblockable },
/*ResurrectBeam*/ { &AddResurrectBeam, &ProcessResurrectBeam, true, 1, DamageType::Physical, MissileGraphicID::Resurrect, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*BoneSpirit*/ { &AddBoneSpirit, &ProcessBoneSpirit, true, 1, DamageType::Magic, MissileGraphicID::BoneSpirit, LS_BONESP, LS_BSIMPCT, MissileMovementDistribution::Blockable },
/*WeaponExplosion*/ { &AddWeaponExplosion, &ProcessWeaponExplosion, true, 2, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*RedPortal*/ { &AddRedPortal, &ProcessRedPortal, true, 2, DamageType::Physical, MissileGraphicID::RedPortal, LS_SENTINEL, LS_ELEMENTL, MissileMovementDistribution::Disabled },
/*DiabloApocalypseBoom*/ { &AddApocalypseBoom, &ProcessApocalypseBoom, true, 2, DamageType::Physical, MissileGraphicID::DiabloApocalypseBoom, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*DiabloApocalypse*/ { &AddDiabloApocalypse, nullptr, false, 2, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Mana*/ { &AddMana, nullptr, false, 1, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Magi*/ { &AddMagi, nullptr, false, 1, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*LightningWall*/ { &AddLightningWall, &ProcessLightningWall, true, 1, DamageType::Lightning, MissileGraphicID::Lightning, LS_LMAG, LS_ELECIMP1, MissileMovementDistribution::Disabled },
/*LightningWallControl*/ { &AddFireWallControl, &ProcessLightningWallControl, false, 1, DamageType::Lightning, MissileGraphicID::Lightning, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Immolation*/ { &AddNova, &ProcessImmolation, true, 1, DamageType::Fire, MissileGraphicID::Fireball, LS_FBOLT1, LS_FIRIMP2, MissileMovementDistribution::Disabled },
/*SpectralArrow*/ { &AddSpectralArrow, &ProcessSpectralArrow, true, 0, DamageType::Physical, MissileGraphicID::Arrow, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*FireballBow*/ { &AddImmolation, &ProcessFireball, true, 1, DamageType::Fire, MissileGraphicID::Fireball, IS_FBALLBOW, LS_FIRIMP2, MissileMovementDistribution::Blockable },
/*LightningBow*/ { &AddLightningBow, &ProcessLightningBow, false, 1, DamageType::Lightning, MissileGraphicID::Lightning, IS_FBALLBOW, SFX_NONE, MissileMovementDistribution::Disabled },
/*ChargedBoltBow*/ { &AddChargedBoltBow, &ProcessChargedBolt, true, 1, DamageType::Lightning, MissileGraphicID::ChargedBolt, LS_CBOLT, SFX_NONE, MissileMovementDistribution::Blockable },
/*HolyBoltBow*/ { &AddHolyBolt, &ProcessHolyBolt, true, 1, DamageType::Physical, MissileGraphicID::HolyBolt, LS_HOLYBOLT, LS_ELECIMP1, MissileMovementDistribution::Blockable },
/*Warp*/ { &AddWarp, &ProcessTeleport, false, 1, DamageType::Physical, MissileGraphicID::None, LS_ETHEREAL, SFX_NONE, MissileMovementDistribution::Disabled },
/*Reflect*/ { &AddReflect, nullptr, false, 1, DamageType::Physical, MissileGraphicID::Reflect, LS_MSHIELD, SFX_NONE, MissileMovementDistribution::Disabled },
/*Berserk*/ { &AddBerserk, nullptr, false, 1, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*RingOfFire*/ { &AddRingOfFire, &ProcessRingOfFire, false, 1, DamageType::Fire, MissileGraphicID::FireWall, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*StealPotions*/ { &AddStealPotions, nullptr, false, 1, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*StealMana*/ { &AddStealMana, nullptr, false, 1, DamageType::Physical, MissileGraphicID::None, IS_CAST7, SFX_NONE, MissileMovementDistribution::Disabled },
/*RingOfLightning*/ { nullptr, nullptr, false, 1, DamageType::Lightning, MissileGraphicID::Lightning, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Search*/ { &AddSearch, &ProcessSearch, false, 1, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Aura*/ { nullptr, nullptr, false, 1, DamageType::Magic, MissileGraphicID::FlashBottom, SFX_NONE, LS_ELECIMP1, MissileMovementDistribution::Disabled },
/*Aura2*/ { nullptr, nullptr, false, 1, DamageType::Magic, MissileGraphicID::FlashTop, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*SpiralFireball*/ { nullptr, nullptr, true, 1, DamageType::Fire, MissileGraphicID::Fireball, LS_FBOLT1, LS_FIRIMP2, MissileMovementDistribution::Disabled },
/*RuneOfFire*/ { &AddRuneOfFire, &ProcessRune, true, 1, DamageType::Physical, MissileGraphicID::Rune, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*RuneOfLight*/ { &AddRuneOfLight, &ProcessRune, true, 1, DamageType::Physical, MissileGraphicID::Rune, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*RuneOfNova*/ { &AddRuneOfNova, &ProcessRune, true, 1, DamageType::Physical, MissileGraphicID::Rune, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*RuneOfImmolation*/ { &AddRuneOfImmolation, &ProcessRune, true, 1, DamageType::Physical, MissileGraphicID::Rune, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*RuneOfStone*/ { &AddRuneOfStone, &ProcessRune, true, 1, DamageType::Physical, MissileGraphicID::Rune, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*BigExplosion*/ { &AddBigExplosion, &ProcessBigExplosion, true, 1, DamageType::Fire, MissileGraphicID::BigExplosion, LS_NESTXPLD, LS_NESTXPLD, MissileMovementDistribution::Disabled },
/*HorkSpawn*/ { &AddHorkSpawn, &ProcessHorkSpawn, false, 2, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*Jester*/ { &AddJester, nullptr, false, 2, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*OpenNest*/ { &AddOpenNest, nullptr, false, 2, DamageType::Physical, MissileGraphicID::None, SFX_NONE, SFX_NONE, MissileMovementDistribution::Disabled },
/*OrangeFlare*/ { &AddGenericMagicMissile, &ProcessGenericProjectile, true, 1, DamageType::Magic, MissileGraphicID::OrangeFlare, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable },
/*BlueFlare*/ { &AddGenericMagicMissile, &ProcessGenericProjectile, true, 1, DamageType::Magic, MissileGraphicID::BlueFlare2, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable },
/*RedFlare*/ { &AddGenericMagicMissile, &ProcessGenericProjectile, true, 1, DamageType::Magic, MissileGraphicID::RedFlare, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable },
/*YellowFlare*/ { &AddGenericMagicMissile, &ProcessGenericProjectile, true, 1, DamageType::Magic, MissileGraphicID::YellowFlare, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable },
/*BlueFlare2*/ { &AddGenericMagicMissile, &ProcessGenericProjectile, true, 1, DamageType::Magic, MissileGraphicID::BlueFlare2, SFX_NONE, SFX_NONE, MissileMovementDistribution::Blockable },
/*YellowExplosion*/ { &AddMissileExplosion, &ProcessMissileExplosion, true, 2, DamageType::Physical, MissileGraphicID::YellowFlareExplosion, LS_FIRIMP2, SFX_NONE, MissileMovementDistribution::Disabled },
/*RedExplosion*/ { &AddMissileExplosion, &ProcessMissileExplosion, true, 2, DamageType::Physical, MissileGraphicID::RedFlareExplosion, LS_FIRIMP2, SFX_NONE, MissileMovementDistribution::Disabled },
/*BlueExplosion*/ { &AddMissileExplosion, &ProcessMissileExplosion, true, 2, DamageType::Physical, MissileGraphicID::BlueFlareExplosion, LS_FIRIMP2, SFX_NONE, MissileMovementDistribution::Disabled },
/*BlueExplosion2*/ { &AddMissileExplosion, &ProcessMissileExplosion, true, 2, DamageType::Physical, MissileGraphicID::BlueFlareExplosion2, LS_FIRIMP2, SFX_NONE, MissileMovementDistribution::Disabled },
/*OrangeExplosion*/ { &AddMissileExplosion, &ProcessMissileExplosion, true, 2, DamageType::Physical, MissileGraphicID::OrangeFlareExplosion, LS_FIRIMP2, SFX_NONE, MissileMovementDistribution::Disabled },
// id mAddProc, mProc, mlSFX, miSFX, mFileNum, flags, MovementDistribution;
/*Arrow*/ { &AddArrow, &ProcessArrow, SFX_NONE, SFX_NONE, MissileGraphicID::Arrow, Physical | Arrow, MissileMovementDistribution::Blockable },
/*Firebolt*/ { &AddFirebolt, &ProcessGenericProjectile, LS_FBOLT1, LS_FIRIMP2, MissileGraphicID::Fireball, Fire, MissileMovementDistribution::Blockable },
/*Guardian*/ { &AddGuardian, &ProcessGuardian, LS_GUARD, LS_GUARDLAN, MissileGraphicID::Guardian, Physical, MissileMovementDistribution::Disabled },
/*Phasing*/ { &AddPhasing, &ProcessTeleport, LS_TELEPORT, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*NovaBall*/ { &AddNovaBall, &ProcessNovaBall, SFX_NONE, SFX_NONE, MissileGraphicID::Lightning, Lightning, MissileMovementDistribution::Unblockable },
/*FireWall*/ { &AddFireWall, &ProcessFireWall, LS_WALLLOOP, LS_FIRIMP2, MissileGraphicID::FireWall, Fire, MissileMovementDistribution::Disabled },
/*Fireball*/ { &AddFireball, &ProcessFireball, LS_FBOLT1, LS_FIRIMP2, MissileGraphicID::Fireball, Fire, MissileMovementDistribution::Blockable },
/*LightningControl*/ { &AddLightningControl, &ProcessLightningControl, SFX_NONE, SFX_NONE, MissileGraphicID::Lightning, Lightning | Invisible, MissileMovementDistribution::Disabled },
/*Lightning*/ { &AddLightning, &ProcessLightning, LS_LNING1, LS_ELECIMP1, MissileGraphicID::Lightning, Lightning, MissileMovementDistribution::Disabled },
/*MagmaBallExplosion*/ { &AddMissileExplosion, &ProcessMissileExplosion, SFX_NONE, SFX_NONE, MissileGraphicID::MagmaBallExplosion, Physical, MissileMovementDistribution::Disabled },
/*TownPortal*/ { &AddTownPortal, &ProcessTownPortal, LS_SENTINEL, LS_ELEMENTL, MissileGraphicID::TownPortal, Magic, MissileMovementDistribution::Disabled },
/*FlashBottom*/ { &AddFlashBottom, &ProcessFlashBottom, LS_NOVA, LS_ELECIMP1, MissileGraphicID::FlashBottom, Magic, MissileMovementDistribution::Disabled },
/*FlashTop*/ { &AddFlashTop, &ProcessFlashTop, SFX_NONE, SFX_NONE, MissileGraphicID::FlashTop, Magic, MissileMovementDistribution::Disabled },
/*ManaShield*/ { &AddManaShield, nullptr, LS_MSHIELD, SFX_NONE, MissileGraphicID::ManaShield, Magic | Invisible, MissileMovementDistribution::Disabled },
/*FlameWave*/ { &AddFlameWave, &ProcessFlameWave, SFX_NONE, SFX_NONE, MissileGraphicID::FireWall, Fire, MissileMovementDistribution::Unblockable },
/*ChainLightning*/ { &AddChainLightning, &ProcessChainLightning, LS_LNING1, LS_ELECIMP1, MissileGraphicID::Lightning, Lightning, MissileMovementDistribution::Disabled },
/*ChainBall*/ { nullptr, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::Lightning, Lightning, MissileMovementDistribution::Disabled },
/*BloodHit*/ { nullptr, nullptr, LS_BLODSTAR, LS_BLSIMPT, MissileGraphicID::BloodHit, Physical, MissileMovementDistribution::Disabled },
/*BoneHit*/ { nullptr, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::BoneHit, Physical, MissileMovementDistribution::Disabled },
/*MetalHit*/ { nullptr, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::MetalHit, Physical, MissileMovementDistribution::Disabled },
/*Rhino*/ { &AddRhino, &ProcessRhino, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical, MissileMovementDistribution::Blockable },
/*MagmaBall*/ { &AddMagmaBall, &ProcessGenericProjectile, SFX_NONE, SFX_NONE, MissileGraphicID::MagmaBall, Fire, MissileMovementDistribution::Blockable },
/*ThinLightningControl*/ { &AddLightningControl, &ProcessLightningControl, SFX_NONE, SFX_NONE, MissileGraphicID::ThinLightning, Lightning | Invisible, MissileMovementDistribution::Disabled },
/*ThinLightning*/ { &AddLightning, &ProcessLightning, SFX_NONE, SFX_NONE, MissileGraphicID::ThinLightning, Lightning, MissileMovementDistribution::Disabled },
/*BloodStar*/ { &AddGenericMagicMissile, &ProcessGenericProjectile, SFX_NONE, SFX_NONE, MissileGraphicID::BloodStar, Magic, MissileMovementDistribution::Blockable },
/*BloodStarExplosion*/ { &AddMissileExplosion, &ProcessMissileExplosion, SFX_NONE, SFX_NONE, MissileGraphicID::BloodStarExplosion, Magic, MissileMovementDistribution::Disabled },
/*Teleport*/ { &AddTeleport, &ProcessTeleport, LS_ELEMENTL, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*FireArrow*/ { &AddElementalArrow, &ProcessElementalArrow, SFX_NONE, SFX_NONE, MissileGraphicID::FireArrow, Fire | Arrow, MissileMovementDistribution::Blockable },
/*DoomSerpents*/ { nullptr, nullptr, LS_DSERP, SFX_NONE, MissileGraphicID::DoomSerpents, Magic | Invisible, MissileMovementDistribution::Disabled },
/*FireOnly*/ { nullptr, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::FireWall, Fire, MissileMovementDistribution::Disabled },
/*StoneCurse*/ { &AddStoneCurse, &ProcessStoneCurse, LS_SCURIMP, SFX_NONE, MissileGraphicID::None, Magic | Invisible, MissileMovementDistribution::Disabled },
/*BloodRitual*/ { nullptr, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical, MissileMovementDistribution::Disabled },
/*Invisibility*/ { nullptr, nullptr, LS_INVISIBL, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*Golem*/ { &AddGolem, nullptr, LS_GOLUM, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*Etherealize*/ { nullptr, nullptr, LS_ETHEREAL, SFX_NONE, MissileGraphicID::Etherealize, Physical, MissileMovementDistribution::Disabled },
/*Spurt*/ { nullptr, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::Spurt, Physical, MissileMovementDistribution::Disabled },
/*ApocalypseBoom*/ { &AddApocalypseBoom, &ProcessApocalypseBoom, SFX_NONE, SFX_NONE, MissileGraphicID::ApocalypseBoom, Physical, MissileMovementDistribution::Disabled },
/*Healing*/ { &AddHealing, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*FireWallControl*/ { &AddFireWallControl, &ProcessFireWallControl, SFX_NONE, SFX_NONE, MissileGraphicID::FireWall, Fire | Invisible, MissileMovementDistribution::Disabled },
/*Infravision*/ { &AddInfravision, &ProcessInfravision, LS_INFRAVIS, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*Identify*/ { &AddIdentify, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*FlameWaveControl*/ { &AddFlameWaveControl, &ProcessFlameWaveControl, LS_FLAMWAVE, SFX_NONE, MissileGraphicID::FireWall, Fire, MissileMovementDistribution::Disabled },
/*Nova*/ { &AddNova, &ProcessNova, LS_NOVA, SFX_NONE, MissileGraphicID::Lightning, Lightning, MissileMovementDistribution::Disabled },
/*Rage*/ { &AddRage, &ProcessRage, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*Apocalypse*/ { &AddApocalypse, &ProcessApocalypse, LS_APOC, SFX_NONE, MissileGraphicID::ApocalypseBoom, Magic, MissileMovementDistribution::Disabled },
/*ItemRepair*/ { &AddItemRepair, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*StaffRecharge*/ { &AddStaffRecharge, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*TrapDisarm*/ { &AddTrapDisarm, nullptr, LS_TRAPDIS, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*Inferno*/ { &AddInferno, &ProcessInferno, LS_SPOUTSTR, SFX_NONE, MissileGraphicID::Inferno, Fire, MissileMovementDistribution::Disabled },
/*InfernoControl*/ { &AddInfernoControl, &ProcessInfernoControl, SFX_NONE, SFX_NONE, MissileGraphicID::None, Fire | Invisible, MissileMovementDistribution::Disabled },
/*FireMan*/ { nullptr, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical, MissileMovementDistribution::Blockable },
/*Krull*/ { nullptr, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::Krull, Fire | Arrow, MissileMovementDistribution::Blockable },
/*ChargedBolt*/ { &AddChargedBolt, &ProcessChargedBolt, LS_CBOLT, SFX_NONE, MissileGraphicID::ChargedBolt, Lightning, MissileMovementDistribution::Blockable },
/*HolyBolt*/ { &AddHolyBolt, &ProcessHolyBolt, LS_HOLYBOLT, LS_ELECIMP1, MissileGraphicID::HolyBolt, Physical, MissileMovementDistribution::Blockable },
/*Resurrect*/ { &AddResurrect, nullptr, SFX_NONE, LS_RESUR, MissileGraphicID::None, Magic | Invisible, MissileMovementDistribution::Disabled },
/*Telekinesis*/ { &AddTelekinesis, nullptr, LS_ETHEREAL, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*LightningArrow*/ { &AddElementalArrow, &ProcessElementalArrow, SFX_NONE, SFX_NONE, MissileGraphicID::LightningArrow, Lightning | Arrow, MissileMovementDistribution::Blockable },
/*Acid*/ { &AddAcid, &ProcessGenericProjectile, LS_ACID, SFX_NONE, MissileGraphicID::Acid, Acid, MissileMovementDistribution::Blockable },
/*AcidSplat*/ { &AddMissileExplosion, &ProcessAcidSplate, SFX_NONE, SFX_NONE, MissileGraphicID::AcidSplat, Acid, MissileMovementDistribution::Disabled },
/*AcidPuddle*/ { &AddAcidPuddle, &ProcessAcidPuddle, LS_PUDDLE, SFX_NONE, MissileGraphicID::AcidPuddle, Acid, MissileMovementDistribution::Disabled },
/*HealOther*/ { &AddHealOther, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*Elemental*/ { &AddElemental, &ProcessElemental, LS_ELEMENTL, SFX_NONE, MissileGraphicID::Elemental, Fire, MissileMovementDistribution::Unblockable },
/*ResurrectBeam*/ { &AddResurrectBeam, &ProcessResurrectBeam, SFX_NONE, SFX_NONE, MissileGraphicID::Resurrect, Physical, MissileMovementDistribution::Disabled },
/*BoneSpirit*/ { &AddBoneSpirit, &ProcessBoneSpirit, LS_BONESP, LS_BSIMPCT, MissileGraphicID::BoneSpirit, Magic, MissileMovementDistribution::Blockable },
/*WeaponExplosion*/ { &AddWeaponExplosion, &ProcessWeaponExplosion, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical, MissileMovementDistribution::Disabled },
/*RedPortal*/ { &AddRedPortal, &ProcessRedPortal, LS_SENTINEL, LS_ELEMENTL, MissileGraphicID::RedPortal, Physical, MissileMovementDistribution::Disabled },
/*DiabloApocalypseBoom*/ { &AddApocalypseBoom, &ProcessApocalypseBoom, SFX_NONE, SFX_NONE, MissileGraphicID::DiabloApocalypseBoom, Physical, MissileMovementDistribution::Disabled },
/*DiabloApocalypse*/ { &AddDiabloApocalypse, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*Mana*/ { &AddMana, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*Magi*/ { &AddMagi, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*LightningWall*/ { &AddLightningWall, &ProcessLightningWall, LS_LMAG, LS_ELECIMP1, MissileGraphicID::Lightning, Lightning, MissileMovementDistribution::Disabled },
/*LightningWallControl*/ { &AddFireWallControl, &ProcessLightningWallControl, SFX_NONE, SFX_NONE, MissileGraphicID::Lightning, Lightning | Invisible, MissileMovementDistribution::Disabled },
/*Immolation*/ { &AddNova, &ProcessImmolation, LS_FBOLT1, LS_FIRIMP2, MissileGraphicID::Fireball, Fire, MissileMovementDistribution::Disabled },
/*SpectralArrow*/ { &AddSpectralArrow, &ProcessSpectralArrow, SFX_NONE, SFX_NONE, MissileGraphicID::Arrow, Physical | Arrow, MissileMovementDistribution::Disabled },
/*FireballBow*/ { &AddImmolation, &ProcessFireball, IS_FBALLBOW, LS_FIRIMP2, MissileGraphicID::Fireball, Fire, MissileMovementDistribution::Blockable },
/*LightningBow*/ { &AddLightningBow, &ProcessLightningBow, IS_FBALLBOW, SFX_NONE, MissileGraphicID::Lightning, Lightning | Invisible, MissileMovementDistribution::Disabled },
/*ChargedBoltBow*/ { &AddChargedBoltBow, &ProcessChargedBolt, LS_CBOLT, SFX_NONE, MissileGraphicID::ChargedBolt, Lightning, MissileMovementDistribution::Blockable },
/*HolyBoltBow*/ { &AddHolyBolt, &ProcessHolyBolt, LS_HOLYBOLT, LS_ELECIMP1, MissileGraphicID::HolyBolt, Physical, MissileMovementDistribution::Blockable },
/*Warp*/ { &AddWarp, &ProcessTeleport, LS_ETHEREAL, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*Reflect*/ { &AddReflect, nullptr, LS_MSHIELD, SFX_NONE, MissileGraphicID::Reflect, Physical | Invisible, MissileMovementDistribution::Disabled },
/*Berserk*/ { &AddBerserk, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*RingOfFire*/ { &AddRingOfFire, &ProcessRingOfFire, SFX_NONE, SFX_NONE, MissileGraphicID::FireWall, Fire | Invisible, MissileMovementDistribution::Disabled },
/*StealPotions*/ { &AddStealPotions, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*StealMana*/ { &AddStealMana, nullptr, IS_CAST7, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*RingOfLightning*/ { nullptr, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::Lightning, Lightning | Invisible, MissileMovementDistribution::Disabled },
/*Search*/ { &AddSearch, &ProcessSearch, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*Aura*/ { nullptr, nullptr, SFX_NONE, LS_ELECIMP1, MissileGraphicID::FlashBottom, Magic | Invisible, MissileMovementDistribution::Disabled },
/*Aura2*/ { nullptr, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::FlashTop, Magic | Invisible, MissileMovementDistribution::Disabled },
/*SpiralFireball*/ { nullptr, nullptr, LS_FBOLT1, LS_FIRIMP2, MissileGraphicID::Fireball, Fire, MissileMovementDistribution::Disabled },
/*RuneOfFire*/ { &AddRuneOfFire, &ProcessRune, SFX_NONE, SFX_NONE, MissileGraphicID::Rune, Physical, MissileMovementDistribution::Disabled },
/*RuneOfLight*/ { &AddRuneOfLight, &ProcessRune, SFX_NONE, SFX_NONE, MissileGraphicID::Rune, Physical, MissileMovementDistribution::Disabled },
/*RuneOfNova*/ { &AddRuneOfNova, &ProcessRune, SFX_NONE, SFX_NONE, MissileGraphicID::Rune, Physical, MissileMovementDistribution::Disabled },
/*RuneOfImmolation*/ { &AddRuneOfImmolation, &ProcessRune, SFX_NONE, SFX_NONE, MissileGraphicID::Rune, Physical, MissileMovementDistribution::Disabled },
/*RuneOfStone*/ { &AddRuneOfStone, &ProcessRune, SFX_NONE, SFX_NONE, MissileGraphicID::Rune, Physical, MissileMovementDistribution::Disabled },
/*BigExplosion*/ { &AddBigExplosion, &ProcessBigExplosion, LS_NESTXPLD, LS_NESTXPLD, MissileGraphicID::BigExplosion, Fire, MissileMovementDistribution::Disabled },
/*HorkSpawn*/ { &AddHorkSpawn, &ProcessHorkSpawn, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*Jester*/ { &AddJester, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*OpenNest*/ { &AddOpenNest, nullptr, SFX_NONE, SFX_NONE, MissileGraphicID::None, Physical | Invisible, MissileMovementDistribution::Disabled },
/*OrangeFlare*/ { &AddGenericMagicMissile, &ProcessGenericProjectile, SFX_NONE, SFX_NONE, MissileGraphicID::OrangeFlare, Magic, MissileMovementDistribution::Blockable },
/*BlueFlare*/ { &AddGenericMagicMissile, &ProcessGenericProjectile, SFX_NONE, SFX_NONE, MissileGraphicID::BlueFlare2, Magic, MissileMovementDistribution::Blockable },
/*RedFlare*/ { &AddGenericMagicMissile, &ProcessGenericProjectile, SFX_NONE, SFX_NONE, MissileGraphicID::RedFlare, Magic, MissileMovementDistribution::Blockable },
/*YellowFlare*/ { &AddGenericMagicMissile, &ProcessGenericProjectile, SFX_NONE, SFX_NONE, MissileGraphicID::YellowFlare, Magic, MissileMovementDistribution::Blockable },
/*BlueFlare2*/ { &AddGenericMagicMissile, &ProcessGenericProjectile, SFX_NONE, SFX_NONE, MissileGraphicID::BlueFlare2, Magic, MissileMovementDistribution::Blockable },
/*YellowExplosion*/ { &AddMissileExplosion, &ProcessMissileExplosion, LS_FIRIMP2, SFX_NONE, MissileGraphicID::YellowFlareExplosion, Physical, MissileMovementDistribution::Disabled },
/*RedExplosion*/ { &AddMissileExplosion, &ProcessMissileExplosion, LS_FIRIMP2, SFX_NONE, MissileGraphicID::RedFlareExplosion, Physical, MissileMovementDistribution::Disabled },
/*BlueExplosion*/ { &AddMissileExplosion, &ProcessMissileExplosion, LS_FIRIMP2, SFX_NONE, MissileGraphicID::BlueFlareExplosion, Physical, MissileMovementDistribution::Disabled },
/*BlueExplosion2*/ { &AddMissileExplosion, &ProcessMissileExplosion, LS_FIRIMP2, SFX_NONE, MissileGraphicID::BlueFlareExplosion2, Physical, MissileMovementDistribution::Disabled },
/*OrangeExplosion*/ { &AddMissileExplosion, &ProcessMissileExplosion, LS_FIRIMP2, SFX_NONE, MissileGraphicID::OrangeFlareExplosion, Physical, MissileMovementDistribution::Disabled },
// clang-format on
};
@ -194,67 +204,67 @@ constexpr uint8_t AnimLen_16x8_8 = 20; // NOLINT(readability-identifier-naming)
/** Data related to each missile graphic ID. */
MissileFileData MissileSpriteData[] = {
// clang-format off
// id sprites, animWidth, animWidth2, name, animFAmt, flags, animDelayIdx, animLenIdx
/*Arrow*/ { {}, 96, 16, "arrows", 1, MissileDataFlags::NotAnimated, 0, AnimLen_16 },
/*Fireball*/ { {}, 96, 16, "fireba", 16, MissileDataFlags::None, 0, AnimLen_14 },
/*Guardian*/ { {}, 96, 16, "guard", 3, MissileDataFlags::None, 1, AnimLen_15_14_3 },
/*Lightning*/ { {}, 96, 16, "lghning", 1, MissileDataFlags::None, 0, AnimLen_8 },
/*FireWall*/ { {}, 128, 32, "firewal", 2, MissileDataFlags::None, 0, AnimLen_13_11 },
/*MagmaBallExplosion*/ { {}, 128, 32, "magblos", 1, MissileDataFlags::None, 1, AnimLen_10 },
/*TownPortal*/ { {}, 96, 16, "portal", 2, MissileDataFlags::None, 3, AnimLen_16 },
/*FlashBottom*/ { {}, 160, 48, "bluexfr", 1, MissileDataFlags::None, 0, AnimLen_19 },
/*FlashTop*/ { {}, 160, 48, "bluexbk", 1, MissileDataFlags::None, 0, AnimLen_19 },
/*ManaShield*/ { {}, 96, 16, "manashld", 1, MissileDataFlags::NotAnimated, 0, AnimLen_1 },
/*BloodHit*/ { {}, 96, 16, {}, 4, MissileDataFlags::None, 0, AnimLen_15 },
/*BoneHit*/ { {}, 128, 32, {}, 3, MissileDataFlags::None, 2, AnimLen_8 },
/*MetalHit*/ { {}, 96, 16, {}, 3, MissileDataFlags::None, 2, AnimLen_10 },
/*FireArrow*/ { {}, 96, 16, "farrow", 16, MissileDataFlags::None, 0, AnimLen_4 },
/*DoomSerpents*/ { {}, 96, 16, "doom", 9, MissileDataFlags::MonsterOwned, 1, AnimLen_15 },
/*Golem*/ { {}, 0, 0, {}, 1, MissileDataFlags::MonsterOwned, 0, AnimLen_0 },
/*Spurt*/ { {}, 128, 32, {}, 2, MissileDataFlags::None, 2, AnimLen_8 },
/*ApocalypseBoom*/ { {}, 96, 16, "newexp", 1, MissileDataFlags::None, 1, AnimLen_15 },
/*StoneCurseShatter*/ { {}, 128, 32, "shatter1", 1, MissileDataFlags::None, 1, AnimLen_12 },
/*BigExplosion*/ { {}, 160, 48, "bigexp", 1, MissileDataFlags::None, 0, AnimLen_15 },
/*Inferno*/ { {}, 96, 16, "inferno", 1, MissileDataFlags::None, 0, AnimLen_20 },
/*ThinLightning*/ { {}, 96, 16, "thinlght", 1, MissileDataFlags::MonsterOwned, 0, AnimLen_8 },
/*BloodStar*/ { {}, 128, 32, "flare", 1, MissileDataFlags::None, 0, AnimLen_16 },
/*BloodStarExplosion*/ { {}, 128, 32, "flareexp", 1, MissileDataFlags::None, 0, AnimLen_7 },
/*MagmaBall*/ { {}, 128, 32, "magball", 8, MissileDataFlags::MonsterOwned, 1, AnimLen_16 },
/*Krull*/ { {}, 96, 16, "krull", 1, MissileDataFlags::MonsterOwned, 0, AnimLen_14 },
/*ChargedBolt*/ { {}, 64, 0, "miniltng", 1, MissileDataFlags::None, 1, AnimLen_8 },
/*HolyBolt*/ { {}, 96, 16, "holy", 16, MissileDataFlags::None, 4, AnimLen_14 },
/*HolyBoltExplosion*/ { {}, 160, 48, "holyexpl", 1, MissileDataFlags::None, 0, AnimLen_8 },
/*LightningArrow*/ { {}, 96, 16, "larrow", 16, MissileDataFlags::None, 0, AnimLen_4 },
/*FireArrowExplosion*/ { {}, 64, 0, {}, 1, MissileDataFlags::None, 0, AnimLen_6 },
/*Acid*/ { {}, 96, 16, "acidbf", 16, MissileDataFlags::MonsterOwned, 0, AnimLen_8 },
/*AcidSplat*/ { {}, 96, 16, "acidspla", 1, MissileDataFlags::MonsterOwned, 0, AnimLen_8 },
/*AcidPuddle*/ { {}, 96, 16, "acidpud", 2, MissileDataFlags::MonsterOwned, 0, AnimLen_9_4 },
/*Etherealize*/ { {}, 96, 16, {}, 1, MissileDataFlags::None, 0, AnimLen_1 },
/*Elemental*/ { {}, 96, 16, "firerun", 8, MissileDataFlags::None, 1, AnimLen_12 },
/*Resurrect*/ { {}, 96, 16, "ressur1", 1, MissileDataFlags::None, 0, AnimLen_16 },
/*BoneSpirit*/ { {}, 96, 16, "sklball", 9, MissileDataFlags::None, 1, AnimLen_16x8_8 },
/*RedPortal*/ { {}, 96, 16, "rportal", 2, MissileDataFlags::None, 0, AnimLen_16 },
/*DiabloApocalypseBoom*/ { {}, 160, 48, "fireplar", 1, MissileDataFlags::MonsterOwned, 1, AnimLen_17 },
/*BloodStarBlue*/ { {}, 96, 16, "scubmisb", 1, MissileDataFlags::MonsterOwned, 0, AnimLen_16 },
/*BloodStarBlueExplosion*/ { {}, 128, 32, "scbsexpb", 1, MissileDataFlags::MonsterOwned, 0, AnimLen_6 },
/*BloodStarYellow*/ { {}, 96, 16, "scubmisc", 1, MissileDataFlags::MonsterOwned, 0, AnimLen_16 },
/*BloodStarYellowExplosion*/ { {}, 128, 32, "scbsexpc", 1, MissileDataFlags::MonsterOwned, 0, AnimLen_6 },
/*BloodStarRed*/ { {}, 96, 16, "scubmisd", 1, MissileDataFlags::MonsterOwned, 0, AnimLen_16 },
/*BloodStarRedExplosion*/ { {}, 128, 32, "scbsexpd", 1, MissileDataFlags::MonsterOwned, 0, AnimLen_6 },
/*HorkSpawn*/ { {}, 96, 16, "spawns", 8, MissileDataFlags::MonsterOwned, 0, AnimLen_9 },
/*Reflect*/ { {}, 160, 64, "reflect", 1, MissileDataFlags::NotAnimated, 0, AnimLen_1 },
/*OrangeFlare*/ { {}, 96, 8, "ms_ora", 16, MissileDataFlags::MonsterOwned, 0, AnimLen_15 },
/*BlueFlare*/ { {}, 96, 8, "ms_bla", 16, MissileDataFlags::MonsterOwned, 0, AnimLen_15 },
/*RedFlare*/ { {}, 96, 8, "ms_reb", 16, MissileDataFlags::MonsterOwned, 0, AnimLen_15 },
/*YellowFlare*/ { {}, 96, 8, "ms_yeb", 16, MissileDataFlags::MonsterOwned, 0, AnimLen_15 },
/*Rune*/ { {}, 96, 8, "rglows1", 1, MissileDataFlags::None, 0, AnimLen_10 },
/*YellowFlareExplosion*/ { {}, 220, 78, "ex_yel2", 1, MissileDataFlags::MonsterOwned, 0, AnimLen_10 },
/*BlueFlareExplosion*/ { {}, 212, 86, "ex_blu2", 1, MissileDataFlags::MonsterOwned, 0, AnimLen_10 },
/*RedFlareExplosion*/ { {}, 292, 114, "ex_red3", 1, MissileDataFlags::MonsterOwned, 0, AnimLen_7 },
/*BlueFlare2*/ { {}, 96, 8, "ms_blb", 16, MissileDataFlags::MonsterOwned, 0, AnimLen_15 },
/*OrangeFlareExplosion*/ { {}, 96, -12, "ex_ora1", 1, MissileDataFlags::MonsterOwned, 0, AnimLen_13 },
/*BlueFlareExplosion2*/ { {}, 292, 114, "ex_blu3", 1, MissileDataFlags::MonsterOwned, 0, AnimLen_7 },
/*None*/ { {}, 0, 0, {}, 0, MissileDataFlags::None, 0, 0 },
// id sprites, animWidth, animWidth2, name, animFAmt, flags, animDelayIdx, animLenIdx
/*Arrow*/ { {}, 96, 16, "arrows", 1, MissileGraphicsFlags::NotAnimated, 0, AnimLen_16 },
/*Fireball*/ { {}, 96, 16, "fireba", 16, MissileGraphicsFlags::None, 0, AnimLen_14 },
/*Guardian*/ { {}, 96, 16, "guard", 3, MissileGraphicsFlags::None, 1, AnimLen_15_14_3 },
/*Lightning*/ { {}, 96, 16, "lghning", 1, MissileGraphicsFlags::None, 0, AnimLen_8 },
/*FireWall*/ { {}, 128, 32, "firewal", 2, MissileGraphicsFlags::None, 0, AnimLen_13_11 },
/*MagmaBallExplosion*/ { {}, 128, 32, "magblos", 1, MissileGraphicsFlags::None, 1, AnimLen_10 },
/*TownPortal*/ { {}, 96, 16, "portal", 2, MissileGraphicsFlags::None, 3, AnimLen_16 },
/*FlashBottom*/ { {}, 160, 48, "bluexfr", 1, MissileGraphicsFlags::None, 0, AnimLen_19 },
/*FlashTop*/ { {}, 160, 48, "bluexbk", 1, MissileGraphicsFlags::None, 0, AnimLen_19 },
/*ManaShield*/ { {}, 96, 16, "manashld", 1, MissileGraphicsFlags::NotAnimated, 0, AnimLen_1 },
/*BloodHit*/ { {}, 96, 16, {}, 4, MissileGraphicsFlags::None, 0, AnimLen_15 },
/*BoneHit*/ { {}, 128, 32, {}, 3, MissileGraphicsFlags::None, 2, AnimLen_8 },
/*MetalHit*/ { {}, 96, 16, {}, 3, MissileGraphicsFlags::None, 2, AnimLen_10 },
/*FireArrow*/ { {}, 96, 16, "farrow", 16, MissileGraphicsFlags::None, 0, AnimLen_4 },
/*DoomSerpents*/ { {}, 96, 16, "doom", 9, MissileGraphicsFlags::MonsterOwned, 1, AnimLen_15 },
/*Golem*/ { {}, 0, 0, {}, 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_0 },
/*Spurt*/ { {}, 128, 32, {}, 2, MissileGraphicsFlags::None, 2, AnimLen_8 },
/*ApocalypseBoom*/ { {}, 96, 16, "newexp", 1, MissileGraphicsFlags::None, 1, AnimLen_15 },
/*StoneCurseShatter*/ { {}, 128, 32, "shatter1", 1, MissileGraphicsFlags::None, 1, AnimLen_12 },
/*BigExplosion*/ { {}, 160, 48, "bigexp", 1, MissileGraphicsFlags::None, 0, AnimLen_15 },
/*Inferno*/ { {}, 96, 16, "inferno", 1, MissileGraphicsFlags::None, 0, AnimLen_20 },
/*ThinLightning*/ { {}, 96, 16, "thinlght", 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_8 },
/*BloodStar*/ { {}, 128, 32, "flare", 1, MissileGraphicsFlags::None, 0, AnimLen_16 },
/*BloodStarExplosion*/ { {}, 128, 32, "flareexp", 1, MissileGraphicsFlags::None, 0, AnimLen_7 },
/*MagmaBall*/ { {}, 128, 32, "magball", 8, MissileGraphicsFlags::MonsterOwned, 1, AnimLen_16 },
/*Krull*/ { {}, 96, 16, "krull", 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_14 },
/*ChargedBolt*/ { {}, 64, 0, "miniltng", 1, MissileGraphicsFlags::None, 1, AnimLen_8 },
/*HolyBolt*/ { {}, 96, 16, "holy", 16, MissileGraphicsFlags::None, 4, AnimLen_14 },
/*HolyBoltExplosion*/ { {}, 160, 48, "holyexpl", 1, MissileGraphicsFlags::None, 0, AnimLen_8 },
/*LightningArrow*/ { {}, 96, 16, "larrow", 16, MissileGraphicsFlags::None, 0, AnimLen_4 },
/*FireArrowExplosion*/ { {}, 64, 0, {}, 1, MissileGraphicsFlags::None, 0, AnimLen_6 },
/*Acid*/ { {}, 96, 16, "acidbf", 16, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_8 },
/*AcidSplat*/ { {}, 96, 16, "acidspla", 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_8 },
/*AcidPuddle*/ { {}, 96, 16, "acidpud", 2, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_9_4 },
/*Etherealize*/ { {}, 96, 16, {}, 1, MissileGraphicsFlags::None, 0, AnimLen_1 },
/*Elemental*/ { {}, 96, 16, "firerun", 8, MissileGraphicsFlags::None, 1, AnimLen_12 },
/*Resurrect*/ { {}, 96, 16, "ressur1", 1, MissileGraphicsFlags::None, 0, AnimLen_16 },
/*BoneSpirit*/ { {}, 96, 16, "sklball", 9, MissileGraphicsFlags::None, 1, AnimLen_16x8_8 },
/*RedPortal*/ { {}, 96, 16, "rportal", 2, MissileGraphicsFlags::None, 0, AnimLen_16 },
/*DiabloApocalypseBoom*/ { {}, 160, 48, "fireplar", 1, MissileGraphicsFlags::MonsterOwned, 1, AnimLen_17 },
/*BloodStarBlue*/ { {}, 96, 16, "scubmisb", 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_16 },
/*BloodStarBlueExplosion*/ { {}, 128, 32, "scbsexpb", 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_6 },
/*BloodStarYellow*/ { {}, 96, 16, "scubmisc", 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_16 },
/*BloodStarYellowExplosion*/ { {}, 128, 32, "scbsexpc", 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_6 },
/*BloodStarRed*/ { {}, 96, 16, "scubmisd", 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_16 },
/*BloodStarRedExplosion*/ { {}, 128, 32, "scbsexpd", 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_6 },
/*HorkSpawn*/ { {}, 96, 16, "spawns", 8, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_9 },
/*Reflect*/ { {}, 160, 64, "reflect", 1, MissileGraphicsFlags::NotAnimated, 0, AnimLen_1 },
/*OrangeFlare*/ { {}, 96, 8, "ms_ora", 16, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_15 },
/*BlueFlare*/ { {}, 96, 8, "ms_bla", 16, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_15 },
/*RedFlare*/ { {}, 96, 8, "ms_reb", 16, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_15 },
/*YellowFlare*/ { {}, 96, 8, "ms_yeb", 16, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_15 },
/*Rune*/ { {}, 96, 8, "rglows1", 1, MissileGraphicsFlags::None, 0, AnimLen_10 },
/*YellowFlareExplosion*/ { {}, 220, 78, "ex_yel2", 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_10 },
/*BlueFlareExplosion*/ { {}, 212, 86, "ex_blu2", 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_10 },
/*RedFlareExplosion*/ { {}, 292, 114, "ex_red3", 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_7 },
/*BlueFlare2*/ { {}, 96, 8, "ms_blb", 16, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_15 },
/*OrangeFlareExplosion*/ { {}, 96, -12, "ex_ora1", 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_13 },
/*BlueFlareExplosion2*/ { {}, 292, 114, "ex_blu3", 1, MissileGraphicsFlags::MonsterOwned, 0, AnimLen_7 },
/*None*/ { {}, 0, 0, {}, 0, MissileGraphicsFlags::None, 0, 0 },
// clang-format on
};
@ -294,7 +304,7 @@ void InitMissileGFX(bool loadHellfireGraphics)
for (size_t mi = 0; MissileSpriteData[mi].animFAmt != 0; mi++) {
if (!loadHellfireGraphics && mi > static_cast<uint8_t>(MissileGraphicID::BloodStarRedExplosion))
break;
if (MissileSpriteData[mi].flags == MissileDataFlags::MonsterOwned)
if (MissileSpriteData[mi].flags == MissileGraphicsFlags::MonsterOwned)
continue;
MissileSpriteData[mi].LoadGFX();
}

47
Source/misdat.h

@ -13,6 +13,7 @@
#include "engine.h"
#include "engine/clx_sprite.hpp"
#include "spelldat.h"
#include "utils/enum_traits.h"
#include "utils/stdcompat/cstddef.hpp"
#include "utils/stdcompat/string_view.hpp"
@ -116,19 +117,51 @@ enum class MissileMovementDistribution : uint8_t {
struct Missile;
struct AddMissileParameter;
enum class MissileDataFlags : uint8_t {
// The lower 3 bytes are used to store DamageType.
Physical = static_cast<uint8_t>(DamageType::Physical),
Fire = static_cast<uint8_t>(DamageType::Fire),
Lightning = static_cast<uint8_t>(DamageType::Lightning),
Magic = static_cast<uint8_t>(DamageType::Magic),
Acid = static_cast<uint8_t>(DamageType::Acid),
Arrow = 1 << 4,
Invisible = 1 << 5,
};
use_enum_as_flags(MissileDataFlags);
struct MissileData {
void (*mAddProc)(Missile &, AddMissileParameter &);
void (*mProc)(Missile &);
bool mDraw;
uint8_t mType;
DamageType damageType;
MissileGraphicID mFileNum;
_sfx_id mlSFX;
_sfx_id miSFX;
MissileMovementDistribution MovementDistribution;
MissileGraphicID mFileNum;
MissileDataFlags flags;
MissileMovementDistribution movementDistribution;
[[nodiscard]] bool isDrawn() const
{
return !HasAnyOf(flags, MissileDataFlags::Invisible);
}
[[nodiscard]] bool isArrow() const
{
return HasAnyOf(flags, MissileDataFlags::Arrow);
}
[[nodiscard]] DamageType damageType() const
{
return static_cast<DamageType>(static_cast<std::underlying_type<MissileDataFlags>::type>(flags) & 0b111U);
}
void setDamageType(DamageType damageType)
{
flags = static_cast<MissileDataFlags>(
(static_cast<std::underlying_type<MissileDataFlags>::type>(flags) & 0b11111000U)
| static_cast<std::underlying_type<DamageType>::type>(damageType));
}
};
enum class MissileDataFlags : uint8_t {
enum class MissileGraphicsFlags : uint8_t {
// clang-format off
None = 0,
MonsterOwned = 1 << 0,
@ -142,7 +175,7 @@ struct MissileFileData {
int8_t animWidth2;
char name[9];
uint8_t animFAmt;
MissileDataFlags flags;
MissileGraphicsFlags flags;
uint8_t animDelayIdx;
uint8_t animLenIdx;

58
Source/missiles.cpp

@ -211,7 +211,7 @@ bool MonsterMHit(int pnum, int monsterId, int mindam, int maxdam, int dist, Miss
int hper = 0;
const Player &player = Players[pnum];
const MissileData &missileData = GetMissileData(t);
if (missileData.mType == 0) {
if (missileData.isArrow()) {
hper = player.GetRangedPiercingToHit();
hper -= player.CalculateArmorPierce(monster.armorClass, false);
hper -= (dist * dist) / 2;
@ -241,7 +241,7 @@ bool MonsterMHit(int pnum, int monsterId, int mindam, int maxdam, int dist, Miss
dam = mindam + GenerateRnd(maxdam - mindam + 1);
}
if (missileData.mType == 0 && missileData.damageType == DamageType::Physical) {
if (missileData.isArrow() && missileData.damageType() == DamageType::Physical) {
dam = player._pIBonusDamMod + dam * player._pIBonusDam / 100 + dam;
if (player._pClass == HeroClass::Rogue)
dam += player._pDamageMod;
@ -257,7 +257,7 @@ bool MonsterMHit(int pnum, int monsterId, int mindam, int maxdam, int dist, Miss
dam >>= 2;
if (&player == MyPlayer)
ApplyMonsterDamage(missileData.damageType, monster, dam);
ApplyMonsterDamage(missileData.damageType(), monster, dam);
if (monster.hitPoints >> 6 <= 0) {
M_StartKill(monster, player);
@ -265,7 +265,7 @@ bool MonsterMHit(int pnum, int monsterId, int mindam, int maxdam, int dist, Miss
monster.tag(player);
PlayEffect(monster, MonsterSound::Hit);
} else {
if (monster.mode != MonsterMode::Petrified && missileData.mType == 0 && HasAnyOf(player._pIFlags, ItemSpecialEffect::Knockback))
if (monster.mode != MonsterMode::Petrified && missileData.isArrow() && HasAnyOf(player._pIFlags, ItemSpecialEffect::Knockback))
M_GetKnockback(monster);
if (monster.type().type != MT_GOLEM)
M_StartHit(monster, player, dam);
@ -301,12 +301,12 @@ bool Plr2PlrMHit(const Player &player, int p, int mindam, int maxdam, int dist,
const MissileData &missileData = GetMissileData(mtype);
if (HasAnyOf(target._pSpellFlags, SpellFlag::Etherealize) && missileData.mType == 0) {
if (HasAnyOf(target._pSpellFlags, SpellFlag::Etherealize) && missileData.isArrow()) {
return false;
}
int8_t resper;
switch (missileData.damageType) {
switch (missileData.damageType()) {
case DamageType::Fire:
resper = target._pFireResist;
break;
@ -325,7 +325,7 @@ bool Plr2PlrMHit(const Player &player, int p, int mindam, int maxdam, int dist,
int hper = GenerateRnd(100);
int hit;
if (missileData.mType == 0) {
if (missileData.isArrow()) {
hit = player.GetRangedToHit()
- (dist * dist / 2)
- target.GetArmor();
@ -354,17 +354,17 @@ bool Plr2PlrMHit(const Player &player, int p, int mindam, int maxdam, int dist,
dam = target._pHitPoints / 3;
} else {
dam = mindam + GenerateRnd(maxdam - mindam + 1);
if (missileData.mType == 0 && missileData.damageType == DamageType::Physical)
if (missileData.isArrow() && missileData.damageType() == DamageType::Physical)
dam += player._pIBonusDamMod + player._pDamageMod + dam * player._pIBonusDam / 100;
if (!shift)
dam <<= 6;
}
if (missileData.mType != 0)
if (!missileData.isArrow())
dam /= 2;
if (resper > 0) {
dam -= (dam * resper) / 100;
if (&player == MyPlayer)
NetSendCmdDamage(true, p, dam, missileData.damageType);
NetSendCmdDamage(true, p, dam, missileData.damageType());
target.Say(HeroSpeech::ArghClang);
return true;
}
@ -374,7 +374,7 @@ bool Plr2PlrMHit(const Player &player, int p, int mindam, int maxdam, int dist,
*blocked = true;
} else {
if (&player == MyPlayer)
NetSendCmdDamage(true, p, dam, missileData.damageType);
NetSendCmdDamage(true, p, dam, missileData.damageType());
StartPlrHit(target, dam, false);
}
@ -562,7 +562,7 @@ void MoveMissileAndCheckMissileCol(Missile &missile, int mindam, int maxdam, boo
if (missile._mirange != 0)
return true;
if (missile._miHitFlag && GetMissileData(missile._mitype).MovementDistribution == MissileMovementDistribution::Blockable)
if (missile._miHitFlag && GetMissileData(missile._mitype).movementDistribution == MissileMovementDistribution::Blockable)
return false;
return !IsMissileBlockedByTile(tile);
@ -953,7 +953,7 @@ bool MonsterTrapHit(int monsterId, int mindam, int maxdam, int dist, MissileID t
dam <<= 6;
if (resist)
dam /= 4;
ApplyMonsterDamage(GetMissileData(t).damageType, monster, dam);
ApplyMonsterDamage(GetMissileData(t).damageType(), monster, dam);
#ifdef _DEBUG
if (DebugGodMode)
monster.hitPoints = 0;
@ -984,7 +984,7 @@ bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, Missil
const MissileData &missileData = GetMissileData(mtype);
if (HasAnyOf(player._pSpellFlags, SpellFlag::Etherealize) && missileData.mType == 0) {
if (HasAnyOf(player._pSpellFlags, SpellFlag::Etherealize) && missileData.isArrow()) {
return false;
}
@ -994,7 +994,7 @@ bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, Missil
hit = 1000;
#endif
int hper = 40;
if (missileData.mType == 0) {
if (missileData.isArrow()) {
int tac = player.GetArmor();
if (monster != nullptr) {
hper = monster->toHit
@ -1033,7 +1033,7 @@ bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, Missil
blkper = clamp(blkper, 0, 100);
int8_t resper;
switch (missileData.damageType) {
switch (missileData.damageType()) {
case DamageType::Fire:
resper = player._pFireResist;
break;
@ -1087,7 +1087,7 @@ bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, Missil
if (resper > 0) {
dam -= dam * resper / 100;
if (&player == MyPlayer) {
ApplyPlrDamage(missileData.damageType, player, 0, 0, dam, earflag);
ApplyPlrDamage(missileData.damageType(), player, 0, 0, dam, earflag);
}
if (player._pHitPoints >> 6 > 0) {
@ -1097,7 +1097,7 @@ bool PlayerMHit(int pnum, Monster *monster, int dist, int mind, int maxd, Missil
}
if (&player == MyPlayer) {
ApplyPlrDamage(missileData.damageType, player, 0, 0, dam, earflag);
ApplyPlrDamage(missileData.damageType(), player, 0, 0, dam, earflag);
}
if (player._pHitPoints >> 6 > 0) {
@ -2144,7 +2144,7 @@ void InitMissileAnimationFromMonster(Missile &mis, Direction midir, const Monste
{
const AnimStruct &anim = mon.type().getAnimData(graphic);
mis._mimfnum = static_cast<int32_t>(midir);
mis._miAnimFlags = MissileDataFlags::None;
mis._miAnimFlags = MissileGraphicsFlags::None;
ClxSpriteList sprites = *anim.spritesForDirection(midir);
const uint16_t width = sprites[0].width();
mis._miAnimData.emplace(sprites);
@ -2714,7 +2714,7 @@ Missile *AddMissile(Point src, Point dst, Direction midir, MissileID mitype, mie
missile.position.start = src;
missile._miAnimAdd = 1;
missile._miAnimType = missileData.mFileNum;
missile._miDrawFlag = missileData.mDraw;
missile._miDrawFlag = missileData.isDrawn();
missile._mlid = NO_LIGHT;
missile.lastCollisionTargetHash = 0;
@ -2770,16 +2770,16 @@ void ProcessElementalArrow(Missile &missile)
maxd = GenerateRnd(10) + 1 + currlevel * 2;
}
MissileData &missileData = GetMissileData(missile._mitype);
DamageType rst = missileData.damageType;
missileData.damageType = DamageType::Physical;
DamageType rst = missileData.damageType();
missileData.setDamageType(DamageType::Physical);
MoveMissileAndCheckMissileCol(missile, mind, maxd, true, false);
missileData.damageType = rst;
missileData.setDamageType(rst);
if (missile._mirange == 0) {
missile._mimfnum = 0;
missile._mirange = missile._miAnimLen - 1;
missile.position.StopMissile();
rst = missileData.damageType;
rst = missileData.damageType();
int eMind;
int eMaxd;
@ -2817,9 +2817,9 @@ void ProcessElementalArrow(Missile &missile)
break;
}
SetMissAnim(missile, eAnim);
missileData.damageType = eRst;
missileData.setDamageType(eRst);
CheckMissileCol(missile, eMind, eMaxd, false, missile.position.tile, true);
missileData.damageType = rst;
missileData.setDamageType(rst);
} else {
if (missile.position.tile != Point { missile.var1, missile.var2 }) {
missile.var1 = missile.position.tile.x;
@ -3545,12 +3545,12 @@ void ProcessWeaponExplosion(Missile &missile)
// BUGFIX: damage of missile should be encoded in missile struct; player can be dead/have left the game before missile arrives.
mind = player._pIFMinDam;
maxd = player._pIFMaxDam;
missileData.damageType = DamageType::Fire;
missileData.setDamageType(DamageType::Fire);
} else {
// BUGFIX: damage of missile should be encoded in missile struct; player can be dead/have left the game before missile arrives.
mind = player._pILMinDam;
maxd = player._pILMaxDam;
missileData.damageType = DamageType::Lightning;
missileData.setDamageType(DamageType::Lightning);
}
CheckMissileCol(missile, mind, maxd, false, missile.position.tile, false);
if (missile.var1 == 0) {
@ -4142,7 +4142,7 @@ void ProcessMissiles()
const MissileData &missileData = GetMissileData(missile._mitype);
if (missileData.mProc != nullptr)
missileData.mProc(missile);
if (missile._miAnimFlags == MissileDataFlags::NotAnimated)
if (missile._miAnimFlags == MissileGraphicsFlags::NotAnimated)
continue;
missile._miAnimCnt++;

2
Source/missiles.h

@ -99,7 +99,7 @@ struct Missile {
int _mispllvl;
bool _miDelFlag; // Indicate whether the missile should be deleted
MissileGraphicID _miAnimType;
MissileDataFlags _miAnimFlags;
MissileGraphicsFlags _miAnimFlags;
OptionalClxSpriteList _miAnimData;
int _miAnimDelay; // Tick length of each frame in the current animation
int _miAnimLen; // Number of frames in current animation

4
Source/monster.cpp

@ -4609,7 +4609,7 @@ bool Monster::isWalking() const
bool Monster::isImmune(MissileID missileType) const
{
DamageType missileElement = GetMissileData(missileType).damageType;
DamageType missileElement = GetMissileData(missileType).damageType();
if (((resistance & IMMUNE_MAGIC) != 0 && missileElement == DamageType::Magic)
|| ((resistance & IMMUNE_FIRE) != 0 && missileElement == DamageType::Fire)
@ -4623,7 +4623,7 @@ bool Monster::isImmune(MissileID missileType) const
bool Monster::isResistant(MissileID missileType) const
{
DamageType missileElement = GetMissileData(missileType).damageType;
DamageType missileElement = GetMissileData(missileType).damageType();
if (((resistance & RESIST_MAGIC) != 0 && missileElement == DamageType::Magic)
|| ((resistance & RESIST_FIRE) != 0 && missileElement == DamageType::Fire)

Loading…
Cancel
Save