diff --git a/Source/engine/render/scrollrt.cpp b/Source/engine/render/scrollrt.cpp index 71a26d76e44..4e5a3b2efe4 100644 --- a/Source/engine/render/scrollrt.cpp +++ b/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; diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp index d81b0749be0..a238f0bb3a7 100644 --- a/Source/loadsave.cpp +++ b/Source/loadsave.cpp @@ -706,7 +706,7 @@ void LoadMissile(LoadHelper *file) missile._miDelFlag = file->NextBool32(); missile._miAnimType = static_cast(file->NextLE()); file->Skip(3); // Alignment - missile._miAnimFlags = static_cast(file->NextLE()); + missile._miAnimFlags = static_cast(file->NextLE()); file->Skip(4); // Skip pointer _miAnimData missile._miAnimDelay = file->NextLE(); missile._miAnimLen = file->NextLE(); diff --git a/Source/misdat.cpp b/Source/misdat.cpp index d0b08538ae3..e43aa8520de 100644 --- a/Source/misdat.cpp +++ b/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(MissileGraphicID::BloodStarRedExplosion)) break; - if (MissileSpriteData[mi].flags == MissileDataFlags::MonsterOwned) + if (MissileSpriteData[mi].flags == MissileGraphicsFlags::MonsterOwned) continue; MissileSpriteData[mi].LoadGFX(); } diff --git a/Source/misdat.h b/Source/misdat.h index 0fc7828f218..a78d6d54141 100644 --- a/Source/misdat.h +++ b/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(DamageType::Physical), + Fire = static_cast(DamageType::Fire), + Lightning = static_cast(DamageType::Lightning), + Magic = static_cast(DamageType::Magic), + Acid = static_cast(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(static_cast::type>(flags) & 0b111U); + } + + void setDamageType(DamageType damageType) + { + flags = static_cast( + (static_cast::type>(flags) & 0b11111000U) + | static_cast::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; diff --git a/Source/missiles.cpp b/Source/missiles.cpp index 2c35bb9e0db..b7d3e652ef2 100644 --- a/Source/missiles.cpp +++ b/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(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++; diff --git a/Source/missiles.h b/Source/missiles.h index cae60129f6e..6277c4f3910 100644 --- a/Source/missiles.h +++ b/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 diff --git a/Source/monster.cpp b/Source/monster.cpp index f96f0c3a808..b14bc689b8c 100644 --- a/Source/monster.cpp +++ b/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)