Preload scripts on boot and grab by ID for less file io operations + general cleanup
This commit is contained in:
parent
3241eafea0
commit
43bbc9e21d
12 changed files with 1195 additions and 1002 deletions
3
Resources/monsters/shooty_peeps.xml
Normal file
3
Resources/monsters/shooty_peeps.xml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
<monster id="monster/shooty/bighead" anim="character/tmp" weapon="gun/pistol" aggressive="true" behaviour="script/behaviour/grunt" hp="10.0"/>
|
||||||
|
<monster id="monster/shooty/clone" anim="character/player" weapon="gun/shotgun" aggressive="true" behaviour="script/behaviour/grunt" hp="15.0"/>
|
||||||
|
|
@ -3,20 +3,17 @@
|
||||||
<scene type="shooter" id="000" bg="backgrounds/blue_sky.png">
|
<scene type="shooter" id="000" bg="backgrounds/blue_sky.png">
|
||||||
<map name="newmap"/>
|
<map name="newmap"/>
|
||||||
<entities>
|
<entities>
|
||||||
<player x="7" y="5" weapon="gun/machine">
|
<player x="7" y="5" weapon="gun/shotgun">
|
||||||
<animation id="character/player"/>
|
<animation id="character/player"/>
|
||||||
</player>
|
</player>
|
||||||
<entity x="10" y="3" weapon="gun/pistol">
|
<entity x="10" y="3" weapon="gun/pistol">
|
||||||
<animation id="character/player"/>
|
<animation id="character/player"/>
|
||||||
<script file="scripts/ai/grunt_behaviour.lua"/>
|
<script id="script/behaviour/grunt"/>
|
||||||
</entity>
|
</entity>
|
||||||
<entity x="6" y="3" weapon="gun/pistol">
|
<entity x="6" y="3" weapon="gun/pistol">
|
||||||
<animation id="character/tmp"/>
|
<animation id="character/tmp"/>
|
||||||
<script file="scripts/ai/grunt_behaviour.lua"/>
|
<script id="script/behaviour/grunt"/>
|
||||||
</entity>
|
|
||||||
<entity x="5" y="3" weapon="gun/pistol">
|
|
||||||
<animation id="character/tmp"/>
|
|
||||||
<script file="scripts/ai/grunt_behaviour.lua"/>
|
|
||||||
</entity>
|
</entity>
|
||||||
|
<entity x="5" y="3" weapon="gun/pistol" monster_id="monster/shooty/bighead"/>
|
||||||
</entities>
|
</entities>
|
||||||
</scene>
|
</scene>
|
||||||
|
|
|
||||||
4
Resources/scripts/ai_scripts.xml
Normal file
4
Resources/scripts/ai_scripts.xml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
<!-- Shooter Scripts -->
|
||||||
|
<script id="script/behaviour/grunt" file="scripts/ai/grunt_behaviour.lua"/>
|
||||||
|
<script id="script/behaviour/scared" file="scripts/ai/scared_behaviour.lua"/>
|
||||||
3
Resources/scripts/weapon_scripts.xml
Normal file
3
Resources/scripts/weapon_scripts.xml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
<!-- Ranged weapon scripts -->
|
||||||
|
<script id="script/weapon/shotgun" file="scripts/weapons/shotgun_script.lua"/>
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
</weapon>
|
</weapon>
|
||||||
|
|
||||||
<weapon id="gun/shotgun" fireSpeed="1750.0" maxAmmo="64" clipSize="4">
|
<weapon id="gun/shotgun" fireSpeed="1750.0" maxAmmo="64" clipSize="4">
|
||||||
<script file="scripts/weapons/shotgun_script.lua"/>
|
<script id="script/weapon/shotgun"/>
|
||||||
<animation>
|
<animation>
|
||||||
<size x="55.0" y="55.0"/>
|
<size x="55.0" y="55.0"/>
|
||||||
<offset x="-30.0" y="0.0"/>
|
<offset x="-30.0" y="0.0"/>
|
||||||
|
|
@ -1,77 +1,90 @@
|
||||||
#ifndef _H_RESOURCEMANAGER_H
|
#ifndef _H_RESOURCEMANAGER_H
|
||||||
#define _H_RESOURCEMANAGER_H
|
#define _H_RESOURCEMANAGER_H
|
||||||
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "sound/soundeffect.h"
|
#include "graphics/background.h"
|
||||||
#include "utility/xmlloader.h"
|
|
||||||
#include "graphics/shader.h"
|
#include "graphics/shader.h"
|
||||||
#include "graphics/sprite.h"
|
#include "graphics/sprite.h"
|
||||||
#include "graphics/background.h"
|
#include "sound/soundeffect.h"
|
||||||
|
#include "utility/script.h"
|
||||||
|
#include "utility/xmlloader.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
class Weapon;
|
class Weapon;
|
||||||
class Script;
|
|
||||||
class AnimationSet;
|
class AnimationSet;
|
||||||
class AIScript;
|
|
||||||
class WeaponScript;
|
|
||||||
class SpriteComponent;
|
class SpriteComponent;
|
||||||
|
|
||||||
class ResourceManager
|
class ResourceManager {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
ResourceManager() :
|
ResourceManager() : xmlLoader(std::make_shared<XMLLoader>()) {
|
||||||
xmlLoader(std::make_shared<XMLLoader>())
|
xmlLoader->loadWeapons("weapons");
|
||||||
{
|
xmlLoader->loadAnimations("animations");
|
||||||
xmlLoader->loadWeapons("weapons");
|
xmlLoader->loadMonsters("monsters");
|
||||||
xmlLoader->loadAnimations("animations");
|
xmlLoader->loadTileSets("maps/tilesets");
|
||||||
xmlLoader->loadTileSets("maps/tilesets");
|
xmlLoader->loadMaps("maps");
|
||||||
xmlLoader->loadMaps("maps");
|
xmlLoader->loadScripts("scripts", loadLuaString);
|
||||||
xmlLoader->loadScenes("scenes");
|
xmlLoader->loadScenes("scenes");
|
||||||
xmlLoader->loadSoundEffects("sounds");
|
xmlLoader->loadSoundEffects("sounds");
|
||||||
shaders["__fallback__"] = std::make_unique<GenericShader>();
|
shaders["__fallback__"] = std::make_unique<GenericShader>();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a NON-OWNING pointer to a sprite atlas
|
// Returns a NON-OWNING pointer to a sprite atlas
|
||||||
SpriteAtlas* loadSpriteAtlas (const std::string& path, float frameSize, bool isDirectional = false);
|
SpriteAtlas *loadSpriteAtlas(const std::string &path, float frameSize,
|
||||||
// Returns a NON-OWNING pointer to a static sprite
|
bool isDirectional = false);
|
||||||
Sprite* loadSpriteStatic (const std::string& path);
|
// Returns a NON-OWNING pointer to a static sprite
|
||||||
// Returns a NON-OWNING pointer to a background
|
Sprite *loadSpriteStatic(const std::string &path);
|
||||||
Background* loadBackground (const std::string& path);
|
// Returns a NON-OWNING pointer to a background
|
||||||
const unsigned loadSoundEffect (const std::string& id);
|
Background *loadBackground(const std::string &path);
|
||||||
std::unique_ptr<AIScript> loadAIScript (const std::string& path);
|
const unsigned loadSoundEffect(const std::string &id);
|
||||||
std::unique_ptr<WeaponScript> loadWeaponScript (const std::string& path);
|
template <typename T = Script>
|
||||||
std::unique_ptr<Weapon> loadWeapon (const std::string& name, const unsigned weaponShaderID, const unsigned bulletShaderID);
|
std::unique_ptr<T> loadScript(const std::string &id);
|
||||||
std::shared_ptr<AnimationSet> loadAnimationSet (const std::string& name, int entityid = 0);
|
std::unique_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);
|
const unsigned loadShader(const std::string &name,
|
||||||
const SceneData* loadScene (const std::string& id);
|
const std::string &vertexPath,
|
||||||
const TileSetData* loadTileSet (const std::string& name);
|
const std::string &fragPath);
|
||||||
|
const SceneData *loadScene(const std::string &id);
|
||||||
|
const TileSetData *loadTileSet(const std::string &name);
|
||||||
|
|
||||||
// Returns a NON-OWNING pointer to a shader by ID
|
// Returns a NON-OWNING pointer to a shader by ID
|
||||||
Shader* getShaderByID(unsigned int ID);
|
Shader *getShaderByID(unsigned int ID);
|
||||||
|
|
||||||
void clearResources();
|
void clearResources();
|
||||||
|
|
||||||
~ResourceManager();
|
~ResourceManager();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, std::unique_ptr<Shader>> shaders;
|
std::unordered_map<std::string, std::unique_ptr<Shader>> shaders;
|
||||||
std::unordered_map<unsigned, Shader*> shaderIDs;
|
std::unordered_map<unsigned, Shader *> shaderIDs;
|
||||||
std::unordered_map<std::string, std::unique_ptr<SoundEffect>> sounds;
|
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::unique_ptr<Sprite>> sprites;
|
||||||
//std::unordered_map<std::string, std::unique_ptr<Weapon>> weapons;
|
std::unordered_map<std::string, std::unique_ptr<Background>> backgrounds;
|
||||||
//std::unordered_map<std::string, std::string> scripts;
|
std::unordered_map<std::string, std::shared_ptr<TileSetData>> tileSets;
|
||||||
std::unordered_map<std::string, std::unique_ptr<Background>> backgrounds;
|
|
||||||
std::unordered_map<std::string, std::shared_ptr<TileSetData>> tileSets;
|
|
||||||
//std::unordered_map<std::string, std::shared_ptr<EntityData>> entityData;
|
|
||||||
//std::unordered_map<std::string, std::shared_ptr<SceneData>> scenes;
|
|
||||||
//std::unordered_map<std::string, std::shared_ptr<MapData>> maps;
|
|
||||||
//std::unordered_map<std::string, std::shared_ptr<TileType>> tiles;
|
|
||||||
|
|
||||||
std::shared_ptr<XMLLoader> xmlLoader;
|
std::shared_ptr<XMLLoader> xmlLoader;
|
||||||
|
|
||||||
|
static bool loadLuaString(ScriptData *script);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::unique_ptr<T> ResourceManager::loadScript(const std::string &id) {
|
||||||
|
const ScriptData *data = xmlLoader->getScriptData(id);
|
||||||
|
if (data == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
try {
|
||||||
|
std::unique_ptr<T> script = std::make_unique<T>(data->script);
|
||||||
|
return std::move(script);
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
LOG(ERROR, "Failed to load script '{}'", data->fileName);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // _H_RESOURCEMANAGER_H
|
#endif // _H_RESOURCEMANAGER_H
|
||||||
|
|
|
||||||
|
|
@ -3,45 +3,45 @@
|
||||||
|
|
||||||
#define SOL_ALL_SAFETIES_ON 1
|
#define SOL_ALL_SAFETIES_ON 1
|
||||||
|
|
||||||
#include <sol/sol.hpp>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <sol/sol.hpp>
|
||||||
|
|
||||||
class Script {
|
class Script {
|
||||||
public:
|
public:
|
||||||
sol::state lua;
|
sol::state lua;
|
||||||
Script(const std::string& path);
|
Script(const std::string &str);
|
||||||
~Script();
|
~Script();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool loadScript(const std::string& path) {
|
bool loadScript(const std::string &str) {
|
||||||
auto result = lua.script_file(path);
|
auto result = lua.script(str);
|
||||||
if (!result.valid())
|
if (!result.valid()) {
|
||||||
{
|
sol::error err = result;
|
||||||
sol::error err = result;
|
std::cerr << "Failed to load script. Error: " << err.what() << std::endl;
|
||||||
std::cerr << "Failed to load script ( " << path << " ) Error: " << err.what() << std::endl;
|
}
|
||||||
}
|
return result.valid();
|
||||||
return result.valid();
|
}
|
||||||
}
|
void registerGlobalUserTypes();
|
||||||
void registerGlobalUserTypes();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AIScript : public Script {
|
class AIScript : public Script {
|
||||||
public:
|
public:
|
||||||
AIScript(const std::string& path) : Script(path) { registerUserTypes(); }
|
AIScript(const std::string &str) : Script(str) { registerUserTypes(); }
|
||||||
|
|
||||||
~AIScript();
|
~AIScript();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void registerUserTypes();
|
||||||
void registerUserTypes() ;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class WeaponScript : public Script {
|
class WeaponScript : public Script {
|
||||||
public:
|
public:
|
||||||
WeaponScript(const std::string& path) : Script(path) { registerUserTypes(); }
|
WeaponScript(const std::string &str) : Script(str) { registerUserTypes(); }
|
||||||
~WeaponScript();
|
~WeaponScript();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void registerUserTypes() ;
|
void registerUserTypes();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _H_SCRIPT_H
|
#endif // _H_SCRIPT_H
|
||||||
|
|
|
||||||
|
|
@ -1,91 +1,103 @@
|
||||||
#ifndef _H_XMLLOADER_H
|
#ifndef _H_XMLLOADER_H
|
||||||
#define _H_XMLLOADER_H
|
#define _H_XMLLOADER_H
|
||||||
|
|
||||||
#include <vector>
|
#include <functional>
|
||||||
#include <string>
|
|
||||||
#include <memory>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
#include <tinyxml2.h>
|
#include <tinyxml2.h>
|
||||||
|
|
||||||
struct Tile;
|
struct Tile;
|
||||||
|
|
||||||
|
// Except for the player, these definitions are mostly overrides of the monster
|
||||||
|
// data
|
||||||
struct EntityData {
|
struct EntityData {
|
||||||
bool isPlayer;
|
bool isPlayer;
|
||||||
bool animated;
|
bool animated;
|
||||||
int x = 0, y = 0;
|
int x = 0, y = 0;
|
||||||
std::string graphic;
|
float hp;
|
||||||
std::string weapon = "pistol";
|
std::string monsterDef;
|
||||||
std::string script;
|
std::string graphic;
|
||||||
|
std::string weapon = "gun/pistol";
|
||||||
|
std::string script;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MapData {
|
struct MapData {
|
||||||
std::string name;
|
std::string name;
|
||||||
struct TileSet {
|
struct TileSet {
|
||||||
int startID = 1;
|
int startID = 1;
|
||||||
std::string path;
|
std::string path;
|
||||||
};
|
};
|
||||||
std::vector<TileSet> tileSets;
|
std::vector<TileSet> tileSets;
|
||||||
int width = 0, height = 0;
|
int width = 0, height = 0;
|
||||||
float tileSize = 32.f;
|
float tileSize = 32.f;
|
||||||
// 3D array, 0: layer, 1: y, 2: x
|
// 3D array, 0: layer, 1: y, 2: x
|
||||||
// Holding tile startID + ids, 0 is an empty tile
|
// Holding tile startID + ids, 0 is an empty tile
|
||||||
std::vector<std::vector<std::vector<int>>> tiles;
|
std::vector<std::vector<std::vector<int>>> tiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TileSetData {
|
struct TileSetData {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string type;
|
std::string type;
|
||||||
std::string file;
|
std::string file;
|
||||||
int width = 0, height = 0;
|
int width = 0, height = 0;
|
||||||
int columns = 0;
|
int columns = 0;
|
||||||
int tileCount = 0;
|
int tileCount = 0;
|
||||||
float tileSize = 64.f;
|
float tileSize = 64.f;
|
||||||
struct TileData {
|
struct TileData {
|
||||||
int id = 0;
|
int id = 0;
|
||||||
std::string type;
|
std::string type;
|
||||||
bool walkable = true;
|
bool walkable = true;
|
||||||
struct ObjectData {
|
struct ObjectData {
|
||||||
int id = 0;
|
int id = 0;
|
||||||
std::string name;
|
std::string name;
|
||||||
glm::vec2 pos;
|
glm::vec2 pos;
|
||||||
glm::vec2 size;
|
glm::vec2 size;
|
||||||
bool collidable = false;
|
bool collidable = false;
|
||||||
bool pickup = false;
|
bool pickup = false;
|
||||||
};
|
};
|
||||||
std::vector<std::shared_ptr<ObjectData>> objects;
|
std::vector<std::shared_ptr<ObjectData>> objects;
|
||||||
};
|
};
|
||||||
std::vector<std::shared_ptr<TileData>> tiles;
|
std::vector<std::shared_ptr<TileData>> tiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SceneData {
|
struct SceneData {
|
||||||
std::string id;
|
std::string id;
|
||||||
std::string type;
|
std::string type;
|
||||||
std::string bgFile;
|
std::string bgFile;
|
||||||
|
|
||||||
const MapData* map;
|
const MapData *map;
|
||||||
std::vector<EntityData> entities;
|
std::vector<EntityData> entities;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Store our script as a string so we only need to read the file at boot
|
||||||
|
struct ScriptData {
|
||||||
|
std::string id;
|
||||||
|
std::string fileName;
|
||||||
|
std::string script;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WeaponData {
|
struct WeaponData {
|
||||||
std::string id;
|
std::string id;
|
||||||
float fireSpeed = 250.0f;
|
float fireSpeed = 250.0f;
|
||||||
int clipSize = 21;
|
int clipSize = 21;
|
||||||
int maxAmmo = 512;
|
int maxAmmo = 512;
|
||||||
std::string script = "";
|
std::string script = "";
|
||||||
std::string graphic;
|
std::string graphic;
|
||||||
bool animated = false;
|
bool animated = false;
|
||||||
float sizeX = 50.f, sizeY = 50.f;
|
float sizeX = 50.f, sizeY = 50.f;
|
||||||
float offsetX = 0.f, offsetY = 0.f;
|
float offsetX = 0.f, offsetY = 0.f;
|
||||||
float bulletSizeX = 50.f, bulletSizeY = 50.f;
|
float bulletSizeX = 50.f, bulletSizeY = 50.f;
|
||||||
std::string bulletGraphic;
|
std::string bulletGraphic;
|
||||||
bool bulletAnimated = false;
|
bool bulletAnimated = false;
|
||||||
float bulletSpread = 1.0f, bulletSpeed = 3.0f, bulletDrop = 500.f;
|
float bulletSpread = 1.0f, bulletSpeed = 3.0f, bulletDrop = 500.f;
|
||||||
float modMin = 0.5f, modMax = 1.0f;
|
float modMin = 0.5f, modMax = 1.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ID is the new tactic I've decided on.
|
// ID is the new tactic I've decided on.
|
||||||
|
|
@ -94,111 +106,141 @@ struct WeaponData {
|
||||||
// This prefix will be used to look up the animation on
|
// This prefix will be used to look up the animation on
|
||||||
// the animation map
|
// the animation map
|
||||||
struct AnimationData {
|
struct AnimationData {
|
||||||
std::string id;
|
std::string id;
|
||||||
std::string spriteAtlas;
|
std::string spriteAtlas;
|
||||||
bool directional = false;
|
bool directional = false;
|
||||||
bool oneShot;
|
bool oneShot;
|
||||||
float FPS = 1.f;
|
float FPS = 1.f;
|
||||||
float frameSize;
|
float frameSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This holds a lot of defaults, but the scene can
|
||||||
|
// override a large portion of the definitions here
|
||||||
|
struct MonsterData {
|
||||||
|
std::string id;
|
||||||
|
std::string anim;
|
||||||
|
std::string weapon;
|
||||||
|
bool aggressive = false;
|
||||||
|
std::string behaviour;
|
||||||
|
float hp;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SoundData {
|
struct SoundData {
|
||||||
std::string id; // <type>/<object>/<state>
|
std::string id; // <type>/<object>/<state>
|
||||||
std::string path;
|
std::string path;
|
||||||
bool spatial;
|
bool spatial;
|
||||||
};
|
};
|
||||||
|
|
||||||
class XMLLoader
|
class XMLLoader {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
XMLLoader() {}
|
XMLLoader() {}
|
||||||
bool loadScenes(const char* sceneFolder);
|
bool loadScenes(const char *sceneFolder);
|
||||||
bool loadWeapons(const char* weaponFolder);
|
bool loadWeapons(const char *weaponFolder);
|
||||||
bool loadAnimations(const char* animationFolder);
|
bool loadAnimations(const char *animationFolder);
|
||||||
bool loadTileSets(const char* tileSetFolder);
|
bool loadTileSets(const char *tileSetFolder);
|
||||||
bool loadMaps(const char* mapFolder);
|
bool loadMaps(const char *mapFolder);
|
||||||
bool loadSoundEffects(const char* soundFolder);
|
bool loadMonsters(const char *monsterFolder);
|
||||||
|
// luaLoader is the function we use to load the lua file.
|
||||||
|
// This will be defined in our resource manager
|
||||||
|
bool loadScripts(const char *scriptFolder,
|
||||||
|
std::function<bool(ScriptData *)> luaLoader);
|
||||||
|
bool loadSoundEffects(const char *soundFolder);
|
||||||
|
|
||||||
const SceneData* getSceneData(const std::string& id) const {
|
const SceneData *getSceneData(const std::string &id) const {
|
||||||
try {
|
try {
|
||||||
return scenes.at(id).get();
|
return scenes.at(id).get();
|
||||||
}
|
} catch (std::exception &) {
|
||||||
catch (std::exception&) {
|
return nullptr;
|
||||||
return nullptr;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const MapData* getMapData(const std::string& name) const {
|
const ScriptData *getScriptData(const std::string &id) const {
|
||||||
try {
|
try {
|
||||||
return maps.at(name).get();
|
return scripts.at(id).get();
|
||||||
}
|
} catch (std::exception &) {
|
||||||
catch (std::exception&) {
|
return nullptr;
|
||||||
return nullptr;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const WeaponData* getWeaponData(const std::string& id) const {
|
const MapData *getMapData(const std::string &name) const {
|
||||||
try {
|
try {
|
||||||
return weapons.at(id).get();
|
return maps.at(name).get();
|
||||||
}
|
} catch (std::exception &) {
|
||||||
catch (std::exception&) {
|
return nullptr;
|
||||||
return nullptr;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const AnimationData* getAnimationData(const std::string& id) const {
|
const WeaponData *getWeaponData(const std::string &id) const {
|
||||||
try {
|
try {
|
||||||
return animations.at(id).get();
|
return weapons.at(id).get();
|
||||||
}
|
} catch (std::exception &) {
|
||||||
catch (std::exception&) {
|
return nullptr;
|
||||||
return nullptr;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const TileSetData* getTileSetData(const std::string& name) const {
|
const AnimationData *getAnimationData(const std::string &id) const {
|
||||||
try {
|
try {
|
||||||
return tileSets.at(name).get();
|
return animations.at(id).get();
|
||||||
}
|
} catch (std::exception &) {
|
||||||
catch (std::exception&) {
|
return nullptr;
|
||||||
return nullptr;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const SoundData* getSoundData(const std::string& id) const {
|
const TileSetData *getTileSetData(const std::string &name) const {
|
||||||
try {
|
try {
|
||||||
return sounds.at(id).get();
|
return tileSets.at(name).get();
|
||||||
}
|
} catch (std::exception &) {
|
||||||
catch (std::exception&) {
|
return nullptr;
|
||||||
return nullptr;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// return a full set of animations, may need further optimization.
|
const SoundData *getSoundData(const std::string &id) const {
|
||||||
// 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,
|
try {
|
||||||
// hash table lookup.
|
return sounds.at(id).get();
|
||||||
std::vector<AnimationData*> getAnimationSet(const std::string& prefix) const {
|
} catch (std::exception &) {
|
||||||
std::vector<AnimationData*> animSet;
|
return nullptr;
|
||||||
animSet.reserve(animations.size());
|
}
|
||||||
for (const auto& [id, anim] : animations) {
|
}
|
||||||
if (id.starts_with(prefix)) animSet.push_back(anim.get());
|
|
||||||
}
|
// return a full set of animations, may need further optimization.
|
||||||
animSet.shrink_to_fit();
|
// one idea is when loading animations we create a seperate map that holds
|
||||||
return animSet;
|
// each set by their reference, so we can just do a simple, hash table lookup.
|
||||||
}
|
std::vector<AnimationData *>
|
||||||
|
getAnimationSet(const std::string &prefix) const {
|
||||||
|
std::vector<AnimationData *> animSet;
|
||||||
|
animSet.reserve(animations.size());
|
||||||
|
for (const auto &[id, anim] : animations) {
|
||||||
|
if (id.starts_with(prefix))
|
||||||
|
animSet.push_back(anim.get());
|
||||||
|
}
|
||||||
|
animSet.shrink_to_fit();
|
||||||
|
return animSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearData() {
|
||||||
|
scenes.clear();
|
||||||
|
weapons.clear();
|
||||||
|
animations.clear();
|
||||||
|
maps.clear();
|
||||||
|
tileSets.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void clearData() { scenes.clear(); weapons.clear(); animations.clear(); maps.clear(); tileSets.clear(); }
|
|
||||||
protected:
|
protected:
|
||||||
bool loadXmlScene(const char* xmlFile, SceneData* out);
|
bool loadXmlScene(const char *xmlFile, SceneData *out);
|
||||||
bool loadEntityData(const char* xmlFile, SceneData* out);
|
bool loadEntityData(const char *xmlFile, SceneData *out);
|
||||||
bool loadTile(tinyxml2::XMLElement* tileElement, TileSetData::TileData* out);
|
bool loadTile(tinyxml2::XMLElement *tileElement, TileSetData::TileData *out);
|
||||||
bool loadObject(tinyxml2::XMLElement* objectElement, TileSetData::TileData::ObjectData* out);
|
bool loadObject(tinyxml2::XMLElement *objectElement,
|
||||||
|
TileSetData::TileData::ObjectData *out);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map<std::string, std::unique_ptr<SceneData>> scenes;
|
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<ScriptData>> scripts;
|
||||||
std::unordered_map<std::string, std::unique_ptr<AnimationData>> animations;
|
std::unordered_map<std::string, std::unique_ptr<WeaponData>> weapons;
|
||||||
std::unordered_map<std::string, std::unique_ptr<MapData>> maps;
|
std::unordered_map<std::string, std::unique_ptr<AnimationData>> animations;
|
||||||
std::unordered_map<std::string, std::unique_ptr<TileSetData>> tileSets;
|
std::unordered_map<std::string, std::unique_ptr<MonsterData>> monsters;
|
||||||
std::unordered_map<std::string, std::unique_ptr<SoundData>> sounds;
|
std::unordered_map<std::string, std::unique_ptr<MapData>> maps;
|
||||||
|
std::unordered_map<std::string, std::unique_ptr<TileSetData>> tileSets;
|
||||||
|
std::unordered_map<std::string, std::unique_ptr<SoundData>> sounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _H_XMLLOADER_H
|
#endif // _H_XMLLOADER_H
|
||||||
|
|
|
||||||
|
|
@ -101,12 +101,14 @@ void Scene::loadDebugShooterScene() {
|
||||||
} else {
|
} else {
|
||||||
// attach ai
|
// attach ai
|
||||||
if (!entityData.script.empty()) {
|
if (!entityData.script.empty()) {
|
||||||
auto behaviour = resourceManager->loadAIScript(entityData.script);
|
auto behaviour =
|
||||||
|
resourceManager->loadScript<AIScript>(entityData.script);
|
||||||
auto rayCaster = std::make_unique<Raycaster>(
|
auto rayCaster = std::make_unique<Raycaster>(
|
||||||
40.f, 300.f, map->getCollisionMap(), mapData->tileSize);
|
40.f, 300.f, map->getCollisionMap(), mapData->tileSize);
|
||||||
auto ai = std::make_shared<AI>(entity.get(), std::move(rayCaster));
|
auto ai = std::make_shared<AI>(entity.get(), std::move(rayCaster));
|
||||||
ai->setTarget(player.get());
|
ai->setTarget(player.get());
|
||||||
ai->attachBehaviourScript(std::move(behaviour));
|
if (behaviour != nullptr)
|
||||||
|
ai->attachBehaviourScript(std::move(behaviour));
|
||||||
entity->addComponent(std::make_unique<AIComponent>(ai));
|
entity->addComponent(std::make_unique<AIComponent>(ai));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,155 +1,129 @@
|
||||||
#include "graphics/texture.h"
|
#include "graphics/texture.h"
|
||||||
#include "utility/logger.h"
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "utility/logger.h"
|
||||||
|
|
||||||
bool Texture::loadTexture(const char* imagePath)
|
bool Texture::loadTexture(const char *imagePath) {
|
||||||
{
|
SDL_Surface *buffer = IMG_Load(imagePath);
|
||||||
SDL_Surface* buffer = IMG_Load(imagePath);
|
if (!buffer)
|
||||||
if (!buffer)
|
ERROR_LOG("Failed to load image file: {}", imagePath);
|
||||||
ERROR_LOG("Failed to load image file: {}", imagePath);
|
// UTIL::flip_surface(buffer);
|
||||||
//UTIL::flip_surface(buffer);
|
|
||||||
|
|
||||||
glGenTextures(1, &ID);
|
glGenTextures(1, &ID);
|
||||||
/*
|
/*
|
||||||
GLenum error = glGetError();
|
GLenum error = glGetError();
|
||||||
if(error != GL_NO_ERROR) {
|
if(error != GL_NO_ERROR) {
|
||||||
std::cout << "OpenGL error: " << error << std::endl;
|
std::cout << "OpenGL error: " << error << std::endl;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, ID);
|
glBindTexture(GL_TEXTURE_2D, ID);
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, buffer->w, buffer->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer->pixels);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, buffer->w, buffer->h, 0, GL_RGBA,
|
||||||
|
GL_UNSIGNED_BYTE, buffer->pixels);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glGenerateMipmap(ID);
|
glGenerateMipmap(ID);
|
||||||
|
|
||||||
textureWidth = buffer->w;
|
textureWidth = buffer->w;
|
||||||
textureHeight = buffer->h;
|
textureHeight = buffer->h;
|
||||||
|
|
||||||
SDL_FreeSurface(buffer);
|
SDL_FreeSurface(buffer);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::bind()
|
void Texture::bind() {
|
||||||
{
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glBindTexture(GL_TEXTURE_2D, ID);
|
||||||
glBindTexture(GL_TEXTURE_2D, ID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Texture::~Texture() { glDeleteTextures(1, &ID); }
|
||||||
|
|
||||||
Texture::~Texture()
|
bool TextureArray::loadTextures(std::vector<const char *> imagePaths) {
|
||||||
{
|
std::vector<SDL_Surface *> surfaces;
|
||||||
glDeleteTextures(1, &ID);
|
surfaces.resize(imagePaths.size());
|
||||||
|
// Fill surfaces vector
|
||||||
|
for (int i = 0; i < imagePaths.size(); ++i) {
|
||||||
|
surfaces[i] = IMG_Load(imagePaths[i]);
|
||||||
|
if (!surfaces[i])
|
||||||
|
ERROR_LOG("Failed to load image file: {}", imagePaths[i]);
|
||||||
|
}
|
||||||
|
if (!adjustCanvasSizes(surfaces))
|
||||||
|
ERROR_LOG(
|
||||||
|
"Failed to adjust canvas size of images! \n Make sure to check that "
|
||||||
|
"every tileset has square dimensions! (512x512, 756x756 ... etc)",
|
||||||
|
NULL);
|
||||||
|
if (surfaces.empty())
|
||||||
|
ERROR_LOG("No surfaces created!", NULL);
|
||||||
|
numOfLayers = imagePaths.size();
|
||||||
|
|
||||||
|
glGenTextures(1, &ID);
|
||||||
|
glBindTexture(GL_TEXTURE_2D_ARRAY, ID);
|
||||||
|
|
||||||
|
// Creating the texture array all of our textures will live in.
|
||||||
|
// adjustCanvasSizes makes every image the same size, so we can just use the
|
||||||
|
// first surface in the list of surfaces
|
||||||
|
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, surfaces[0]->w, surfaces[0]->h,
|
||||||
|
(GLsizei)numOfLayers, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||||
|
|
||||||
|
for (int layer = 0; layer < numOfLayers; ++layer) {
|
||||||
|
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, surfaces[layer]->w,
|
||||||
|
surfaces[layer]->h, 1, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||||
|
surfaces[layer]->pixels);
|
||||||
|
}
|
||||||
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
|
||||||
|
|
||||||
|
for (auto &surface : surfaces)
|
||||||
|
SDL_FreeSurface(surface);
|
||||||
|
surfaces.clear();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureArray::loadTextures(std::vector<const char*> imagePaths)
|
void TextureArray::bind() {
|
||||||
{
|
glActiveTexture(GL_TEXTURE0);
|
||||||
std::vector<SDL_Surface*> surfaces;
|
glBindTexture(GL_TEXTURE_2D_ARRAY, ID);
|
||||||
surfaces.resize(imagePaths.size());
|
|
||||||
// Fill surfaces vector
|
|
||||||
for (int i = 0; i < imagePaths.size(); ++i)
|
|
||||||
{
|
|
||||||
surfaces[i] = IMG_Load(imagePaths[i]);
|
|
||||||
if (!surfaces[i])
|
|
||||||
ERROR_LOG("Failed to load image file: {}", imagePaths[i]);
|
|
||||||
}
|
|
||||||
if (!adjustCanvasSizes(surfaces))
|
|
||||||
ERROR_LOG("Failed to adjust canvas size of images! \n Make sure to check that every tileset has square dimensions! (512x512, 756x756 ... etc)", NULL);
|
|
||||||
if (surfaces.empty())
|
|
||||||
ERROR_LOG("No surfaces created!", NULL);
|
|
||||||
numOfLayers = imagePaths.size();
|
|
||||||
|
|
||||||
glGenTextures(1, &ID);
|
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, ID);
|
|
||||||
|
|
||||||
// Creating the texture array all of our textures will live in.
|
|
||||||
// adjustCanvasSizes makes every image the same size, so we can just use the first
|
|
||||||
// surface in the list of surfaces
|
|
||||||
glTexImage3D(GL_TEXTURE_2D_ARRAY,
|
|
||||||
0,
|
|
||||||
GL_RGBA,
|
|
||||||
surfaces[0]->w,
|
|
||||||
surfaces[0]->h,
|
|
||||||
(GLsizei)numOfLayers,
|
|
||||||
0,
|
|
||||||
GL_RGBA,
|
|
||||||
GL_UNSIGNED_BYTE,
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
for (int layer = 0; layer < numOfLayers; ++layer)
|
|
||||||
{
|
|
||||||
glTexSubImage3D(GL_TEXTURE_2D_ARRAY,
|
|
||||||
0,
|
|
||||||
0, 0, layer,
|
|
||||||
surfaces[layer]->w,
|
|
||||||
surfaces[layer]->h,
|
|
||||||
1,
|
|
||||||
GL_RGBA,
|
|
||||||
GL_UNSIGNED_BYTE,
|
|
||||||
surfaces[layer]->pixels);
|
|
||||||
}
|
|
||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
|
|
||||||
glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
|
|
||||||
|
|
||||||
for (auto& surface : surfaces)
|
|
||||||
SDL_FreeSurface(surface);
|
|
||||||
surfaces.clear();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureArray::bind()
|
bool TextureArray::adjustCanvasSizes(std::vector<SDL_Surface *> &surfaces) {
|
||||||
{
|
int maxWidth = 0;
|
||||||
glActiveTexture(GL_TEXTURE0);
|
int maxHeight = 0;
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, ID);
|
for (auto &surface : surfaces) {
|
||||||
|
if (surface->w != surface->h)
|
||||||
|
ERROR_LOG("Image must be a square!", NULL);
|
||||||
|
|
||||||
|
if (surface->w > maxWidth)
|
||||||
|
maxWidth = surface->w;
|
||||||
|
if (surface->h > maxHeight)
|
||||||
|
maxHeight = surface->h;
|
||||||
|
textures.push_back(TextureData({surface->w, surface->h}));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < surfaces.size(); ++i) {
|
||||||
|
SDL_Surface *canvas = SDL_CreateRGBSurface(
|
||||||
|
0, maxWidth, maxHeight, surfaces[i]->format->BitsPerPixel,
|
||||||
|
surfaces[i]->format->Rmask, surfaces[i]->format->Gmask,
|
||||||
|
surfaces[i]->format->Bmask, surfaces[i]->format->Amask);
|
||||||
|
|
||||||
|
SDL_FillRect(canvas, NULL, SDL_MapRGBA(canvas->format, 0, 0, 0, 0));
|
||||||
|
|
||||||
|
SDL_BlitSurface(surfaces[i], NULL, canvas, NULL);
|
||||||
|
|
||||||
|
SDL_FreeSurface(surfaces[i]);
|
||||||
|
surfaces[i] = canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvasWidth = maxWidth;
|
||||||
|
canvasHeight = maxHeight;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextureArray::adjustCanvasSizes(std::vector<SDL_Surface*>& surfaces)
|
TextureArray::~TextureArray() { glDeleteTextures(1, &ID); }
|
||||||
{
|
|
||||||
int maxWidth = 0;
|
|
||||||
int maxHeight = 0;
|
|
||||||
for (auto& surface : surfaces)
|
|
||||||
{
|
|
||||||
if (surface->w != surface->h)
|
|
||||||
ERROR_LOG("Image must be a square!", NULL);
|
|
||||||
|
|
||||||
if (surface->w > maxWidth) maxWidth = surface->w;
|
|
||||||
if (surface->h > maxHeight) maxHeight = surface->h;
|
|
||||||
textures.push_back(TextureData({ surface->w, surface->h }));
|
|
||||||
}
|
|
||||||
for (int i = 0; i < surfaces.size(); ++i)
|
|
||||||
{
|
|
||||||
SDL_Surface* canvas = SDL_CreateRGBSurface(0, maxWidth, maxHeight,
|
|
||||||
surfaces[i]->format->BitsPerPixel,
|
|
||||||
surfaces[i]->format->Rmask,
|
|
||||||
surfaces[i]->format->Gmask,
|
|
||||||
surfaces[i]->format->Bmask,
|
|
||||||
surfaces[i]->format->Amask);
|
|
||||||
|
|
||||||
SDL_FillRect(canvas, NULL, SDL_MapRGBA(canvas->format, 0, 0, 0, 0));
|
|
||||||
|
|
||||||
SDL_BlitSurface(surfaces[i], NULL, canvas, NULL);
|
|
||||||
|
|
||||||
SDL_FreeSurface(surfaces[i]);
|
|
||||||
surfaces[i] = canvas;
|
|
||||||
}
|
|
||||||
|
|
||||||
canvasWidth = maxWidth;
|
|
||||||
canvasHeight = maxHeight;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureArray::~TextureArray()
|
|
||||||
{
|
|
||||||
glDeleteTextures(1, &ID);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,149 +1,145 @@
|
||||||
#include "utility/resourcemanager.h"
|
#include "utility/resourcemanager.h"
|
||||||
|
#include "gameplay/weapons/weapons.h"
|
||||||
|
#include "graphics/animation.h"
|
||||||
|
#include "graphics/background.h"
|
||||||
|
#include "graphics/shader.h"
|
||||||
#include "graphics/sprite.h"
|
#include "graphics/sprite.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "utility/script.h"
|
#include "utility/script.h"
|
||||||
#include "graphics/shader.h"
|
|
||||||
#include "graphics/animation.h"
|
|
||||||
#include "graphics/background.h"
|
|
||||||
#include "gameplay/weapons/weapons.h"
|
|
||||||
|
|
||||||
SpriteAtlas* ResourceManager::loadSpriteAtlas(const std::string& path, float frameSize, bool isDirectional)
|
SpriteAtlas *ResourceManager::loadSpriteAtlas(const std::string &path,
|
||||||
{
|
float frameSize,
|
||||||
auto iterator = sprites.find(path);
|
bool isDirectional) {
|
||||||
if (iterator != sprites.end())
|
auto iterator = sprites.find(path);
|
||||||
return static_cast<SpriteAtlas*>(iterator->second.get());
|
if (iterator != sprites.end())
|
||||||
auto sprite = std::make_unique<SpriteAtlas>(path.c_str(), frameSize, isDirectional);
|
return static_cast<SpriteAtlas *>(iterator->second.get());
|
||||||
sprites[path] = std::move(sprite);
|
auto sprite =
|
||||||
SpriteAtlas& l = static_cast<SpriteAtlas&>(*sprites[path].get());
|
std::make_unique<SpriteAtlas>(path.c_str(), frameSize, isDirectional);
|
||||||
return static_cast<SpriteAtlas*>(sprites[path].get());
|
sprites[path] = std::move(sprite);
|
||||||
|
SpriteAtlas &l = static_cast<SpriteAtlas &>(*sprites[path].get());
|
||||||
|
return static_cast<SpriteAtlas *>(sprites[path].get());
|
||||||
}
|
}
|
||||||
|
|
||||||
Sprite* ResourceManager::loadSpriteStatic(const std::string& path)
|
Sprite *ResourceManager::loadSpriteStatic(const std::string &path) {
|
||||||
{
|
auto iterator = sprites.find(path);
|
||||||
auto iterator = sprites.find(path);
|
if (iterator != sprites.end())
|
||||||
if (iterator != sprites.end())
|
return iterator->second.get();
|
||||||
return iterator->second.get();
|
auto sprite = std::make_unique<SpriteStatic>(path.c_str());
|
||||||
auto sprite = std::make_unique<SpriteStatic>(path.c_str());
|
if (!sprite->loaded())
|
||||||
if (!sprite->loaded())
|
return nullptr;
|
||||||
return nullptr;
|
sprites[path] = std::move(sprite);
|
||||||
sprites[path] = std::move(sprite);
|
return sprites[path].get();
|
||||||
return sprites[path].get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<AIScript> ResourceManager::loadAIScript(const std::string& path)
|
const TileSetData *ResourceManager::loadTileSet(const std::string &name) {
|
||||||
{
|
return xmlLoader->getTileSetData(name);
|
||||||
return std::make_unique<AIScript>(path.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<WeaponScript> ResourceManager::loadWeaponScript(const std::string& path)
|
const unsigned ResourceManager::loadShader(const std::string &name,
|
||||||
{
|
const std::string &vertexPath,
|
||||||
return std::make_unique<WeaponScript>(path.c_str());
|
const std::string &fragPath) {
|
||||||
|
auto iterator = shaders.find(name);
|
||||||
|
if (iterator != shaders.end())
|
||||||
|
return iterator->second->ID;
|
||||||
|
auto shader = std::make_unique<Shader>(vertexPath.c_str(), fragPath.c_str());
|
||||||
|
if (!shader->isValid()) {
|
||||||
|
return shaders["__fallback__"]->ID;
|
||||||
|
}
|
||||||
|
unsigned id = shader->ID;
|
||||||
|
shaderIDs[shader->ID] = shader.get();
|
||||||
|
shaders[name] = std::move(shader);
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TileSetData* ResourceManager::loadTileSet(const std::string& name)
|
Shader *ResourceManager::getShaderByID(unsigned int ID) {
|
||||||
{
|
auto iterator = shaderIDs.find(ID);
|
||||||
return xmlLoader->getTileSetData(name);
|
return (iterator != shaderIDs.end() ? iterator->second
|
||||||
|
: shaders["__fallback__"].get());
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned ResourceManager::loadShader(const std::string& name, const std::string& vertexPath, const std::string& fragPath)
|
Background *ResourceManager::loadBackground(const std::string &path) {
|
||||||
{
|
auto iterator = backgrounds.find(path);
|
||||||
auto iterator = shaders.find(name);
|
if (iterator != backgrounds.end())
|
||||||
if (iterator != shaders.end())
|
return iterator->second.get();
|
||||||
return iterator->second->ID;
|
auto background = std::make_unique<Background>(path);
|
||||||
auto shader = std::make_unique<Shader>(vertexPath.c_str(), fragPath.c_str());
|
backgrounds[path] = std::move(background);
|
||||||
if (!shader->isValid()) {
|
return backgrounds[path].get();
|
||||||
return shaders["__fallback__"]->ID;
|
|
||||||
}
|
|
||||||
unsigned id = shader->ID;
|
|
||||||
shaderIDs[shader->ID] = shader.get();
|
|
||||||
shaders[name] = std::move(shader);
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Shader* ResourceManager::getShaderByID(unsigned int ID)
|
// We attach our script after we create our weapon because we are passing a
|
||||||
{
|
// reference to the weapon into the script and we don't want to pass an
|
||||||
auto iterator = shaderIDs.find(ID);
|
|
||||||
return (iterator != shaderIDs.end() ? iterator->second : shaders["__fallback__"].get());
|
|
||||||
}
|
|
||||||
|
|
||||||
Background* ResourceManager::loadBackground(const std::string& path)
|
|
||||||
{
|
|
||||||
auto iterator = backgrounds.find(path);
|
|
||||||
if (iterator != backgrounds.end())
|
|
||||||
return iterator->second.get();
|
|
||||||
auto background = std::make_unique<Background>(path);
|
|
||||||
backgrounds[path] = std::move(background);
|
|
||||||
return backgrounds[path].get();
|
|
||||||
}
|
|
||||||
|
|
||||||
// We attach our script after we create our weapon because we are passing a reference to the weapon into the script and we don't want to pass an
|
|
||||||
// incomplete reference to our script.
|
// incomplete reference to our script.
|
||||||
std::unique_ptr<Weapon> ResourceManager::loadWeapon(const std::string& id, const unsigned weaponShaderID, const unsigned bulletShaderID)
|
std::unique_ptr<Weapon>
|
||||||
{
|
ResourceManager::loadWeapon(const std::string &id,
|
||||||
const WeaponData* data = xmlLoader->getWeaponData(id);
|
const unsigned weaponShaderID,
|
||||||
if (!data) {
|
const unsigned bulletShaderID) {
|
||||||
LOG(ERROR, "Could not load weapon id '{}', falling back to pistol", id);
|
const WeaponData *data = xmlLoader->getWeaponData(id);
|
||||||
data = xmlLoader->getWeaponData("gun/pistol");// using this as a fallback for now
|
if (!data) {
|
||||||
}
|
LOG(ERROR, "Could not load weapon id '{}', falling back to pistol", id);
|
||||||
auto weapon = std::make_unique<Weapon>(data, weaponShaderID, bulletShaderID, this);
|
data = xmlLoader->getWeaponData(
|
||||||
if (!data->script.empty())
|
"gun/pistol"); // using this as a fallback for now
|
||||||
weapon->attachScript(loadWeaponScript(data->script));
|
}
|
||||||
return std::move(weapon);
|
auto weapon =
|
||||||
|
std::make_unique<Weapon>(data, weaponShaderID, bulletShaderID, this);
|
||||||
|
if (!data->script.empty())
|
||||||
|
weapon->attachScript(loadScript<WeaponScript>(data->script));
|
||||||
|
return std::move(weapon);
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned ResourceManager::loadSoundEffect(const std::string& id)
|
const unsigned ResourceManager::loadSoundEffect(const std::string &id) {
|
||||||
{
|
auto iterator = sounds.find(id);
|
||||||
auto iterator = sounds.find(id);
|
if (iterator != sounds.end())
|
||||||
if (iterator != sounds.end())
|
return iterator->second->getBuffer();
|
||||||
return iterator->second->getBuffer();
|
auto soundData = xmlLoader->getSoundData(id);
|
||||||
auto soundData = xmlLoader->getSoundData(id) ;
|
if (!soundData) {
|
||||||
if (!soundData) {
|
soundData = xmlLoader->getSoundData(UTIL::get_generic(id));
|
||||||
soundData = xmlLoader->getSoundData(UTIL::get_generic(id));
|
LOG(WARN, "Could not load sound id: '{}' trying generic", id);
|
||||||
LOG(WARN, "Could not load sound id: '{}' trying generic", id);
|
if (!soundData)
|
||||||
if (!soundData)
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
auto sound = std::make_unique<SoundEffect>(soundData->path);
|
||||||
auto sound = std::make_unique<SoundEffect>(soundData->path);
|
sounds[id] = std::move(sound);
|
||||||
sounds[id] = std::move(sound);
|
return sounds[id]->getBuffer();
|
||||||
return sounds[id]->getBuffer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const SceneData* ResourceManager::loadScene(const std::string& id)
|
const SceneData *ResourceManager::loadScene(const std::string &id) {
|
||||||
{
|
return xmlLoader->getSceneData(id);
|
||||||
return xmlLoader->getSceneData(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<AnimationSet> ResourceManager::loadAnimationSet(const std::string& prefix, int entityid)
|
std::shared_ptr<AnimationSet>
|
||||||
{
|
ResourceManager::loadAnimationSet(const std::string &prefix, int entityid) {
|
||||||
auto animSetData = xmlLoader->getAnimationSet(prefix);
|
auto animSetData = xmlLoader->getAnimationSet(prefix);
|
||||||
|
|
||||||
return std::make_shared<AnimationSet>(entityid, this, animSetData);
|
return std::make_shared<AnimationSet>(entityid, this, animSetData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this will need some work, but for now where there is only one weapon type we can work with it
|
void ResourceManager::clearResources() {
|
||||||
// TODO: Allow different weapon types!
|
sprites.clear();
|
||||||
/*
|
shaders.clear();
|
||||||
template <typename T>
|
shaderIDs.clear();
|
||||||
std::shared_ptr<T> ResourceManager::loadWeapon(const std::string& name, std::shared_ptr<Shader> shader, std::shared_ptr<SpriteComponent> spriteComponent)
|
tileSets.clear();
|
||||||
{
|
|
||||||
auto iterator = weapons.find(name);
|
|
||||||
if (iterator != weapons.end())
|
|
||||||
return iterator->second;
|
|
||||||
auto weapon = std::make_shared<T>(T(shader, spriteComponent));
|
|
||||||
weapons[name] = weapon;
|
|
||||||
return weapon;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
void ResourceManager::clearResources()
|
|
||||||
{
|
|
||||||
sprites.clear();
|
|
||||||
shaders.clear();
|
|
||||||
shaderIDs.clear();
|
|
||||||
tileSets.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceManager::~ResourceManager()
|
ResourceManager::~ResourceManager() {
|
||||||
{
|
clearResources();
|
||||||
clearResources();
|
xmlLoader.reset();
|
||||||
xmlLoader.reset();
|
}
|
||||||
|
|
||||||
|
bool ResourceManager::loadLuaString(ScriptData *scriptData) {
|
||||||
|
std::filesystem::path file(scriptData->fileName);
|
||||||
|
if (file.empty() || !file.has_extension())
|
||||||
|
return false;
|
||||||
|
try {
|
||||||
|
|
||||||
|
std::ifstream fileStream(file);
|
||||||
|
std::ostringstream sstr;
|
||||||
|
sstr << fileStream.rdbuf();
|
||||||
|
scriptData->script = sstr.str().c_str();
|
||||||
|
fileStream.close();
|
||||||
|
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
ERROR_LOG("Failed to read script file: '{}' - '{}'", scriptData->fileName,
|
||||||
|
e.what());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue