You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
4.5 KiB
216 lines
4.5 KiB
/** |
|
* @file misdat.h |
|
* |
|
* Interface of data related to missiles. |
|
*/ |
|
#pragma once |
|
|
|
#include <cstddef> |
|
#include <cstdint> |
|
#include <string_view> |
|
#include <type_traits> |
|
#include <vector> |
|
|
|
#include "effects.h" |
|
#include "engine.h" |
|
#include "engine/clx_sprite.hpp" |
|
#include "spelldat.h" |
|
#include "utils/enum_traits.h" |
|
|
|
namespace devilution { |
|
|
|
enum mienemy_type : uint8_t { |
|
TARGET_MONSTERS, |
|
TARGET_PLAYERS, |
|
TARGET_BOTH, |
|
}; |
|
|
|
enum class DamageType : uint8_t { |
|
Physical, |
|
Fire, |
|
Lightning, |
|
Magic, |
|
Acid, |
|
}; |
|
|
|
enum class MissileGraphicID : uint8_t { |
|
Arrow, |
|
Fireball, |
|
Guardian, |
|
Lightning, |
|
FireWall, |
|
MagmaBallExplosion, |
|
TownPortal, |
|
FlashBottom, |
|
FlashTop, |
|
ManaShield, |
|
BloodHit, |
|
BoneHit, |
|
MetalHit, |
|
FireArrow, |
|
DoomSerpents, |
|
Golem, |
|
Spurt, |
|
ApocalypseBoom, |
|
StoneCurseShatter, |
|
BigExplosion, |
|
Inferno, |
|
ThinLightning, |
|
BloodStar, |
|
BloodStarExplosion, |
|
MagmaBall, |
|
Krull, |
|
ChargedBolt, |
|
HolyBolt, |
|
HolyBoltExplosion, |
|
LightningArrow, |
|
FireArrowExplosion, |
|
Acid, |
|
AcidSplat, |
|
AcidPuddle, |
|
Etherealize, |
|
Elemental, |
|
Resurrect, |
|
BoneSpirit, |
|
RedPortal, |
|
DiabloApocalypseBoom, |
|
BloodStarBlue, |
|
BloodStarBlueExplosion, |
|
BloodStarYellow, |
|
BloodStarYellowExplosion, |
|
BloodStarRed, |
|
BloodStarRedExplosion, |
|
HorkSpawn, |
|
Reflect, |
|
OrangeFlare, |
|
BlueFlare, |
|
RedFlare, |
|
YellowFlare, |
|
Rune, |
|
YellowFlareExplosion, |
|
BlueFlareExplosion, |
|
RedFlareExplosion, |
|
BlueFlare2, |
|
OrangeFlareExplosion, |
|
BlueFlareExplosion2, |
|
None, |
|
}; |
|
|
|
/** |
|
* @brief Specifies what if and how movement distribution is applied |
|
*/ |
|
enum class MissileMovementDistribution : uint8_t { |
|
/** |
|
* @brief No movement distribution is calculated. Normally this means the missile doesn't move at all. |
|
*/ |
|
Disabled, |
|
/** |
|
* @brief The missile moves and if it hits a enemey it stops (for example firebolt) |
|
*/ |
|
Blockable, |
|
/** |
|
* @brief The missile moves and even it hits a enemy it keeps moving (for example flame wave) |
|
*/ |
|
Unblockable, |
|
}; |
|
|
|
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 &); |
|
_sfx_id mlSFX; |
|
_sfx_id miSFX; |
|
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); |
|
} |
|
}; |
|
|
|
enum class MissileGraphicsFlags : uint8_t { |
|
// clang-format off |
|
None = 0, |
|
MonsterOwned = 1 << 0, |
|
NotAnimated = 1 << 1, |
|
// clang-format on |
|
}; |
|
|
|
struct MissileFileData { |
|
OptionalOwnedClxSpriteListOrSheet sprites; |
|
uint16_t animWidth; |
|
int8_t animWidth2; |
|
char name[9]; |
|
uint8_t animFAmt; |
|
MissileGraphicsFlags flags; |
|
uint8_t animDelayIdx; |
|
uint8_t animLenIdx; |
|
|
|
[[nodiscard]] uint8_t animDelay(uint8_t dir) const; |
|
[[nodiscard]] uint8_t animLen(uint8_t dir) const; |
|
|
|
void LoadGFX(); |
|
|
|
void FreeGFX() |
|
{ |
|
sprites = std::nullopt; |
|
} |
|
|
|
/** |
|
* @brief Returns the sprite list for a given direction. |
|
* |
|
* @param direction One of the 16 directions. Valid range: [0, 15]. |
|
* @return OptionalClxSpriteList |
|
*/ |
|
[[nodiscard]] OptionalClxSpriteList spritesForDirection(size_t direction) const |
|
{ |
|
if (!sprites) |
|
return std::nullopt; |
|
return sprites->isSheet() ? sprites->sheet()[direction] : sprites->list(); |
|
} |
|
}; |
|
|
|
extern const MissileData MissilesData[]; |
|
|
|
inline const MissileData &GetMissileData(MissileID missileId) |
|
{ |
|
return MissilesData[static_cast<std::underlying_type<MissileID>::type>(missileId)]; |
|
} |
|
|
|
extern MissileFileData MissileSpriteData[]; |
|
|
|
inline MissileFileData &GetMissileSpriteData(MissileGraphicID graphicId) |
|
{ |
|
return MissileSpriteData[static_cast<std::underlying_type<MissileGraphicID>::type>(graphicId)]; |
|
} |
|
|
|
void InitMissileGFX(bool loadHellfireGraphics = false); |
|
void FreeMissileGFX(); |
|
|
|
} // namespace devilution
|
|
|