Skip to content

Commit

Permalink
Added VFX entity definitions.
Browse files Browse the repository at this point in the history
Not used anywhere yet but can be looked up by VFX key.
  • Loading branch information
afritz1 committed Dec 31, 2024
1 parent 2f8b593 commit 3c1ba4e
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 50 deletions.
27 changes: 7 additions & 20 deletions OpenTESArena/src/Entities/EntityAnimationLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,24 +47,25 @@ void CitizenEntityAnimationKey::init(bool male, ArenaTypes::ClimateType climateT
VfxEntityAnimationKey::VfxEntityAnimationKey()
{
this->type = static_cast<VfxEntityAnimationType>(-1);
this->index = -1;
}

void VfxEntityAnimationKey::initSpellProjectile(int spellIndex)
{
this->type = VfxEntityAnimationType::SpellProjectile;
this->spellIndex = spellIndex;
this->index = spellIndex;
}

void VfxEntityAnimationKey::initSpellExplosion(int spellIndex)
{
this->type = VfxEntityAnimationType::SpellExplosion;
this->spellIndex = spellIndex;
this->index = spellIndex;
}

void VfxEntityAnimationKey::initMeleeStrike(int bloodIndex)
{
this->type = VfxEntityAnimationType::MeleeStrike;
this->bloodIndex = bloodIndex;
this->index = bloodIndex;
}

void EntityAnimationLibrary::init(const BinaryAssetLibrary &binaryAssetLibrary, const CharacterClassLibrary &charClassLibrary, TextureManager &textureManager)
Expand Down Expand Up @@ -152,8 +153,8 @@ void EntityAnimationLibrary::init(const BinaryAssetLibrary &binaryAssetLibrary,
}

// VFX
const int spellTypeCount = 12;
const int meleeVfxCount = 3;
const int spellTypeCount = EntityAnimationUtils::SPELL_TYPE_COUNT;
const int meleeVfxCount = EntityAnimationUtils::MELEE_VFX_COUNT;
const int spellProjectileStartIndex = spellTypeCount;
const int spellExplosionStartIndex = 0;
const int meleeVfxStartIndex = spellProjectileStartIndex + spellTypeCount;
Expand Down Expand Up @@ -265,21 +266,7 @@ EntityAnimationDefinitionID EntityAnimationLibrary::getVfxAnimDefID(const VfxEnt
[&key](const auto &pair)
{
const VfxEntityAnimationKey &animKey = pair.first;
if (animKey.type != key.type)
{
return false;
}

switch (animKey.type)
{
case VfxEntityAnimationType::SpellProjectile:
case VfxEntityAnimationType::SpellExplosion:
return animKey.spellIndex == key.spellIndex;
case VfxEntityAnimationType::MeleeStrike:
return animKey.bloodIndex == key.bloodIndex;
default:
DebugUnhandledReturnMsg(bool, std::to_string(static_cast<int>(animKey.type)));
}
return (animKey.type == key.type) && (animKey.index == key.index);
});

DebugAssert(iter != this->vfxDefIDs.end());
Expand Down
15 changes: 2 additions & 13 deletions OpenTESArena/src/Entities/EntityAnimationLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <vector>

#include "EntityAnimationDefinition.h"
#include "EntityDefinition.h"
#include "../Assets/ArenaTypes.h"

#include "components/utilities/Singleton.h"
Expand Down Expand Up @@ -43,22 +44,10 @@ struct CitizenEntityAnimationKey
void init(bool male, ArenaTypes::ClimateType climateType);
};

enum class VfxEntityAnimationType
{
SpellProjectile,
SpellExplosion,
MeleeStrike
};

struct VfxEntityAnimationKey
{
VfxEntityAnimationType type;

union
{
int spellIndex; // 0-11
int bloodIndex; // 0-2
};
int index; // 0-11 for spells, 0-2 for melee effects.

VfxEntityAnimationKey();

Expand Down
3 changes: 3 additions & 0 deletions OpenTESArena/src/Entities/EntityAnimationUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ namespace EntityAnimationUtils

// Max length of animation state name.
constexpr int NAME_LENGTH = 32;

constexpr int SPELL_TYPE_COUNT = 12;
constexpr int MELEE_VFX_COUNT = 3;
}

#endif
34 changes: 34 additions & 0 deletions OpenTESArena/src/Entities/EntityDefinition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,28 @@ bool EntityDefinition::ProjectileDefinition::operator==(const ProjectileDefiniti
return this->hasGravity == other.hasGravity;
}

EntityDefinition::VfxDefinition::VfxDefinition()
{
this->type = static_cast<VfxEntityAnimationType>(-1);
this->index = -1;
}

void EntityDefinition::VfxDefinition::init(VfxEntityAnimationType type, int index)
{
this->type = type;
this->index = index;
}

