- fixed grass squishing
- player sits on cat better
- world shading is good-er
+
+5/31/2016:
+==========
+
+ - fixed name generation-er
+ - move random dialogs to file
+ - entitys can modify their XMLs
+ - 'alive' XML attribute works
+ - lighting's pretty neat
--- /dev/null
+What a beautiful day it is.
+Have you ever went fast? I have.
+I heard if you complete a quest, you'll get a special reward.
+How much wood could a woodchuck chuck if a woodchuck could chuck wood?
+I don't think anyone has ever been able to climb up that hill.
+If you ever see a hole in the ground, watch out; it could mean the end for you.
+Did you know this game has over 5000 lines of code? I didn't. I didn't even know I was in a game until now...
+HELP MY CAPS LOCK IS STUCK
+You know, if anyone ever asked me who I wanted to be when I grow up, I would say Abby Ross.
+I want to have the wallpaper in our house changed. It doesn't really fit the environment.
+Frig.
+The sine of theta equals the opposite over the hypotenuese.
+Did you know the developers spelt brazier as brazzier.
+What's a bagel? I don't know because I'm mormon
+
2
-canSprint
-1
canJump
1
+canSprint
+1
// reads the given file into a buffer and returns a pointer to the buffer
const char *readFile(const char *path);
+std::string readFile(const std::string& path);
+std::vector<std::string> readFileA(const std::string& path);
// aborts the program, printing the given error
void UserError(std::string reason);
#include <inventory.hpp>
#include <texture.hpp>
+// local library includes
+#include <tinyxml2.h>
+using namespace tinyxml2;
+
/* ----------------------------------------------------------------------------
** Structures section
** --------------------------------------------------------------------------*/
// the max cooldown display
float maxHitDuration;
+
+ // the entity's XML element, for saving/loading stuff
+ XMLElement *xmle;
+
public:
// contains the entity's coordinates, in pixels
vec2 loc;
int subtype;
// the entity's name, randomly generated on spawn
- char *name;
+ std::string name;
// the entity's gender
GENDER gender;
// returns true if the coordinate is within the entity
bool isInside(vec2 coord) const;
+ // constructs the entity with an XML thing-thang
+ virtual void createFromXML(XMLElement *e, World *w=nullptr) =0;
+
// a common constructor, clears variables
Entity(void);
virtual ~Entity(){}
};
-class Player : public Entity{
+class Player : public Entity {
public:
Entity *ride;
QuestHandler qh;
~Player();
void save(void);
void sspawn(float x,float y);
+ void createFromXML(XMLElement *e, World *w);
};
-class Structures : public Entity{
+class Structures : public Entity {
public:
BUILD_SUB bsubtype;
World *inWorld;
~Structures();
unsigned int spawn(BUILD_SUB, float, float);
+ void createFromXML(XMLElement *e, World *w);
};
virtual void interact();
virtual void wander(int);
+ void createFromXML(XMLElement *e, World *w);
};
class Merchant : public NPC {
void interact(void);
bool operator==(const Object &o) {
- return !strcmp(name, o.name) && (loc == o.loc);
+ return (name == o.name) && (loc == o.loc);
}
+ void createFromXML(XMLElement *e, World *w);
};
/**
void makeFlame(void){
flame = true;
}
+
+ void createFromXML(XMLElement *e);
};
#include <mob.hpp>
class Mob : public Entity {
protected:
+ XMLElement *xmle;
std::forward_list<Drop> drop;
unsigned int actCounter;
virtual void onDeath(void);
virtual bool bindTex(void) =0;
- virtual void createFromXML(const XMLElement *e) =0;
};
constexpr Mob *Mobp(Entity *e) {
void act(void);
void onHit(unsigned int);
bool bindTex(void);
- void createFromXML(const XMLElement *e);
+ void createFromXML(XMLElement *e, World *w) final;
};
class Door : public Mob {
void act(void);
void onHit(unsigned int);
bool bindTex(void);
- void createFromXML(const XMLElement *e);
+ void createFromXML(XMLElement *e, World *w) final;
};
class Cat : public Mob {
void act(void);
void onHit(unsigned int);
bool bindTex(void);
- void createFromXML(const XMLElement *e);
+ void createFromXML(XMLElement *e, World *w) final;
};
class Rabbit : public Mob {
void act(void);
void onHit(unsigned int);
bool bindTex(void);
- void createFromXML(const XMLElement *e);
+ void createFromXML(XMLElement *e, World *w) final;
};
class Bird : public Mob {
void act(void);
void onHit(unsigned int);
bool bindTex(void);
- void createFromXML(const XMLElement *e);
+ void createFromXML(XMLElement *e, World *w) final;
};
class Trigger : public Mob {
void act(void);
void onHit(unsigned int);
bool bindTex(void);
- void createFromXML(const XMLElement *e);
+ void createFromXML(XMLElement *e, World *w) final;
};
#endif // MOB_H_
* This enum contains all different possibilities for world backgrounds; used
* in World::setBackground() to select the appropriate images.
*/
-enum class WorldBGType : unsigned char {
+enum class WorldBGType : unsigned int {
Forest, /**< A forest theme. */
WoodHouse /**< An indoor wooden house theme. */
};
void addMob(Mob *m, vec2 coord);
- void addNPC(float x, float y);
+ void addNPC(NPC *n);
void addObject(std::string in, std::string pickupDialog, float x, float y);
void addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int dur);
void addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int dur, unsigned char flags);
- void addStructure(BUILD_SUB subtype, float x, float y, std::string tex, std::string inside);
+ void addStructure(Structures *s);
Village *addVillage(std::string name, World *world);
};
WorldSwitchInfo exitArena(Player *p);
};
+/**
+ * Constructs an XML object for accessing/modifying the current world's XML
+ * file.
+ */
+const XMLDocument& loadWorldXML(void);
+
/**
* Loads the player into the world created by the given XML file. If a world is
* already loaded it will be saved before the transition is made.
*/
World *loadWorldFromXMLNoSave(std::string path);
+/**
+ * Loads a world using a pointer to the current world (used for loading adjacent
+ * worlds that have already been read into memory.
+ */
World *loadWorldFromPtr(World *ptr);
+/**
+ * Casts a normal world to an indoor world, to access IndoorWorld-exclusive
+ * elements.
+ */
constexpr IndoorWorld *Indoorp(World *w)
{
return (IndoorWorld *)w;
// load mouse texture, and other inventory textures
mouseTex = Texture::loadTexture("assets/mouse.png");
- // read in all XML file names in the folder
- std::vector<std::string> xmlFiles;
+ // spawn the player
+ player = new Player();
+ player->sspawn(0,100);
+
+ // get a world
if (xmlFolder.empty())
xmlFolder = "xml/";
- if (getdir(std::string("./" + xmlFolder).c_str(), xmlFiles))
- UserError("Error reading XML files!!!");
-
- // alphabetically sort files
- strVectorSortAlpha(&xmlFiles);
-
- // load the first valid XML file for the world
- for (const auto &xf : xmlFiles) {
- if (xf[0] != '.' && strcmp(&xf[xf.size() - 3], "dat")){
- // read it in
- std::cout << "File to load: " << xf << '\n';
- currentWorld = loadWorldFromXML(xf);
- break;
+
+ if (currentWorld == nullptr) {
+ // read in all XML file names in the folder
+ std::vector<std::string> xmlFiles;
+ if (getdir(std::string("./" + xmlFolder).c_str(), xmlFiles))
+ UserError("Error reading XML files!!!");
+
+ // alphabetically sort files
+ strVectorSortAlpha(&xmlFiles);
+
+ // load the first valid XML file for the world
+ for (const auto &xf : xmlFiles) {
+ if (xf[0] != '.' && strcmp(&xf[xf.size() - 3], "dat")){
+ // read it in
+ std::cout << "File to load: " << xf << '\n';
+ currentWorld = loadWorldFromXML(xf);
+ break;
+ }
}
}
// make sure the world was made
- if (currentWorld == NULL)
+ if (currentWorld == nullptr)
UserError("Plot twist: The world never existed...?");
- // spawn the player
- player = new Player();
- player->sspawn(0,100);
ui::menu::init();
currentWorld->bgmPlay(nullptr);
* Call the world's draw function, drawing the player, the world, the background, and entities. Also
* draw the player's inventory if it exists.
*/
- //player->near = true; // allow player's name to be drawn
+ player->near = true; // allow player's name to be drawn
currentWorld->draw(player);
// draw the player's inventory
return buf;
}
+std::string readFile(const std::string& path)
+{
+ std::ifstream in (path, std::ios::in);
+ std::string buffer;
+
+ if (!in.is_open())
+ UserError("Error reading file " + path);
+
+ in.seekg(0, in.end);
+ buffer.reserve(in.tellg());
+ in.seekg(0, in.beg);
+ in.read(&buffer[0], buffer.size());
+
+ in.close();
+ return buffer;
+}
+
+std::vector<std::string> readFileA(const std::string& path)
+{
+ std::ifstream in (path, std::ios::in);
+ std::vector<std::string> lines;
+ std::string line;
+
+ if (!in.is_open())
+ UserError("Error reading file " + path);
+
+ while(std::getline(in, line))
+ lines.push_back(line);
+
+ in.close();
+ return lines;
+}
+
void UserError(std::string reason)
{
std::cout << "User error: " << reason << "!\n";
extern unsigned int loops; // main.cpp
extern std::string xmlFolder;
+extern XMLDocument currentXMLDoc;
// a dynamic array of pointers to the NPC's that are being assigned the preloads
std::vector<NPC *> aipreload;
// the size of an NPC's inventory
const unsigned int NPC_INV_SIZE = 3;
-static const unsigned int RAND_DIALOG_COUNT = 14;
-const char *randomDialog[RAND_DIALOG_COUNT] = {
- "What a beautiful day it is.",
- "Have you ever went fast? I have.",
- "I heard if you complete a quest, you'll get a special reward.",
- "How much wood could a woodchuck chuck if a woodchuck could chuck wood?",
- "I don\'t think anyone has ever been able to climb up that hill.",
- "If you ever see a hole in the ground, watch out; it could mean the end for you.",
- "Did you know this game has over 5000 lines of code? I didn\'t. I didn't even know I was in a game until now...",
- "HELP MY CAPS LOCK IS STUCK",
- "You know, if anyone ever asked me who I wanted to be when I grow up, I would say Abby Ross.",
- "I want to have the wallpaper in our house changed. It doesn\'t really fit the environment.",
- "Frig.",
- "The sine of theta equals the opposite over the hdaypotenuese.",
- "Did you know the developers spelt brazier as brazzier.",
- "What's a bagel? I don't know because I'm mormon"
-};
-
-void randGetomName(Entity *e)
-{
- unsigned int tempNum,max=0;
- char *bufs;
-
- std::ifstream names ("assets/names_en-us",std::ios::in);
-
- names.seekg(0,names.beg);
-
- bufs = new char[32];
-
- for(;!names.eof();max++)
- names.getline(bufs,32);
+static std::vector<std::string> randomDialog (readFileA("assets/dialog_en-us"));
- tempNum = rand() % max;
- names.seekg(0,names.beg);
-
- for(unsigned int i=0;i<tempNum;i++)
- names.getline(bufs,32);
-
- names.close();
+void getRandomName(Entity *e)
+{
+ auto names = readFileA("assets/names_en-us");
+ auto name = names[randGet() % names.size()];
// gender is a binary construct
- e->gender = (bufs[0] == 'm') ? MALE : FEMALE;
-
- strcpy(e->name, bufs + 1);
+ e->gender = (name[0] == 'm') ? MALE : FEMALE;
- delete[] bufs;
+ e->name = &name[1];
}
Entity::Entity(void)
hitDuration = maxHitDuration = 0;
inv = nullptr;
- name = nullptr;
}
// spawns the entity you pass to it based off of coords and global entity settings
health = maxHealth = 1;
// generate a name
- name = new char[32];
if (type == MOBT)
- strncpy(name, "mob", 3);
+ name = "mob";
else
- randGetomName(this);
+ getRandomName(this);
setCooldown(0);
}
{
alive = false;
health = 0;
+
+ if (xmle) {
+ xmle->SetAttribute("alive", false);
+ currentXMLDoc.SaveFile(currentXML.c_str(), false);
+ }
}
bool Entity::isAlive(void) const
Player::~Player()
{
delete inv;
- delete[] name;
+}
+
+void Player::createFromXML(XMLElement *e, World *w=nullptr)
+{
+ (void)e;
+ (void)w;
}
NPC::NPC() : Entity()
tex = TextureIterator({"assets/NPC.png"});
inv = new Inventory(NPC_INV_SIZE);
- randDialog = rand() % RAND_DIALOG_COUNT - 1;
+ randDialog = randGet() % randomDialog.size();
dialogIndex = 0;
dialogCount = 0;
NPC::~NPC()
{
delete inv;
- delete[] name;
+}
+
+void NPC::createFromXML(XMLElement *e, World *w=nullptr)
+{
+ std::string npcname;
+ bool dialog;
+ float spawnx, Xhealth;
+ unsigned int flooor;
+
+ // spawn at coordinates if desired
+ if (e->QueryFloatAttribute("x", &spawnx) == XML_NO_ERROR)
+ spawn(spawnx, 100);
+ else
+ spawn(0, 100);
+
+ // name override
+ if (!(npcname = e->StrAttribute("name")).empty())
+ name = npcname;
+
+ // dialog enabling
+ dialog = false;
+ if (e->QueryBoolAttribute("hasDialog", &dialog) == XML_NO_ERROR && dialog)
+ addAIFunc(false);
+ else
+ dialogIndex = 9999;
+
+
+ if (/*Indoor && */e->QueryUnsignedAttribute("floor", &flooor) == XML_NO_ERROR)
+ Indoorp(w)->moveToFloor(this, flooor);
+
+ // custom health value
+ if (e->QueryFloatAttribute("health", &Xhealth) == XML_NO_ERROR) {
+ health = maxHealth = Xhealth;
+ }
+
+ xmle = e;
}
Merchant::Merchant() : NPC()
Merchant::~Merchant()
{
- //delete inv;
- delete[] name;
}
Structures::Structures() : Entity()
Structures::~Structures()
{
- delete[] name;
+}
+
+void Structures::createFromXML(XMLElement *e, World *w)
+{
+ float spawnx;
+
+ inWorld = w;
+ inside = e->StrAttribute("inside");
+ textureLoc = e->StrAttribute("texture");
+
+ spawn(static_cast<BUILD_SUB>(e->UnsignedAttribute("type")),
+ e->QueryFloatAttribute("x", &spawnx) == XML_NO_ERROR ? spawnx : (randGet() % w->getTheWidth() / 2.0f),
+ 100);
}
Object::Object()
Object::~Object()
{
- delete[] name;
+}
+
+void Object::createFromXML(XMLElement *e, World *w=nullptr)
+{
+ (void)e;
+ (void)w;
}
void Object::reloadTexture(void)
void Merchant::interact() {
std::thread([this]{
- ui::merchantBox(name, trade[currTrade], ":Accept:Good-Bye", false, toSay->c_str());
+ ui::merchantBox(name.c_str(), trade[currTrade], ":Accept:Good-Bye", false, toSay->c_str());
ui::waitForDialog();
// handle normal dialog options
type = MOBT;
inv = nullptr;
rider = nullptr;
+ xmle = nullptr;
canMove = true;
loc = 0;
}
return true;
}
-void Page::createFromXML(const XMLElement *e)
+void Page::createFromXML(XMLElement *e, World *w=nullptr)
{
+ (void)w;
float Xlocx;
if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR)
loc.x = Xlocx;
return true;
}
-void Door::createFromXML(const XMLElement *e)
+void Door::createFromXML(XMLElement *e, World *w=nullptr)
{
+ (void)w;
float Xlocx;
if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR)
loc.x = Xlocx;
return true;
}
-void Cat::createFromXML(const XMLElement *e)
+void Cat::createFromXML(XMLElement *e, World *w=nullptr)
{
+ (void)w;
float Xlocx;
if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR)
loc.x = Xlocx;
return true;
}
-void Rabbit::createFromXML(const XMLElement *e)
+void Rabbit::createFromXML(XMLElement *e, World *w=nullptr)
{
+ (void)w;
float Xlocx, Xhealth;
if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR)
loc.x = Xlocx;
if (e->QueryFloatAttribute("health", &Xhealth) == XML_NO_ERROR)
maxHealth = health = Xhealth;
- if (e->QueryBoolAttribute("aggressive", &aggressive) != XML_NO_ERROR)
+ if (e->QueryBoolAttribute("aggressive", &aggressive) != XML_NO_ERROR) {
aggressive = false;
+ }
+
+ xmle = e;
}
Bird::Bird(void) : Mob()
return true;
}
-void Bird::createFromXML(const XMLElement *e)
+void Bird::createFromXML(XMLElement *e, World *w=nullptr)
{
+ (void)w;
float Xlocx, Xhealth;
if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR)
loc.x = Xlocx;
return false;
}
-void Trigger::createFromXML(const XMLElement *e)
+void Trigger::createFromXML(XMLElement *e, World *w=nullptr)
{
+ (void)w;
float Xlocx;
if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR)
loc.x = Xlocx;
Mob::~Mob()
{
delete inv;
- delete[] name;
}
extern World *currentWorld;
if (debug)
posFlag ^= true;
else {
- currentWorld->addStructure(FIRE_PIT, player->loc.x, player->loc.y, "", "");
+ auto s = new Structures();
+ s->spawn(FIRE_PIT, player->loc.x, player->loc.y);
+ currentWorld->addStructure(s);
currentWorld->addLight({player->loc.x + SCREEN_WIDTH/2, player->loc.y},{1.0f,1.0f,1.0f});
//currentWorld->getLastLight()->follow(currentWorld->build.back());
currentWorld->getLastLight()->makeFlame();
#include <algorithm>
#include <sstream>
#include <fstream>
+#include <memory>
// local game headers
#include <ui.hpp>
if (worldShade > 0) {
auto xcoord = offset.x * 0.9f;
-
+
for (auto &s : star) {
*(si++) = s.x + xcoord;
*(si++) = s.y,
pOffset = (offset.x + p->width / 2 - worldStart) / HLINE;
// only draw world within player vision
- iStart = static_cast<int>(fmax(pOffset - (SCREEN_WIDTH / 2 / HLINE) - GROUND_HILLINESS, 0));
+ iStart = std::clamp(static_cast<int>(pOffset - (SCREEN_WIDTH / 2 / HLINE) - GROUND_HILLINESS),
+ 0, static_cast<int>(lineCount));
iEnd = std::clamp(static_cast<int>(pOffset + (SCREEN_WIDTH / 2 / HLINE)),
- static_cast<int>(GROUND_HILLINESS),
- static_cast<int>(worldData.size()));
+ 0, static_cast<int>(lineCount));
// draw the dirt
bgTex++;
std::vector<std::pair<vec2,vec3>> c;
for (int i = iStart; i < iEnd; i++) {
- if (worldData[i].groundHeight <= 0) {
+ if (worldData[i].groundHeight <= 0) { // TODO holes (andy)
worldData[i].groundHeight = GROUND_HEIGHT_MINIMUM - 1;
glColor4ub(0, 0, 0, 255);
} else {
vec2 World::
getStructurePos(int index)
{
+ if (build.empty())
+ return vec2 {0, 0};
+
if (index < 0)
return build.back()->loc;
else if ((unsigned)index >= build.size())
}
void World::
-addStructure(BUILD_SUB sub, float x,float y, std::string tex, std::string inside)
+addStructure(Structures *s)
{
- build.push_back(new Structures());
- build.back()->inWorld = this;
- build.back()->textureLoc = tex;
- build.back()->spawn(sub, x, y);
- build.back()->inside = inside;
+ build.push_back(s);
entity.push_back(build.back());
}
}
void World::
-addNPC(float x, float y)
+addNPC(NPC *n)
{
- npc.push_back(new NPC());
- npc.back()->spawn(x, y);
-
+ npc.push_back(n);
entity.push_back(npc.back());
}
/**
* Loads a world from the given XML file.
*/
+
+static std::string currentXMLRaw;
+XMLDocument currentXMLDoc;
+
+const XMLDocument& loadWorldXML(void)
+{
+ static XMLDocument xml;
+ if (xml.Parse(currentXMLRaw.data()) != XML_NO_ERROR)
+ UserError("XML Error: Failed to parse file (not your fault though..?)");
+
+ return xml;
+}
+
World *
loadWorldFromXMLNoSave(std::string path) {
-XMLDocument currentXMLDoc;
+ XMLDocument *_currentXMLDoc;
+ std::string _currentXML,
+ _currentXMLRaw;
+
XMLElement *wxml;
XMLElement *vil;
World *tmp;
- float spawnx, randx;
- bool dialog,Indoor;
- unsigned int flooor;
+ Entity *newEntity;
+ float spawnx;
+ bool Indoor;
const char *ptr;
std::string name, sptr;
// no file? -> no world
if (path.empty())
- return NULL;
+ return nullptr;
- currentXML = std::string(xmlFolder + path);
- currentXMLDoc.LoadFile(currentXML.c_str());
+ _currentXML = xmlFolder + path;
+ _currentXMLRaw = readFile(_currentXML.c_str());
+
+ // create a temporary XMLDocument if this isn't the main world
+ if (!loadedLeft && !loadedRight)
+ _currentXMLDoc = ¤tXMLDoc;
+ else
+ _currentXMLDoc = new XMLDocument();
+
+ // parse the file
+ if (_currentXMLDoc->Parse(_currentXMLRaw.data()) != XML_NO_ERROR)
+ UserError("XML Error: Failed to parse file (not your fault though..?)");
// attempt to load a <World> tag
- if ((wxml = currentXMLDoc.FirstChildElement("World"))) {
+ if ((wxml = _currentXMLDoc->FirstChildElement("World"))) {
wxml = wxml->FirstChildElement();
- vil = currentXMLDoc.FirstChildElement("World")->FirstChildElement("village");
+ vil = _currentXMLDoc->FirstChildElement("World")->FirstChildElement("village");
tmp = new World();
Indoor = false;
}
// attempt to load an <IndoorWorld> tag
- else if ((wxml = currentXMLDoc.FirstChildElement("IndoorWorld"))) {
+ else if ((wxml = _currentXMLDoc->FirstChildElement("IndoorWorld"))) {
wxml = wxml->FirstChildElement();
vil = NULL;
tmp = new IndoorWorld();
// error: can't load a world...
else
- UserError("XML Error: Cannot find a <World> or <IndoorWorld> tag in " + currentXML + "!");
+ UserError("XML Error: Cannot find a <World> or <IndoorWorld> tag in " + _currentXML + "!");
// iterate through world tags
while (wxml) {
+ newEntity = nullptr;
name = wxml->Name();
// world linkage
// load the left world if it isn't
if (!loadedLeft) {
- loadedLeft = true;
+ loadedRight = true;
currentWorldToLeft = loadWorldFromXMLNoSave(ptr);
- loadedLeft = false;
- }
+ loadedRight = false;
+ } else {
+ currentWorldToLeft = nullptr;
+ }
}
// links world to the right
// load the right world if it isn't
if (!loadedRight) {
- loadedRight = true;
+ loadedLeft = true;
currentWorldToRight = loadWorldFromXMLNoSave(ptr);
- loadedRight = false;
- }
+ loadedLeft = false;
+ } else {
+ currentWorldToRight = nullptr;
+ }
}
// tells what world is outside, if in a structure
// error, invalid link tag
else
- UserError("XML Error: Invalid <link> tag in " + currentXML + "!");
+ UserError("XML Error: Invalid <link> tag in " + _currentXML + "!");
}
tmp->setStyle(wxml->StrAttribute("folder"));
// set background folder
- if (wxml->QueryUnsignedAttribute("background", &flooor) != XML_NO_ERROR)
- UserError("XML Error: No background given in <style> in " + currentXML + "!");
- tmp->setBackground((WorldBGType)flooor);
+ unsigned int bgt;
+ if (wxml->QueryUnsignedAttribute("background", &bgt) != XML_NO_ERROR)
+ UserError("XML Error: No background given in <style> in " + _currentXML + "!");
+ tmp->setBackground(static_cast<WorldBGType>(bgt));
// set BGM file
tmp->setBGM(wxml->StrAttribute("bgm"));
tmp->generate(wxml->UnsignedAttribute("width"));
else {
if (Indoor)
- UserError("XML Error: <generation> tags can't be in <IndoorWorld> tags (in " + currentXML + ")!");
+ UserError("XML Error: <generation> tags can't be in <IndoorWorld> tags (in " + _currentXML + ")!");
else
- UserError("XML Error: Invalid <generation> tag in " + currentXML + "!");
+ UserError("XML Error: Invalid <generation> tag in " + _currentXML + "!");
}
}
// mob creation
- else if (name == "rabbit") {
- tmp->addMob(new Rabbit(), vec2 {0, 0});
- tmp->getLastMob()->createFromXML(wxml);
- } else if (name == "bird") {
- tmp->addMob(new Bird(), vec2 {0, 0});
- tmp->getLastMob()->createFromXML(wxml);
- } else if (name == "trigger") {
- tmp->addMob(new Trigger(), vec2 {0, 0});
- tmp->getLastMob()->createFromXML(wxml);
- } else if (name == "door") {
- tmp->addMob(new Door(), vec2 {0, 0});
- tmp->getLastMob()->createFromXML(wxml);
- } else if (name == "page") {
- tmp->addMob(new Page(), vec2 {0, 0});
- tmp->getLastMob()->createFromXML(wxml);
- } else if (name == "cat") {
- tmp->addMob(new Cat(), vec2 {0, 0});
- tmp->getLastMob()->createFromXML(wxml);
- }
+ else if (name == "rabbit") {
+ newEntity = new Rabbit();
+ } else if (name == "bird") {
+ newEntity = new Bird();
+ } else if (name == "trigger") {
+ newEntity = new Trigger();
+ } else if (name == "door") {
+ newEntity = new Door();
+ } else if (name == "page") {
+ newEntity = new Page();
+ } else if (name == "cat") {
+ newEntity = new Cat();
+ }
// npc creation
else if (name == "npc") {
- const char *npcname;
-
- // spawn at coordinates if desired
- if (wxml->QueryFloatAttribute("x", &spawnx) == XML_NO_ERROR)
- tmp->addNPC(spawnx, 100);
- else
- tmp->addNPC(0, 100);
-
- // name override
- if ((npcname = wxml->Attribute("name"))) {
- delete[] tmp->npc.back()->name;
- tmp->npc.back()->name = new char[strlen(npcname) + 1];
- strcpy(tmp->npc.back()->name, npcname);
- }
-
- // dialog enabling
- dialog = false;
- if (wxml->QueryBoolAttribute("hasDialog", &dialog) == XML_NO_ERROR && dialog) {
- tmp->npc.back()->addAIFunc(false);
- } else
- tmp->npc.back()->dialogIndex = 9999;
-
- if (Indoor && wxml->QueryUnsignedAttribute("floor", &flooor) == XML_NO_ERROR)
- Indoorp(tmp)->moveToFloor(tmp->npc.back(), flooor);
-
- // custom health value
- if (wxml->QueryFloatAttribute("health", &spawnx) == XML_NO_ERROR)
- tmp->npc.back()->health = tmp->npc.back()->maxHealth = spawnx;
+ newEntity = new NPC();
}
// structure creation
else if (name == "structure") {
- tmp->addStructure((BUILD_SUB) wxml->UnsignedAttribute("type"),
- wxml->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ?
- randGet() % tmp->getTheWidth() / 2.0f : spawnx,
- 100,
- wxml->StrAttribute("texture"),
- wxml->StrAttribute("inside")
- );
- } else if (name == "hill") {
+ newEntity = new Structures();
+ }
+
+ // hill creation
+ else if (name == "hill") {
tmp->addHill(ivec2 { wxml->IntAttribute("peakx"), wxml->IntAttribute("peaky") }, wxml->UnsignedAttribute("width"));
- } else if (name == "time") {
+ }
+
+ // time setting
+ else if (name == "time") {
game::time::setTickCount(std::stoi(wxml->GetText()));
- } else if (Indoor && name == "floor") {
+ }
+
+ // floor adding
+ else if (Indoor && name == "floor") {
if (wxml->QueryFloatAttribute("start",&spawnx) == XML_NO_ERROR)
Indoorp(tmp)->addFloor(wxml->UnsignedAttribute("width"), spawnx);
else
Indoorp(tmp)->addFloor(wxml->UnsignedAttribute("width"));
}
+ if (newEntity != nullptr) {
+ bool alive = true;
+ if (wxml->QueryBoolAttribute("alive", &alive) != XML_NO_ERROR || alive) {
+ newEntity->createFromXML(wxml, tmp);
+
+ switch (newEntity->type) {
+ case NPCT:
+ tmp->addNPC(dynamic_cast<NPC *>(newEntity));
+ break;
+ case MOBT:
+ tmp->addMob(dynamic_cast<Mob *>(newEntity), vec2 {0, 0});
+ break;
+ case STRUCTURET:
+ tmp->addStructure(dynamic_cast<Structures *>(newEntity));
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
spawnx = 0;
wxml = wxml->NextSiblingElement();
}
Village *vptr;
+ Structures *s;
if (vil) {
vptr = tmp->addVillage(vil->StrAttribute("name"), tmp);
vil = vil->FirstChildElement();
}
- std::cout << currentXML << ' ' << tmp->build.size() << '\n';
-
while(vil) {
name = vil->Name();
- randx = 0;
/**
* READS DATA ABOUT STRUCTURE CONTAINED IN VILLAGE
*/
if (name == "structure") {
- tmp->addStructure((BUILD_SUB)vil->UnsignedAttribute("type"),
- vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? randx : spawnx,
- 100,
- vil->StrAttribute("texture"),
- vil->StrAttribute("inside"));
+ s = new Structures();
+ s->createFromXML(vil, tmp);
+ tmp->addStructure(s);
} else if (name == "stall") {
sptr = vil->StrAttribute("type");
if (sptr == "market") {
// create a structure and a merchant, and pair them
- tmp->addStructure(STALL_MARKET,
- vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? randx : spawnx,
- 100,
- vil->StrAttribute("texture"),
- vil->StrAttribute("inside")
- );
+ s = new Structures();
+ s->createFromXML(vil, tmp);
+ tmp->addStructure(s);
tmp->addMerchant(0, 100, true);
}
// handle traders
else if (sptr == "trader") {
- tmp->addStructure(STALL_TRADER,
- vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? randx : spawnx,
- 100,
- vil->StrAttribute("texture"),
- vil->StrAttribute("inside")
- );
+ s = new Structures();
+ s->createFromXML(vil, tmp);
+ tmp->addStructure(s);
}
// loop through buy/sell/trade tags
vil = vil->NextSiblingElement();
}
- std::ifstream dat (((std::string)currentXML + ".dat").data());
+ std::ifstream dat ((_currentXML + ".dat").data());
if (dat.good()) {
dat.close();
tmp->load();
}
+ if (!loadedLeft && !loadedRight) {
+ currentXML = _currentXML;
+ currentXMLRaw = _currentXMLRaw;
+ } else {
+ delete _currentXMLDoc;
+ }
+
return tmp;
}
<?xml version="1.0"?>
<World>
- <style background="0" bgm="assets/music/embark.wav" folder="assets/style/classic/" />
- <generation type="Random" width="500" />
- <link right="playerSpawnHill2.xml" />
- <time>12000</time>
-
- <hill peakx="0" peaky="1000" width="50" />
-
- <rabbit x="300" aggressive="false" health="100" />
- <bird y="500"/>
- <cat />
-
- <trigger x="-300" id="Test" />
-
- <npc name="Ralph" hasDialog="true" x="300" />
- <npc name="Johnny" hasDialog="false" x="300" />
- <npc name="Big Dave" hasDialog="true" x="300" />
-
- <page x="-200" id="assets/pages/gootaGoFast.png" cid="canSprint" cvalue="1" />
- <page x="-500" id="assets/pages/gootaJump.png" cid="canJump" cvalue="1" />
-
- <village name="Big Dave's bagel emporium! The greatest place on earth!">
- <structure type="0" x="-300" inside="playerSpawnHill1_Building1.xml"/>
- <structure type="5" x="-500" />
- <stall type="market" texture="assets/style/classic/stall.png">
- <text>
- <greet>Welcome to Smithy's! What would you like to purchase today?</greet>
- <accept>Thanks!</accept>
- <deny>Come back with more money to get this item!</deny>
- <leave>Have a great day, and watch out for my rabbit Mr. Cuddles, he might try to attack you.</leave>
- </text>
- <trade quantity="420" item="Dank MayMay" quantity1="1" item1="Wood Sword"/>
- <trade quantity="666" item="Wood Sword" quantity1="420" item1="Dank MayMay"/>
- </stall>
- </village>
+ <style background="0" bgm="assets/music/embark.wav" folder="assets/style/classic/"/>
+ <generation type="Random" width="500"/>
+ <link right="playerSpawnHill2.xml"/>
+ <time>12000</time>
+ <hill peakx="0" peaky="1000" width="50"/>
+ <rabbit x="300" aggressive="false" health="100" alive="0"/>
+ <bird y="500"/>
+ <cat/>
+ <trigger x="-300" id="Test"/>
+ <npc name="Ralph" hasDialog="true" x="300"/>
+ <npc name="Johnny" hasDialog="false" x="300"/>
+ <npc name="Big Dave" hasDialog="true" x="300"/>
+ <page x="-200" id="assets/pages/gootaGoFast.png" cid="canSprint" cvalue="1"/>
+ <page x="-500" id="assets/pages/gootaJump.png" cid="canJump" cvalue="1"/>
+ <village name="Big Dave's bagel emporium! The greatest place on earth!">
+ <structure type="0" x="-300" inside="playerSpawnHill1_Building1.xml"/>
+ <structure type="5" x="-500"/>
+ <stall type="market" texture="assets/style/classic/stall.png">
+ <text>
+ <greet>Welcome to Smithy's! What would you like to purchase today?</greet>
+ <accept>Thanks!</accept>
+ <deny>Come back with more money to get this item!</deny>
+ <leave>Have a great day, and watch out for my rabbit Mr. Cuddles, he might try to attack you.</leave>
+ </text>
+ <trade quantity="420" item="Dank MayMay" quantity1="1" item1="Wood Sword"/>
+ <trade quantity="666" item="Wood Sword" quantity1="420" item1="Dank MayMay"/>
+ </stall>
+ </village>
</World>
<Trigger id="Test">It was a dark and stormy night...
...</Trigger>
<Dialog name="Ralph">
-
- <text id="0" nextid="1">
+ <text id="0" nextid="1">
Hello there! My name is Ralph.
- <gotox>300</gotox>
- </text>
-
- <text id="1" nextid="2" call="Johnny" callid="0" pause="true" >
+ <gotox>300</gotox>
+ </text>
+ <text id="1" nextid="2" call="Johnny" callid="0" pause="true">
You should go talk to my friend Johnny. He's a pretty chill dude.
</text>
-
- <text id="2" >
+ <text id="2">
Niice.
- <quest check="Your First Quest" fail="3" />
- </text>
-
- <text id="3">
+ <quest check="Your First Quest" fail="3"/></text>
+ <text id="3">
Go check out Johnny. He's cool.
</text>
</Dialog>
<Dialog name="Johnny">
- <text id="0" nextid="1" pause="true" >
+ <text id="0" nextid="1" pause="true">
Sup bro! Have a quest. To complete it, just go talk to Ralph again.
- <quest assign="Your First Quest" >
+ <quest assign="Your First Quest">
Dank MayMay,2
Wood Sword,1
</quest>
- </text>
-
- <text id="1" nextid="1" pause="true" >
+ </text>
+ <text id="1" nextid="1" pause="true">
Broooooooooooooo...
</text>
</Dialog>
<Dialog name="Big Dave">
- <text id="0" pause="true">
+ <text id="0" pause="true">
Hey friend! It's dangerous out there, here take these!
Wait, promise you'll stop by my stand in the local market!
- <give id="Wood Sword" count="1"/>
- <give id="Hunters Bow" count="1"/>
- <give id="Crude Arrow" count="110"/>
- <give id="Fried Chicken" count="1"/>
- </text>
+ <give id="Wood Sword" count="1"/> <give id="Hunters Bow" count="1"/> <give id="Crude Arrow" count="110"/> <give id="Fried Chicken" count="1"/></text>
</Dialog>