Adjusted animation definition storage to be consistent

This commit is contained in:
Ethan 2025-04-02 19:33:13 -04:00
parent dccd19ac80
commit d3ad840169
30 changed files with 216 additions and 137 deletions

View file

@ -1,6 +1,8 @@
<!--
<animations>
<animation name="bubble_idle_anim" type="idle">
<FPS>2</FPS>
<sprite path="sprites/bubbleoAtlas64.png" frameSize="64.0"/>
</animation>
</animations>
</animations>
-->

View file

@ -0,0 +1,22 @@
<!-- Player Animations -->
<animation id="character/player/idle" directional="true" FPS="5" frameSize="64.0" atlas="sprites/player3AtlasIdle64.png"/>
<animation id="character/player/move" directional="true" FPS="7" frameSize="64.0" atlas="sprites/player3AtlasMove64.png"/>
<!-- Fallback animations -->
<animation id="character/tmp/move" directional="false" FPS="7" frameSize="128.0" atlas="sprites/player2Atlas.png"/>
<!--
<animations directional="true">
<animation name="player_move_anim" type="move">
<FPS>7</FPS>
<sprite path="sprites/player3AtlasMove64.png" frameSize="64.0"/>
</animation>
<animation name="player_idle_anim" type="idle">
<FPS>5</FPS>
<sprite path="sprites/player3AtlasIdle64.png" frameSize="64.0"/>
</animation>
</animations>
-->

View file

@ -1,3 +1,4 @@
<!--
<animations>
<animation name="machine_gun_idle_anim" type="idle">
<FPS>4</FPS>
@ -8,3 +9,4 @@
<sprite path="sprites/machineGunAtlasReload256.png" frameSize="256.0"/>
</animation>
</animations>
-->

View file

@ -0,0 +1,2 @@
<!-- Bubble -->
<animation id="obj/bubble/idle" FPS="2" frameSize="64.0" atlas="sprites/bubbleoAtlas64.png"/>

View file

@ -1,3 +1,4 @@
<!--
<animations>
<animation name="pistol_idle_anim" type="idle">
<FPS>4</FPS>
@ -8,3 +9,4 @@
<sprite path="sprites/pistolAtlasReload256.png" frameSize="256.0"/>
</animation>
</animations>
-->

View file

@ -1,11 +0,0 @@
<animations directional="true">
<animation name="player_move_anim" type="move">
<FPS>7</FPS>
<sprite path="sprites/player3AtlasMove64.png" frameSize="64.0"/>
</animation>
<animation name="player_idle_anim" type="idle">
<FPS>5</FPS>
<sprite path="sprites/player3AtlasIdle64.png" frameSize="64.0"/>
</animation>
</animations>

View file

@ -1,3 +1,4 @@
<!--
<animations>
<animation name="shot_gun_idle_anim" type="idle">
<FPS>4</FPS>
@ -11,4 +12,5 @@
<FPS>8</FPS>
<sprite path="sprites/shotGunReload128.png" frameSize="128.0"/>
</animation>
</animations>
</animations>
-->

View file

@ -1,6 +1,8 @@
<!--
<animations>
<animation name="tmp_enemy_move_anim" type="move">
<FPS>7</FPS>
<sprite path="sprites/player2Atlas.png" frameSize="128.0"/>
</animation>
</animations>
-->

View file

@ -0,0 +1,13 @@
<!-- Machine Gun -->
<animation id="gun/machine/idle" FPS="4" frameSize="256.0" atlas="sprites/machineGunAtlas256.png"/>
<animation id="gun/machine/reload" FPS="6" frameSize="256.0" atlas="sprites/machineGunAtlasReload256.png"/>
<!-- Pistol -->
<animation id="gun/pistol/idle" FPS="4" frameSize="256.0" atlas="sprites/pistolAtlas256.png"/>
<animation id="gun/pistol/reload" FPS="8" frameSize="256.0" atlas="sprites/pistolAtlasReload256.png"/>
<!-- Shotgun -->
<animation id="gun/shotgun/idle" FPS="4" frameSize="128.0" atlas="sprites/shotGunIdle128.png"/>
<animation id="gun/shotgun/fire" FPS="8" frameSize="128.0" atlas="sprites/shotGunFire128.png"/>
<animation id="gun/shotgun/reload" FPS="8" frameSize="128.0" atlas="sprites/shotGunReload128.png"/>