bool EntityDefinition::VfxDefinition::operator==(const VfxDefinition &other) const
{
if (this == &other)
{
return true;
}

return (this->type == other.type) && (this->index == other.index);
}

EntityDefinition::TransitionDefinition::TransitionDefinition()
{
this->transitionDefID = -1;
Expand Down Expand Up @@ -676,6 +698,12 @@ const EntityDefinition::ProjectileDefinition &EntityDefinition::getProjectile()
return this->projectile;
}

const EntityDefinition::VfxDefinition &EntityDefinition::getVfx() const
{
DebugAssert(this->type == EntityDefinitionType::Vfx);
return this->vfx;
}

const EntityDefinition::TransitionDefinition &EntityDefinition::getTransition() const
{
DebugAssert(this->type == EntityDefinitionType::Transition);
Expand Down Expand Up @@ -751,6 +779,12 @@ void EntityDefinition::initProjectile(bool hasGravity, EntityAnimationDefinition
this->projectile.init(hasGravity);
}

void EntityDefinition::initVfx(VfxEntityAnimationType type, int index, EntityAnimationDefinition &&animDef)
{
this->init(EntityDefinitionType::Vfx, std::move(animDef));
this->vfx.init(type, index);
}

void EntityDefinition::initTransition(LevelDefinition::TransitionDefID defID,
EntityAnimationDefinition &&animDef)
{
Expand Down
44 changes: 29 additions & 15 deletions OpenTESArena/src/Entities/EntityDefinition.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,19 @@ enum class EntityDefinitionType
StaticNPC, // Bartenders, priests, etc..
Item, // Keys, tablets, staff pieces, etc..
Container, // Chests, loot piles, etc..
Projectile, // Arrows, spells, etc..
Projectile, // Arrows
Vfx, // Spell projectile, explosion, or melee strike
Transition, // Wilderness den.
Doodad // Trees, chairs, streetlights, etc..
};

enum class VfxEntityAnimationType
{
SpellProjectile,
SpellExplosion,
MeleeStrike
};

class EntityDefinition
{
public:
Expand Down Expand Up @@ -257,6 +265,18 @@ class EntityDefinition
bool operator==(const ProjectileDefinition &other) const;
};

struct VfxDefinition
{
VfxEntityAnimationType type;
int index; // Points into projectiles, explosions, or blood effects.

VfxDefinition();

void init(VfxEntityAnimationType type, int index);

bool operator==(const VfxDefinition &other) const;
};

struct TransitionDefinition
{
// Should be fine to store this ID that points into a LevelInfoDefinition since transition
Expand Down Expand Up @@ -302,6 +322,7 @@ class EntityDefinition
ItemDefinition item;
ContainerDefinition container;
ProjectileDefinition projectile;
VfxDefinition vfx;
TransitionDefinition transition;
DoodadDefinition doodad;
};
Expand All @@ -320,39 +341,32 @@ class EntityDefinition
const ItemDefinition &getItem() const;
const ContainerDefinition &getContainer() const;
const ProjectileDefinition &getProjectile() const;
const VfxDefinition &getVfx() const;
const TransitionDefinition &getTransition() const;
const DoodadDefinition &getDoodad() const;

// Enemy.
void initEnemyCreature(int creatureIndex, bool isFinalBoss, const ExeData &exeData,
EntityAnimationDefinition &&animDef);
void initEnemyCreature(int creatureIndex, bool isFinalBoss, const ExeData &exeData, EntityAnimationDefinition &&animDef);
void initEnemyHuman(bool male, int charClassID, EntityAnimationDefinition &&animDef);

// Citizen.
void initCitizen(bool male, ArenaTypes::ClimateType climateType, EntityAnimationDefinition &&animDef);

// Static NPC.
void initStaticNpcShopkeeper(StaticNpcDefinition::ShopkeeperDefinition::Type type,
EntityAnimationDefinition &&animDef);
void initStaticNpcShopkeeper(StaticNpcDefinition::ShopkeeperDefinition::Type type, EntityAnimationDefinition &&animDef);
void initStaticNpcPerson(EntityAnimationDefinition &&animDef);

// Item.
void initItemKey(EntityAnimationDefinition &&animDef);
void initItemQuestItem(EntityAnimationDefinition &&animDef);

// Container.
void initContainerHolder(bool locked, EntityAnimationDefinition &&animDef);
void initContainerPile(EntityAnimationDefinition &&animDef);

// Projectile.
void initProjectile(bool hasGravity, EntityAnimationDefinition &&animDef);

void initVfx(VfxEntityAnimationType type, int index, EntityAnimationDefinition &&animDef);

// Transition.
void initTransition(LevelDefinition::TransitionDefID defID, EntityAnimationDefinition &&animDef);

// Doodad.
void initDoodad(int yOffset, double scale, bool collider, bool transparent, bool ceiling,
bool streetlight, bool puddle, int lightIntensity, EntityAnimationDefinition &&animDef);
void initDoodad(int yOffset, double scale, bool collider, bool transparent, bool ceiling, bool streetlight, bool puddle,
int lightIntensity, EntityAnimationDefinition &&animDef);
};

