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) {
--- /dev/null
+#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_
#include <entityx/entityx.h>
#include <events.hpp>
+#include <common.hpp>
constexpr const float PLAYER_SPEED_CONSTANT = 0.15f;
inline void setPlayer(const entityx::Entity& e)
{ pid = e.id(); }
+
+ vec2 getPosition(void) const;
};
#endif // PLAYER_HPP_
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) {
XMLDocument xmlDoc;
+ std::string currentXMLFile;
+
public:
explicit WorldSystem(void);
~WorldSystem(void);
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;
#include <world.hpp>
#include <ui.hpp>
#include <gametime.hpp>
+#include <player.hpp>
#include <fstream>
#include <mutex>
*/
static unsigned int fps=0;
-static float debugY=0;
+//static float debugY=0;
// handles all logic operations
void logic(void);
// draw the world and player
game::engine.getSystem<WorldSystem>()->render();
-
+
// draw the player's inventory
//player->inv->draw();
// 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,
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));
#include <config.hpp>
#include <world.hpp>
#include <ui.hpp>
-//#include <inventory.hpp>
+#include <inventory.hpp>
#include <window.hpp>
#include <components.hpp>
#include <player.hpp>
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();
{
systems.update<RenderSystem>(dt);
systems.update<WindowSystem>(dt);
+ systems.update<InventorySystem>(dt);
ui::fadeUpdate();
}
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);
--- /dev/null
+#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;
+}
game::time::tick(50);
}
}
+
+vec2 PlayerSystem::getPosition(void) const
+{
+ auto loc = *game::entities.get(pid).component<Position>().get();
+ return vec2 {loc.x, loc.y};
+}
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;
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) {
}
world.toLeft = world.toRight = "";
+ currentXMLFile = file;
+
+
// iterate through tags
while (wxml) {
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
wxml = wxml->NextSiblingElement();
}
+
+ game::events.emit<BGMToggleEvent>();
}
/*
<?xml version="1.0"?>
+
+<include file="entities.xml" />
+
<World>
<style background="0" bgm="assets/music/embark.wav" folder="assets/style/classic/"/>
<generation width="1600"/>
<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>
--- /dev/null
+<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>