View file

@ -3,19 +3,19 @@
<scene type="shooter" id="000" bg="backgrounds/blue_sky.png">
<map name="newmap"/>
<entities>
<player x="7" y="5" weapon="shotGun">
<animation name="player_anim"/>
<player x="7" y="5" weapon="shotgun">
<animation id="character/player"/>
</player>
<entity x="10" y="3" weapon="pistolGun">
<animation name="player_anim"/>
<entity x="10" y="3" weapon="pistol">
<animation id="character/player"/>
<script file="scripts/ai/grunt_behaviour.lua"/>
</entity>
<entity x="6" y="3" weapon="pistolGun">
<animation name="tmp_enemy_anim"/>
<entity x="6" y="3" weapon="pistol">
<animation id="character/tmp"/>
<script file="scripts/ai/grunt_behaviour.lua"/>
</entity>
<entity x="5" y="3" weapon="pistolGun">
<animation name="tmp_enemy_anim"/>
<entity x="5" y="3" weapon="pistol">
<animation id="character/tmp"/>
<script file="scripts/ai/grunt_behaviour.lua"/>
</entity>
</entities>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Shotgun Sounds -->
<sound id="gun/shotgun/shoot" spatial="true" path="sounds/gun/big_boom.ogg"/>
<!-- Pistol Sounds -->
<sound id="gun/pistol/shoot" spatial="true" path="sounds/gun/small_pew.ogg"/>
<!-- Generic Sounds -->
<sound id="gun/generic/shoot" spatial="true" path="sounds/gun/small_pew.ogg"/>

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<weapons>
<weapon name="bubbleGun" fireSpeed="100.0" maxAmmo="40000" clipSize="1000">
<bullet anim="bubble_anim">
<weapon name="bubblegun" fireSpeed="100.0" maxAmmo="40000" clipSize="1000">
<bullet anim="obj/bubble">
<spread>60</spread>
<speed>20.0</speed>
<drop>250.0</drop>
@ -11,9 +11,9 @@
</bullet>
</weapon>
<weapon name="shotGun" fireSpeed="1750.0" maxAmmo="64" clipSize="4">
<weapon name="shotgun" fireSpeed="1750.0" maxAmmo="64" clipSize="4">
<script file="scripts/weapons/shotgun_script.lua"/>
<animation name="shot_gun_anim">
<animation id="gun/shotgun">
<size x="55.0" y="55.0"/>
<offset x="-30.0" y="0.0"/>
</animation>
@ -26,8 +26,8 @@
</bullet>
</weapon>
<weapon name="machineGun" fireSpeed="50.0" maxAmmo="512" clipSize="64">
<animation name="machine_gun_anim">
<weapon name="machine_gun" fireSpeed="50.0" maxAmmo="512" clipSize="64">
<animation id="gun/machine">
<size x="55.0" y="55.0"/>
<offset x="-30.0" y="0.0"/>
</animation>
@ -40,8 +40,8 @@
</bullet>
</weapon>
<weapon name="pistolGun" fireSpeed="750.0" maxAmmo="512" clipSize="21">
<animation name="pistol_anim">
<weapon name="pistol" fireSpeed="750.0" maxAmmo="512" clipSize="21">
<animation id="gun/pistol">
<size x="55.0" y="55.0"/>
<offset x="-30.0" y="0.0"/>
</animation>

View file

@ -16,7 +16,7 @@ struct TileSetData;
class Map : public Drawable
{
public:
Map(std::shared_ptr<MapData> mapData, const unsigned shaderID, std::shared_ptr<ResourceManager> resourceManager);
Map(const MapData* mapData, const unsigned shaderID, std::shared_ptr<ResourceManager> resourceManager);
const std::vector<std::vector<int>> getCollisionMap() const { return collisionMap; }
@ -28,8 +28,8 @@ private:
size_t getTileSetIndex(int id) const;
std::shared_ptr<MapData> mapData;
std::vector<std::shared_ptr<TileSetData>> tileSetData;
const MapData* mapData;
std::vector<const TileSetData*> tileSetData;
std::vector<std::shared_ptr<TileTextureInstance>> instanceHandles;
std::vector<std::vector<std::vector<int>>> tileIds;
@ -37,4 +37,4 @@ private:
std::vector<std::vector<InstanceData>> tileData;
};
#endif
#endif

