aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog14
-rw-r--r--include/common.hpp27
-rw-r--r--include/config.hpp25
-rw-r--r--include/entities.hpp41
-rw-r--r--include/gametime.hpp18
-rw-r--r--include/inventory.hpp3
-rw-r--r--include/mob.hpp88
-rw-r--r--include/threadpool.hpp53
-rw-r--r--include/ui.hpp2
-rw-r--r--include/world.hpp9
-rw-r--r--main.cpp536
-rw-r--r--src/common.cpp75
-rw-r--r--src/config.cpp142
-rw-r--r--src/entities.cpp371
-rw-r--r--src/gameplay.cpp267
-rw-r--r--src/gametime.cpp76
-rw-r--r--src/inventory.cpp11
-rw-r--r--src/items.cpp7
-rw-r--r--src/mob.cpp260
-rw-r--r--src/threadpool.cpp99
-rw-r--r--src/ui.cpp100
-rw-r--r--src/ui_action.cpp1
-rw-r--r--src/ui_menu.cpp13
-rw-r--r--src/world.cpp323
-rw-r--r--xml/playerSpawnHill1.xml7
-rw-r--r--xml/playerSpawnHill1_Building1.xml38
26 files changed, 1119 insertions, 1487 deletions
diff --git a/Changelog b/Changelog
index 2f6b9ce..5e96726 100644
--- a/Changelog
+++ b/Changelog
@@ -924,4 +924,16 @@
- fixed segfaults in inventory
- Andy learned how to use GDB
- - fixed
+
+4/16/2016-
+4/27/2016:
+==========
+
+ - added action menu
+ - freakin rewrote half the code
+ - redid mobs, moved to separate file
+ - library-ized game time stuff
+ - made the game:: namespace
+ - removed threadpool, gameplay
+ - redoing inventory system
+ - added -g flag
diff --git a/include/common.hpp b/include/common.hpp
index 7f36be2..1f7b9fc 100644
--- a/include/common.hpp
+++ b/include/common.hpp
@@ -18,8 +18,7 @@
#include <thread>
#include <mutex>
#include <future>
-#include <math.h>
-#include <threadpool.hpp>
+#include <cmath>
#include <algorithm>
#define GLEW_STATIC
@@ -103,6 +102,10 @@ struct _vec2 {
x = y = n;
return *this;
}
+ template<typename T>
+ const _vec2 operator+(const T &n) {
+ return _vec2 {x + n, y + n};
+ }
};
typedef struct _vec2 vec2;
@@ -149,19 +152,6 @@ typedef col Color;
#define GAME_NAME "Independent Study v0.7 alpha - NOW WITH lights and snow and stuff"
-/**
- * The desired width of the game window.
- */
-
-extern unsigned int SCREEN_WIDTH;
-
-/**
- * The desired height of the game window.
- */
-
-extern unsigned int SCREEN_HEIGHT;
-
-extern bool FULLSCREEN;
extern bool uiLoop;
extern std::mutex mtx;
@@ -175,13 +165,8 @@ extern std::mutex mtx;
*
*/
-#define HLINES(n) (HLINE * n)
-
-extern unsigned int HLINE;
+#define HLINES(n) (game::HLINE * n)
-extern float VOLUME_MASTER;
-extern float VOLUME_MUSIC;
-extern float VOLUME_SFX;
/**
* A 'wrapper' for libc's srand(), as we hope to eventually have our own random number
* generator.
diff --git a/include/config.hpp b/include/config.hpp
index 8bd0bc9..bc9d052 100644
--- a/include/config.hpp
+++ b/include/config.hpp
@@ -1,18 +1,25 @@
#ifndef CONFIG_H
#define CONFIG_H
-#include <iostream>
+#include <string>
-#include <SDL2/SDL_mixer.h>
+namespace game {
+ extern unsigned int HLINE;
+ extern unsigned int SCREEN_WIDTH;
+ extern unsigned int SCREEN_HEIGHT;
+ extern bool FULLSCREEN;
-#include <tinyxml2.h>
-#include <ui.hpp>
+ namespace config {
+ extern float VOLUME_MASTER;
+ extern float VOLUME_MUSIC;
+ extern float VOLUME_SFX;
-
-namespace config {
- void read(void);
- void update(void);
- void save(void);
+ extern std::string xmlFolder;
+
+ void read(void);
+ void update(void);
+ void save(void);
+ }
}
#endif //CONFIG_H
diff --git a/include/entities.hpp b/include/entities.hpp
index 864c863..567380a 100644
--- a/include/entities.hpp
+++ b/include/entities.hpp
@@ -42,19 +42,6 @@ enum GENDER{
};
/**
- * An enumerator for mob types.. 'species'.
- * The subtype of a Mob will affect what texture is used to draw it as well as
- * how the Mob will behave.
- */
-enum MOB_SUB {
- MS_RABBIT = 1, /**< rabbits */
- MS_BIRD, /**< birds */
- MS_TRIGGER, /**< triggers, used to cue cutscenes */
- MS_DOOR, /**< doors, for exiting arenas */
- MS_PAGE /**< pages, cues page overlay */
-};
-
-/**
* An enumerator for strcture types.
* The subtype of a structure will affect how it is drawn and how it functions.
*/
@@ -190,9 +177,6 @@ protected:
// if set false, entity will be destroyed
bool alive;
- // if not null, the entity will move towards this one
- Entity *followee;
-
// TODO
float targetx;
@@ -259,6 +243,7 @@ public:
// allows the entity to wander, according to what class is deriving this.
virtual void wander(int){}
+ virtual void wander(void){}
// allows the entity to interact with the player
virtual void interact(void){}
@@ -360,19 +345,6 @@ public:
void wander(int);
};
-class Mob : public Entity{
-public:
- bool aggressive;
- double init_y;
- void (*hey)(Mob *callee);
- std::string heyid;
-
- Mob(int);
- ~Mob();
-
- void wander(int);
-};
-
class Object : public Entity{
private:
std::string iname;
@@ -424,13 +396,10 @@ public:
void makeFlame(void){
flame = true;
}
-
- void follow(Entity *f){
- following = f;
- belongsTo = true;
- }
};
+#include <mob.hpp>
+
constexpr Object *Objectp(Entity *e) {
return (Object *)e;
}
@@ -443,8 +412,8 @@ constexpr Structures *Structurep(Entity *e) {
return (Structures *)e;
}
-constexpr Mob *Mobp(Entity *e) {
- return (Mob *)e;
+constexpr Merchant *Merchantp(Entity *e) {
+ return (Merchant *)e;
}
#endif // ENTITIES_H
diff --git a/include/gametime.hpp b/include/gametime.hpp
index c2991d2..a809ef9 100644
--- a/include/gametime.hpp
+++ b/include/gametime.hpp
@@ -1,16 +1,18 @@
#ifndef GAMETIME_H_
#define GAMETIME_H_
-namespace gtime {
- void setTickCount(unsigned int t);
- unsigned int getTickCount(void);
- unsigned int getDeltaTime(void);
+namespace game {
+ namespace time {
+ void setTickCount(unsigned int t);
+ unsigned int getTickCount(void);
+ unsigned int getDeltaTime(void);
- void tick(void);
- void tick(unsigned int ticks);
- bool tickHasPassed(void);
+ void tick(void);
+ void tick(unsigned int ticks);
+ bool tickHasPassed(void);
- void mainLoopHandler(void);
+ void mainLoopHandler(void);
+ }
}
#endif // GAMETIME_H_
diff --git a/include/inventory.hpp b/include/inventory.hpp
index a568faf..a41d4d4 100644
--- a/include/inventory.hpp
+++ b/include/inventory.hpp
@@ -26,6 +26,9 @@ public:
// the array of textures for each frame of animation
Texturec *tex;
+ // how much the item is rotated in the hand
+ float rotation = 0.0f;
+
/**
* The function we use to call the child classes ability
* Note: Since this function is abstract, we HAVE to create one for each
diff --git a/include/mob.hpp b/include/mob.hpp
new file mode 100644
index 0000000..9f006b9
--- /dev/null
+++ b/include/mob.hpp
@@ -0,0 +1,88 @@
+#ifndef MOB_H_
+#define MOB_H_
+
+#include <common.hpp>
+#include <entities.hpp>
+#include <gametime.hpp>
+#include <ui.hpp>
+
+// local library headers
+#include <tinyxml2.h>
+using namespace tinyxml2;
+
+extern Player *player;
+extern std::string currentXML;
+
+class Mob : public Entity {
+protected:
+ unsigned int actCounter;
+ unsigned int actCounterInitial;
+public:
+ bool aggressive;
+ std::string heyid;
+
+ ~Mob(void);
+
+ void wander(void);
+ virtual void act(void) =0;
+ virtual bool bindTex(void) =0;
+ virtual void createFromXML(const XMLElement *e) =0;
+};
+
+constexpr Mob *Mobp(Entity *e) {
+ return (Mob *)e;
+}
+
+class Page : public Mob {
+private:
+ std::string pageTexPath;
+public:
+ Page(void);
+
+ void act(void);
+ bool bindTex(void);
+ void createFromXML(const XMLElement *e);
+};
+
+class Door : public Mob {
+public:
+ Door(void);
+
+ void act(void);
+ bool bindTex(void);
+ void createFromXML(const XMLElement *e);
+};
+
+class Rabbit : public Mob {
+public:
+ Rabbit(void);
+
+ void act(void);
+ bool bindTex(void);
+ void createFromXML(const XMLElement *e);
+};
+
+class Bird : public Mob {
+private:
+ float initialY;
+public:
+ Bird(void);
+
+ void act(void);
+ bool bindTex(void);
+ void createFromXML(const XMLElement *e);
+};
+
+class Trigger : public Mob {
+private:
+ std::string id;
+ bool triggered;
+public:
+ Trigger(void);
+
+ void act(void);
+ bool bindTex(void);
+ void createFromXML(const XMLElement *e);
+};
+
+#endif // MOB_H_
diff --git a/include/threadpool.hpp b/include/threadpool.hpp
deleted file mode 100644
index c341673..0000000
--- a/include/threadpool.hpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef THREADPOOL_H
-#define THREADPOOL_H
-
-#include <vector>
-#include <queue>
-#include <thread>
-#include <mutex>
-#include <condition_variable>
-#include <iostream>
-#include <unistd.h>
-
-using namespace std;
-
-class ThreadPool
-{
-public:
-
- // Constructor.
- ThreadPool(int threads);
-
- // Destructor.
- ~ThreadPool();
-
- // Adds task to a task queue.
- void Enqueue(function<void()> f);
-
- // Shut down the pool.
- void ShutDown();
-
-private:
- // Thread pool storage.
- vector<thread> threadPool;
-
- // Queue to keep track of incoming tasks.
- queue<function<void()>> tasks;
-
- // Task queue mutex.
- mutex tasksMutex;
-
- // Condition variable.
- condition_variable condition;
-
- // Indicates that pool needs to be shut down.
- bool terminate;
-
- // Indicates that pool has been terminated.
- bool stopped;
-
- // Function that will be invoked by our threads.
- void Invoke();
-};
-
-#endif //THRE \ No newline at end of file
diff --git a/include/ui.hpp b/include/ui.hpp
index 9e69497..7cee885 100644
--- a/include/ui.hpp
+++ b/include/ui.hpp
@@ -21,10 +21,10 @@
// local game headers
#include <common.hpp>
#include <config.hpp>
+#include <entities.hpp>
#include <inventory.hpp>
#include <ui_menu.hpp>
#include <ui_action.hpp>
-#include <world.hpp>
// local library headers
#include <SDL2/SDL_opengl.h>
diff --git a/include/world.hpp b/include/world.hpp
index c6eaf06..b99e9ab 100644
--- a/include/world.hpp
+++ b/include/world.hpp
@@ -159,7 +159,7 @@ public:
virtual ~World(void);
// generates a world of the specified width
- void generate(unsigned int width);
+ void generate(int width);
// draws everything to the screen
virtual void draw(Player *p);
@@ -220,7 +220,7 @@ public:
bool goWorldLeft(NPC *e);
// attempts to enter a structure that the player would be standing in front of
- World *goInsideStructure(Player *p);
+ std::pair<World *, float> goInsideStructure(Player *p);
// adds a hole at the specified start and end x-coordinates
void addHole(unsigned int start,unsigned int end);
@@ -233,8 +233,9 @@ public:
void addMerchant(float x, float y, bool housed);
- void addMob(int type, float x, float y);
- void addMob(int type, float x, float y, void (*hey)(Mob *));
+ //void addMob(int type, float x, float y);
+ //void addMob(int type, float x, float y, void (*hey)(Mob *));
+ void addMob(Mob *m, vec2 coord);
void addNPC(float x, float y);
diff --git a/main.cpp b/main.cpp
index 329028b..99e8308 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,15 +1,16 @@
-/*! @file main.cpp
- * @brief The file that links everything together for the game to run.
- * The main game loop contains all of the global variables the game uses, and it runs the main game loop, the render loop, and the logic loop that control all of the entities.
- */
-
+/* ----------------------------------------------------------------------------
+** The main file, home of the main loop.
+** --------------------------------------------------------------------------*/
+// ...
+/* ----------------------------------------------------------------------------
+** Includes section
+** --------------------------------------------------------------------------*/
+
+// local library includes
#include <tinyxml2.h>
using namespace tinyxml2;
-/*
- * Game includes
- */
-
+// local game includes
#include <common.hpp>
#include <config.hpp>
#include <entities.hpp>
@@ -17,118 +18,58 @@ using namespace tinyxml2;
#include <ui.hpp>
#include <gametime.hpp>
+/* ----------------------------------------------------------------------------
+** Variables section
+** --------------------------------------------------------------------------*/
+
+// the current weather, declared in world.cpp
+extern WorldWeather weather;
+
// SDL's window object
SDL_Window *window = NULL;
// main loop runs based on this variable's value
-bool gameRunning;
+bool gameRunning = false;
// world objects for the current world and the two that are adjacent
World *currentWorld = NULL,
*currentWorldToLeft = NULL,
*currentWorldToRight = NULL;
+// the currently used folder to grab XML files
+std::string xmlFolder;
+
+// the current menu
Menu *currentMenu;
// the player object
Player *player;
-/**
- * TODO
- */
-
+// shaders for rendering
GLuint fragShader;
-
-/**
- * TODO
- */
-
GLuint shaderProgram;
-/**
- * Threads and various variables to be used when multithreading the game,
- * mutex will prevent multiple threads from changing the same data,
- * and the condition_variable will wait for threads to reach the same point
- */
-
-std::mutex mtx;
-std::condition_variable cv;
-ThreadPool pool(10);
-
-/*
- * loops is used for texture animation. It is believed to be passed to entity
- * draw functions, although it may be externally referenced instead.
-*/
-
-/**
- * TODO
- */
-
+// keeps a simple palette of colors for single-color draws
GLuint colorIndex;
-/**
- * TODO
- */
-
+// the mouse's texture
GLuint mouseTex;
-/**
- * Used for texture animation. It is externally referenced by ui.cpp
- * and entities.cpp.
- */
-
-unsigned int loops = 0;
-
-/**
- * Gives a coordinate based off of the player's location to allow for drawing to
- * be in a constant 'absolute' place on the window.
- */
-
+// the center of the screen
vec2 offset;
-std::string xmlFolder;
-
-extern WorldWeather weather;
-
-unsigned int SCREEN_WIDTH;
-unsigned int SCREEN_HEIGHT;
-unsigned int HLINE;
-bool FULLSCREEN;
-
-float VOLUME_MASTER;
-float VOLUME_MUSIC;
-float VOLUME_SFX;
-
-/**
- * Defined in gameplay.cpp, should result in `currentWorld` containing a pointer
- * to a valid World.
- */
-
-extern void initEverything(void);
-
-/**
- * The game logic function, should handle all logic-related operations for the
- * game.
- */
-
+// handles all logic operations
void logic(void);
-/**
- * The game render function, should handle all drawing to the window.
- */
-
+// handles all rendering operations
void render(void);
-/**
- * The main loop, calls logic(), render(), and does timing operations in the
- * appropriate order.
- */
-
+// takes care of *everything*
void mainLoop(void);
/*******************************************************************************
- * MAIN ************************************************************************
- *******************************************************************************/
+** MAIN ************************************************************************
+********************************************************************************/
int main(int argc, char *argv[]){
(void)argc;
@@ -136,148 +77,73 @@ int main(int argc, char *argv[]){
static SDL_GLContext mainGLContext = NULL;
- gameRunning = false;
-
- /**
- * (Attempt to) Initialize SDL libraries so that we can use SDL facilities and eventually
- * make openGL calls. Exit if there was an error.
- */
-
- if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0){
- std::cout << "SDL was not able to initialize! Error: " << SDL_GetError() << std::endl;
- return -1;
- }
+ // attempt to initialize SDL
+ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
+ UserError(std::string("SDL was not able to initialize! Error: ") + SDL_GetError());
+ atexit(SDL_Quit);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
- // Run SDL_Quit when main returns
- atexit(SDL_Quit);
-
- /**
- * (Attempt to) Initialize SDL_image libraries with IMG_INIT_PNG so that we can load PNG
- * textures for the entities and stuff.
- */
-
- if(!(IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG) & (IMG_INIT_PNG | IMG_INIT_JPG))){
- std::cout << "Could not init image libraries! Error: " << IMG_GetError() << std::endl;
- return -1;
- }
-
- // Run IMG_Quit when main returns
+ // attempt to initialize SDL_image
+ if (!(IMG_Init(IMG_INIT_PNG | IMG_INIT_JPG) & (IMG_INIT_PNG | IMG_INIT_JPG)))
+ UserError(std::string("Could not init image libraries! Error: ") + IMG_GetError());
atexit(IMG_Quit);
- /**
- * (Attempt to) Initialize SDL_mixer libraries for loading and playing music/sound files.
- */
-
- if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0){
- std::cout << "SDL_mixer could not initialize! Error: " << Mix_GetError() << std::endl;
- return -1;
- }
-
+ // attempt to initialize SDL_mixer
+ if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0)
+ UserError(std::string("SDL_mixer could not initialize! Error: ") + Mix_GetError());
Mix_AllocateChannels(8);
-
- config::update();
-
- // Run Mix_Quit when main returns
atexit(Mix_Quit);
- /**
- * Load saved settings into the game (see config/settings.xml)
- */
-
- config::read();
-
- /*
- * Create a window for SDL to draw to. Most parameters are the default, except for the
- * following which are defined in include/common.h:
- *
- * GAME_NAME the name of the game that is displayed in the window title bar
- * SCREEN_WIDTH the width of the created window
- * SCREEN_HEIGHT the height of the created window
- * FULLSCREEN makes the window fullscreen
- *
- */
-
- uint32_t SDL_CreateWindowFlags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | (FULLSCREEN ? SDL_WINDOW_FULLSCREEN : 0);
+ // update values by reading the config file (config/settings.xml)
+ game::config::update();
+ game::config::read();
+ // create the SDL window object
window = SDL_CreateWindow(GAME_NAME,
SDL_WINDOWPOS_UNDEFINED, // Spawn the window at random (undefined) x and y coordinates
SDL_WINDOWPOS_UNDEFINED, //
- SCREEN_WIDTH,
- SCREEN_HEIGHT,
- SDL_CreateWindowFlags
- );
-
- /*
- * Exit if the window cannot be created
- */
-
- if(window==NULL){
- std::cout << "The window failed to generate! SDL_Error: " << SDL_GetError() << std::endl;
- return -1;
- }
-
- /*
- * Create the SDL OpenGL context. Once created, we are allowed to use OpenGL functions.
- * Saving this context to mainGLContext does not appear to be necessary as mainGLContext
- * is never referenced again.
- */
-
- if((mainGLContext = SDL_GL_CreateContext(window)) == NULL){
- std::cout << "The OpenGL context failed to initialize! SDL_Error: " << SDL_GetError() << std::endl;
- return -1;
- }
+ game::SCREEN_WIDTH,
+ game::SCREEN_HEIGHT,
+ SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | (game::FULLSCREEN ? SDL_WINDOW_FULLSCREEN : 0)
+ );
- /*
- * Initialize GLEW libraries, and exit if there was an error.
- * Not sure what they're for yet.
- */
+ if (window == NULL)
+ UserError(std::string("The window failed to generate! SDL_Error: ") + SDL_GetError());
- GLenum err;
+ // create the OpenGL object that SDL provides
+ if ((mainGLContext = SDL_GL_CreateContext(window)) == NULL)
+ UserError(std::string("The OpenGL context failed to initialize! SDL_Error: ") + SDL_GetError());
+
+ // initialize GLEW
#ifndef __WIN32__
glewExperimental = GL_TRUE;
#endif
- if((err=glewInit()) != GLEW_OK){
- std::cout << "GLEW was not able to initialize! Error: " << glewGetErrorString(err) << std::endl;
- return -1;
- }
- /*
- * Initialize the random number generator. At the moment, initRand is a macro pointing to libc's
- * srand, and its partner getRand points to rand. This is because having our own random number
- * generator may be favorable in the future, but at the moment is not implemented.
- */
+ GLenum err;
+ if ((err = glewInit()) != GLEW_OK)
+ UserError(std::string("GLEW was not able to initialize! Error: ") + reinterpret_cast<const char *>(glewGetErrorString(err)));
+ // start the random number generator
initRand(millis());
- /*
- * Do some basic setup for openGL. Enable double buffering, switch to by-pixel coordinates,
- * setup the alpha channel for textures/transparency, and finally hide the system's mouse
- * cursor so that we may draw our own.
- */
-
+ // 'basic' OpenGL setup
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- SDL_GL_SetSwapInterval(0);
-
- glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
-
+ SDL_GL_SetSwapInterval(0); // v-sync
+ SDL_ShowCursor(SDL_DISABLE); // hide the mouse
+ glViewport(0, 0, game::SCREEN_WIDTH, game::SCREEN_HEIGHT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glClearColor(1,1,1,1);
- SDL_ShowCursor(SDL_DISABLE);
-
+ // TODO
Texture::initColorIndex();
- /*
- * Initializes our shaders so that the game has shadows.
- */
-
- std::cout << "Initializing shaders!" << std::endl;
+ // initialize shaders
+ std::cout << "Initializing shaders!\n";
const GLchar *shaderSource = readFile("frig.frag");
-
GLint bufferln = GL_FALSE;
int logLength;
@@ -316,48 +182,50 @@ int main(int argc, char *argv[]){
*/
initInventorySprites();
+ // load mouse texture, and other inventory textures
+ mouseTex = Texture::loadTexture("assets/mouse.png");
- /*
- * Create all the worlds, entities, mobs, and the player. This function is defined in
- * src/gameplay.cpp
- */
- initEverything();
+ // read in all XML file names in the folder
+ std::vector<std::string> xmlFiles;
+ if (xmlFolder.empty())
+ xmlFolder = "xml/";
+ if (getdir(std::string("./" + xmlFolder).c_str(), xmlFiles))
+ UserError("Error reading XML files!!!");
- if(!currentWorld){
- std::cout<<"currentWorld == NULL!"<<std::endl;
-#ifndef __WIN32__
- system("systemctl poweroff");
-#else
- system("shutdown -s -t 0");
-#endif // __WIN32__
- abort();
+ // alphabetically sort files
+ strVectorSortAlpha(&xmlFiles);
+
+ // load the first valid XML file for the world
+ for (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;
+ }
}
+ // spawn the player
+ player = new Player();
+ player->sspawn(0,100);
+ ui::menu::init();
+ currentWorld->bgmPlay(NULL);
- mouseTex = Texture::loadTexture("assets/mouse.png");
+ // make sure the world was made
+ if (currentWorld == NULL)
+ UserError("Plot twist: The world never existed...?");
/**************************
**** GAMELOOP ****
**************************/
- std::cout << "Num threads: " << std::thread::hardware_concurrency() << std::endl;
-
- glClearColor(1,1,1,1);
- //ui::toggleBlackFast();
-
+ // the main loop, in all of its gloriousness..
gameRunning = true;
while (gameRunning)
mainLoop();
- /**************************
- **** CLOSE PROGRAM ****
- **************************/
-
- /*
- * Close the window and free resources
- */
-
+ // free library resources
Mix_HaltMusic();
Mix_CloseAudio();
@@ -368,6 +236,12 @@ int main(int argc, char *argv[]){
SDL_GL_DeleteContext(mainGLContext);
SDL_DestroyWindow(window);
+ // close up the game stuff
+ currentWorld->save();
+ //delete currentWorld;
+ //delete[] currentXML;
+ //aipreload.clear();
+
return 0; // Calls everything passed to atexit
}
@@ -384,7 +258,7 @@ void mainLoop(void){
static unsigned int debugDiv=0; // A divisor used to update the debug menu if it's open
World *prev;
- gtime::mainLoopHandler();
+ game::time::mainLoopHandler();
if (currentMenu)
goto MENU;
@@ -398,16 +272,16 @@ void mainLoop(void){
ui::dialogBoxExists = false;
}
- if (gtime::tickHasPassed())
+ if (game::time::tickHasPassed())
logic();
- currentWorld->update(player, gtime::getDeltaTime());
+ currentWorld->update(player, game::time::getDeltaTime());
currentWorld->detect(player);
if (++debugDiv == 20) {
debugDiv=0;
- fps = 1000 / (gtime::getDeltaTime() + .000001);
+ fps = 1000 / game::time::getDeltaTime();
if (!(debugDiv % 10))
debugY = player->loc.y;
}
@@ -416,74 +290,33 @@ MENU:
}
void render() {
+ auto SCREEN_WIDTH = game::SCREEN_WIDTH;
+ auto SCREEN_HEIGHT = game::SCREEN_HEIGHT;
- /*
- * This offset variable is what we use to move the camera and locked
- * objects on the screen so they always appear to be in the same relative area
- */
-
+ // offset should contain the coordinates of the center of the player's view
offset.x = player->loc.x + player->width/2;
offset.y = SCREEN_HEIGHT/2;
- /*
- * If the camera will go off of the left or right of the screen we want to lock it so we can't
- * see past the world render
- */
-
- if(currentWorld->getTheWidth() < (int)SCREEN_WIDTH){
+ // snap the player's view if we're at a world edge
+ if (currentWorld->getTheWidth() < (int)SCREEN_WIDTH) {
offset.x = 0;
- }else{
- if(player->loc.x - SCREEN_WIDTH/2 < currentWorld->getTheWidth() * -0.5f)
+ } else {
+ if (player->loc.x - SCREEN_WIDTH/2 < currentWorld->getTheWidth() * -0.5f)
offset.x = ((currentWorld->getTheWidth() * -0.5f) + SCREEN_WIDTH / 2) + player->width / 2;
- if(player->loc.x + player->width + SCREEN_WIDTH/2 > currentWorld->getTheWidth() * 0.5f)
+ if (player->loc.x + player->width + SCREEN_WIDTH/2 > currentWorld->getTheWidth() * 0.5f)
offset.x = ((currentWorld->getTheWidth() * 0.5f) - SCREEN_WIDTH / 2) - player->width / 2;
}
if(player->loc.y > SCREEN_HEIGHT/2)
offset.y = player->loc.y + player->height;
- /*
- * These functions run everyloop to update the current stacks presets
- *
- * Matrix ---- A matrix is a blank "canvas" for the renderer to draw on,
- * this canvas can be rotated, scales, skewed, etc..
- *
- * Stack ---- A stack is exactly what it sounds like, it is a stack.. A
- * stack is a "stack" of matrices for the renderer to draw on.
- * Each stack can be made up of varying amounts of matricies.
- *
- * glMatrixMode This changes our current stacks mode so the drawings below
- * it can take on certain traits.
- *
- * GL_PROJECTION This is the matrix mode that sets the cameras position,
- * GL_PROJECTION is made up of a stack with two matrices which
- * means we can make up to 2 seperate changes to the camera.
- *
- * GL_MODELVIEW This matrix mode is set to have the dimensions defined above
- * by GL_PROJECTION so the renderer can draw only what the camera
- * is looking at. GL_MODELVIEW has a total of 32 matrices on it's
- * stack, so this way we can make up to 32 matrix changes like,
- * scaling, rotating, translating, or flipping.
- *
- * glOrtho glOrtho sets our ortho, or our cameras resolution. This can also
- * be used to set the position of the camera on the x and y axis
- * like we have done. The glOrtho must be set while the stack is in
- * GL_PROJECTION mode, as this is the mode that gives the
- * camera properties.
- *
- * glPushMatrix This creates a "new" matrix. What it really does is pull a matrix
- * off the bottom of the stack and puts it on the top so the renderer
- * can draw on it.
- *
- * glLoadIdentity This scales the current matrix back to the origin so the
- * translations are seen normally on a stack.
- */
-
+ // "setup"
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
- // glOrtho((offset.x-SCREEN_WIDTH/2),(offset.x+SCREEN_WIDTH/2),(offset.y-SCREEN_HEIGHT/2),(offset.y+SCREEN_HEIGHT/2),-1,1);
- glOrtho(floor(offset.x-SCREEN_WIDTH/2),floor(offset.x+SCREEN_WIDTH/2),floor(offset.y-SCREEN_HEIGHT/2),floor(offset.y+SCREEN_HEIGHT/2),20,-20);
+ glOrtho(floor(offset.x - SCREEN_WIDTH / 2), floor(offset.x + SCREEN_WIDTH / 2),
+ floor(offset.y - SCREEN_HEIGHT / 2), floor(offset.y + SCREEN_HEIGHT / 2),
+ 20, -20);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
@@ -502,35 +335,17 @@ void render() {
glPushAttrib(GL_DEPTH_BUFFER_BIT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- /**************************
- **** RENDER STUFF HERE ****
- **************************/
-
- /*
- * 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; // Draw the player's name
-
+ // draw the world
+ player->near = true; // allow player's name to be drawn
currentWorld->draw(player);
- /*
- * Draw the player's inventory.
- */
-
+ // draw the player's inventory
player->inv->draw();
- /*
- * Here we draw a black overlay if it's been requested.
- */
-
+ // draw the fade overlay
ui::drawFade();
- /*
- * Draw UI elements. This includes the player's health bar and the dialog box.
- */
-
+ // draw ui elements
ui::draw();
/*
@@ -538,9 +353,7 @@ void render() {
*/
if(ui::debug){
-
- ui::putText(offset.x-SCREEN_WIDTH/2,
- (offset.y+SCREEN_HEIGHT/2)-ui::fontSize,
+ ui::putText(offset.x-SCREEN_WIDTH/2, (offset.y+SCREEN_HEIGHT/2)-ui::fontSize,
"fps: %d\ngrounded:%d\nresolution: %ux%u\nentity cnt: %d\nloc: (%+.2f, %+.2f)\nticks: %u\nvolume: %f\nweather: %s",
fps,
player->ground,
@@ -549,35 +362,20 @@ void render() {
currentWorld->entity.size(),// Size of entity array
player->loc.x, // The player's x coordinate
debugY, // The player's y coordinate
- gtime::getTickCount(),
- VOLUME_MASTER,
+ game::time::getTickCount(),
+ game::config::VOLUME_MASTER,
getWorldWeatherStr(weather).c_str()
);
if (ui::posFlag) {
glBegin(GL_LINES);
- /*glColor3ub(255,0,0);
- glVertex2i(0,0);
- glVertexdw2i(0,SCREEN_HEIGHT);*/
-
- /*glColor3ub(255,255,255);
- glVertex2i(player->loc.x + player->width/2,0);
- glVertex2i(player->loc.x + player->width/2,SCREEN_HEIGHT);
- glVertex2i(offset.x - SCREEN_WIDTH / 2, player->loc.y + player->height / 2);
- glVertex2i(offset.x + SCREEN_WIDTH / 2, player->loc.y + player->height / 2);*/
-
- /*glVertex2i(-SCREEN_WIDTH / 2 + offset.x, player->loc.y);
- glVertex2i( SCREEN_WIDTH / 2 + offset.x, player->loc.y);*/
-
glColor3ub(100,100,255);
for (auto &e : currentWorld->entity) {
glVertex2i(player->loc.x + player->width / 2, player->loc.y + player->height / 2);
glVertex2i(e->loc.x + e->width / 2, e->loc.y + e->height / 2);
}
-
glEnd();
}
-
}
if (currentMenu)
@@ -589,16 +387,13 @@ void render() {
glBindTexture(GL_TEXTURE_2D, mouseTex);
glBegin(GL_QUADS);
glTexCoord2f(0,0);glVertex2i(ui::mouse.x ,ui::mouse.y );
- glTexCoord2f(1,0);glVertex2i(ui::mouse.x+HLINE*5 ,ui::mouse.y );
- glTexCoord2f(1,1);glVertex2i(ui::mouse.x+HLINE*5 ,ui::mouse.y-HLINE*5 );
- glTexCoord2f(0,1);glVertex2i(ui::mouse.x ,ui::mouse.y-HLINE*5 );
+ glTexCoord2f(1,0);glVertex2i(ui::mouse.x+HLINES(5) ,ui::mouse.y );
+ glTexCoord2f(1,1);glVertex2i(ui::mouse.x+HLINES(5) ,ui::mouse.y-HLINES(5) );
+ glTexCoord2f(0,1);glVertex2i(ui::mouse.x ,ui::mouse.y-HLINES(5) );
glEnd();
glDisable(GL_TEXTURE_2D);
- /**************************
- **** END RENDERING ****
- **************************/
-
+ // wrap up
glPopMatrix();
SDL_GL_SwapWindow(window);
}
@@ -649,60 +444,32 @@ void logic(){
}
} else if (e->type == MOBT) {
e->near = player->isNear(*e);
-
- switch (e->subtype) {
- case MS_RABBIT:
- case MS_BIRD:
- e->wander((rand()%240 + 15));
- break;
- case MS_TRIGGER:
- case MS_PAGE:
- e->wander(0);
- break;
- case MS_DOOR:
- break;
- default:
- std::cout<<"Unhandled mob of subtype "<<e->subtype<<"."<<std::endl;
- break;
- }
+ e->wander();
}
}
- /*
- * Switch between day and night (SUNNY and DARK) if necessary.
- */
-
- if (!(gtime::getTickCount() % DAY_CYCLE) || !gtime::getTickCount()){
+ // switch from day to night?
+ auto tickCount = game::time::getTickCount();
+ if (!(tickCount % DAY_CYCLE) || !tickCount){
if (weather == WorldWeather::Sunny)
weather = WorldWeather::Dark;
- else {
+ else
weather = WorldWeather::Sunny;
- Mix_Pause(2);
- }
}
- /*
- * Calculate an in-game shading value (as opposed to GLSL shading).
- */
-
- worldShade = 50 * sin((gtime::getTickCount() + (DAY_CYCLE / 2)) / (DAY_CYCLE / PI));
-
- /*
- * Transition to and from black if necessary.
- */
+ // calculate the world shading value
+ worldShade = 50 * sin((tickCount + (DAY_CYCLE / 2)) / (DAY_CYCLE / PI));
+ // update fades
ui::fadeUpdate();
- /*
- * Rain?
- */
-
+ // create weather particles if necessary
if (weather == WorldWeather::Rain) {
for (unsigned int r = (randGet() % 25) + 11; r--;) {
currentWorld->addParticle(randGet() % currentWorld->getTheWidth() - (currentWorld->getTheWidth() / 2),
- offset.y + SCREEN_HEIGHT / 2,
- HLINE * 1.25, // width
- HLINE * 1.25, // height
+ offset.y + game::SCREEN_HEIGHT / 2,
+ 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
@@ -713,9 +480,9 @@ void logic(){
} else if (weather == WorldWeather::Snowy) {
for (unsigned int r = (randGet() % 25) + 11; r--;) {
currentWorld->addParticle(randGet() % currentWorld->getTheWidth() - (currentWorld->getTheWidth() / 2),
- offset.y + SCREEN_HEIGHT / 2,
- HLINE * 1.25, // width
- HLINE * 1.25, // height
+ offset.y + game::SCREEN_HEIGHT / 2,
+ HLINES(1.25), // width
+ HLINES(1.25), // height
.0001 + randGet() % 7 * .01 * (randGet() % 2 == 0 ? -1 : 1), // vel.x
(4 + randGet() % 6) * -.03, // vel.y
{ 255, 255, 255 }, // RGB color
@@ -725,11 +492,8 @@ void logic(){
}
}
- /*
- * Increment a loop counter used for animating sprites.
- */
-
- loops++;
- gtime::tick();
- NPCSelected=false; // See above
+ // increment game ticker
+ game::time::tick();
+ NPCSelected = false;
+ ObjectSelected = false;
}
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();
- }
-}
diff --git a/src/ui.cpp b/src/ui.cpp
index 6465730..48c260b 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -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(&currentXML[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 = &currentXML[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);
diff --git a/xml/playerSpawnHill1.xml b/xml/playerSpawnHill1.xml
index dac5160..d4691a5 100644
--- a/xml/playerSpawnHill1.xml
+++ b/xml/playerSpawnHill1.xml
@@ -7,9 +7,10 @@
<hill peakx="0" peaky="1000" width="50" />
- <mob x="300" type="1" aggressive="false" health="100" />
+ <rabbit x="300" aggressive="true" health="100" />
+ <bird />
- <!--<trigger x="-300" id="Test" />-->
+ <trigger x="-300" id="Test" />
<npc name="Ralph" hasDialog="true" x="300" />
<npc name="Johnny" hasDialog="false" x="300" />
@@ -17,7 +18,7 @@
<page x="-200" id="assets/door.png" />
- <village name="Swaggggggggggggg">
+ <village name="Swagville U.S.A.">
<structure type="0" x="-300" inside="playerSpawnHill1_Building1.xml"/>
<structure type="5" x="-500" />
<stall type="market" texture="assets/style/classic/stall.png">
diff --git a/xml/playerSpawnHill1_Building1.xml b/xml/playerSpawnHill1_Building1.xml
index 381f160..0cf04c1 100644
--- a/xml/playerSpawnHill1_Building1.xml
+++ b/xml/playerSpawnHill1_Building1.xml
@@ -32,44 +32,6 @@
<text id="4">
Have a sword though.
<give id="Wood Sword" count="1"/>
- <give id="Wood Sword2" count="1"/>
- <give id="Wood Sword3" count="1"/>
- <give id="Wood Sword4" count="1"/>
- <give id="Wood Sword5" count="1"/>
- <give id="Wood Sword6" count="1"/>
- <give id="Wood Sword7" count="1"/>
- <give id="Wood Sword8" count="1"/>
- <give id="Wood Sword9" count="1"/>
- <give id="Wood Sword10" count="1"/>
- <give id="Wood Sword11" count="1"/>
- <give id="Wood Sword12" count="1"/>
- <give id="Wood Sword13" count="1"/>
- <give id="Wood Sword14" count="1"/>
- <give id="Wood Sword15" count="1"/>
- <give id="Wood Sword16" count="1"/>
- <give id="Wood Sword17" count="1"/>
- <give id="Wood Sword18" count="1"/>
- <give id="Wood Sword19" count="1"/>
- <give id="Wood Sword20" count="1"/>
- <give id="Wood Sword21" count="1"/>
- <give id="Wood Sword22" count="1"/>
- <give id="Wood Sword23" count="1"/>
- <give id="Wood Sword24" count="1"/>
- <give id="Wood Sword25" count="6"/>
- <give id="Wood Sword26" count="1"/>
- <give id="Wood Sword27" count="1"/>
- <give id="Wood Sword28" count="1"/>
- <give id="Wood Sword29" count="1"/>
- <give id="Wood Sword30" count="1"/>
- <give id="Wood Sword31" count="1"/>
- <give id="Wood Sword32" count="1"/>
- <give id="Wood Sword33" count="1"/>
- <give id="Wood Sword34" count="1"/>
- <give id="Wood Sword35" count="1"/>
- <give id="Wood Sword36" count="1"/>
- <give id="Wood Sword37" count="1"/>
- <give id="Wood Sword38" count="1"/>
- <give id="Wood Sword39" count="1"/>
</text>
</Dialog>