aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClyne Sullivan <tullivan99@gmail.com>2016-10-23 18:05:12 -0500
committerClyne Sullivan <tullivan99@gmail.com>2016-10-23 18:05:12 -0500
commit2dd2f42ff1c683331e7192b4bfb832e41543d2df (patch)
tree50a8c022ed2f38cfae462296b28cd1543e4db42c
parentb32c68a5a4bfb06f321a1d78357c65458b24e760 (diff)
scriptable tags, inv. system
-rw-r--r--include/common.hpp5
-rw-r--r--include/inventory.hpp35
-rw-r--r--include/player.hpp3
-rw-r--r--include/texture.hpp4
-rw-r--r--include/world.hpp7
-rw-r--r--main.cpp15
-rw-r--r--src/engine.cpp8
-rw-r--r--src/inventory.cpp46
-rw-r--r--src/player.cpp6
-rw-r--r--src/world.cpp82
-rw-r--r--xml/!town.xml9
-rw-r--r--xml/entities.xml19
12 files changed, 208 insertions, 31 deletions
diff --git a/include/common.hpp b/include/common.hpp
index 0364b8b..d152bb7 100644
--- a/include/common.hpp
+++ b/include/common.hpp
@@ -99,6 +99,11 @@ struct vec2 {
return vec2 (x + n, y + n);
}
+ template<typename T>
+ const vec2 operator*(const T &n) {
+ return vec2 (x * n, y * n);
+ }
+
// std::swap can't work due to being packed
inline void swapX(vec2 &v) {
diff --git a/include/inventory.hpp b/include/inventory.hpp
new file mode 100644
index 0000000..fa24de4
--- /dev/null
+++ b/include/inventory.hpp
@@ -0,0 +1,35 @@
+#ifndef INVENTORY_HPP_
+#define INVENTORY_HPP_
+
+#include <entityx/entityx.h>
+
+#include <components.hpp>
+#include <events.hpp>
+
+struct Item {
+ GLuint icon;
+};
+
+using InventoryEntry = std::pair<Item, unsigned int>;
+
+class InventorySystem : public entityx::System<InventorySystem>, public entityx::Receiver<InventorySystem> {
+private:
+ entityx::Entity currentItemEntity;
+
+ std::vector<InventoryEntry> items;
+ unsigned int maxItemCount;
+
+public:
+ InventorySystem(unsigned int mic = 1)
+ : maxItemCount(mic) {}
+
+ void configure(entityx::EventManager &ev);
+
+ void loadIcons(void);
+
+ void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override;
+
+ void receive(const KeyDownEvent &kde);
+};
+
+#endif // INVENTORY_HPP_
diff --git a/include/player.hpp b/include/player.hpp
index 1caccc8..6bad917 100644
--- a/include/player.hpp
+++ b/include/player.hpp
@@ -4,6 +4,7 @@
#include <entityx/entityx.h>
#include <events.hpp>
+#include <common.hpp>
constexpr const float PLAYER_SPEED_CONSTANT = 0.15f;
@@ -29,6 +30,8 @@ public:
inline void setPlayer(const entityx::Entity& e)
{ pid = e.id(); }
+
+ vec2 getPosition(void) const;
};
#endif // PLAYER_HPP_
diff --git a/include/texture.hpp b/include/texture.hpp
index 7426a46..88dae65 100644
--- a/include/texture.hpp
+++ b/include/texture.hpp
@@ -51,11 +51,11 @@ private:
return freeID;
}
id_t++;
- }
+ }
}
public:
uint64_t loadSprite(std::string s) {
- uint64_t tex_e;
+ uint64_t tex_e = 0;
try {
tex_e = spritesLoc.at(s);
} catch (const std::out_of_range& oor) {
diff --git a/include/world.hpp b/include/world.hpp
index 1f54292..58dfc2c 100644
--- a/include/world.hpp
+++ b/include/world.hpp
@@ -134,6 +134,8 @@ private:
XMLDocument xmlDoc;
+ std::string currentXMLFile;
+
public:
explicit WorldSystem(void);
~WorldSystem(void);
@@ -156,13 +158,16 @@ public:
inline const WorldWeather& getWeatherId(void) const
{ return weather; }
+ inline const std::string& getXMLFile(void) const
+ { return currentXMLFile; }
+
void setWeather(const std::string &s);
void detect(entityx::TimeDelta dt);
void goWorldLeft(Position& p);
void goWorldRight(Position& p);
-
+
// worlddata2 stuff
WorldData2 worldData;
diff --git a/main.cpp b/main.cpp
index 7a4f0ca..c6c41af 100644
--- a/main.cpp
+++ b/main.cpp
@@ -25,6 +25,7 @@ using namespace tinyxml2;
#include <world.hpp>
#include <ui.hpp>
#include <gametime.hpp>
+#include <player.hpp>
#include <fstream>
#include <mutex>
@@ -55,7 +56,7 @@ vec2 offset;
*/
static unsigned int fps=0;
-static float debugY=0;
+//static float debugY=0;
// handles all logic operations
void logic(void);
@@ -314,7 +315,7 @@ void render() {
// draw the world and player
game::engine.getSystem<WorldSystem>()->render();
-
+
// draw the player's inventory
//player->inv->draw();
@@ -326,7 +327,15 @@ void render() {
// draw the debug overlay if desired
if (ui::debug) {
+ auto pos = game::engine.getSystem<PlayerSystem>()->getPosition();
ui::putText(offset.x-SCREEN_WIDTH/2, (offset.y+SCREEN_HEIGHT/2)-ui::fontSize,
+ "loc: (%+.2f, %+.2f)\nticks: %u\nxml: %s",
+ pos.x,
+ pos.y,
+ game::time::getTickCount(),
+ game::engine.getSystem<WorldSystem>()->getXMLFile().c_str()
+ );
+ /*ui::putText(offset.x-SCREEN_WIDTH/2, (offset.y+SCREEN_HEIGHT/2)-ui::fontSize,
"fps: %d\ngrounded:%d\nresolution: %ux%u\nentity cnt: %d\nloc: (%+.2f, %+.2f)\nticks: %u\nvolume: %f\nweather: %s\nxml: %s",
fps,
0,//player->ground,
@@ -339,7 +348,7 @@ void render() {
game::config::VOLUME_MASTER,
game::engine.getSystem<WorldSystem>()->getWeatherStr().c_str(),
""//currentXML.c_str()
- );
+ );*/
// draw tracer lines if desired
//static const GLuint tracerText = Texture::genColor(Color(100,100,255));
diff --git a/src/engine.cpp b/src/engine.cpp
index 54181c8..a367e27 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -3,7 +3,7 @@
#include <config.hpp>
#include <world.hpp>
#include <ui.hpp>
-//#include <inventory.hpp>
+#include <inventory.hpp>
#include <window.hpp>
#include <components.hpp>
#include <player.hpp>
@@ -22,11 +22,10 @@ void Engine::init(void) {
systems.add<WindowSystem>();
systems.add<RenderSystem>();
systems.add<InputSystem>();
-// systems.add<InventorySystem>();
+ systems.add<InventorySystem>();
systems.add<WorldSystem>();
systems.add<PlayerSystem>();
systems.add<MovementSystem>();
-// systems.add<PlayerSystem>(&player);
systems.configure();
@@ -37,6 +36,7 @@ void Engine::render(entityx::TimeDelta dt)
{
systems.update<RenderSystem>(dt);
systems.update<WindowSystem>(dt);
+ systems.update<InventorySystem>(dt);
ui::fadeUpdate();
}
@@ -44,8 +44,6 @@ void Engine::render(entityx::TimeDelta dt)
void Engine::update(entityx::TimeDelta dt)
{
systems.update<InputSystem>(dt);
-// systems.update<InventorySystem>(dt);
-// systems.update<PlayerSystem>(dt);
systems.update<MovementSystem>(dt);
systems.update<WorldSystem>(dt);
systems.update<PlayerSystem>(dt);
diff --git a/src/inventory.cpp b/src/inventory.cpp
new file mode 100644
index 0000000..91e81da
--- /dev/null
+++ b/src/inventory.cpp
@@ -0,0 +1,46 @@
+#include <inventory.hpp>
+
+#include <common.hpp>
+#include <events.hpp>
+#include <texture.hpp>
+#include <render.hpp>
+
+constexpr const char* ICON_TEX_FILE_PATH = "config/invIcons.txt";
+
+static std::vector<GLuint> iconTextures;
+
+void InventorySystem::configure(entityx::EventManager &ev)
+{
+ ev.subscribe<KeyDownEvent>(*this);
+}
+
+void InventorySystem::loadIcons(void) {
+ iconTextures.clear();
+ auto icons = readFileA(ICON_TEX_FILE_PATH);
+ for (const auto& s : icons)
+ iconTextures.push_back(Texture::loadTexture(s));
+}
+
+void InventorySystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt)
+{
+ (void)en;
+ (void)ev;
+ (void)dt;
+
+ static auto color = Texture::genColor(Color(0, 0, 0));
+ vec2 start = vec2(offset.x, 100);// - game::SCREEN_WIDTH / 2 + 20, game::SCREEN_HEIGHT - 40);
+
+ //std::cout << start.x << ' ' << start.y << std::endl;
+
+ Render::textShader.use();
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, color);
+ Render::useShader(&Render::textShader);
+ Render::drawRect(start, start + 20, -9.9f);
+ Render::textShader.unuse();
+}
+
+void InventorySystem::receive(const KeyDownEvent &kde)
+{
+ (void)kde;
+}
diff --git a/src/player.cpp b/src/player.cpp
index 82de470..bc4ae76 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -142,3 +142,9 @@ void PlayerSystem::receive(const KeyDownEvent &kde)
game::time::tick(50);
}
}
+
+vec2 PlayerSystem::getPosition(void) const
+{
+ auto loc = *game::entities.get(pid).component<Position>().get();
+ return vec2 {loc.x, loc.y};
+}
diff --git a/src/world.cpp b/src/world.cpp
index 508e2ac..78de9ed 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -205,6 +205,14 @@ loadWorldFromXMLNoTakeover(std::string path)
void WorldSystem::load(const std::string& file)
{
+ auto str2coord = [](std::string s) -> vec2 {
+ auto cpos = s.find(',');
+ s[cpos] = '\0';
+ return vec2 (std::stof(s), std::stof(s.substr(cpos + 1)));
+ };
+
+ entityx::Entity entity;
+
std::string xmlRaw;
std::string xmlPath;
@@ -222,6 +230,19 @@ void WorldSystem::load(const std::string& file)
if (xmlDoc.Parse(xmlRaw.data()) != XML_NO_ERROR)
UserError("XML Error: Failed to parse file (not your fault though..?)");
+ // include headers
+ auto ixml = xmlDoc.FirstChildElement("include");
+ while (ixml) {
+ auto file = ixml->Attribute("file");
+ if (file != nullptr) {
+ DEBUG_printf("Including file: %s\n", file);
+ xmlRaw.append(readFile((xmlFolder + file).c_str()));
+ }
+ ixml = ixml->NextSiblingElement();
+ }
+
+ xmlDoc.Parse(xmlRaw.data());
+
// look for an opening world tag
auto wxml = xmlDoc.FirstChildElement("World");
if (wxml != nullptr) {
@@ -238,6 +259,9 @@ void WorldSystem::load(const std::string& file)
}
world.toLeft = world.toRight = "";
+ currentXMLFile = file;
+
+
// iterate through tags
while (wxml) {
@@ -302,25 +326,47 @@ void WorldSystem::load(const std::string& file)
game::time::setTickCount(std::stoi(wxml->GetText()));
}
- else if (tagName == "entity") {
- auto str2coord = [](std::string s) -> vec2 {
- auto cpos = s.find(',');
- s[cpos] = '\0';
- return vec2 (std::stof(s), std::stof(s.substr(cpos + 1)));
- };
-
- auto entity = game::entities.create();
+ // custom entity tags
+ else {
+ auto cxml = xmlDoc.FirstChildElement(tagName.c_str());
+ if (cxml != nullptr) {
+ DEBUG_printf("Using custom tag <%s>\n", tagName.c_str());
+
+ entity = game::entities.create();
+ auto abcd = cxml->FirstChildElement();
+
+ while (abcd) {
+ std::string tname = abcd->Name();
+
+ if (tname == "Position") {
+ vec2 coords;
+
+ if (wxml->Attribute("position") != nullptr) {
+ coords = str2coord(wxml->StrAttribute("position"));
+ } else {
+ coords = str2coord(abcd->StrAttribute("value"));
+ }
+
+ float cdat[2] = {coords.x, coords.y};
+ entity.assign<Position>(cdat[0], cdat[1]);
+ } else if (tname == "Visible") {
+ entity.assign<Visible>(abcd->FloatAttribute("value"));
+ } else if (tname == "Sprite") {
+ auto sprite = entity.assign<Sprite>();
+ auto tex = abcd->Attribute("image");
+ auto dim = Texture::imageDim(tex);
+ sprite->addSpriteSegment(SpriteData(game::sprite_l.loadSprite(tex),
+ vec2(0, 0),
+ vec2(dim.x, dim.y) * 2),
+ vec2(0, 0));
+ }
+
+ abcd = abcd->NextSiblingElement();
+ }
- auto loc = wxml->Attribute("loc");
- if (loc != nullptr) {
- auto locVec = str2coord(loc);
- float locDat[2] = {locVec.x, locVec.y};
- entity.assign<Position>(locDat[0], locDat[1]);
+ } else {
+ UserError("Unknown tag <" + tagName + "> in file " + currentXMLFile);
}
-
- unsigned int health;
- if (wxml->QueryUnsignedAttribute("health", &health) != XML_NO_ERROR)
- entity.assign<Health>(health, health);
}
// hill creation
@@ -330,6 +376,8 @@ void WorldSystem::load(const std::string& file)
wxml = wxml->NextSiblingElement();
}
+
+ game::events.emit<BGMToggleEvent>();
}
/*
diff --git a/xml/!town.xml b/xml/!town.xml
index 69441f3..4a64ee0 100644
--- a/xml/!town.xml
+++ b/xml/!town.xml
@@ -1,4 +1,7 @@
<?xml version="1.0"?>
+
+<include file="entities.xml" />
+
<World>
<style background="0" bgm="assets/music/embark.wav" folder="assets/style/classic/"/>
<generation width="1600"/>
@@ -6,9 +9,9 @@
<link right="!town2.xml" />
<spawnx>-300</spawnx>
<npc name="Sanc" hasDialog="true"/>
- <npc name="Bob" hasDialog="true" spawnx="30"/>
- <structure type="1" spawnx="300"/>
- <structure inside="bobshouse.xml" type="1" spawnx="10"/>
+ <npc name="Bob" hasDialog="true" position="50.0,100.0"/>
+ <structure type="1" position="300.0,100.0"/>
+ <structure inside="bobshouse.xml" type="1" position="10.0,100.0"/>
<chest/>
</World>
diff --git a/xml/entities.xml b/xml/entities.xml
new file mode 100644
index 0000000..d955e38
--- /dev/null
+++ b/xml/entities.xml
@@ -0,0 +1,19 @@
+<spawnx/>
+
+<npc>
+ <Position value="0.0,100.0" />
+ <Visible value="0.2" />
+ <Sprite image="assets/NPC.png" />
+</npc>
+
+<structure>
+ <Position value="0.0,100.0" />
+ <Visible value="0.25" />
+ <Sprite image="assets/style/classic/house1.png" />
+</structure>
+
+<chest>
+ <Position value="0.0,100.0" />
+ <Visible value="0.15" />
+ <Sprite image="assets/chest.png" />
+</chest>