#endif
72 changes: 71 additions & 1 deletion OpenTESArena/src/Entities/EntityDefinitionLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ void CitizenEntityDefinitionKey::init(bool male, ArenaTypes::ClimateType climate
this->climateType = climateType;
}

bool VfxEntityDefinitionKey::operator==(const VfxEntityDefinitionKey &other) const
{
return (this->type == other.type) && (this->index == other.index);
}

void VfxEntityDefinitionKey::init(VfxEntityAnimationType type, int index)
{
this->type = type;
this->index = index;
}

EntityDefinitionKey::EntityDefinitionKey()
{
this->type = static_cast<EntityDefinitionKeyType>(-1);
Expand All @@ -65,6 +76,10 @@ bool EntityDefinitionKey::operator==(const EntityDefinitionKey &other) const
{
return this->citizen == other.citizen;
}
else if (this->type == EntityDefinitionKeyType::Vfx)
{
return this->vfx == other.vfx;
}
else
{
DebugUnhandledReturnMsg(bool, std::to_string(static_cast<int>(this->type)));
Expand Down Expand Up @@ -94,6 +109,12 @@ void EntityDefinitionKey::initCitizen(bool male, ArenaTypes::ClimateType climate
this->citizen.init(male, climateType);
}

void EntityDefinitionKey::initVfx(VfxEntityAnimationType type, int index)
{
this->init(EntityDefinitionKeyType::Vfx);
this->vfx.init(type, index);
}

EntityDefinitionLibrary::Entry::Entry(EntityDefinitionKey &&key, EntityDefinition &&def)
: key(std::move(key)), def(std::move(def)) { }

Expand Down Expand Up @@ -169,6 +190,37 @@ void EntityDefinitionLibrary::init(const ExeData &exeData, const CharacterClassL
this->addDefinition(std::move(key), std::move(entityDef));
};

auto addVfxDef = [this, &exeData, &entityAnimLibrary](VfxEntityAnimationType type, int index)
{
VfxEntityAnimationKey animKey;
switch (type)
{
case VfxEntityAnimationType::SpellProjectile:
animKey.initSpellProjectile(index);
break;
case VfxEntityAnimationType::SpellExplosion:
animKey.initSpellExplosion(index);
break;
case VfxEntityAnimationType::MeleeStrike:
animKey.initMeleeStrike(index);
break;
default:
DebugNotImplemented();
break;
}

const EntityAnimationDefinitionID animDefID = entityAnimLibrary.getVfxAnimDefID(animKey);
EntityAnimationDefinition animDef = entityAnimLibrary.getDefinition(animDefID); // @todo: make const ref and give anim def ID to EntityDefinition instead

EntityDefinitionKey key;
key.initVfx(type, index);

EntityDefinition entityDef;
entityDef.initVfx(type, index, std::move(animDef));

this->addDefinition(std::move(key), std::move(entityDef));
};

// Iterate all creatures + final boss.
const int creatureCount = static_cast<int>(exeData.entities.creatureNames.size());
for (int i = 0; i < creatureCount; i++)
Expand All @@ -190,13 +242,31 @@ void EntityDefinitionLibrary::init(const ExeData &exeData, const CharacterClassL
addHumanEnemyDef(false, charClassID);
}

// Iterate all climate type + gender combinations.
// Iterate all climate type + gender combinations for citizens.
for (int i = 0; i < ArenaClimateUtils::getClimateTypeCount(); i++)
{
const ArenaTypes::ClimateType climateType = ArenaClimateUtils::getClimateType(i);
addCitizenDef(climateType, true);
addCitizenDef(climateType, false);
}

// Iterate all spell effects and melee effects.
const int spellTypeCount = EntityAnimationUtils::SPELL_TYPE_COUNT;
const int meleeVfxCount = EntityAnimationUtils::MELEE_VFX_COUNT;
for (int i = 0; i < spellTypeCount; i++)
{
addVfxDef(VfxEntityAnimationType::SpellProjectile, i);
}

for (int i = 0; i < spellTypeCount; i++)
{
addVfxDef(VfxEntityAnimationType::SpellExplosion, i);
}

for (int i = 0; i < meleeVfxCount; i++)
{
addVfxDef(VfxEntityAnimationType::MeleeStrike, i);
}
}

int EntityDefinitionLibrary::getDefinitionCount() const
Expand Down
Loading

0 comments on commit 3c1ba4e

Please sign in to comment.