View file

@ -78,7 +78,7 @@ private:
std::shared_ptr<ResourceManager> resourceManager;
std::weak_ptr<EventManager> globalEventManager;
std::shared_ptr<EventManager> eventManager;
std::shared_ptr<SceneData> sceneData;
const SceneData* sceneData;
};
#endif //_H_SCENE_H

View file

@ -27,7 +27,7 @@ struct WeaponData;
class Weapon : public Entity, public std::enable_shared_from_this<Weapon>
{
public:
Weapon(std::shared_ptr<WeaponData> data, const unsigned weaponShaderID, const unsigned bulletShaderID, ResourceManager* resourceManager);
Weapon(const WeaponData* data, const unsigned weaponShaderID, const unsigned bulletShaderID, ResourceManager* resourceManager);
void setWielder(GameActor* wielder) { this->wielder = wielder; }
void toggleInfiniteAmmo() { infiniteAmmo = !infiniteAmmo; }

View file

@ -23,10 +23,11 @@ struct AnimationData;
class Animation
{
public:
Animation(const std::shared_ptr<AnimationData>& animData, ResourceManager* resourceManager);
Animation(const AnimationData* animData, ResourceManager* resourceManager);
std::string getName() const { return animName; }
std::string getType() const { return animType; }
std::string getPrefix() const { return prefix; }
std::string getType() const { return type; }
std::string getID() const { return prefix + "/" + type; }
void bind();
void draw();
@ -34,7 +35,7 @@ public:
void play() { isPlaying = true; }
void stop() { isPlaying = false; }
void reset() { currentFrame = 0; }
void reset() { currentFrame = 0; lastFrameTick = 0; elapsedTime = 0; }
const bool getPlaying() const { return isPlaying; }
const bool getDirectional() const { return isDirectional; }
@ -43,8 +44,8 @@ public:
void setFPS(const float fps) { FPS = fps; }
private:
std::string animName;
std::string animType;
std::string prefix;
std::string type;
SpriteAtlas* spriteAtlas;
@ -70,7 +71,7 @@ class AnimationSet : public std::enable_shared_from_this<AnimationSet>
{
public:
AnimationSet(const int& entityid);
AnimationSet(const int& entityid, ResourceManager* resourceManager, std::vector<std::shared_ptr<AnimationData>> animSet);
AnimationSet(const int& entityid, ResourceManager* resourceManager, std::vector<AnimationData*> animSet);
AnimationSet(const int& entityid, std::unordered_map<std::string, std::unique_ptr<Animation>> animations);
Animation* operator [](std::string animType) { return anims[animType].get(); }

View file

@ -26,13 +26,15 @@ class SoundEffect
public:
SoundEffect(const std::string& filename);
ALuint getBuffer() const { return buffer; }
bool isValid() const { return valid; }
~SoundEffect();
private:
bool loadFile(const std::string &filename);
ALuint buffer;
bool valid;
};
#endif // _H_SOUNDEFFECT_H

View file

@ -12,8 +12,26 @@ namespace UTIL
}
constexpr float INF_TIME = -99.6875f;
constexpr auto split = [](const std::string& s, size_t *left, size_t *right, std::string *out) {
if ((*right = s.find("/", *left)) != std::string::npos) {
if (out) {
*out = s.substr(*left, *right - *left);
}
*left = *right + 1;
} else {
if (out) {
out->append(s.substr(*left));
}
}
};
constexpr auto get_type = [](const std::string& id) {
auto pos = id.find_last_of("/");
return (pos != std::string::npos) ? id.substr(pos + 1) : id;
};
void flip_surface(SDL_Surface* surface);
std::string parsePrefix(const std::string& id);
class RandomGenerator
{

View file

@ -5,6 +5,7 @@
#include <memory>
#include <string>
#include "sound/soundeffect.h"
#include "utility/xmlloader.h"
#include "graphics/shader.h"
#include "graphics/sprite.h"
@ -40,12 +41,12 @@ public:
Background* loadBackground (const std::string& path);
std::shared_ptr<AIScript> loadAIScript (const std::string& path);
std::shared_ptr<WeaponScript> loadWeaponScript (const std::string& path);
std::shared_ptr<Weapon> loadWeapon (const std::string& name, const unsigned weaponShaderID, const unsigned bulletShaderID);
std::shared_ptr<AnimationSet> loadAnimationSet (const std::string& name, int entityid = 0);
const unsigned loadShader (const std::string& name, const std::string& vertexPath, const std::string& fragPath);
std::shared_ptr<Weapon> loadWeapon (const std::string& name, const unsigned weaponShaderID, const unsigned bulletShaderID);
std::shared_ptr<SceneData> loadScene (const std::string& id);
std::shared_ptr<AnimationSet> loadAnimationSet (const std::string& name, int entityid = 0);
std::shared_ptr<TileSetData> loadTileSet (const std::string& name);
const SceneData* loadScene (const std::string& id);
const TileSetData* loadTileSet (const std::string& name);
// Returns a NON-OWNING pointer to a shader by ID
Shader* getShaderByID(unsigned int ID);
@ -57,6 +58,7 @@ public:
private:
std::unordered_map<std::string, std::unique_ptr<Shader>> shaders;
std::unordered_map<unsigned, Shader*> shaderIDs;
std::unordered_map<std::string, std::unique_ptr<SoundEffect>> sounds;
std::unordered_map<std::string, std::unique_ptr<Sprite>> sprites;
std::unordered_map<std::string, std::shared_ptr<Weapon>> weapons;
std::unordered_map<std::string, std::shared_ptr<Script>> scripts;

View file

@ -19,7 +19,7 @@ struct EntityData {
bool animated;
int x = 0, y = 0;
std::string graphic;
std::string weapon = "pistolGun";
std::string weapon = "pistol";
std::string script;
};
@ -67,7 +67,7 @@ struct SceneData {
std::string type;
std::string bgFile;
std::shared_ptr<MapData> map;
const MapData* map;
std::vector<EntityData> entities;
};
@ -78,7 +78,7 @@ struct WeaponData {
int maxAmmo = 512;
std::string script = "";
std::string graphic;
std::string animSet;
std::string animPrefix;
bool animated = false;
float sizeX = 50.f, sizeY = 50.f;
float offsetX = 0.f, offsetY = 0.f;
@ -89,22 +89,26 @@ struct WeaponData {
float modMin = 0.5f, modMax = 1.0f;
};
// ID is the new tactic I've decided on.
// Each animationable object will be given a prefix
// denoting their type and object so <type>/<object>
// This prefix will be used to look up the animation on
// the animation map
struct AnimationData {
std::string name;
std::string type;
std::string id;
std::string spriteAtlas;
// Each entity will have a set of animations,
// this animation set is meant to keep each group
// of animations within their set.
// The actual set name is based on the file the animation
// is held in.
std::string animSet;
bool directional = false;
bool oneShot;
float FPS = 1.f;
float frameSize;
};
struct SoundData {
std::string id; // <type>/<object>/<state>
std::string path;
bool spatial;
};
class XMLLoader
{
public:
@ -115,45 +119,45 @@ public:
bool loadTileSets(const char* tileSetFolder);
bool loadMaps(const char* mapFolder);
const std::shared_ptr<SceneData> getSceneData(const std::string& id) const {
const SceneData* getSceneData(const std::string& id) const {
try {
return scenes.at(id);
return scenes.at(id).get();
}
catch (std::exception&) {
return nullptr;
}
}
const std::shared_ptr<MapData> getMapData(const std::string& name) const {
const MapData* getMapData(const std::string& name) const {
try {
return maps.at(name);
return maps.at(name).get();
}
catch (std::exception&) {
return nullptr;
}
}
const std::shared_ptr<WeaponData> getWeaponData(const std::string& name) const {
const WeaponData* getWeaponData(const std::string& name) const {
try {
return weapons.at(name);
return weapons.at(name).get();
}
catch (std::exception&) {
return nullptr;
}
}
const std::shared_ptr<AnimationData> getAnimationData(const std::string& name) const {
const AnimationData* getAnimationData(const std::string& id) const {
try {
return animations.at(name);
return animations.at(id).get();
}
catch (std::exception&) {
return nullptr;
}
}
const std::shared_ptr<TileSetData> getTileSetData(const std::string& name) const {
const TileSetData* getTileSetData(const std::string& name) const {
try {
return tileSets.at(name);
return tileSets.at(name).get();
}
catch (std::exception&) {
return nullptr;
@ -163,11 +167,11 @@ public:
// return a full set of animations, may need further optimization.
// one idea is when loading animations we create a seperate map that holds each set by their reference, so we can just do a simple,
// hash table lookup.
std::vector<std::shared_ptr<AnimationData>> getAnimationSet(const std::string& set) const {
std::vector<std::shared_ptr<AnimationData>> animSet;
std::vector<AnimationData*> getAnimationSet(const std::string& prefix) const {
std::vector<AnimationData*> animSet;
animSet.reserve(animations.size());
for (const auto& [name, anim] : animations) {
if (anim->animSet == set) animSet.push_back(anim);
for (const auto& [id, anim] : animations) {
if (id.starts_with(prefix)) animSet.push_back(anim.get());
}
animSet.shrink_to_fit();
return animSet;
@ -180,11 +184,11 @@ protected:
bool loadTile(tinyxml2::XMLElement* tileElement, TileSetData::TileData* out);
bool loadObject(tinyxml2::XMLElement* objectElement, TileSetData::TileData::ObjectData* out);
private:
std::unordered_map<std::string, std::shared_ptr<SceneData>> scenes;
std::unordered_map<std::string, std::shared_ptr<WeaponData>> weapons;
std::unordered_map<std::string, std::shared_ptr<AnimationData>> animations;
std::unordered_map<std::string, std::shared_ptr<MapData>> maps;
std::unordered_map<std::string, std::shared_ptr<TileSetData>> tileSets;
std::unordered_map<std::string, std::unique_ptr<SceneData>> scenes;
std::unordered_map<std::string, std::unique_ptr<WeaponData>> weapons;
std::unordered_map<std::string, std::unique_ptr<AnimationData>> animations;
std::unordered_map<std::string, std::unique_ptr<MapData>> maps;
std::unordered_map<std::string, std::unique_ptr<TileSetData>> tileSets;
};
#endif // _H_XMLLOADER_H
#endif // _H_XMLLOADER_H

View file

@ -8,7 +8,7 @@
#include <glm/gtc/matrix_transform.hpp>
Map::Map(std::shared_ptr<MapData> mapData, const unsigned shaderID, std::shared_ptr<ResourceManager> resourceManager) :
Map::Map(const MapData* mapData, const unsigned shaderID, std::shared_ptr<ResourceManager> resourceManager) :
mapData(mapData),
tileIds(mapData->tiles)
{
@ -122,4 +122,4 @@ size_t Map::getTileSetIndex(int id) const
break;
}
return (tileSetIndex >= mapData->tileSets.size()) ? -1 : tileSetIndex;
}
}

View file

@ -88,7 +88,7 @@ void Scene::loadDebugShooterScene()
auto entitySprite = resourceManager->loadSpriteStatic(entityData.graphic);
entity->addComponent(std::make_unique<SpriteComponent>(entitySprite));
}
auto defaultWeapon = resourceManager->loadWeapon("pistolGun", weaponShader, bubbleShader);
auto defaultWeapon = resourceManager->loadWeapon("pistol", weaponShader, bubbleShader);
auto entityWeapon = resourceManager->loadWeapon(entityData.weapon, weaponShader, bubbleShader);
entity->pickupWeapon(defaultWeapon);

View file

@ -14,7 +14,7 @@
// TODO: Regular clean up, make this mess readable!
Weapon::Weapon(std::shared_ptr<WeaponData> data, const unsigned weaponShaderID, const unsigned bulletShaderID, ResourceManager* resourceManager)
Weapon::Weapon(const WeaponData* data, const unsigned weaponShaderID, const unsigned bulletShaderID, ResourceManager* resourceManager)
:
Entity (weaponShaderID),
weaponType (data->name),
@ -54,7 +54,7 @@ void Weapon::reload()
{
if (auto event = eventManager.lock())
{
event->notify<EntityReloadEvent>((EntityReloadEvent){ entityid, wielder->getPosition(), weaponType });
event->notify<EntityReloadEvent>({ entityid, wielder->getPosition(), weaponType });
reloading = true;
if (weaponAmmo < weaponMagSize) {
weaponMag = weaponAmmo;
@ -172,7 +172,7 @@ void Weapon::update(double deltaTime)
{
wasReloading = false;
if (auto event = eventManager.lock()) {
event->notify<EntityFinishReloadEvent>((EntityFinishReloadEvent){entityid});
event->notify<EntityFinishReloadEvent>({entityid});
}
}
}
@ -258,7 +258,7 @@ void Weapon::createBullet(const Weapon::BulletData& data)
bullet->getPhysicsComponent()->rigidBody.velocity += bulletSpeed * data.direction / data.mass;
if (auto event = eventManager.lock())
event->notify<BulletFiredEvent>((BulletFiredEvent){bullet});
event->notify<BulletFiredEvent>({bullet});
bulletManager->addBullet(bullet);
}

View file

@ -3,17 +3,19 @@
#include "utility/xmlloader.h"
#include "utility/resourcemanager.h"
#include "utility/events.h"
#include "util.h"
Animation::Animation(const std::shared_ptr<AnimationData>& animData, ResourceManager* resourceManager) :
animName(animData->name),
animType(animData->type),
Animation::Animation(const AnimationData* animData, ResourceManager* resourceManager) :
spriteAtlas(resourceManager->loadSpriteAtlas(animData->spriteAtlas, animData->frameSize, animData->directional)),
FPS(animData->FPS),
currentFrame(0),
cycles(0),
isDirectional(animData->directional),
isPlaying(isDirectional)
{}
{
prefix = UTIL::parsePrefix(animData->id);
type = UTIL::get_type(animData->id);
}
void Animation::bind()
{
@ -74,24 +76,25 @@ void Animation::frameTick()
}
AnimationSet::AnimationSet(const int& entityid) : entityid(entityid), isDirectional(false) {};
AnimationSet::AnimationSet(const int& entityid, ResourceManager* resourceManager, std::vector<std::shared_ptr<AnimationData>> animSet) : entityid(entityid)
AnimationSet::AnimationSet(const int& entityid, ResourceManager* resourceManager, std::vector<AnimationData*> animSet) : entityid(entityid)
{
curAnim = nullptr;
for (const auto& anim : animSet)
{
anims.try_emplace(anim->type, std::make_unique<Animation>(anim, resourceManager));
if (anim->type == "idle")
curAnim = anims[anim->type].get();
std::string type = UTIL::get_type(anim->id);
anims.try_emplace(type, std::make_unique<Animation>(anim, resourceManager));
if (type == "idle")
curAnim = anims[type].get();
}
// if we don't have an idle animation, we are just gonna set the current animation to the top of the set
if (curAnim == nullptr)
curAnim = anims[animSet[0]->type].get();
curAnim = anims[UTIL::get_type(animSet[0]->id)].get();
isDirectional = curAnim->getDirectional();
}
AnimationSet::AnimationSet(const int& entityid, std::unordered_map<std::string, std::unique_ptr<Animation>> animations)
: entityid(entityid), anims(std::move(animations))
{
for (auto& [type, anim] : animations)
for (auto& [type, anim] : anims)
{
curAnim = anim.get();
if (type == "idle")
@ -165,8 +168,10 @@ void AnimationSet::attachEventManager(std::weak_ptr<EventManager> e)
if (auto self = weakSelf.lock()) {
if (e.entityid == self->entityid)
{
if (self->anims["idle"] != NULL)
if (self->anims["idle"] != NULL) {
self->curAnim->reset();
self->curAnim = self->anims["idle"].get();
}
}
}
});
@ -215,7 +220,7 @@ void AnimationSet::draw()
// If the animation has cycled, we send this event after every cycle
if ((curAnim->getCycles() - lastCycle) > 0) {
if (auto event = eventManager.lock()) {
event->notify((AnimationFinishedEvent){entityid, curAnim->getType()});
event->notify<AnimationFinishedEvent>({entityid, curAnim->getType()});
}
}
}

View file

@ -4,9 +4,7 @@
SoundEffect::SoundEffect(const std::string& filename)
{
if (!loadFile(filename)) {
return;
}
valid = loadFile(filename);
}
// load the whole file into a buffer, this should only be used for small sound effects. Never with music or sounds exceeding 10MB!

View file

@ -22,4 +22,16 @@ namespace UTIL
delete[] temp;
SDL_UnlockSurface(surface);
}
}
std::string parsePrefix(const std::string& id)
{
std::string prefix;
size_t left = 0;
size_t right = 0;
UTIL::split(id, &left, &right, &prefix);
prefix += "/";
UTIL::split(id, &left, &right, &prefix);
return prefix;
}
}

View file

@ -39,7 +39,7 @@ std::shared_ptr<WeaponScript> ResourceManager::loadWeaponScript(const std::strin
return std::make_shared<WeaponScript>(path.c_str());
}
std::shared_ptr<TileSetData> ResourceManager::loadTileSet(const std::string& name)
const TileSetData* ResourceManager::loadTileSet(const std::string& name)
{
return xmlLoader->getTileSetData(name);
}
@ -79,21 +79,21 @@ Background* ResourceManager::loadBackground(const std::string& path)
// incomplete reference to our script.
std::shared_ptr<Weapon> ResourceManager::loadWeapon(const std::string& name, const unsigned weaponShaderID, const unsigned bulletShaderID)
{
std::shared_ptr<WeaponData> data = xmlLoader->getWeaponData(name);
const WeaponData* data = xmlLoader->getWeaponData(name);
auto weapon = std::make_shared<Weapon>(data, weaponShaderID, bulletShaderID, this);
if (!data->script.empty())
weapon->attachScript(loadWeaponScript(data->script));
return weapon;
}
std::shared_ptr<SceneData> ResourceManager::loadScene(const std::string& id)
const SceneData* ResourceManager::loadScene(const std::string& id)
{
return xmlLoader->getSceneData(id);
}
std::shared_ptr<AnimationSet> ResourceManager::loadAnimationSet(const std::string& name, int entityid)
std::shared_ptr<AnimationSet> ResourceManager::loadAnimationSet(const std::string& prefix, int entityid)
{
auto animSetData = xmlLoader->getAnimationSet(name);
auto animSetData = xmlLoader->getAnimationSet(prefix);
return std::make_shared<AnimationSet>(entityid, this, animSetData);
}

View file

@ -1,6 +1,7 @@
#include "utility/xmlloader.h"
#include "utility/logger.h"
#include <tinyxml2.h>
/*
Loading every scene in the scene folder and storing in hashmap scenes
@ -18,7 +19,7 @@ bool XMLLoader::loadScenes(const char* sceneFolder)
SceneData scene;
if (!loadXmlScene((const char*)file.path().string().c_str(), &scene))
continue;
scenes.try_emplace(scene.id, std::make_shared<SceneData>(scene));
scenes.try_emplace(scene.id, std::make_unique<SceneData>(scene));
}
return true;
}
@ -76,7 +77,7 @@ bool XMLLoader::loadEntityData(const char* xmlFile, SceneData* out)
ERROR_LOG("Player element not found in scene! File: {}", xmlFile);
EntityData playData;
const char *graphic, *weaponName = "pistolGun";
const char *graphic, *weaponName = "pistol";
if (playerElement->QueryIntAttribute("x", &playData.x) != tinyxml2::XML_SUCCESS ||
playerElement->QueryIntAttribute("y", &playData.y) != tinyxml2::XML_SUCCESS)
@ -95,7 +96,7 @@ bool XMLLoader::loadEntityData(const char* xmlFile, SceneData* out)
else
{
playData.animated = true;
if (anim->QueryStringAttribute("name", &graphic) != tinyxml2::XML_SUCCESS)
if (anim->QueryStringAttribute("id", &graphic) != tinyxml2::XML_SUCCESS)
ERROR_LOG("Could not find 'name' attribute in 'animation' tag. File: {}", xmlFile);
}
playData.isPlayer = true;
@ -111,7 +112,7 @@ bool XMLLoader::loadEntityData(const char* xmlFile, SceneData* out)
for (tinyxml2::XMLElement* e = entities->FirstChildElement("entity"); e != NULL; e = e->NextSiblingElement("entity"))
{
EntityData data;
const char *graphic, *weaponName = "pistolGun", *scriptPath;
const char *graphic, *weaponName = "pistol", *scriptPath;
if (e->QueryIntAttribute("x", &data.x) != tinyxml2::XML_SUCCESS ||
e->QueryIntAttribute("y", &data.y) != tinyxml2::XML_SUCCESS)
ERROR_LOG("Could not load position coordinates for entity. File: {}", xmlFile);
@ -129,7 +130,7 @@ bool XMLLoader::loadEntityData(const char* xmlFile, SceneData* out)
else
{
data.animated = true;
if (anim->QueryStringAttribute("name", &graphic) != tinyxml2::XML_SUCCESS)
if (anim->QueryStringAttribute("id", &graphic) != tinyxml2::XML_SUCCESS)
continue;
}
tinyxml2::XMLElement* script = e->FirstChildElement("script");
@ -198,7 +199,7 @@ bool XMLLoader::loadWeapons(const char* weaponFolder)
if (anim)
{
data.animated = true;
if (anim->QueryStringAttribute("name", &graphic) != tinyxml2::XML_SUCCESS)
if (anim->QueryStringAttribute("id", &graphic) != tinyxml2::XML_SUCCESS)
continue;
if (anim->ChildElementCount() != 0)
@ -272,14 +273,15 @@ bool XMLLoader::loadWeapons(const char* weaponFolder)
}
LOG(DEBUG, "Loaded {} from {}", data.name, file.path().filename().generic_string());
weapons.try_emplace(data.name, std::make_shared<WeaponData>(data));
weapons.try_emplace(data.name, std::make_unique<WeaponData>(data));
}
}
return (!weapons.empty());
}
/*
Load every animation file and store inside of hashmap -> animations, filename is the hash key
* Load each animation node and store inside a hashmap by their id. Each object that needs an animation will be given a prefix <type>/<object>.
* Which will be used to look up the corresponding animation
*/
bool XMLLoader::loadAnimations(const char* animationFolder)
{
@ -295,35 +297,24 @@ bool XMLLoader::loadAnimations(const char* animationFolder)
if (doc.LoadFile(file.path().generic_string().c_str()) != tinyxml2::XML_SUCCESS)
continue;
tinyxml2::XMLElement* anims = doc.FirstChildElement("animations");
bool directional = false;
anims->QueryBoolAttribute("directional", &directional);
if (anims == NULL)
continue;
for (tinyxml2::XMLElement* e = anims->FirstChildElement("animation"); e != NULL; e = e->NextSiblingElement("animation"))
for (tinyxml2::XMLElement* e = doc.FirstChildElement("animation"); e != NULL; e = e->NextSiblingElement("animation"))
{
AnimationData animData;
const char *name, *type, *spriteAtlas;
const char *id, *spriteAtlas;
if (e->QueryStringAttribute("name", &name) != tinyxml2::XML_SUCCESS ||
e->QueryStringAttribute("type", &type) != tinyxml2::XML_SUCCESS)
if (e->QueryStringAttribute("id", &id) != tinyxml2::XML_SUCCESS)
continue;
tinyxml2::XMLElement* fps = e->FirstChildElement("FPS");
fps->QueryFloatText(&animData.FPS);
tinyxml2::XMLElement* sprite = e->FirstChildElement("sprite");
if (sprite->QueryStringAttribute("path", &spriteAtlas) != tinyxml2::XML_SUCCESS ||
sprite->QueryFloatAttribute("frameSize", &animData.frameSize) != tinyxml2::XML_SUCCESS)
if (e->QueryStringAttribute("atlas", &spriteAtlas) != tinyxml2::XML_SUCCESS ||
e->QueryFloatAttribute("frameSize", &animData.frameSize) != tinyxml2::XML_SUCCESS)
continue;
animData.name = name;
animData.type = type;
e->QueryFloatAttribute("FPS", &animData.FPS);
e->QueryBoolAttribute("directional", &animData.directional);
animData.id = id;
animData.spriteAtlas = spriteAtlas;
animData.animSet = file.path().stem().string();
animData.directional = directional;
animations.try_emplace(animData.name, std::make_shared<AnimationData>(animData));
animations.try_emplace(animData.id, std::make_unique<AnimationData>(animData));
}
}
return true;
@ -395,7 +386,7 @@ bool XMLLoader::loadTileSets(const char* tileSetFolder)
tileSetData.file = file.path().parent_path().string() + "/" + std::string(setFile);
std::string key = folder.filename().string() + "/" + file.path().filename().string();
tileSets.try_emplace(key, std::make_shared<TileSetData>(tileSetData));
tileSets.try_emplace(key, std::make_unique<TileSetData>(tileSetData));
}
return true;
}
@ -589,7 +580,7 @@ bool XMLLoader::loadMaps(const char* mapFolder)
mapData.name = file.path().stem().string();
maps.try_emplace(mapData.name, std::make_shared<MapData>(mapData));
maps.try_emplace(mapData.name, std::make_unique<MapData>(mapData));
}
return true;
}