diff options
author | drumsetmonkey <abelleisle@roadrunner.com> | 2016-04-28 10:46:38 -0400 |
---|---|---|
committer | drumsetmonkey <abelleisle@roadrunner.com> | 2016-04-28 10:46:38 -0400 |
commit | 68cb663a370747c325eeeeea66cca86803e4b8e5 (patch) | |
tree | b82b7b8d77ff2a3439e99d11589bbf1a3ef1f07c /src | |
parent | 2e026aff928b30267a39ef6fdeec3e43e9f106e6 (diff) | |
parent | 174bcd3a415c21fc2c59a3af1b6333faa78b37d0 (diff) |
New inventory system
Diffstat (limited to 'src')
-rw-r--r-- | src/common.cpp | 75 | ||||
-rw-r--r-- | src/config.cpp | 142 | ||||
-rw-r--r-- | src/entities.cpp | 371 | ||||
-rw-r--r-- | src/gameplay.cpp | 267 | ||||
-rw-r--r-- | src/gametime.cpp | 76 | ||||
-rw-r--r-- | src/inventory.cpp | 11 | ||||
-rw-r--r-- | src/items.cpp | 7 | ||||
-rw-r--r-- | src/mob.cpp | 260 | ||||
-rw-r--r-- | src/threadpool.cpp | 99 | ||||
-rw-r--r-- | src/ui.cpp | 100 | ||||
-rw-r--r-- | src/ui_action.cpp | 1 | ||||
-rw-r--r-- | src/ui_menu.cpp | 13 | ||||
-rw-r--r-- | src/world.cpp | 323 |
13 files changed, 818 insertions, 927 deletions
diff --git a/src/common.cpp b/src/common.cpp index 34b2a61..c86454b 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -1,17 +1,15 @@ +#include <common.hpp> + #include <cstring> #include <cstdio> #include <chrono> #ifndef __WIN32__ -# include <sys/types.h> -# include <dirent.h> -# include <errno.h> -# include <vector> -#endif // __WIN32__ -#include <common.hpp> - -#ifndef __WIN32__ +#include <sys/types.h> +#include <dirent.h> +#include <errno.h> +#include <vector> unsigned int millis(void) { std::chrono::system_clock::time_point now=std::chrono::system_clock::now(); @@ -20,37 +18,33 @@ unsigned int millis(void) { #endif // __WIN32__ -void DEBUG_prints(const char* file, int line, const char *s,...) { +void DEBUG_prints(const char* file, int line, const char *s,...) +{ va_list args; - printf("%s:%d: ",file,line); - va_start(args,s); - vprintf(s,args); + printf("%s:%d: ", file, line); + va_start(args, s); + vprintf(s, args); va_end(args); } -void safeSetColor(int r,int g,int b) { // safeSetColor() is an alternative to directly using glColor3ub() to set - if (r>255)r=255; // the color for OpenGL drawing. safeSetColor() checks for values that are - if (g>255)g=255; // outside the range of an unsigned character and sets them to a safer value. - if (b>255)b=255; - if (r<0)r=0; - if (g<0)g=0; - if (b<0)b=0; - glColor3ub(r,g,b); +void safeSetColor(int r, int g, int b) +{ + r = static_cast<int>(fmax(fmin(r, 255), 0)); + g = static_cast<int>(fmax(fmin(g, 255), 0)); + b = static_cast<int>(fmax(fmin(b, 255), 0)); + glColor3ub(r, g, b); } void safeSetColorA(int r,int g,int b,int a) { - if (r>255)r=255; - if (g>255)g=255; - if (b>255)b=255; - if (a>255)a=255; - if (r<0)r=0; - if (g<0)g=0; - if (b<0)b=0; - if (a<0)a=0; - glColor4ub(r,g,b,a); + r = static_cast<int>(fmax(fmin(r, 255), 0)); + g = static_cast<int>(fmax(fmin(g, 255), 0)); + b = static_cast<int>(fmax(fmin(b, 255), 0)); + a = static_cast<int>(fmax(fmin(a, 255), 0)); + glColor4ub(r, g, b, a); } -int getdir(std::string dir, std::vector<std::string> &files) { +int getdir(std::string dir, std::vector<std::string> &files) +{ DIR *dp; struct dirent *dirp; if (!(dp = opendir(dir.c_str()))) { @@ -63,20 +57,22 @@ int getdir(std::string dir, std::vector<std::string> &files) { return 0; } -void strVectorSortAlpha(std::vector<std::string> *v) { +void strVectorSortAlpha(std::vector<std::string> *v) +{ static bool change; - do{ + do { change = false; - for(unsigned int i=0;i<v->size()-1;i++) { - if (v[0][i] > v[0][i+1]) { - std::swap(v[0][i],v[0][i+1]); + for (unsigned int i=0; i < v->size() - 1; i++) { + if (v[0][i] > v[0][i + 1]) { + std::swap(v[0][i], v[0][i + 1]); change = true; } } - }while(change); + } while (change); } -const char *readFile(const char *path) { +const char *readFile(const char *path) +{ std::ifstream in (path,std::ios::in); unsigned int size; GLchar *buf; @@ -94,9 +90,8 @@ const char *readFile(const char *path) { return buf; } -void -UserError(std::string reason) +void UserError(std::string reason) { - std::cout << "User error: " << reason << "!" << std::endl; + std::cout << "User error: " << reason << "!\n"; abort(); } diff --git a/src/config.cpp b/src/config.cpp index 752b365..d18016f 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -2,82 +2,74 @@ #include <ui.hpp> -using namespace tinyxml2; - -extern unsigned int HLINE; -extern unsigned int SCREEN_WIDTH; -extern unsigned int SCREEN_HEIGHT; -extern bool FULLSCREEN; - -extern float VOLUME_MASTER; -extern float VOLUME_MUSIC; -extern float VOLUME_SFX; - -extern std::string xmlFolder; - -XMLDocument xml; -XMLElement *scr; -XMLElement *vol; - -namespace config { - - void read(void) { - unsigned int uval; - float fval; - bool bval; - - xml.LoadFile("config/settings.xml"); - scr = xml.FirstChildElement("screen"); - - if (scr->QueryUnsignedAttribute("width",&uval) == XML_NO_ERROR) - SCREEN_WIDTH = uval; - else SCREEN_WIDTH = 1280; - if (scr->QueryUnsignedAttribute("height",&uval) == XML_NO_ERROR) - SCREEN_HEIGHT = uval; - else SCREEN_HEIGHT = 800; - if (scr->QueryBoolAttribute("fullscreen",&bval) == XML_NO_ERROR) - FULLSCREEN = bval; - else FULLSCREEN = false; - if (xml.FirstChildElement("hline")->QueryUnsignedAttribute("size",&uval) == XML_NO_ERROR) - HLINE = uval; - else HLINE = 3; - - vol = xml.FirstChildElement("volume"); - - if (vol->FirstChildElement("master")->QueryFloatAttribute("volume",&fval) == XML_NO_ERROR) - VOLUME_MASTER = fval; - else VOLUME_MASTER = 50; - if (vol->FirstChildElement("music")->QueryFloatAttribute("volume",&fval) == XML_NO_ERROR) - VOLUME_MUSIC = fval; - else VOLUME_MUSIC = 50; - if (vol->FirstChildElement("sfx")->QueryFloatAttribute("volume",&fval) == XML_NO_ERROR) - VOLUME_SFX = fval; - else VOLUME_SFX = 50; - - xmlFolder = xml.FirstChildElement("world")->Attribute("start"); - if (xmlFolder=="\0")xmlFolder = "xml/"; - std::cout << "Folder: " << xmlFolder << std::endl; - - ui::initFonts(); - ui::setFontFace(xml.FirstChildElement("font")->Attribute("path")); - - if (xml.FirstChildElement("debug")) - ui::debug = ui::posFlag = true; - - config::update(); - } +#include <SDL2/SDL_mixer.h> - void update(void) { - Mix_Volume(0,VOLUME_MASTER); - Mix_Volume(1,VOLUME_SFX * (VOLUME_MASTER/100.0f)); - Mix_VolumeMusic(VOLUME_MUSIC * (VOLUME_MASTER/100.0f)); - } - - void save(void) { - vol->FirstChildElement("master")->SetAttribute("volume",VOLUME_MASTER); - vol->FirstChildElement("music")->SetAttribute("volume",VOLUME_MUSIC); - vol->FirstChildElement("sfx")->SetAttribute("volume", VOLUME_SFX); +#include <tinyxml2.h> +using namespace tinyxml2; - xml.SaveFile("config/settings.xml", false); +namespace game { + unsigned int HLINE; + unsigned int SCREEN_WIDTH; + unsigned int SCREEN_HEIGHT; + bool FULLSCREEN; + + namespace config { + static XMLDocument xml; + static XMLElement *vol; + + float VOLUME_MASTER; + float VOLUME_MUSIC; + float VOLUME_SFX; + + std::string xmlFolder; + + void read(void) { + xml.LoadFile("config/settings.xml"); + auto exml = xml.FirstChildElement("screen"); + + if (exml->QueryUnsignedAttribute("width", &SCREEN_WIDTH) != XML_NO_ERROR) + SCREEN_WIDTH = 1024; + if (exml->QueryUnsignedAttribute("height", &SCREEN_HEIGHT) != XML_NO_ERROR) + SCREEN_HEIGHT = 768; + if (exml->QueryBoolAttribute("fullscreen", &FULLSCREEN) != XML_NO_ERROR) + FULLSCREEN = false; + + if (xml.FirstChildElement("hline")->QueryUnsignedAttribute("size", &HLINE) != XML_NO_ERROR) + HLINE = 3; + + vol = exml = xml.FirstChildElement("volume"); + if (exml->FirstChildElement("master")->QueryFloatAttribute("volume", &VOLUME_MASTER) != XML_NO_ERROR) + VOLUME_MASTER = 50; + if (exml->FirstChildElement("music")->QueryFloatAttribute("volume", &VOLUME_MUSIC) != XML_NO_ERROR) + VOLUME_MUSIC = 50; + if (exml->FirstChildElement("sfx")->QueryFloatAttribute("volume", &VOLUME_SFX) != XML_NO_ERROR) + VOLUME_SFX = 50; + + xmlFolder = xml.FirstChildElement("world")->StrAttribute("start"); + if (xmlFolder.empty()) + xmlFolder = "xml/"; + + ui::initFonts(); + ui::setFontFace(xml.FirstChildElement("font")->Attribute("path")); + + if (xml.FirstChildElement("debug")) + ui::debug = ui::posFlag = true; + + config::update(); + } + + void update(void) { + Mix_Volume(0, VOLUME_MASTER); + Mix_Volume(1, VOLUME_SFX * (VOLUME_MASTER / 100.0f)); + Mix_VolumeMusic(VOLUME_MUSIC * (VOLUME_MASTER / 100.0f)); + } + + void save(void) { + vol->FirstChildElement("master")->SetAttribute("volume", VOLUME_MASTER); + vol->FirstChildElement("music")->SetAttribute("volume", VOLUME_MUSIC); + vol->FirstChildElement("sfx")->SetAttribute("volume", VOLUME_SFX); + + xml.SaveFile("config/settings.xml", false); + } } } diff --git a/src/entities.cpp b/src/entities.cpp index aa236fe..869f0d4 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -4,6 +4,7 @@ #include <sstream> #include <ui.hpp> +#include <world.hpp> #include <gametime.hpp> extern std::istream *names; @@ -97,21 +98,14 @@ void Entity::spawn(float x, float y) ticksToUse = 0; hitCooldown = 0; - if (!maxHealth)health = maxHealth = 1; - - if (type==MOBT) { - if (Mobp(this)->subtype == MS_BIRD) { - Mobp(this)->init_y=loc.y; - } - } + if (!maxHealth) + health = maxHealth = 1; name = new char[32]; if (type == MOBT) name[0] = '\0'; else getRandomName(this); - - followee = NULL; } void Entity::takeHit(unsigned int _health, unsigned int cooldown) @@ -160,8 +154,8 @@ void Entity::moveTo(float dest_x) } Player::Player(){ //sets all of the player specific traits on object creation - width = HLINE * 10; - height = HLINE * 16; + width = HLINES(10); + height = HLINES(16); type = PLAYERT; //set type to player subtype = 0; @@ -188,8 +182,8 @@ Player::~Player() { } NPC::NPC() { //sets all of the NPC specific traits on object creation - width = HLINE * 10; - height = HLINE * 16; + width = HLINES(10); + height = HLINES(16); type = NPCT; //sets type to npc subtype = 0; @@ -214,8 +208,8 @@ NPC::~NPC() } Merchant::Merchant() { //sets all of the Merchant specific traits on object creation - width = HLINE * 10; - height = HLINE * 16; + width = HLINES(10); + height = HLINES(16); type = MERCHT; //sets type to merchant subtype = 0; @@ -266,50 +260,6 @@ Structures::~Structures() { delete[] name; } -Mob::Mob(int sub) { - type = MOBT; - aggressive = false; - - maxHealth = health = 50; - canMove = true; - - switch((subtype = sub)) { - case MS_RABBIT: - width = HLINE * 10; - height = HLINE * 8; - tex = new Texturec(2, "assets/rabbit.png", "assets/rabbit1.png"); - break; - case MS_BIRD: - width = HLINE * 8; - height = HLINE * 8; - tex = new Texturec(1, "assets/robin.png"); - break; - case MS_TRIGGER: - width = HLINE * 20; - height = 2000; - tex = new Texturec(0); - break; - case MS_DOOR: - width = HLINE * 12; - height = HLINE * 20; - tex = new Texturec(1,"assets/door.png"); - break; - case MS_PAGE: - width = HLINE * 6; - height = HLINE * 4; - tex = new Texturec(1,"assets/items/ITEM_PAGE.png"); - break; - } - - inv = new Inventory(NPC_INV_SIZE); -} - -Mob::~Mob() { - delete inv; - delete tex; - delete[] name; -} - Object::Object() { type = OBJECTT; alive = true; @@ -355,7 +305,7 @@ void Object::reloadTexture(void) { } bool Entity::isNear(Entity e) { - return pow(e.loc.x - loc.x, 2) + pow(e.loc.y - loc.y, 2) <= pow(40 * HLINE, 2); + return pow(e.loc.x - loc.x, 2) + pow(e.loc.y - loc.y, 2) <= pow(HLINES(40), 2); } void NPC::drawThingy(void) const @@ -393,7 +343,7 @@ void Entity::draw(void) switch(type) { case PLAYERT: static int texState = 0; - if (speed && !(loops % ((2.0f/speed) < 1 ? 1 : (int)((float)2.0f/(float)speed)))) { + if (speed && !(game::time::getTickCount() % ((2.0f/speed) < 1 ? 1 : (int)((float)2.0f/(float)speed)))) { if (++texState==9)texState=1; glActiveTexture(GL_TEXTURE0); tex->bind(texState); @@ -410,22 +360,8 @@ void Entity::draw(void) } break; case MOBT: - switch(subtype) { - case MS_RABBIT: - glActiveTexture(GL_TEXTURE0 + 0); - tex->bind(!ground); - break; - case MS_TRIGGER: - goto NOPE; - break; - case MS_BIRD: - case MS_DOOR: - case MS_PAGE: - default: - glActiveTexture(GL_TEXTURE0); - tex->bind(0); - break; - } + if (!Mobp(this)->bindTex()) + goto NOPE; break; case STRUCTURET: /* fall through */ @@ -454,10 +390,10 @@ NOPE: glMatrixMode(GL_MODELVIEW); glPopMatrix(); if (near && type != MOBT) - ui::putStringCentered(loc.x+width/2,loc.y-ui::fontSize-HLINE/2,name); + ui::putStringCentered(loc.x + width / 2, loc.y - ui::fontSize - game::HLINE / 2, name); if (health != maxHealth) { - glColor3ub(150,0,0); glRectf(loc.x, loc.y + height, loc.x + width, loc.y + height + HLINE * 2); - glColor3ub(255,0,0); glRectf(loc.x, loc.y + height, loc.x + width * (health / maxHealth), loc.y + height + HLINE * 2); + glColor3ub(150,0,0); glRectf(loc.x, loc.y + height, loc.x + width, loc.y + height + HLINES(2)); + glColor3ub(255,0,0); glRectf(loc.x, loc.y + height, loc.x + width * (health / maxHealth), loc.y + height + HLINES(2)); } } @@ -476,26 +412,17 @@ wander(int timeRun) if (hitCooldown) hitCooldown--; - if (followee) { - if (loc.x < followee->loc.x - 40) - direction = 1; - else if (loc.x > followee->loc.x + 40) - direction = -1; - else - direction = 0; - - vel.x = .018 * HLINE * direction; - } else if (targetx != 0.9112001f) { - if (loc.x > targetx + HLINE * 5) - vel.x = -0.018 * HLINE; - else if (loc.x < targetx - HLINE * 5) - vel.x = 0.018 * HLINE; + if (targetx != 0.9112001f) { + if (loc.x > targetx + HLINES(5)) + vel.x = HLINES(-0.018); + else if (loc.x < targetx - HLINES(5)) + vel.x = HLINES(0.018); else targetx = 0.9112001f; } else if (ticksToUse == 0) { ticksToUse = timeRun; - vel.x = .008 * HLINE; + vel.x = HLINES(0.008); direction = (getRand() % 3 - 1); if (direction == 0) @@ -522,6 +449,15 @@ extern int commonAIFunc(NPC *speaker); void NPC::interact() { //have the npc's interact back to the player std::thread([this]{ + std::vector<XMLElement *> dopt; + XMLDocument xml; + XMLElement *exml,*oxml; + + static unsigned int oldidx = 9999; + std::string nname; + unsigned int idx; + bool stop; + loc.y += 5; canMove=false; @@ -529,14 +465,144 @@ void NPC::interact() { //have the npc's interact back to the player right = !left; if (dialogCount && dialogIndex != 9999) { - if (!commonAIFunc(this)) - dialogCount--; + // load the XML file and find the dialog tags + xml.LoadFile(currentXML.c_str()); +COMMONAIFUNC: + idx = 0; + stop = false; + exml = xml.FirstChildElement("Dialog"); + + // search for the dialog block associated with this npc + while (exml->StrAttribute("name") != name) + exml = exml->NextSiblingElement(); + + // search for the desired text block + exml = exml->FirstChildElement(); + do { + if (std::string("text") == exml->Name() && exml->UnsignedAttribute("id") == (unsigned)dialogIndex) + break; + } while ((exml = exml->NextSiblingElement())); + + // handle quest tags + if ((oxml = exml->FirstChildElement("quest"))) { + std::string qname; + + // iterate through all quest tags + do { + // assign quest + if (!(qname = oxml->StrAttribute("assign")).empty()) + player->qh.assign(qname, "None", std::string(oxml->GetText())); // TODO add descriptions + + // check / finish quest + else if (!(qname = oxml->StrAttribute("check")).empty()) { + if (player->qh.hasQuest(qname) && player->qh.finish(qname)) { + // QuestHandler::finish() did all the work.. + break; + } else { + // run error dialog + oldidx = dialogIndex; + dialogIndex = oxml->UnsignedAttribute("fail"); + goto COMMONAIFUNC; + } + } + } while((oxml = oxml->NextSiblingElement())); + } + + // handle give tags + if ((oxml = exml->FirstChildElement("give"))) { + do player->inv->addItem(oxml->Attribute("id"), oxml->UnsignedAttribute("count")); + while ((oxml = oxml->NextSiblingElement())); + } + + // handle take tags + if ((oxml = exml->FirstChildElement("take"))) { + do player->inv->takeItem(oxml->Attribute("id"), oxml->UnsignedAttribute("count")); + while ((oxml = oxml->NextSiblingElement())); + } + + // handle movement directs + if ((oxml = exml->FirstChildElement("gotox"))) + moveTo(std::stoi(oxml->GetText())); + + // handle dialog options + if ((oxml = exml->FirstChildElement("option"))) { + std::string optstr; + + // convert option strings to a colon-separated format + do { + // append the next option + optstr.append(std::string(":") + oxml->Attribute("text")); + + // save the associated XMLElement + dopt.push_back(oxml); + } while ((oxml = oxml->NextSiblingElement())); + + // run the dialog stuff + ui::dialogBox(name, optstr, false, exml->GetText() + 1); + ui::waitForDialog(); + + if (ui::dialogOptChosen) + exml = dopt[ui::dialogOptChosen - 1]; + + dopt.clear(); + } + + // optionless dialog + else { + ui::dialogBox(name, "", false, exml->GetText()); + ui::waitForDialog(); + } + + // trigger other npcs if desired + if (!(nname = exml->StrAttribute("call")).empty()) { + NPC *n = *std::find_if(std::begin(currentWorld->npc), std::end(currentWorld->npc), [nname](NPC *npc) { + return (npc->name == nname); + }); + + if (exml->QueryUnsignedAttribute("callid", &idx) == XML_NO_ERROR) { + n->dialogIndex = idx; + n->addAIFunc(false); + } + } + + // handle potential following dialogs + if ((idx = exml->UnsignedAttribute("nextid"))) { + dialogIndex = idx; + + // stop talking + if (exml->QueryBoolAttribute("stop", &stop) == XML_NO_ERROR && stop) { + dialogIndex = 9999; + dialogCount--; + } + + // pause, allow player to click npc to continue + else if (exml->QueryBoolAttribute("pause", &stop) == XML_NO_ERROR && stop) { + //return 1; + } + + // instantly continue + else { + goto COMMONAIFUNC; + } + } + + // stop talking + else { + // error text? + if (oldidx != 9999) { + dialogIndex = oldidx; + oldidx = 9999; + } else { + dialogIndex = 9999; + dialogCount--; + } + } } else { ui::dialogBox(name, "", false, randomDialog[randDialog]); } ui::waitForDialog(); - canMove=true; + canMove = true; }).detach(); } @@ -549,7 +615,7 @@ void Merchant::wander(int timeRun) { if (ticksToUse == 0) { ticksToUse = timeRun; - vel.x = .008 * HLINE; + vel.x = HLINES(0.008); direction = (getRand() % 3 - 1); if (direction == 0) @@ -561,12 +627,12 @@ void Merchant::wander(int timeRun) { if (vel.x < 0) currentWorld->goWorldLeft(this); if (inside != nullptr) { - loc.y = inside->loc.y + HLINE * 2; + loc.y = inside->loc.y + HLINES(2); vel.y = GRAVITY_CONSTANT * 5; - if (loc.x <= inside->loc.x + HLINE * 5) - loc.x = inside->loc.x + HLINE * 5; - else if (loc.x + width >= inside->loc.x + inside->width - HLINE * 5) - loc.x = inside->loc.x + inside->width - width - HLINE * 5; + if (loc.x <= inside->loc.x + HLINES(5)) + loc.x = inside->loc.x + HLINES(5); + else if (loc.x + width >= inside->loc.x + inside->width - HLINES(5)) + loc.x = inside->loc.x + inside->width - width - HLINES(5); } ticksToUse--; } @@ -646,10 +712,6 @@ bool Entity::isInside(vec2 coord) const { coord.y <= loc.y + height; } -void Entity::follow(Entity *e) { - followee = e; -} - /* * This spawns the structures * @@ -701,93 +763,6 @@ unsigned int Structures::spawn(BUILD_SUB sub, float x, float y) { return 0; } -/* - * Mob::wander this is the function that makes the mobs wander around - * - * See NPC::wander for the explaination of the argument's variable -*/ - -void Mob::wander(int timeRun) { - static int direction; //variable to decide what direction the entity moves - static unsigned int heya=0,hi=0; - static bool YAYA = false; - - auto deltaTime = gtime::getDeltaTime(); - - if (forcedMove) - return; - - if (followee) { - if (loc.x < followee->loc.x - 40) - direction = 1; - else if (loc.x > followee->loc.x + 40) - direction = -1; - else - direction = 0; - - vel.x = .018 * HLINE * direction; - return; - } - - if (aggressive && !YAYA && - player->loc.x + (width / 2) > loc.x && player->loc.x + (width / 2) < loc.x + width && - player->loc.y + (height / 3) > loc.y && player->loc.y + (height / 3) < loc.y + height) { - if (!ui::dialogBoxExists) { - Arena *a = new Arena(currentWorld,player,this); - a->setStyle(""); - a->setBackground(WorldBGType::Forest); - a->setBGM("assets/music/embark.wav"); - - ui::toggleWhiteFast(); - YAYA = true; - ui::waitForCover(); - YAYA = false; - currentWorld = a; - ui::toggleWhiteFast(); - } - } - - switch(subtype) { - case MS_RABBIT: - if (!ticksToUse) { - ticksToUse = timeRun; - direction = (getRand() % 3 - 1); //sets the direction to either -1, 0, 1 - //this lets the entity move left, right, or stay still - if (direction==0)ticksToUse/=2; - vel.x *= direction; //changes the velocity based off of the direction - } - if (ground && direction) { - vel.y=.15; - loc.y+=HLINE*.25; - ground=false; - vel.x = (.07*HLINE)*direction; //sets the inital velocity of the entity - } - ticksToUse--; //removes one off of the entities timer - break; - case MS_BIRD: - if (loc.y<=init_y-.2)vel.y=.02*deltaTime; // TODO handle direction - vel.x = 0.02f * deltaTime; - if (++heya==200) {heya=0;hi^=1;} - if (hi)vel.x*=-1; - break; - case MS_TRIGGER: - if (player->loc.x + player->width / 2 > loc.x && - player->loc.x + player->width / 2 < loc.x + width) - std::thread([this]{hey(this);}).detach(); - //hey(this); - break; - case MS_PAGE: - if (player->loc.x > loc.x - 100 && player->loc.x < loc.x + 100 && // within player ranger - ui::mouse.x > loc.x && ui::mouse.x < loc.x + width && // mouse x - ui::mouse.y > loc.y - width / 2 && ui::mouse.y < loc.y + width * 1.5 && // mouse y - SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT)) // right click - hey(this); - break; - default: - break; - } -} - Particles::Particles(float x, float y, float w, float h, float vx, float vy, Color c, float d) { loc = vec2 {x, y}; @@ -833,7 +808,7 @@ void Particles::update(float _gravity, float ground_y) // handle gravity else if (gravity && vel.y > -1.0f) { - vel.y -= _gravity * gtime::getDeltaTime(); + vel.y -= _gravity * game::time::getDeltaTime(); } } @@ -850,7 +825,7 @@ void Player::save(void) { data.append(std::to_string((int)loc.y) + "\n"); data.append(std::to_string((int)health) + "\n"); data.append(std::to_string((int)maxHealth) + "\n"); - data.append(std::to_string((int)gtime::getTickCount()) + "\n"); + data.append(std::to_string((int)game::time::getTickCount()) + "\n"); data.append("qwer\n"); data.append(std::to_string((int)inv->Items.size()) + "\n"); @@ -896,7 +871,7 @@ void Player::sspawn(float x,float y) { std::getline(data,ddata); maxHealth = std::stoi(ddata); std::getline(data,ddata); - gtime::tick(std::stoi(ddata)); + game::time::tick(std::stoi(ddata)); std::getline(data,ddata); std::getline(data,ddata); diff --git a/src/gameplay.cpp b/src/gameplay.cpp deleted file mode 100644 index d5969ac..0000000 --- a/src/gameplay.cpp +++ /dev/null @@ -1,267 +0,0 @@ -#include <common.hpp> -#include <entities.hpp> -#include <world.hpp> -#include <ui.hpp> - -#include <tinyxml2.h> -using namespace tinyxml2; - -extern Player *player; // main.cpp -extern World *currentWorld; // main.cpp - -extern Menu pauseMenu; -extern Menu optionsMenu; - -extern std::string xmlFolder; - -extern std::vector<NPC *> aipreload; - -extern void mainLoop(void); // main.cpp - -std::vector<XMLElement *> dopt; - -void destroyEverything(void); - -int commonAIFunc(NPC *speaker) -{ - XMLDocument xml; - XMLElement *exml,*oxml; - - static unsigned int oldidx = 9999; - - std::string name; - unsigned int idx = 0; - bool stop = false; - - // load the XML file and find the dialog tags - xml.LoadFile(currentXML.c_str()); - exml = xml.FirstChildElement("Dialog"); - - // search for the dialog block associated with this npc - while (exml->StrAttribute("name") != speaker->name) - exml = exml->NextSiblingElement(); - - // search for the desired text block - exml = exml->FirstChildElement(); - std::cout << speaker->dialogIndex << '\n'; - do { - if (std::string("text") == exml->Name() && exml->UnsignedAttribute("id") == (unsigned)speaker->dialogIndex) - break; - } while ((exml = exml->NextSiblingElement())); - - // handle quest tags - if ((oxml = exml->FirstChildElement("quest"))) { - std::string qname; - - // iterate through all quest tags - do { - // assign quest - if (!(qname = oxml->StrAttribute("assign")).empty()) - player->qh.assign(qname, "None", std::string(oxml->GetText())); // TODO add descriptions - - // check / finish quest - else if (!(qname = oxml->StrAttribute("check")).empty()) { - if (player->qh.hasQuest(qname) && player->qh.finish(qname)) { - // QuestHandler::finish() did all the work.. - break; - } else { - // run error dialog - oldidx = speaker->dialogIndex; - speaker->dialogIndex = oxml->UnsignedAttribute("fail"); - return commonAIFunc(speaker); - } - } - } while((oxml = oxml->NextSiblingElement())); - } - - // handle give tags - if ((oxml = exml->FirstChildElement("give"))) { - do player->inv->addItem(oxml->Attribute("id"), oxml->UnsignedAttribute("count")); - while ((oxml = oxml->NextSiblingElement())); - } - - // handle take tags - if ((oxml = exml->FirstChildElement("take"))) { - do player->inv->takeItem(oxml->Attribute("id"), oxml->UnsignedAttribute("count")); - while ((oxml = oxml->NextSiblingElement())); - } - - // handle movement directs - if ((oxml = exml->FirstChildElement("gotox"))) - speaker->moveTo(std::stoi(oxml->GetText())); - - // handle dialog options - if ((oxml = exml->FirstChildElement("option"))) { - std::string optstr; - - // convert option strings to a colon-separated format - do { - // append the next option - optstr.append(std::string(":") + oxml->Attribute("text")); - - // save the associated XMLElement - dopt.push_back(oxml); - } while ((oxml = oxml->NextSiblingElement())); - - // run the dialog stuff - ui::dialogBox(speaker->name, optstr, false, exml->GetText() + 1); - ui::waitForDialog(); - - if (ui::dialogOptChosen) - exml = dopt[ui::dialogOptChosen - 1]; - - dopt.clear(); - } - - // optionless dialog - else { - ui::dialogBox(speaker->name, "", false, exml->GetText()); - ui::waitForDialog(); - } - - // trigger other npcs if desired - if (!(name = exml->StrAttribute("call")).empty()) { - NPC *n = *std::find_if(std::begin(currentWorld->npc), std::end(currentWorld->npc), [name](NPC *npc) { - return (npc->name == name); - }); - - if (exml->QueryUnsignedAttribute("callid", &idx) == XML_NO_ERROR) { - n->dialogIndex = idx; - n->addAIFunc(false); - } - } - - // handle potential following dialogs - if ((idx = exml->UnsignedAttribute("nextid"))) { - speaker->dialogIndex = idx; - - // stop talking - if (exml->QueryBoolAttribute("stop", &stop) == XML_NO_ERROR && stop) { - speaker->dialogIndex = 9999; - return 0; - } - - // pause, allow player to click npc to continue - else if (exml->QueryBoolAttribute("pause", &stop) == XML_NO_ERROR && stop) { - return 1; - } - - // instantly continue - else { - return commonAIFunc(speaker); - } - } - - // stop talking - else { - // error text? - if (oldidx != 9999) { - speaker->dialogIndex = oldidx; - oldidx = 9999; - return 1; - } else { - speaker->dialogIndex = 9999; - return 0; - } - } - - return 0; -} - -void commonPageFunc(Mob *callee) -{ - ui::drawPage(callee->heyid); - ui::waitForDialog(); - callee->health = 0; -} - -void commonTriggerFunc(Mob *callee) { - static bool lock = false; - XMLDocument xml; - XMLElement *exml; - - char *text,*pch; - if (!lock) { - lock = true; - - xml.LoadFile(currentXML.c_str()); - exml = xml.FirstChildElement("Trigger"); - - while(exml->StrAttribute("id") != callee->heyid) - exml = exml->NextSiblingElement(); - - player->vel.x = 0; - - ui::toggleBlackFast(); - ui::waitForCover(); - - text = new char[256]; - strcpy(text,exml->GetText()); - pch = strtok(text,"\n"); - - while(pch) { - ui::importantText(pch); - ui::waitForDialog(); - - pch = strtok(NULL,"\n"); - } - - delete[] text; - - ui::toggleBlackFast(); - - callee->health = 0; - lock = false; - } -} - -void initEverything(void) { - std::vector<std::string> xmlFiles; - XMLDocument xml; - - /* - * Read the XML directory into an array. - */ - - if (getdir(std::string("./" + xmlFolder).c_str(), xmlFiles)) - UserError("Error reading XML files!!!"); - - /* - * Sort the files alphabetically. - */ - - strVectorSortAlpha(&xmlFiles); - - /* - * Load the first file found as currentWorld. - */ - - for (xf : xmlFiles) { //unsigned int i=0;i<xmlFiles.size();i++){ - if (xf[0] != '.' && strcmp(&xf[xf.size() - 3], "dat")){ - // read the xml file - std::cout << "File to load: " << xf << std::endl; - currentWorld = loadWorldFromXML(xf); - break; - } - } - - /* - * Spawn the player and begin the game. - */ - - player = new Player(); - player->sspawn(0,100); - - ui::menu::init(); - - currentWorld->bgmPlay(NULL); - atexit(destroyEverything); -} - -void destroyEverything(void) { - currentWorld->save(); - //delete currentWorld; - //delete[] currentXML; - - aipreload.clear(); -} diff --git a/src/gametime.cpp b/src/gametime.cpp index be63885..598cd4f 100644 --- a/src/gametime.cpp +++ b/src/gametime.cpp @@ -9,42 +9,44 @@ static unsigned int deltaTime = 1; static unsigned int currentTime = 0; static unsigned int prevTime, prevPrevTime; -namespace gtime { - void setTickCount(unsigned int t) { - tickCount = t; - } - - unsigned int getTickCount(void) { - return tickCount; - } - - unsigned int getDeltaTime(void) { - return deltaTime; - } - - void tick(void) { - tickCount++; - } - - void tick(unsigned int ticks) { - tickCount += ticks; - } - - void mainLoopHandler(void) { - if (!currentTime) - currentTime = prevTime = millis(); - - currentTime = millis(); - deltaTime = currentTime - prevTime; - prevTime = currentTime; - } - - bool tickHasPassed(void) { - if (prevPrevTime + MSEC_PER_TICK <= currentTime) { - prevPrevTime = currentTime; - return true; - } - - return false; +namespace game { + namespace time { + void setTickCount(unsigned int t) { + tickCount = t; + } + + unsigned int getTickCount(void) { + return tickCount; + } + + unsigned int getDeltaTime(void) { + return (deltaTime > 0) ? deltaTime : 1; + } + + void tick(void) { + tickCount++; + } + + void tick(unsigned int ticks) { + tickCount += ticks; + } + + void mainLoopHandler(void) { + if (!currentTime) + currentTime = prevTime = millis(); + + currentTime = millis(); + deltaTime = currentTime - prevTime; + prevTime = currentTime; + } + + bool tickHasPassed(void) { + if (prevPrevTime + MSEC_PER_TICK <= currentTime) { + prevPrevTime = currentTime; + return true; + } + + return false; + } } } diff --git a/src/inventory.cpp b/src/inventory.cpp index 4564c20..78502a7 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -8,7 +8,6 @@ using namespace tinyxml2; extern Player *player; extern GLuint invUI; -static float hangle = 0.0f; static vec2 itemLoc; static const unsigned char numSlot = 7; Mix_Chunk* swordSwing; @@ -101,7 +100,7 @@ void items(void) int Inventory::addItem(std::string name, uint count) { - std::cout << "Adding: " << count << name << "s\'" << std::endl; + std::cout << "Adding: " << count << name << "\'s" << std::endl; for (uint i = 0; i < ItemMap.size(); i++) { if (strCaseCmp(ItemMap[i]->name, name)) { for (auto &it : Items) { @@ -229,7 +228,7 @@ Inventory::Inventory(unsigned int s) { Items.resize(size); for (auto &i : Items) { - i = make_pair(nullptr, 0); + i = std::make_pair(nullptr, 0); } } @@ -274,7 +273,9 @@ void Inventory::draw(void) { //static vec2 mouseStart = {0,0}; C("End define"); - auto deltaTime = gtime::getDeltaTime(); + auto deltaTime = game::time::getDeltaTime(); + auto SCREEN_WIDTH = game::SCREEN_WIDTH; + auto SCREEN_HEIGHT = game::SCREEN_HEIGHT; for (auto &r : iray) { r.start.x = player->loc.x + (player->width / 2); @@ -584,7 +585,7 @@ void itemDraw(Player *p, Item *d) { glUseProgram(shaderProgram); glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0); glTranslatef(itemLoc.x,itemLoc.y,0); - glRotatef(hangle, 0.0f, 0.0f, 1.0f); + glRotatef(d->rotation, 0.0f, 0.0f, 1.0f); glTranslatef(-itemLoc.x,-itemLoc.y,0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,d->tex->image[0]); diff --git a/src/items.cpp b/src/items.cpp index b25b482..403c49e 100644 --- a/src/items.cpp +++ b/src/items.cpp @@ -1,4 +1,7 @@ #include <inventory.hpp> +#include <entities.hpp> + +extern Player *player; /************************************************************************************ * GLOBAL * @@ -16,6 +19,10 @@ int BaseItem::useItem() int Sword::useItem() { std::cout << "Swing!" << std::endl; + if (player->left) + rotation += 10.0f; + else + rotation -= 10.0f; return 0; } diff --git a/src/mob.cpp b/src/mob.cpp new file mode 100644 index 0000000..c783209 --- /dev/null +++ b/src/mob.cpp @@ -0,0 +1,260 @@ +#include <mob.hpp> +#include <ui.hpp> + +Page::Page(void) +{ + type = MOBT; + aggressive = false; + maxHealth = health = 50; + canMove = true; + width = HLINES(6); + height = HLINES(4); + tex = new Texturec({"assets/items/ITEM_PAGE.png"}); +} + +void Page::act(void) +{ + if (player->loc.x > loc.x - 100 && player->loc.x < loc.x + 100 && isInside(ui::mouse) && + (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT))) { + std::thread([this](void){ + ui::drawPage(pageTexPath); + ui::waitForDialog(); + die(); + }).detach(); + } +} + +bool Page::bindTex(void) +{ + glActiveTexture(GL_TEXTURE0); + tex->bind(0); + return true; +} + +void Page::createFromXML(const XMLElement *e) +{ + float Xlocx; + if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR) + loc.x = Xlocx; + pageTexPath = e->StrAttribute("id"); +} + +Door::Door(void) +{ + type = MOBT; + aggressive = false; + maxHealth = health = 50; + canMove = true; + width = HLINES(12); + height = HLINES(20); + tex = new Texturec({"assets/door.png"}); +} + +void Door::act(void) +{ +} + +bool Door::bindTex(void) +{ + glActiveTexture(GL_TEXTURE0); + tex->bind(0); + return true; +} + +void Door::createFromXML(const XMLElement *e) +{ + float Xlocx; + if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR) + loc.x = Xlocx; +} + +Rabbit::Rabbit(void) +{ + type = MOBT; + canMove = true; + aggressive = false; + maxHealth = health = 50; + width = HLINES(10); + height = HLINES(8); + tex = new Texturec({"assets/rabbit.png", "assets/rabbit1.png"}); + actCounterInitial = getRand() % 240 + 15; + actCounter = 1; +} + +void Rabbit::act(void) +{ + static int direction = 0; + if (!--actCounter) { + actCounter = actCounterInitial; + direction = (getRand() % 3 - 1); //sets the direction to either -1, 0, 1 + if (direction == 0) + ticksToUse /= 2; + vel.x *= direction; + } + + if (ground && direction) { + ground = false; + vel.y = .15; + loc.y += HLINES(0.25f); + vel.x = 0.05f * direction; + } +} + +bool Rabbit::bindTex(void) +{ + glActiveTexture(GL_TEXTURE0); + tex->bind(!ground); + return true; +} + +void Rabbit::createFromXML(const XMLElement *e) +{ + 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) + aggressive = false; +} + +Bird::Bird(void) +{ + type = MOBT; + aggressive = false; + maxHealth = health = 50; + canMove = true; + width = HLINES(8); + height = HLINES(8); + tex = new Texturec({"assets/robin.png"}); + actCounterInitial = actCounter = 200; +} + +void Bird::act(void) +{ + static bool direction = false; + auto deltaTime = game::time::getDeltaTime(); + if (!--actCounter) { + actCounter = actCounterInitial; + direction ^= 1; + } + + if (loc.y <= initialY) + vel.y = 0.02f * deltaTime; + vel.x = (direction ? -0.02f : 0.02f) * deltaTime; +} + +bool Bird::bindTex(void) +{ + glActiveTexture(GL_TEXTURE0); + tex->bind(0); + return true; +} + +void Bird::createFromXML(const XMLElement *e) +{ + 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->QueryFloatAttribute("y", &initialY) != XML_NO_ERROR) + initialY = 300; + if (e->QueryBoolAttribute("aggressive", &aggressive) != XML_NO_ERROR) + aggressive = false; +} + +Trigger::Trigger(void) +{ + type = MOBT; + aggressive = false; + maxHealth = health = 50; + canMove = true; + width = HLINES(20); + height = 2000; + tex = new Texturec(0); + triggered = false; +} + +void Trigger::act(void) +{ + auto c = player->loc.x + player->width / 2; + static bool running = false; + + if (triggered) { + die(); + } else if (!running && c > loc.x && c < loc.x + width) { + std::thread([&]{ + running = true; + + XMLDocument xml; + XMLElement *exml; + + xml.LoadFile(currentXML.c_str()); + exml = xml.FirstChildElement("Trigger"); + + while(exml->StrAttribute("id") != id) + exml = exml->NextSiblingElement(); + + player->vel.x = 0; + + ui::toggleBlackFast(); + ui::waitForCover(); + + std::string text = exml->GetText(); + char *pch = strtok(&text[0], "\n"); + + while (pch) { + ui::importantText(pch); + ui::waitForDialog(); + pch = strtok(NULL, "\n"); + } + + ui::toggleBlackFast(); + + triggered = true; + running = false; + }).detach(); + } +} + +bool Trigger::bindTex(void) +{ + return false; +} + +void Trigger::createFromXML(const XMLElement *e) +{ + float Xlocx; + if (e->QueryFloatAttribute("x", &Xlocx) == XML_NO_ERROR) + loc.x = Xlocx; + id = e->StrAttribute("id"); +} + +Mob::~Mob() { + delete inv; + delete tex; + delete[] name; +} + +void Mob::wander(void) { + //static bool YAYA = false; + if (forcedMove) + return; + /*if (aggressive && !YAYA && isInside(vec2 {player->loc.x + width / 2, player->loc.y + height / 4})) { + if (!ui::dialogBoxExists) { + Arena *a = new Arena(currentWorld, player, this); + a->setStyle(""); + a->setBackground(WorldBGType::Forest); + a->setBGM("assets/music/embark.wav"); + + ui::toggleWhiteFast(); + YAYA = true; + ui::waitForCover(); + YAYA = false; + currentWorld = a; + ui::toggleWhiteFast(); + } + }*/ + act(); +} diff --git a/src/threadpool.cpp b/src/threadpool.cpp deleted file mode 100644 index c4f1c4a..0000000 --- a/src/threadpool.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include <threadpool.hpp> - -/** - * Stolen from some guy. - */ - -// Constructor. -ThreadPool::ThreadPool(int threads) : - terminate(false), - stopped(false) -{ - // Create number of required threads and add them to the thread pool vector. - for(int i = 0; i < threads; i++) - { - threadPool.emplace_back(thread(&ThreadPool::Invoke, this)); - } -} - -void ThreadPool::Enqueue(function<void()> f) -{ - // Scope based locking. - { - // Put unique lock on task mutex. - unique_lock<mutex> lock(tasksMutex); - - // Push task into queue. - tasks.push(f); - } - - // Wake up one thread. - condition.notify_one(); -} - -void ThreadPool::Invoke() { - - function<void()> task; - while(true) - { - // Scope based locking. - { - // Put unique lock on task mutex. - unique_lock<mutex> lock(tasksMutex); - - // Wait until queue is not empty or termination signal is sent. - condition.wait(lock, [this]{ return !tasks.empty() || terminate; }); - - // If termination signal received and queue is empty then exit else continue clearing the queue. - if (terminate && tasks.empty()) - { - return; - } - - // Get next task in the queue. - task = tasks.front(); - - // Remove it from the queue. - tasks.pop(); - } - - // Execute the task. - task(); - } -} - -void ThreadPool::ShutDown() -{ - // Scope based locking. - { - // Put unique lock on task mutex. - unique_lock<mutex> lock(tasksMutex); - - // Set termination flag to true. - terminate = true; - } - - // Wake up all threads. - condition.notify_all(); - - // Join all threads. - for(thread &thread : threadPool) - { - thread.join(); - } - - // Empty workers vector. - threadPool.empty(); - - // Indicate that the pool has been shut down. - stopped = true; -} - -// Destructor. -ThreadPool::~ThreadPool() -{ - if (!stopped) - { - ShutDown(); - } -} @@ -1,5 +1,6 @@ #include <ui.hpp> +#include <world.hpp> #include <gametime.hpp> extern Menu* currentMenu; @@ -410,7 +411,7 @@ namespace ui { linc=0, // Contains the number of letters that should be drawn. size=0; // Contains the full size of the current string. - auto tickCount = gtime::getTickCount(); + auto tickCount = game::time::getTickCount(); // reset values if a new string is being passed. if (!linc || ret.substr(0, linc) != str.substr(0, linc)) { @@ -560,8 +561,7 @@ namespace ui { } void waitForCover(void) { - while (fadeIntensity < 255) - mainLoop(); + while (fadeIntensity < 255); fadeIntensity = 255; } @@ -572,33 +572,31 @@ namespace ui { void importantText(const char *text,...) { va_list textArgs; - char *printfbuf; + std::unique_ptr<char[]> printfbuf (new char[512]); dialogBoxText.clear(); - printfbuf = new char[ 512 ]; va_start(textArgs,text); - vsnprintf(printfbuf,512,text,textArgs); + vsnprintf(printfbuf.get(),512,text,textArgs); va_end(textArgs); - dialogBoxText = printfbuf; - delete[] printfbuf; + dialogBoxText = printfbuf.get(); dialogBoxExists = true; dialogImportant = true; + dialogPassive = false; + dialogPassiveTime = 0; } void passiveImportantText(int duration, const char *text, ...) { va_list textArgs; - char *printfbuf; + std::unique_ptr<char[]> printfbuf (new char[512]); dialogBoxText.clear(); - printfbuf = new char[ 512 ]; va_start(textArgs,text); - vsnprintf(printfbuf,512,text,textArgs); + vsnprintf(printfbuf.get(),512,text,textArgs); va_end(textArgs); - dialogBoxText = printfbuf; - delete[] printfbuf; + dialogBoxText = printfbuf.get(); dialogBoxExists = true; dialogImportant = true; @@ -633,8 +631,11 @@ namespace ui { float x,y,tmp; std::string rtext; + auto SCREEN_WIDTH = game::SCREEN_WIDTH; + auto SCREEN_HEIGHT = game::SCREEN_HEIGHT; + // will return if not toggled - action::draw(vec2 {player->loc.x + player->width / 2, player->loc.y + player->height + HLINE}); + action::draw(vec2 {player->loc.x + player->width / 2, player->loc.y + player->height + game::HLINE}); if (pageTexReady) { glEnable(GL_TEXTURE_2D); @@ -648,32 +649,32 @@ namespace ui { glDisable(GL_TEXTURE_2D); } else if (dialogBoxExists) { - - rtext=typeOut(dialogBoxText); + rtext = typeOut(dialogBoxText); if (dialogImportant) { setFontColor(255,255,255); if (dialogPassive) { - dialogPassiveTime -= gtime::getDeltaTime(); + dialogPassiveTime -= game::time::getDeltaTime(); if (dialogPassiveTime < 0) { dialogPassive = false; dialogImportant = false; dialogBoxExists = false; } } + if (fadeIntensity == 255 || dialogPassive) { setFontSize(24); putStringCentered(offset.x,offset.y,rtext); setFontSize(16); } }else if (dialogMerchant) { - x=offset.x-SCREEN_WIDTH/6; - y=(offset.y+SCREEN_HEIGHT/2)-HLINE*8; + x = offset.x - SCREEN_WIDTH / 6; + y = (offset.y + SCREEN_HEIGHT / 2) - HLINES(8); drawBox(vec2 {x, y}, vec2 {x + SCREEN_WIDTH / 3, y - SCREEN_HEIGHT * 0.6f}); // draw typeOut'd text - putString(x + HLINE, y - fontSize - HLINE, (rtext = typeOut(dialogBoxText))); + putString(x + game::HLINE, y - fontSize - game::HLINE, (rtext = typeOut(dialogBoxText))); std::string itemString1 = std::to_string(merchTrade.quantity[0]) + "x", itemString2 = std::to_string(merchTrade.quantity[1]) + "x"; @@ -735,7 +736,7 @@ namespace ui { setFontColor(255, 255, 255); // draw option - dialogOptText[i].second.y = y - SCREEN_HEIGHT / 2 - (fontSize + HLINE) * (i + 1); + dialogOptText[i].second.y = y - SCREEN_HEIGHT / 2 - (fontSize + game::HLINE) * (i + 1); tmp = putStringCentered(offset.x, dialogOptText[i].second.y, dialogOptText[i].first); // get coordinate information on option @@ -753,21 +754,20 @@ namespace ui { setFontColor(255, 255, 255); } else { //normal dialog box - x = offset.x - SCREEN_WIDTH / 2 + HLINE * 8; - y = offset.y + SCREEN_HEIGHT / 2 - HLINE * 8; + x = offset.x - SCREEN_WIDTH / 2 + HLINES(8); + y = offset.y + SCREEN_HEIGHT / 2 - HLINES(8); - drawBox(vec2 {x, y}, vec2 {x + SCREEN_WIDTH - HLINE * 16, y - SCREEN_HEIGHT / 4}); + drawBox(vec2 {x, y}, vec2 {x + SCREEN_WIDTH - HLINES(16), y - SCREEN_HEIGHT / 4}); rtext = typeOut(dialogBoxText); - - putString(x+HLINE,y-fontSize-HLINE,rtext); + putString(x + game::HLINE, y - fontSize - game::HLINE, rtext); for(i=0;i<dialogOptText.size();i++) { setFontColor(255,255,255); tmp = putStringCentered(offset.x,dialogOptText[i].second.y,dialogOptText[i].first); dialogOptText[i].second.z = offset.x + tmp; dialogOptText[i].second.x = offset.x - tmp; - dialogOptText[i].second.y = y - SCREEN_HEIGHT / 4 + (fontSize + HLINE) * (i + 1); + dialogOptText[i].second.y = y - SCREEN_HEIGHT / 4 + (fontSize + game::HLINE) * (i + 1); if (mouse.x > dialogOptText[i].second.x && mouse.x < dialogOptText[i].second.z && mouse.y > dialogOptText[i].second.y && @@ -843,8 +843,8 @@ namespace ui { dialogBoxExists = false; currentMenu = NULL; gameRunning = false; - config::update(); - config::save(); + game::config::update(); + game::config::save(); } void closeBox() { @@ -855,6 +855,9 @@ namespace ui { void dialogAdvance(void) { unsigned char i; + dialogPassive = false; + dialogPassiveTime = 0; + if (pageTex) { glDeleteTextures(1, &pageTex); pageTex = 0; @@ -897,9 +900,6 @@ EXIT: //if (!dialogMerchant)closeBox(); dialogBoxExists = false; dialogMerchant = false; - dialogPassive = false; - - //DONE: // handle important text if (dialogImportant) { @@ -912,6 +912,10 @@ EXIT: static bool left=true,right=false; static int heyOhLetsGo = 0; static int mouseWheelUpCount = 0, mouseWheelDownCount = 0; + + auto SCREEN_WIDTH = game::SCREEN_WIDTH; + auto SCREEN_HEIGHT = game::SCREEN_HEIGHT; + World *tmp; vec2 oldpos,tmppos; SDL_Event e; @@ -1000,7 +1004,7 @@ EXIT: // space - make player jump if (SDL_KEY == SDLK_SPACE) { if (player->ground) { - player->loc.y += HLINE * 2; + player->loc.y += HLINES(2); player->vel.y = .4; player->ground = false; } @@ -1011,7 +1015,7 @@ EXIT: tmp = currentWorld; switch(SDL_KEY) { case SDLK_t: - gtime::tick(50); + game::time::tick(50); break; case SDLK_a: if (fadeEnable)break; @@ -1059,8 +1063,20 @@ EXIT: currentWorld = ((Arena *)currentWorld)->exitArena(player); if (tmp != currentWorld) toggleBlackFast(); - } else if ((tmp = currentWorld->goInsideStructure(player)) != currentWorld) - currentWorld = tmp; + } else { + auto tmpp = currentWorld->goInsideStructure(player); + + if (tmpp.first != currentWorld) { + ui::toggleBlackFast(); + ui::waitForCover(); + + currentWorld = tmpp.first; + if (tmpp.second) + player->loc.x = tmpp.second; + + ui::toggleBlackFast(); + } + } break; case SDLK_LSHIFT: if (debug) { @@ -1077,12 +1093,12 @@ EXIT: // start hover counter? if (!heyOhLetsGo) { - heyOhLetsGo = loops; + heyOhLetsGo = game::time::getTickCount(); player->inv->mouseSel = false; } // run hover thing - if (loops - heyOhLetsGo >= 2 && !(player->inv->invOpen) && !(player->inv->selected)) { + if (game::time::getTickCount() - heyOhLetsGo >= 2 && !(player->inv->invOpen) && !(player->inv->selected)) { player->inv->invHover = true; // enable action ui @@ -1165,7 +1181,7 @@ EXIT: break; case SDLK_l: currentWorld->addLight({player->loc.x + SCREEN_WIDTH/2, player->loc.y},{1.0f,1.0f,1.0f}); - currentWorld->getLastLight()->follow(player); + //currentWorld->getLastLight()->follow(player); currentWorld->getLastLight()->makeFlame(); break; case SDLK_f: @@ -1219,6 +1235,9 @@ EXIT: } void drawFade(void) { + auto SCREEN_WIDTH = game::SCREEN_WIDTH; + auto SCREEN_HEIGHT = game::SCREEN_HEIGHT; + if (!fadeIntensity) { if (fontSize != 16) setFontSize(16); @@ -1279,6 +1298,9 @@ EXIT: } void takeScreenshot(GLubyte* pixels) { + auto SCREEN_WIDTH = game::SCREEN_WIDTH; + auto SCREEN_HEIGHT = game::SCREEN_HEIGHT; + std::vector<GLubyte> bgr (SCREEN_WIDTH * SCREEN_HEIGHT * 3, 0); for(uint x = 0; x < SCREEN_WIDTH*SCREEN_HEIGHT*3; x+=3) { diff --git a/src/ui_action.cpp b/src/ui_action.cpp index 264100d..960b222 100644 --- a/src/ui_action.cpp +++ b/src/ui_action.cpp @@ -1,4 +1,5 @@ #include <ui_action.hpp> +#include <world.hpp> #define ACTION_PROLOUGE { actioning = true; } #define ACTION_EPILOUGE { actioning = false; actionHover = 0; } diff --git a/src/ui_menu.cpp b/src/ui_menu.cpp index 0c7a6d8..09b09c8 100644 --- a/src/ui_menu.cpp +++ b/src/ui_menu.cpp @@ -11,7 +11,7 @@ void Menu::gotoParent(void) { if (!parent) { currentMenu = nullptr; - config::update(); + game::config::update(); } else { currentMenu = parent; } @@ -90,9 +90,9 @@ namespace ui { pauseMenu.items.push_back(ui::menu::createButton({-256/2,-300},{256,75},{0.0f,0.0f,0.0f}, "Segfault", segFault)); pauseMenu.child = &optionsMenu; - optionsMenu.items.push_back(ui::menu::createSlider({0-(float)SCREEN_WIDTH/4,0-(512/2)}, {50,512}, {0.0f, 0.0f, 0.0f}, 0, 100, "Master", &VOLUME_MASTER)); - optionsMenu.items.push_back(ui::menu::createSlider({-200,100}, {512,50}, {0.0f, 0.0f, 0.0f}, 0, 100, "Music", &VOLUME_MUSIC)); - optionsMenu.items.push_back(ui::menu::createSlider({-200,000}, {512,50}, {0.0f, 0.0f, 0.0f}, 0, 100, "SFX", &VOLUME_SFX)); + optionsMenu.items.push_back(ui::menu::createSlider({0-static_cast<float>(game::SCREEN_WIDTH)/4,0-(512/2)}, {50,512}, {0.0f, 0.0f, 0.0f}, 0, 100, "Master", &game::config::VOLUME_MASTER)); + optionsMenu.items.push_back(ui::menu::createSlider({-200,100}, {512,50}, {0.0f, 0.0f, 0.0f}, 0, 100, "Music", &game::config::VOLUME_MUSIC)); + optionsMenu.items.push_back(ui::menu::createSlider({-200,000}, {512,50}, {0.0f, 0.0f, 0.0f}, 0, 100, "SFX", &game::config::VOLUME_SFX)); optionsMenu.parent = &pauseMenu; } @@ -101,10 +101,13 @@ namespace ui { } void draw(void) { + auto SCREEN_WIDTH = game::SCREEN_WIDTH; + auto SCREEN_HEIGHT = game::SCREEN_HEIGHT; + SDL_Event e; setFontSize(24); - config::update(); + game::config::update(); mouse.x = ui::premouse.x+offset.x-(SCREEN_WIDTH/2); mouse.y = (offset.y+SCREEN_HEIGHT/2)-ui::premouse.y; diff --git a/src/world.cpp b/src/world.cpp index c5ed9d0..ab2c908 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -17,17 +17,6 @@ using namespace tinyxml2; /* ---------------------------------------------------------------------------- -** Macros section -** --------------------------------------------------------------------------*/ - -// defines grass height in HLINEs -#define GRASS_HEIGHT 4 - -// indoor world constants -#define INDOOR_FLOOR_THICKNESS 50 -#define INDOOR_FLOOR_HEIGHTT 400 - -/* ---------------------------------------------------------------------------- ** Variables section ** --------------------------------------------------------------------------*/ @@ -39,7 +28,6 @@ extern World *currentWorldToRight; // main.cpp extern bool inBattle; // ui.cpp? extern std::string xmlFolder; - // externally referenced in main.cpp const unsigned int DAY_CYCLE = 12000; int worldShade = 0; @@ -54,6 +42,13 @@ static const float GROUND_HEIGHT_MINIMUM = 60.0f; static const float GROUND_HEIGHT_MAXIMUM = 110.0f; static const float GROUND_HILLINESS = 10.0f; +// defines grass height in HLINEs +static const unsigned int GRASS_HEIGHT = 4; + +// indoor world constants +static const unsigned int INDOOR_FLOOR_THICKNESS = 50; +static const unsigned int INDOOR_FLOOR_HEIGHTT = 400; + // the path of the currently loaded XML file, externally referenced in places std::string currentXML; @@ -61,14 +56,15 @@ std::string currentXML; WorldWeather weather = WorldWeather::Sunny; // keeps track of pathnames of XML file'd worlds the player has left to enter structures -std::vector<std::string> inside; +static std::vector<std::string> inside; // keeps track of information of worlds the player has left to enter arenas static std::vector<World *> battleNest; static std::vector<vec2> battleNestLoc; // pathnames of images for world themes -static const std::string bgPaths[][9] = { +static const unsigned int BG_PATHS_ENTRY_SIZE = 9; +static const std::string bgPaths[][BG_PATHS_ENTRY_SIZE] = { {"bg.png", // Daytime background "bgn.png", // Nighttime background "bgFarMountain.png", // Furthest layer @@ -188,13 +184,12 @@ deleteEntities(void) * object for usage. */ void World:: -generate(unsigned int width) +generate(int width) { - // see below for description/usage float geninc = 0; // check for valid width - if ((int)width <= 0) + if (width <= 0) UserError("Invalid world dimensions"); // allocate space for world @@ -207,30 +202,30 @@ generate(unsigned int width) // give every GROUND_HILLINESSth entry a groundHeight value for (; wditer < std::end(worldData); wditer += GROUND_HILLINESS) - (*(wditer - GROUND_HILLINESS)).groundHeight = (*wditer).groundHeight + (randGet() % 8 - 4); + (*(wditer - GROUND_HILLINESS)).groundHeight = (*wditer).groundHeight + (getRand() % 8 - 4); // create slopes from the points that were just defined, populate the rest of the WorldData structure for (wditer = std::begin(worldData) + 1; wditer < std::end(worldData); wditer++){ auto w = &*(wditer); - if (w->groundHeight) - geninc = ((w + (int)GROUND_HILLINESS)->groundHeight - w->groundHeight) / GROUND_HILLINESS; + if (w->groundHeight != 0) + geninc = ((w + static_cast<int>(GROUND_HILLINESS))->groundHeight - w->groundHeight) / GROUND_HILLINESS; w->groundHeight = fmin(fmax((w - 1)->groundHeight + geninc, GROUND_HEIGHT_MINIMUM), GROUND_HEIGHT_MAXIMUM); - w->groundColor = randGet() % 32 / 8; + w->groundColor = getRand() % 32 / 8; w->grassUnpressed = true; - w->grassHeight[0] = (randGet() % 16) / 3 + 2; - w->grassHeight[1] = (randGet() % 16) / 3 + 2; + w->grassHeight[0] = (getRand() % 16) / 3 + 2; + w->grassHeight[1] = (getRand() % 16) / 3 + 2; } // define x-coordinate of world's leftmost 'line' - worldStart = (width - GROUND_HILLINESS) * HLINE / 2 * -1; + worldStart = (width - GROUND_HILLINESS) * game::HLINE / 2 * -1; // create empty star array, should be filled here as well... star = std::vector<vec2> (100, vec2 { 0, 400 }); for (auto &s : star) { s.x = (getRand() % (-worldStart * 2)) + worldStart; - s.y = (getRand() % SCREEN_HEIGHT) + 100.0f; + s.y = (getRand() % game::SCREEN_HEIGHT) + 100; } } @@ -242,12 +237,16 @@ generate(unsigned int width) void World:: draw(Player *p) { + auto SCREEN_WIDTH = game::SCREEN_WIDTH; + auto SCREEN_HEIGHT = game::SCREEN_HEIGHT; + auto HLINE = game::HLINE; + const ivec2 backgroundOffset = ivec2 { - (int)(SCREEN_WIDTH / 2), (int)(SCREEN_HEIGHT / 2) + static_cast<int>(SCREEN_WIDTH) / 2, static_cast<int>(SCREEN_HEIGHT) / 2 }; - // iterators - int i, iStart, iEnd; + // iterators ranges + int iStart, iEnd; // shade value for draws -- may be unnecessary int shadeBackground = -worldShade; @@ -262,10 +261,10 @@ draw(Player *p) int alpha; // shade value for GLSL - float shadeAmbient = fmax(0, -worldShade / 50.0f + 0.5f); // 0 to 1.5f + float shadeAmbient = std::max(0.0f, static_cast<float>(-worldShade) / 50 + 0.5f); // 0 to 1.5f if (shadeAmbient > 0.9f) - shadeAmbient = 1.0f; + shadeAmbient = 1; // draw background images. glEnable(GL_TEXTURE_2D); @@ -273,8 +272,12 @@ draw(Player *p) // the sunny wallpaper is faded with the night depending on tickCount bgTex->bind(0); switch (weather) { - case WorldWeather::Snowy : alpha = 150; break; - case WorldWeather::Rain : alpha = 0; break; + case WorldWeather::Snowy: + alpha = 150; + break; + case WorldWeather::Rain: + alpha = 0; + break; default: alpha = 255 - worldShade * 4; break; @@ -315,7 +318,7 @@ draw(Player *p) safeSetColorA(150 + shadeBackground * 2, 150 + shadeBackground * 2, 150 + shadeBackground * 2, 255); glBegin(GL_QUADS); { auto xcoord = width / 2 * -1 + offset.x * 0.85f; - for (i = 0; i <= (int)(worldData.size() * HLINE / 1920); i++) { + for (unsigned int i = 0; i <= worldData.size() * HLINE / 1920; i++) { glTexCoord2i(0, 1); glVertex2i(1920 * i + xcoord, GROUND_HEIGHT_MINIMUM); glTexCoord2i(1, 1); glVertex2i(1920 * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM); glTexCoord2i(1, 0); glVertex2i(1920 * (i + 1) + xcoord, GROUND_HEIGHT_MINIMUM + 1080); @@ -323,7 +326,7 @@ draw(Player *p) } } glEnd(); - for (i = 0; i < 4; i++) { + for (unsigned int i = 0; i < 4; i++) { bgTex->bindNext(); safeSetColorA(bgDraw[i][0] + shadeBackground * 2, bgDraw[i][0] + shadeBackground * 2, @@ -353,17 +356,17 @@ draw(Player *p) glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0); glUseProgram(shaderProgram); - std::for_each(std::begin(particles), std::end(particles), [](Particles &p) { + for (auto &p : particles) { if (p.behind) p.draw(); - }); + } glUseProgram(0); for (auto &b : build) { if (b->bsubtype == STALL_MARKET) { for (auto &n : npc) { - if (n->type == MERCHT && ((Merchant *)n)->inside == b) { + if (n->type == MERCHT && static_cast<Merchant *>(n)->inside == b) { n->draw(); break; } @@ -374,15 +377,15 @@ draw(Player *p) for (auto &l : light) { if (l.belongsTo) { - l.loc.x = l.following->loc.x + SCREEN_WIDTH/2; + l.loc.x = l.following->loc.x + SCREEN_WIDTH / 2; l.loc.y = l.following->loc.y; } if (l.flame) { - l.fireFlicker = .9+((rand()%2)/10.0f); - l.fireLoc.x = l.loc.x + (rand()%2-1)*3; - l.fireLoc.y = l.loc.y + (rand()%2-1)*3; + l.fireFlicker = 0.9f + ((rand()% 2 ) / 10.0f); + l.fireLoc.x = l.loc.x + (rand() % 2 - 1) * 3; + l.fireLoc.y = l.loc.y + (rand() % 2 - 1) * 3; } else { - l.fireFlicker = 1.0f; + l.fireFlicker = 1; } } @@ -395,7 +398,7 @@ draw(Player *p) auto pointArray = pointArrayBuf.get(); GLfloat flameArray[64]; - for (uint i = 0; i < light.size(); i++) { + for (unsigned int i = 0; i < light.size(); i++) { if (light[i].flame) { pointArray[2 * i ] = light[i].fireLoc.x - offset.x; pointArray[2 * i + 1] = light[i].fireLoc.y; @@ -405,7 +408,7 @@ draw(Player *p) } } - for (uint i = 0; i < light.size(); i++) + for (unsigned int i = 0; i < light.size(); i++) flameArray[i] = light[i].fireFlicker; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); @@ -415,7 +418,7 @@ draw(Player *p) glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0); glUniform1f(glGetUniformLocation(shaderProgram, "amb"), shadeAmbient); - if (light.size() == 0) + if (light.empty()) glUniform1i(glGetUniformLocation(shaderProgram, "numLight"), 0); else { glUniform1i (glGetUniformLocation(shaderProgram, "numLight"), light.size()); @@ -428,14 +431,14 @@ draw(Player *p) pOffset = (offset.x + p->width / 2 - worldStart) / HLINE; // only draw world within player vision - iStart = (int)fmax(pOffset - (SCREEN_WIDTH / 2 / HLINE) - GROUND_HILLINESS, 0); - iEnd = (int)fmin(pOffset + (SCREEN_WIDTH / 2 / HLINE) + GROUND_HILLINESS + HLINE, worldData.size()); - iEnd = (int)fmax(iEnd, GROUND_HILLINESS); + iStart = static_cast<int>(fmax(pOffset - (SCREEN_WIDTH / 2 / HLINE) - GROUND_HILLINESS, 0)); + iEnd = static_cast<int>(fmin(pOffset + (SCREEN_WIDTH / 2 / HLINE) + GROUND_HILLINESS + HLINE, worldData.size())); + iEnd = static_cast<int>(fmax(iEnd, GROUND_HILLINESS)); // draw the dirt glBegin(GL_QUADS); //std::for_each(std::begin(worldData) + iStart, std::begin(worldData) + iEnd, [&](WorldData wd) { - for (i = iStart; i < iEnd; i++) { + for (int i = iStart; i < iEnd; i++) { if (worldData[i].groundHeight <= 0) { worldData[i].groundHeight = GROUND_HEIGHT_MINIMUM - 1; glColor4ub(0, 0, 0, 255); @@ -465,12 +468,12 @@ draw(Player *p) glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0); safeSetColorA(255, 255, 255, 255); - for (i = iStart; i < iEnd; i++) { + for (int i = iStart; i < iEnd; i++) { auto wd = worldData[i]; auto gh = wd.grassHeight; // flatten the grass if the player is standing on it. - if (!worldData[i].grassUnpressed) { + if (!wd.grassUnpressed) { gh[0] /= 4; gh[1] /= 4; } @@ -520,11 +523,11 @@ draw(Player *p) // flatten grass under the player if the player is on the ground if (p->ground) { - for (i = 0; i < (int)worldData.size(); i++) - worldData[i].grassUnpressed = !(i < pOffset + 6 && i > pOffset - 6); + for (unsigned int i = 0; i < worldData.size(); i++) + worldData[i].grassUnpressed = !(i < static_cast<unsigned int>(pOffset + 6) && i > static_cast<unsigned int>(pOffset - 6)); } else { - for (i = 0; i < (int)worldData.size(); i++) - worldData[i].grassUnpressed = true; + for (auto &wd : worldData) + wd.grassUnpressed = true; } // draw the player @@ -543,7 +546,7 @@ singleDetect(Entity *e) unsigned int i; int l; - auto deltaTime = gtime::getDeltaTime(); + auto deltaTime = game::time::getDeltaTime(); // kill dead entities if (!e->isAlive()) { @@ -576,14 +579,14 @@ singleDetect(Entity *e) break; } - std::cout << "Killed a " << killed << "..." << std::endl; + std::cout << "Killed a " << killed << "...\n"; entity.erase(entity.begin() + i); return; } } // exit on player death - std::cout << "RIP " << e->name << "." << std::endl; + std::cout << "RIP " << e->name << ".\n"; exit(0); } @@ -593,17 +596,15 @@ singleDetect(Entity *e) // forced movement gravity (sword hits) e->handleHits(); - if (e->subtype == MS_TRIGGER) - return; - // calculate the line that this entity is currently standing on - l = (int)fmax((e->loc.x + e->width / 2 - worldStart) / HLINE, 0); - l = (int)fmin(l, lineCount - 1); + l = static_cast<int>(fmax((e->loc.x + e->width / 2 - worldStart) / game::HLINE, 0)); + l = static_cast<int>(fmin(l, lineCount - 1)); // if the entity is under the world/line, pop it back to the surface if (e->loc.y < worldData[l].groundHeight) { int dir = e->vel.x < 0 ? -1 : 1; - if (l + (dir * 2) < (int)worldData.size() && worldData[l + (dir * 2)].groundHeight - 30 > worldData[l + dir].groundHeight) { + if (l + (dir * 2) < static_cast<int>(worldData.size()) && + worldData[l + (dir * 2)].groundHeight - 30 > worldData[l + dir].groundHeight) { e->loc.x -= (PLAYER_SPEED_CONSTANT + 2.7f) * e->speed * 2 * dir; e->vel.x = 0; } else { @@ -629,10 +630,10 @@ singleDetect(Entity *e) // insure that the entity doesn't fall off either edge of the world. if (e->loc.x < worldStart) { e->vel.x = 0; - e->loc.x = worldStart + HLINE / 2; - } else if (e->loc.x + e->width + HLINE > worldStart + worldStart * -2) { + e->loc.x = worldStart + game::HLINE / 2; + } else if (e->loc.x + e->width + game::HLINE > worldStart + worldStart * -2) { e->vel.x = 0; - e->loc.x = worldStart + worldStart * -2 - e->width - HLINE; + e->loc.x = worldStart + worldStart * -2 - e->width - game::HLINE; } } } @@ -659,7 +660,7 @@ detect(Player *p) // handle particles for (auto &part : particles) { // get particle's current world line - l = (int)fmax((part.loc.x + part.width / 2 - worldStart) / HLINE, 0); + l = (int)fmax((part.loc.x + part.width / 2 - worldStart) / game::HLINE, 0); l = (int)fmin(lineCount - 1, l); part.update(GRAVITY_CONSTANT, worldData[l].groundHeight); } @@ -669,10 +670,10 @@ detect(Player *p) switch (b->bsubtype) { case FOUNTAIN: for (unsigned int r = (randGet() % 25) + 11; r--;) { - addParticle(randGet() % HLINE * 3 + b->loc.x + b->width / 2, // x + addParticle(randGet() % HLINES(3) + b->loc.x + b->width / 2, // x b->loc.y + b->height, // y - HLINE * 1.25, // width - HLINE * 1.25, // height + HLINES(1.25), // width + HLINES(1.25), // height randGet() % 7 * .01 * (randGet() % 2 == 0 ? -1 : 1), // vel.x (4 + randGet() % 6) * .05, // vel.y { 0, 0, 255 }, // RGB color @@ -684,9 +685,9 @@ detect(Player *p) case FIRE_PIT: for(unsigned int r = (randGet() % 20) + 11; r--;) { addParticle(randGet() % (int)(b->width / 2) + b->loc.x + b->width / 4, // x - b->loc.y + 3 * HLINE, // y - HLINE, // width - HLINE, // height + b->loc.y + HLINES(3), // y + game::HLINE, // width + game::HLINE, // height randGet() % 3 * .01 * (randGet() % 2 == 0 ? -1 : 1), // vel.x (4 + randGet() % 6) * .005, // vel.y { 255, 0, 0 }, // RGB color @@ -703,11 +704,13 @@ detect(Player *p) // draws the village welcome message if the player enters the village bounds for (auto &v : village) { - if (p->loc.x > v.start.x && p->loc.x < v.end.x && !v.in) { - ui::passiveImportantText(5000, "Welcome to %s", v.name.c_str()); - v.in = true; - } else { - v.in = false; + if (p->loc.x > v.start.x && p->loc.x < v.end.x) { + if (!v.in) { + ui::passiveImportantText(5000, "Welcome to %s", v.name.c_str()); + v.in = true; + } + } else { + v.in = false; } } } @@ -1045,12 +1048,12 @@ goWorldLeft(Player *p) World *tmp; // check if player is at world edge - if (!toLeft.empty() && p->loc.x < worldStart + HLINE * 15.0f) { + if (!toLeft.empty() && p->loc.x < worldStart + HLINES(15)) { // load world (`toLeft` conditional confirms existance) tmp = loadWorldFromPtr(currentWorldToLeft); // adjust player location - p->loc.x = tmp->worldStart + HLINE * 20; + p->loc.x = tmp->worldStart + HLINES(20); p->loc.y = tmp->worldData[tmp->lineCount - 1].groundHeight; return tmp; @@ -1067,10 +1070,10 @@ goWorldRight(Player *p) { World *tmp; - if (!toRight.empty() && p->loc.x + p->width > -worldStart - HLINE * 15) { + if (!toRight.empty() && p->loc.x + p->width > -worldStart - HLINES(15)) { tmp = loadWorldFromPtr(currentWorldToRight); - p->loc.x = tmp->worldStart - HLINE * -15.0f; + p->loc.x = tmp->worldStart - HLINES(-15.0); p->loc.y = GROUND_HEIGHT_MINIMUM; return tmp; @@ -1086,7 +1089,7 @@ bool World:: goWorldLeft(NPC *e) { // check if entity is at world edge - if(!toLeft.empty() && e->loc.x < worldStart + HLINE * 15.0f) { + if(!toLeft.empty() && e->loc.x < worldStart + HLINES(15)) { currentWorldToLeft->addNPC(e->loc.x,e->loc.y); e->die(); @@ -1102,7 +1105,7 @@ goWorldLeft(NPC *e) /** * Attempts to enter a building that the player is standing in front of. */ -World *World:: +std::pair<World *, float> World:: goInsideStructure(Player *p) { World *tmp; @@ -1114,52 +1117,42 @@ goInsideStructure(Player *p) auto b = *d; if ((d == std::end(build)) || b->inside.empty()) - return this; + return std::make_pair(this, 0); // +size cuts folder prefix inside.push_back(¤tXML[xmlFolder.size()]); tmp = loadWorldFromXML(b->inside); - // make the fade, as we let it fade back the worlds should be switched - ui::toggleBlackFast(); - ui::waitForCover(); - ui::toggleBlackFast(); - glClearColor(0, 0, 0, 1); - - return tmp; + return std::make_pair(tmp, 0); } else { std::string current = ¤tXML[xmlFolder.size()]; tmp = loadWorldFromXML(inside.back()); inside.clear(); - Structures *b; - for (auto &s : build) { + Structures *b = nullptr; + for (auto &s : tmp->build) { if (s->inside == current) { b = s; break; } } - //auto b = *std::find_if(std::begin(build), std::end(build), [&](const Structures *s) { - // return (s->inside == current); - //}); - ui::toggleBlackFast(); - ui::waitForCover(); - p->loc.x = b->loc.x + (b->width / 2); - ui::toggleBlackFast(); - glClearColor(1, 1, 1, 1); + if (b == nullptr) + return std::make_pair(this, 0); - return tmp; + return std::make_pair(tmp, b->loc.x + (b->width / 2)); } - return this; + return std::make_pair(this, 0); } -void World::addStructure(BUILD_SUB sub, float x,float y, std::string tex, std::string inside){ +void World:: +addStructure(BUILD_SUB sub, float x,float y, std::string tex, std::string inside) +{ build.push_back(new Structures()); build.back()->inWorld = this; build.back()->textureLoc = tex; - build.back()->spawn(sub,x,y); + build.back()->spawn(sub, x, y); build.back()->inside = inside; entity.push_back(build.back()); } @@ -1171,31 +1164,47 @@ addVillage(std::string name, World *world) return &village.back(); } -void World::addMob(int t,float x,float y){ - mob.push_back(new Mob(t)); - mob.back()->spawn(x,y); +/*void World:: +addMob(int t, float x, float y) +{ + mob.push_back(new new(auto *&t)); + mob.back()->spawn(x, y); + + entity.push_back(mob.back()); +}*/ + +void World::addMob(Mob *m, vec2 coord) +{ + mob.push_back(m); + mob.back()->spawn(coord.x, coord.y); entity.push_back(mob.back()); } -void World::addMob(int t,float x,float y,void (*hey)(Mob *)){ +/*void World:: +addMob(int t, float x, float y, void (*hey)(Mob *)) +{ mob.push_back(new Mob(t)); - mob.back()->spawn(x,y); + mob.back()->spawn(x, y); mob.back()->hey = hey; entity.push_back(mob.back()); -} +}*/ -void World::addNPC(float x,float y){ +void World:: +addNPC(float x, float y) +{ npc.push_back(new NPC()); - npc.back()->spawn(x,y); + npc.back()->spawn(x, y); entity.push_back(npc.back()); } -void World::addMerchant(float x, float y, bool housed){ +void World:: +addMerchant(float x, float y, bool housed) +{ merchant.push_back(new Merchant()); - merchant.back()->spawn(x,y); + merchant.back()->spawn(x, y); if (housed) merchant.back()->inside = build.back(); @@ -1204,7 +1213,9 @@ void World::addMerchant(float x, float y, bool housed){ entity.push_back(npc.back()); } -void World::addObject(std::string in, std::string p, float x, float y){ +void World:: +addObject(std::string in, std::string p, float x, float y) +{ object.emplace_back(in, p); object.back().spawn(x, y); @@ -1343,8 +1354,6 @@ singleDetect(Entity *e) if (!e->isAlive()) return; - if (e->type == MOBT && e->subtype == MS_TRIGGER) - return; for (; floornum < floor.size(); floornum++) { if (floor[floornum][0] + INDOOR_FLOOR_HEIGHTT - 100 > e->loc.y) { @@ -1358,22 +1367,22 @@ singleDetect(Entity *e) } if (e->vel.y > -2) - e->vel.y -= GRAVITY_CONSTANT * gtime::getDeltaTime(); + e->vel.y -= GRAVITY_CONSTANT * game::time::getDeltaTime(); if (e->ground) { e->loc.y = ceil(e->loc.y); e->vel.y = 0; } - start = worldStart + fstart[floornum] * HLINE; - end = start + floor[floornum].size() * HLINE; + start = worldStart + HLINES(fstart[floornum]); + end = start + HLINES(floor[floornum].size()); if (e->loc.x < start) { e->vel.x = 0; - e->loc.x = start + HLINE / 2; - } else if (e->loc.x + e->width + HLINE > end) { + e->loc.x = start + game::HLINE / 2; + } else if (e->loc.x + e->width + game::HLINE > end) { e->vel.x = 0; - e->loc.x = end - e->width - HLINE; + e->loc.x = end - e->width - game::HLINE; } } @@ -1384,6 +1393,10 @@ draw(Player *p) unsigned int i,f; int x; + auto SCREEN_WIDTH = game::SCREEN_WIDTH; + auto SCREEN_HEIGHT = game::SCREEN_HEIGHT; + auto HLINE = game::HLINE; + // draw lights for (auto &l : light) { if (l.belongsTo) { @@ -1456,7 +1469,7 @@ draw(Player *p) for (f = 0; f < floor.size(); f++) { i = 0; for (h : floor[f]) { - x = worldStart + fstart[f] * HLINE + (i * HLINE); + x = worldStart + fstart[f] * HLINE + HLINES(i); glVertex2i(x , h ); glVertex2i(x + HLINE, h ); glVertex2i(x + HLINE, h - INDOOR_FLOOR_THICKNESS); @@ -1491,7 +1504,7 @@ draw(Player *p) Arena::Arena(World *leave,Player *p,Mob *m) { generate(800); - addMob(MS_DOOR,100,100); + addMob(new Door(), vec2 {100, 100}); inBattle = true; mmob = m; @@ -1512,7 +1525,7 @@ World *Arena::exitArena(Player *p) { World *tmp; if (!mmob->isAlive() && p->loc.x + p->width / 2 > mob[0]->loc.x && - p->loc.x + p->width / 2 < mob[0]->loc.x + HLINE * 12) { + p->loc.x + p->width / 2 < mob[0]->loc.x + HLINES(12)) { tmp = battleNest.front(); battleNest.erase(battleNest.begin()); @@ -1527,9 +1540,9 @@ World *Arena::exitArena(Player *p) { mmob->die(); return tmp; - }else{ - return this; } + + return this; } std::string getWorldWeatherStr(WorldWeather ww) @@ -1578,7 +1591,6 @@ World *loadWorldFromPtr(World *ptr) /** * Loads a world from the given XML file. */ - World * loadWorldFromXMLNoSave(std::string path) { XMLDocument xml; @@ -1689,29 +1701,22 @@ loadWorldFromXMLNoSave(std::string path) { } // mob creation - else if (name == "mob") { - // type info - if (wxml->QueryUnsignedAttribute("type", &flooor) != XML_NO_ERROR) - UserError("XML Error: Invalid type value in <mob> in " + currentXML + "!"); - - // spawn at coordinate if desired - if (wxml->QueryFloatAttribute("x", &spawnx) == XML_NO_ERROR) - tmp->addMob(flooor, spawnx, wxml->FloatAttribute("y")); - else - tmp->addMob(flooor, 0, 100); - - // aggressive tag - if (wxml->QueryBoolAttribute("aggressive", &dialog) == XML_NO_ERROR) - tmp->getLastMob()->aggressive = dialog; - - // indoor spawning floor selection - 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->getLastMob()->health = tmp->getLastMob()->maxHealth = spawnx; - } + 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); + } // npc creation else if (name == "npc") { @@ -1754,16 +1759,10 @@ loadWorldFromXMLNoSave(std::string path) { wxml->StrAttribute("texture"), wxml->StrAttribute("inside") ); - } else if (name == "trigger") { - tmp->addMob(MS_TRIGGER, wxml->FloatAttribute("x"), 0, commonTriggerFunc); - tmp->getLastMob()->heyid = wxml->Attribute("id"); - } else if (name == "page") { - tmp->addMob(MS_PAGE, wxml->FloatAttribute("x"), 0, commonPageFunc); - tmp->getLastMob()->heyid = wxml->Attribute("id"); } else if (name == "hill") { tmp->addHill(ivec2 { wxml->IntAttribute("peakx"), wxml->IntAttribute("peaky") }, wxml->UnsignedAttribute("width")); } else if (name == "time") { - gtime::setTickCount(std::stoi(wxml->GetText())); + game::time::setTickCount(std::stoi(wxml->GetText())); } else if (Indoor && name == "floor") { if (wxml->QueryFloatAttribute("start",&spawnx) == XML_NO_ERROR) Indoorp(tmp)->addFloor(wxml->UnsignedAttribute("width"), spawnx); |