diff options
author | drumsetmonkey <abelleisle@roadrunner.com> | 2016-03-21 08:17:06 -0400 |
---|---|---|
committer | drumsetmonkey <abelleisle@roadrunner.com> | 2016-03-21 08:17:06 -0400 |
commit | 51c6e601c3d6451294506b72213244e3aee9822f (patch) | |
tree | ff811ba8bec3c207eacd126f6e5e3764abca8a70 | |
parent | bbdc924d409f74594bd8c8b0d4bf55d5e5f32209 (diff) | |
parent | 8dae5eeac2c6254bb8288c0479c193ab185a312f (diff) |
Created currency and new inventory
-rw-r--r-- | .gitattributes | 2 | ||||
-rw-r--r-- | Changelog | 74 | ||||
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | assets/pages/gootaGoFast.png | bin | 20663 -> 20631 bytes | |||
-rw-r--r-- | config/items.h | 45 | ||||
-rw-r--r-- | config/quest_list.txt | 1 | ||||
-rw-r--r-- | include/Texture.h | 2 | ||||
-rw-r--r-- | include/ui.h | 4 | ||||
-rw-r--r-- | include/world.h | 221 | ||||
-rw-r--r-- | main.cpp | 13 | ||||
-rw-r--r-- | src/entities.cpp | 22 | ||||
-rw-r--r-- | src/gameplay.cpp | 18 | ||||
-rw-r--r-- | src/inventory.cpp | 10 | ||||
-rw-r--r-- | src/ui.cpp | 182 | ||||
-rw-r--r-- | src/world.cpp | 170 | ||||
-rw-r--r-- | xml/playerSpawnHill1.xml | 28 | ||||
-rw-r--r-- | xml/playerSpawnHill1_Building1.xml | 12 | ||||
-rw-r--r-- | xml/playerSpawnHill2.xml | 4 |
18 files changed, 427 insertions, 382 deletions
diff --git a/.gitattributes b/.gitattributes index b98fd9b..7bb2418 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,6 @@ +include/tinyxml2.h linguist-vendored src/tinyxml2.cpp linguist-vendored src/threadpool.cpp linguist-vendored -include/tinyxml2.h linguist-vendored include/threadpool.h linguist-vendored include/SDL2/* linguist-vendored include/freetype/* linguist-vendored @@ -44,7 +44,7 @@ - successfully ran game 200 entities - improved debug screen - added mouse interaction w/ NPCs - + 9/30/2015: ========== @@ -54,10 +54,10 @@ - began work on giving names to NPCs - began working on config file - created a bug file - + - added displaying of entity names on mouse hover - found more fonts - + 10/1/2015: ========== @@ -125,20 +125,20 @@ - fixed delaying quest assignments until dialog is closed - checked and secured errors in malloc/calloc calls - + 10/19/2015: =========== - fixed malloc/strlen bug that crashes the game on some linux systems - broke andy's linux system on his laptop, allowing for test game build on Windows - began extensive documentation in main.cpp - + 10/20/2015: =========== - andy's laptop 'can' boot - added 200+ lines of documentation to main.cpp - + 10/21/2015: =========== @@ -156,14 +156,14 @@ - successfully build game on 32-bit Windows (game crashes on execution) - removed npc array; NPCs are now created in the entity array - created a basic texture handling library - + 10/23/2015: =========== - fixed entity initialization - added multiple mobs - improved texture handling - + 10/26/2015: =========== @@ -231,7 +231,7 @@ - added typewriter-esque text drawing - documented ui.h - continued work on GLSL shaders - + 11/4/2015: ========== @@ -266,7 +266,7 @@ - added drawing/handling of entities on all layers at all times - removed building entering/exiting - andy broke SDL cuz he's bad - + 11/10/2015: =========== @@ -296,7 +296,7 @@ - minor bug fixes - began working on arenas - began working on cutscene triggers - + 11/17/2015: =========== @@ -317,7 +317,7 @@ - texture loaded tracks loaded textures to prevent re-loading (frees resources) - continued work on things finished the following day (11/20) :) - + 11/20/2015: =========== @@ -408,7 +408,7 @@ - imrpoved BGM handling - continued work on particles, made a fountain - added sanic - + ~ Broke 5000 lines of code/doc, now with some file Doxygen'd 12/14/2015: @@ -488,21 +488,21 @@ - can save NPCs and Structures - more shadering - + 1/6/2016: ========= - flashlight! - XML-scripted worlds!!! - !!!!!!!!!!!!!!!!!!!!!!!! - + 1/7/2016: ========= - xml'd npc and mob spawning - xml'd npc dialogs - drafted page xml - + 1/11/2016: ========== @@ -518,7 +518,7 @@ - xml'ing indoors - shaderssss - more music - + 1/13/2016: ========== @@ -533,7 +533,7 @@ - pondered on non-random generation - fixed some drawing issues - made spritesheet for easier solid-color-texture drawing - + - began to incorporate XML into the world class for dynamic world loading... 1/16/2016: @@ -587,7 +587,7 @@ - wrote paper regarding what we've learned, and where we're at - ported game to Windows, left EXE and DLLs in repo - + 2/1/2016: ========= @@ -632,7 +632,7 @@ - partially fixed text drawing - XML'd quest checking, working on quest requirements - worked on XML'ing villages - + 2/9/2016: ========= @@ -673,7 +673,7 @@ - mob deaths are saved - fixed building spawning - volumes are better - + ~ 5 month Changelog anniversary!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 2/23/2016: @@ -741,7 +741,7 @@ - arenas work - cleaned up world codes - andy got here - + ~ Total of 7,379 lines of code! 3/8/2016: @@ -749,3 +749,33 @@ - fixed world draw shadings - improved merchant menu + +3/9/2016: +========= + + - pages are XMLable and can be drawn + - dialogs are cool with threads + - better lighting + +3/14/2016: +========== + + - began implementing hills in worlds + - more inventory stuffs + +3/15/2016: +========== + + - finished hills, fixed hill collision physics + - fixed player repositioning when switching worlds + - XML'd tickCount setting + - even more inventory stuffs (side panes) + +3/16/2016: +========== + + - cleaned up world and ui functions (std::string'ing) + - oh so more inventory stuffs (animations) + - planned ahead + + ~ set finish date for game engine: 3/31 @@ -38,6 +38,7 @@ cleandata: $(EXEC): $(CXXOUTDIR)/$(CXXOBJ) main.cpp @echo " CXX/LD main" @$(CXX) $(CXXFLAGS) $(CXXINC) $(CXXWARN) -o $(EXEC) main.cpp out/*.o $(LIBS) + @rm -rf xml/*.dat $(CXXOUTDIR)/%.o: $(CXXSRCDIR)/%.cpp @echo " CXX " $< diff --git a/assets/pages/gootaGoFast.png b/assets/pages/gootaGoFast.png Binary files differindex a113f5d..639c0f0 100644 --- a/assets/pages/gootaGoFast.png +++ b/assets/pages/gootaGoFast.png diff --git a/config/items.h b/config/items.h deleted file mode 100644 index ee1024c..0000000 --- a/config/items.h +++ /dev/null @@ -1,45 +0,0 @@ - -ID DEBUG_ITEM - NAME "Debug" - TYPE TOOL - WIDTH 1 - HEIGHT 1 - STACKSIZE 1 - TEX "assets/items/ITEM_TEST.png" - ENI - -ID TEST_ITEM - NAME "Dank MayMay" - TYPE TOOL - WIDTH HLINE*10 - HEIGHT HLINE*10 - STACKSIZE 420 - TEX "assets/items/ITEM_TEST.png" - ENI - -ID PLAYER_BAG - NAME "Your Bag" - TYPE EQUIP - WIDTH HLINE*5 - HEIGHT HLINE*5 - STACKSIZE 1 - TEX "assets/items/ITEM_TEST.png" - ENI - -ID FLASHLIGHT - NAME "Flashlight" - TYPE TOOL - WIDTH HLINE*4 - HEIGHT HLINE*8 - STACKSIZE 1 - TEX "assets/items/flashlight_off.png" - ENI - -ID SWORD_WOOD - NAME "Wood Sword" - TYPE SWORD - WIDTH HLINE*4 - HEIGHT HLINE*10 - STACKSIZE 1 - TEX "assets/items/SWORD_WOOD.png" - STOP diff --git a/config/quest_list.txt b/config/quest_list.txt deleted file mode 100644 index 484a2cc..0000000 --- a/config/quest_list.txt +++ /dev/null @@ -1 +0,0 @@ -TITLE "Test" DESC "A test quest" REWARD 1 x SWORD_WOOD END diff --git a/include/Texture.h b/include/Texture.h index 7201a4c..816a8bf 100644 --- a/include/Texture.h +++ b/include/Texture.h @@ -20,7 +20,7 @@ * Texture functions are given a namespace for better organization. */ -namespace Texture{ +namespace Texture { /** * Loads a texture from the given file name, returning the GLuint used for diff --git a/include/ui.h b/include/ui.h index a4fed3e..2a7518f 100644 --- a/include/ui.h +++ b/include/ui.h @@ -131,12 +131,11 @@ namespace ui { void setFontSize(unsigned int size); void setFontColor(unsigned char r,unsigned char g,unsigned char b, unsigned char a); - /* * Draw a centered string. */ - float putStringCentered(const float x,const float y,const char *s); + float putStringCentered(const float x,const float y,std::string s); /* * Draws a formatted string at the given coordinates. @@ -156,6 +155,7 @@ namespace ui { void closeBox(); void waitForDialog(void); + void drawPage( std::string path ); /* * Draws a larger string in the center of the screen. Drawing is done inside this function. */ diff --git a/include/world.h b/include/world.h index 2290b18..a2469ff 100644 --- a/include/world.h +++ b/include/world.h @@ -1,6 +1,6 @@ /** @file world.h * @brief The world system. - * + * * This file contains the classes and variables necessary to create an in-game * world. */ @@ -96,7 +96,7 @@ public: vec2 end; bool in; std::vector<Structures *> build; - + Village(const char *meme, World *w); ~Village(void){} }; @@ -107,112 +107,118 @@ public: class World { protected: + /** * The line array. + * * This array is created through 'new' in World::generate(), with an amount * of elements provided by the function. */ - + std::vector<WorldData> worldData; - + /** * Starting x coordinate. + * * This x value is the point at which line[0] should reside, can be used to * calculate the width of the world. */ - + int worldStart; - + /** * Handle physics for a single entity. + * * This function handles gravity and death for an entity. The public version * of this, World::detect(), handles all entities in the world as well as * the player. World::singleDetect() should never be used outside of * World::detect(), which is why it is declared private. */ - - void singleDetect(Entity *e); - + + void singleDetect( Entity *e ); + /** * Empties all entity vectors. + * * Each entity vector is iterated through, calling delete for each entry. * Once all specific vectors are cleared, the general entity vector is * emptied of the pointers to those other vectors. This function should only * be called in World's destructor, as there shouldn't be another reason to * call this function. */ - - void deleteEntities(void); - + + void deleteEntities( void ); + /** * Number of lines in the world. + * * While this number is helpful for knowing the world's width, it is kept * private for security reasons. To compensate for this, * World::getTheWidth() is provided (see below). */ - + unsigned int lineCount; - + /** * An array of star coordinates. */ - + std::vector<vec2> star; - + /** * The Texturec object that holds the background sprites for this world. */ - + Texturec *bgTex; /** * Defines the set of background images that should be used for this world. */ - + WorldBGType bgType; - + /** * The Mix_Music object that holds the background soundtrack for the world. */ - + Mix_Music *bgmObj; - + /** * The file path of the song wished to be loaded by bgmObj. */ - + std::string bgm; - - std::vector<std::string>bgFiles; - std::vector<std::string>bgFilesIndoors; - + + std::vector<std::string> bgFiles; + std::vector<std::string> bgFilesIndoors; + public: /** * The filename of the XML file for the world to the left; NULL if no world * is present. */ - - char *toLeft; - + + std::string toLeft; + /** * The filename of the XML file for the world to the right; NULL if no world * is present. */ - - char *toRight; - + + std::string toRight; + /** * Sets what XML file to use for loading the world to the left. */ - - char *setToLeft(const char *file); - + + std::string setToLeft( std::string file ); + /** * Sets what XML file to use for loading the world to the right. */ - - char *setToRight(const char *file); + + std::string setToRight( std::string file ); /** * A vector of pointers to every NPC, Structure, Mob, and Object in this @@ -227,38 +233,38 @@ public: std::vector<NPC *> npc; std::vector<Merchant *> merchant; - + /** * A vector of all Structures in this world. */ - + std::vector<Structures *> build; - + /** * A vector of all Mobs in this world. */ - + std::vector<Mob *> mob; - + /** * A vector of all Objects in this world. */ - + std::vector<Object *> object; - + /** * A vector of all particles in this world. */ - + std::vector<Particles> particles; - - + + std::vector<Village *> village; - + /** * A vector of all light elements in this world. */ - + std::vector<Light> light; /** @@ -266,168 +272,175 @@ public: */ std::vector<std::string> sTexLoc; - + /** * NULLifies pointers and allocates necessary memory. This should be * followed by some combination of setBackground(), setBGM(), or * generate(). */ - + World( void ); - + /** * Frees resources taken by the world. */ - + virtual ~World(void); - + /** * Adds a structure to the world, with the specified subtype and * coordinates. `inside` is a file name for the IndoorWorld XML file that * this structure will lead to; if NULL the player won't be able to enter * the structure. */ - + void addStructure(BUILD_SUB subtype,float x,float y, std::string tex, std::string inside); - + /** * Adds a Mob to the world with the specified type and coordinates. */ - + void addMob(int type,float x,float y); - + /** * Adds a Mob to the world with a handler function that can be called by * certain mobs to trigger events. */ - + void addMob(int t,float x,float y,void (*hey)(Mob *)); - + /** * Adds an NPC to the world with the specified coordinates. */ - + void addNPC(float x,float y); - + /** * Adds a Merchant to the world at the specified coordinates. */ - + void addMerchant(float x, float y); - + /** * Adds an object to the world with the specified item id and coordinates. * If `pickupDialog` is not NULL, that string will display in a dialog box * upon object interaction. */ - + void addObject( std::string in, std::string pickupDialog, float x, float y); - + /** * Adds a particle to the world with the specified coordinates, dimensions, * velocity, color and duration (time to live). */ - + void addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int duration); - + /** * Adds a light to the world with the specified coordinates and color. */ - + void addLight(vec2 xy, Color color); - + /** * Updates the coordinates of everything in the world that has coordinates * and a velocity. The provided delta time is used for smoother updating. */ - - void update(Player *p,unsigned int delta); - + + void update( Player *p, unsigned int delta ); + /** * Generate a world of the provided width. Worlds are drawn centered on the * y-axis, so the reachable coordinates on the world would be from negative * half-width to positive half-width. */ - + virtual void generate(unsigned int width); - + /** * Sets the background theme, collecting the required textures into a * Texturec object. */ - + void setBackground(WorldBGType bgt); - + /** * Sets the background music for the world, required for the world to be * playable. */ - + void setBGM(std::string path); /** * Sets the worlds style folder */ - void setStyle(std::string pre); - + void setStyle(std::string pre); + /** * Plays/stops this world's BGM. If `prev` is not NULL, that world's BGM * will be faded out followed by the fading in of this world's BGM. */ - + void bgmPlay(World *prev) const; - + /** * Draw the world and entities based on the player's coordinates. */ virtual void draw(Player *p); - + /** * Handles collision between the entities and the world, as well as entity * death. */ - + void detect(Player *p); - + /** * Attempts to let the player enter the left-linked world specified by * `toLeft`. Returns the world to the left if the movement is possible, * otherwise returns this world. */ - + World *goWorldLeft(Player *p); - + /** * Attempts to let the player enter the right-linked world specified by * `toRight`. Returns the world to the right if the movement is possible, * otherwise returns this world. */ - + World *goWorldRight(Player *p); - + /** * This function looks for any structure the player is standing in front of * that also have an inside world. Returns the inside world if those * conditions are met, otherwise returns this world. */ - + World *goInsideStructure(Player *p); - + /** * Adds a hole between the specified y coordinates. If the player falls in * this hole the game will exit. */ - + void addHole(unsigned int start,unsigned int end); - - /* - * Get's the world's width. + + /** + * Adds a hill to the world, given the peak's coordinates and how wide the + * hill can be. */ - + + void addHill( ivec2 peak, unsigned int width ); + + /** + * Gets the world's width. + */ + int getTheWidth(void) const; - + void save(void); void load(void); }; @@ -435,19 +448,19 @@ public: /* * IndoorWorld - Indoor settings stored in a World class */ - + class IndoorWorld : public World { public: IndoorWorld(void); ~IndoorWorld(void); - + void generate(unsigned int width); // Generates a flat world of width 'width' void draw(Player *p); // Draws the world (ignores layers) }; /** * The arena class - creates an arena. - * + * * This world, when created, expects a pointer to a Mob. This mob will be * transported to a temporary world with the player, and the Mob will be * killed upon exiting the arena. @@ -470,18 +483,18 @@ public: */ Arena( World *leave, Player *p, Mob *m ); - + /** * Frees resources taken by the arena. */ - + ~Arena( void ); - + /** * Attempts to exit the world, returning the player to the world they were * last in. */ - + World *exitArena( Player *p ); }; @@ -415,9 +415,8 @@ int main(int argc, char *argv[]){ //currentWorld->mob.back()->followee = player; gameRunning = true; - while(gameRunning){ - mainLoop(); - } + + while(gameRunning)mainLoop(); /************************** **** CLOSE PROGRAM **** @@ -431,7 +430,7 @@ int main(int argc, char *argv[]){ Mix_CloseAudio(); destroyInventory(); - ui::destroyFonts(); + ui::destroyFonts(); Texture::freeTextures(); SDL_GL_DeleteContext(mainGLContext); @@ -499,8 +498,7 @@ void mainLoop(void){ /*pool.Enqueue([](){ currentWorld->update(player,deltaTime); });*/ - - currentWorld->update(player,deltaTime); + currentWorld->update( player, deltaTime ); /* * Update debug variables if necessary @@ -511,7 +509,7 @@ void mainLoop(void){ if ( deltaTime ) fps = 1000 / deltaTime; - else if(!(debugDiv%10)) + if(!(debugDiv % 10)) debugY = player->loc.y; } MENU: @@ -790,7 +788,6 @@ void logic(){ currentWorld->addParticle(rand()%HLINE*3 + n->loc.x - .05f,n->loc.y + n->height*.5, HLINE,HLINE, -(rand()%10)*.01,((rand()%10)*.01-.05), {(rand()%75)+10/100.0f,0,0}, 10000); } } - /* * Don't bother handling the NPC if another has already been handled. */ diff --git a/src/entities.cpp b/src/entities.cpp index 6d0f052..c047eff 100644 --- a/src/entities.cpp +++ b/src/entities.cpp @@ -581,17 +581,19 @@ void Mob::wander(int timeRun){ 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 ){ - Arena *a = new Arena(currentWorld,player,this); - a->setStyle(""); - a->setBackground( WorldBGType::Forest ); - a->setBGM("assets/music/embark.wav"); + 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(); + ui::toggleWhiteFast(); + YAYA = true; + ui::waitForCover(); + YAYA = false; + currentWorld = a; + ui::toggleWhiteFast(); + } } switch(subtype){ diff --git a/src/gameplay.cpp b/src/gameplay.cpp index 7d52629..075aec3 100644 --- a/src/gameplay.cpp +++ b/src/gameplay.cpp @@ -9,7 +9,6 @@ using namespace tinyxml2; extern Player *player; // main.cpp extern World *currentWorld; // main.cpp -extern float shit; extern Menu *currentMenu; extern Menu pauseMenu; extern Menu optionsMenu; @@ -23,7 +22,7 @@ std::vector<XMLElement *> dopt; void destroyEverything(void); -void segFault(){ +inline void segFault() { (*((int *)NULL))++; } @@ -210,6 +209,21 @@ CONT: return 0; } +void commonPageFunc( Mob *callee ) +{ + static bool lock = false; + + if ( !lock ) { + lock = true; + + ui::drawPage( callee->heyid ); + ui::waitForDialog(); + + callee->alive = false; + lock = false; + } +} + void commonTriggerFunc(Mob *callee){ static bool lock = false; XMLDocument xml; diff --git a/src/inventory.cpp b/src/inventory.cpp index 1390719..7ba5909 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -143,12 +143,12 @@ const char *getItemTexturePath(std::string name){ } GLuint getItemTexture(std::string name){ - for(auto &i : itemMap){ - if(i->name == name) - return Texture::loadTexture(i->texloc); + for ( int i = itemMap.size(); i--; ) { + if ( itemMap[i]->name == name ) + return itemtex[i]; } - - return Texture::loadTexture("assets/items/ITEM_TEST.png"); + DEBUG_printf("Failed to find texture for item %s!", name.c_str() ); + return 0; } float getItemWidth(std::string name){ @@ -6,7 +6,7 @@ #define SDL_KEY e.key.keysym.sym -extern std::vector<menuItem>optionsMenu; +extern std::vector<menuItem> optionsMenu; extern SDL_Window *window; @@ -82,6 +82,8 @@ Mix_Chunk *battleStart; Mix_Chunk *sanic; +static GLuint pageTex = 0; + void Menu::gotoParent(){ if(parent == NULL){ currentMenu = NULL; @@ -126,7 +128,6 @@ namespace ui { int fontTransInv = 255; - /* * Dialog stuff that needs to be 'public'. */ @@ -323,11 +324,9 @@ namespace ui { * Draw a string at the specified coordinates. */ - float putString(const float x,const float y,const char *s){ + float putString( const float x, const float y, std::string s ) { unsigned int i=0; - float xo=x,yo=y; - vec2 add; - //vec2 off = { (float)floor(x), (float)floor(y) }; + vec2 add, o = {x, y}; /* * Loop on each character: @@ -335,57 +334,67 @@ namespace ui { do{ if(i && ((i / 110.0) == (i / 110))){ - yo-=fontSize*1.05; - xo=x; + o.y -= fontSize * 1.05f; + o.x = x; if(s[i] == ' ') i++; } + if(i && (i / (float)textWrapLimit == i / textWrapLimit)){ - yo -= fontSize * 1.05; - xo = x; + o.y -= fontSize * 1.05f; + o.x = x; // skip a space if it's there since we just newline'd if(s[i] == ' ') i++; } - if(s[i] == '\n'){ - yo-=fontSize*1.05; - xo=x; - }else if(s[i] == '\r' || s[i] == '\t'){ - /*if(s[i] == '\n'){ - yo-=fontSize*1.05; - xo=x; - */}else if(s[i]==' '){ // Handle spaces - xo+=fontSize/2; - }else if(s[i]=='\b'){ // Handle backspaces? - xo-=add.x; - }else{ - add=putChar(floor(xo),floor(yo),s[i]); - xo+=add.x; - yo+=add.y; + + switch ( s[i] ) { + case '\n': + o.y -= fontSize * 1.05f; + o.x = x; + break; + case '\r': + break; + case '\t': + break; + case '\b': + o.x -= add.x; + break; + case ' ': + o.x += fontSize / 2; + break; + default: + add = putChar( floor(o.x), floor(o.y), s[i] ); + o.x += add.x; + o.y += add.y; + break; } + }while(s[++i]); - return xo; // i.e. the string width + return o.x; // i.e. the string width } - float putStringCentered(const float x,const float y,const char *s){ + float putStringCentered( const float x, const float y, std::string s ) { unsigned int i = 0; float width = 0; - do{ - if(s[i]=='\n'){ // Handle newlines + do { + switch ( s[i] ) { + case '\n': // TODO - }else if(s[i]==' '){ // Handle spaces - width+=fontSize/2; - }else if(s[i]=='\b'){ // Handle backspaces? - // Why? - // Cuz - }else{ - width+=ftexwh[i].x+fontSize*.1; + break; + case '\b': + break; + case ' ': + width += fontSize / 2; + break; + default: + width += ftexwh[i].x + fontSize * 0.1f; + break; } - }while(s[++i]); - + } while(s[++i]); putString(floor(x-width/2),y,s); return width; } @@ -395,28 +404,18 @@ namespace ui { * to this function. Passing a different string to the function will reset the counters. */ - static char *ret = NULL; - char *typeOut(char *str){ + std::string ret; + std::string typeOut(char *str){ static unsigned int sinc, // Acts as a delayer for the space between each character. linc=0, // Contains the number of letters that should be drawn. size=0; // Contains the full size of the current string. - //static char *ret = NULL; - - /* - * Create a well-sized buffer if we haven't yet. - */ - - if(!ret){ - ret = new char[512]; //(char *)calloc(512,sizeof(char)); - memset(ret,0,512*sizeof(char)); - } /* * Reset values if a new string is being passed. */ - if(strncmp(ret,str,linc-1)){ - memset(ret,0,512); // Zero the buffer + if(strncmp(ret.c_str(),str,linc-1)){ + ret.clear(); // Zero the buffer size=strlen(str); // Set the new target string size linc=0; // Reset the incrementers sinc=1; @@ -432,7 +431,7 @@ namespace ui { else if(++sinc==2){ sinc=0; - strncpy(ret+linc,str+linc,1); // Get next character + ret.append( 1, *(str + linc) ); if(linc<size) linc++; @@ -542,8 +541,7 @@ namespace ui { dialogBoxExists = true; dialogImportant = false; - if(ret) - ret[0] = '\0'; + ret.clear(); } @@ -604,9 +602,7 @@ namespace ui { dialogMerchant = true; textWrapLimit = 50; - // kill the string created by typeOut if it contains something - if(ret) - *ret = '\0'; + ret.clear(); } void merchantBox(){ @@ -669,12 +665,28 @@ namespace ui { } + void drawPage( std::string path ) { + pageTex = Texture::loadTexture( path ); + } + void draw(void){ unsigned char i; float x,y,tmp; - char *rtext; + std::string rtext; + + if ( pageTex ) { - if(dialogBoxExists){ + glEnable( GL_TEXTURE_2D); + glBindTexture( GL_TEXTURE_2D, pageTex ); + glBegin( GL_QUADS ); + glTexCoord2i( 0, 0 ); glVertex2i( offset.x - 300, SCREEN_HEIGHT - 100 ); + glTexCoord2i( 1, 0 ); glVertex2i( offset.x + 300, SCREEN_HEIGHT - 100 ); + glTexCoord2i( 1, 1 ); glVertex2i( offset.x + 300, SCREEN_HEIGHT - 600 ); + glTexCoord2i( 0, 1 ); glVertex2i( offset.x - 300, SCREEN_HEIGHT - 600 ); + glEnd(); + glDisable( GL_TEXTURE_2D); + + } else if (dialogBoxExists){ rtext=typeOut(dialogBoxText); @@ -690,7 +702,7 @@ namespace ui { } if(fadeIntensity == 255 || dialogPassive){ setFontSize(24); - putStringCentered(offset.x,offset.y,rtext); + putStringCentered(offset.x,offset.y,rtext.c_str()); setFontSize(16); } }else if(dialogMerchant){ @@ -702,11 +714,11 @@ namespace ui { glColor3ub(255,255,255); glBegin(GL_LINE_STRIP); - glVertex2f(x-1 ,y+1); + glVertex2f(x-1 ,y+1); glVertex2f(x+1+(SCREEN_WIDTH/3),y+1); glVertex2f(x+1+(SCREEN_WIDTH/3),y-1-SCREEN_HEIGHT*.6); glVertex2f(x-1,y-1-SCREEN_HEIGHT*.6); - glVertex2f(x-1,y+1); + glVertex2f(x - 1,y+1); glEnd(); glColor3ub(0,0,0); @@ -832,9 +844,8 @@ namespace ui { setFontColor(255,255,255); } - if(strcmp(rtext,dialogBoxText)){ + if ( rtext != dialogBoxText ) Mix_PlayChannel(1,dialogClick,0); - } }if(!fadeIntensity){ vec2 hub = { @@ -1230,6 +1241,13 @@ namespace ui { void dialogAdvance(void){ unsigned char i; + + if ( pageTex ) { + glDeleteTextures( 1, &pageTex ); + pageTex = 0; + return; + } + if(!typeOutDone){ typeOutDone = true; return; @@ -1299,7 +1317,7 @@ namespace ui { // mouse clicks case SDL_MOUSEBUTTONDOWN: // right click advances dialog - if ( ( e.button.button & SDL_BUTTON_RIGHT ) && dialogBoxExists ) + if ( ( e.button.button & SDL_BUTTON_RIGHT ) && (dialogBoxExists | pageTex) ) dialogAdvance(); // left click uses item if ( ( e.button.button & SDL_BUTTON_LEFT ) && !dialogBoxExists ) @@ -1344,7 +1362,7 @@ namespace ui { player->right = false; left = true; right = false; - if(currentWorld->toLeft){ + if ( !currentWorld->toLeft.empty() ) { oldpos = player->loc; if((tmp = currentWorld->goWorldLeft(player)) != currentWorld){ tmppos = player->loc; @@ -1366,7 +1384,7 @@ namespace ui { player->left = false; left = false; right = true; - if(currentWorld->toRight){ + if ( !currentWorld->toRight.empty() ) { oldpos = player->loc; if((tmp = currentWorld->goWorldRight(player)) != currentWorld){ tmppos = player->loc; @@ -1384,37 +1402,17 @@ namespace ui { case SDLK_s: break; case SDLK_w: - if(inBattle){ + if ( inBattle ) { tmp = currentWorld; - currentWorld = ((Arena *)currentWorld)->exitArena(player); - if(tmp != currentWorld){ - //delete &tmp; + currentWorld = ((Arena *)currentWorld)->exitArena( player ); + if ( tmp != currentWorld ) toggleBlackFast(); - } - }else{ - if((tmp = currentWorld->goInsideStructure(player)) != currentWorld) + } else if( (tmp = currentWorld->goInsideStructure( player )) != currentWorld ) currentWorld = tmp; - } break; case SDLK_i: - /*currentWorld=currentWorld->goWorldBack(player); // Go back a layer if possible - if(tmp!=currentWorld){ - currentWorld->detect(player); - player->vel.y=.2; - player->loc.y+=HLINE*5; - player->ground=false; - }*/ player->health -= 5; break; - case SDLK_k: - /*currentWorld=currentWorld->goWorldFront(player); // Go forward a layer if possible - if(tmp!=currentWorld){ - currentWorld->behind->detect(player); - player->vel.y=.2; - player->loc.y+=HLINE*5; - player->ground=false; - }*/ - break; case SDLK_LSHIFT: if(debug){ Mix_PlayChannel(1,sanic,-1); diff --git a/src/world.cpp b/src/world.cpp index c31f551..b1eb12e 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -23,7 +23,8 @@ using namespace tinyxml2; extern Player *player; // main.cpp? extern World *currentWorld; // main.cpp extern int commonAIFunc(NPC *); // entities.cpp -extern void commonTriggerFunc(Mob *); // entities.cpp +extern void commonTriggerFunc(Mob *); // gameplay.cpp +extern void commonPageFunc(Mob *); // gameplay.cpp extern bool inBattle; extern unsigned int tickCount; // main.cpp @@ -150,9 +151,6 @@ World:: World( void ) { bgmObj = NULL; - - toLeft = NULL; - toRight = NULL; } /** @@ -220,10 +218,6 @@ World:: Mix_FreeMusic(bgmObj); delete bgTex; - - delete[] toLeft; - delete[] toRight; - deleteEntities(); } @@ -308,6 +302,11 @@ update( Player *p, unsigned int delta ) p->loc.y += p->vel.y * delta; p->loc.x +=(p->vel.x * p->speed) * delta; + if ( p->loc.y > 5000 ) { + std::cout << "Too high for me m8." << std::endl; + abort(); + } + // update entity coords for ( auto &e : entity ) { e->loc.y += e->vel.y * delta; @@ -772,22 +771,28 @@ singleDetect( Entity *e ) if ( e->loc.y < worldData[i].groundHeight ) { - e->loc.y= worldData[i].groundHeight - .001 * deltaTime; - e->ground=true; - e->vel.y=0; + if ( worldData[i].groundHeight - e->loc.y > 30 ) { + int dir = e->vel.x > 0 ? -1 : 1; + e->loc.x += HLINE * 8 * dir; + e->loc.y = worldData[i + 8 * dir].groundHeight; + } else { + e->loc.y = worldData[i].groundHeight - .001 * deltaTime; + e->ground = true; + e->vel.y = 0; + } /* * Handle gravity if the entity is above the line. */ }else{ - if(e->type == STRUCTURET && e->loc.y > 2000){ e->loc.y = worldData[i].groundHeight; e->vel.y = 0; e->ground = true; return; - }else if(e->vel.y > -2)e->vel.y-=.003 * deltaTime; + } else if ( e->vel.y > -2 ) + e->vel.y -= .003 * deltaTime; } @@ -962,30 +967,23 @@ addParticle( float x, float y, float w, float h, float vx, float vy, Color color void World::addLight(vec2 loc, Color color){ Light l; - if(light.size() < 64){ + if ( light.size() < 64 ) { l.loc = loc; l.color = color; light.push_back(l); } } -char *World::setToLeft(const char *file){ - if(toLeft) - delete[] toLeft; - if(!file) - return (toLeft = NULL); - - strcpy((toLeft = new char[strlen(file) + 1]),file); - return toLeft; +std::string World:: +setToLeft( std::string file ) +{ + return (toLeft = file); } -char *World::setToRight(const char *file){ - if(toRight) - delete[] toRight; - if(!file) - return (toRight = NULL); - - strcpy((toRight = new char[strlen(file) + 1]),file); - return toRight; + +std::string World:: +setToRight( std::string file ) +{ + return (toRight = file); } //what is this clyne why are they differnet @@ -994,32 +992,36 @@ goWorldLeft( Player *p ) { World *tmp; - // check if player is at world edge - if(toLeft && p->loc.x < worldStart + HLINE * 15.0f){ + // check if player is at world edge + if( !toLeft.empty() && p->loc.x < worldStart + HLINE * 15.0f ) { - // load world (`toLeft` conditional confirms existance) + // load world (`toLeft` conditional confirms existance) tmp = loadWorldFromXML(toLeft); - // adjust player location - p->loc.x = -tmp->worldStart - (int)HLINE * -10.0f; + // adjust player location + p->loc.x = tmp->worldStart + HLINE * 20; p->loc.y = tmp->worldData[tmp->lineCount - 1].groundHeight; return tmp; } + return this; } -World *World::goWorldRight(Player *p){ +World *World:: +goWorldRight( Player *p ) +{ World *tmp; - if(toRight && p->loc.x + p->width > -worldStart - HLINE * 15){ + if( !toRight.empty() && p->loc.x + p->width > -worldStart - HLINE * 15 ) { tmp = loadWorldFromXML(toRight); - p->loc.x = tmp->worldStart + (int)HLINE * 10; + p->loc.x = tmp->worldStart - HLINE * -15.0f; p->loc.y = GROUND_HEIGHT_MINIMUM; return tmp; } + return this; } @@ -1027,14 +1029,19 @@ World *World:: goInsideStructure( Player *p ) { World *tmp; - char *current; - if(inside.empty()){ - for(auto &b : build){ - if(p->loc.x > b->loc.x && - p->loc.x + p->width < b->loc.x + b->width ){ - inside.push_back((std::string)(currentXML.c_str() + 4)); + std::string current; + + if ( inside.empty() ) { + for ( auto &b : build ) { + if ( p->loc.x > b->loc.x && + p->loc.x + p->width < b->loc.x + b->width ) { - tmp = loadWorldFromXML(b->inside.c_str()); + if ( b->inside.empty() ) + return this; + + inside.push_back(currentXML.c_str() + 4); + + tmp = loadWorldFromXML( b->inside ); ui::toggleBlackFast(); ui::waitForCover(); @@ -1043,11 +1050,11 @@ goInsideStructure( Player *p ) return tmp; } } - }else{ - strcpy((current = new char[strlen((const char *)(currentXML.c_str() + 4)) + 1]),(const char *)(currentXML.c_str() + 4)); - tmp = loadWorldFromXML(inside.back().c_str()); - for(auto &b : tmp->build){ - if(!strcmp(current,b->inside.c_str())){ + } else { + current = currentXML.c_str() + 4; + tmp = loadWorldFromXML( inside.back() ); + for ( auto &b : tmp->build ) { + if ( current == b->inside ) { inside.pop_back(); ui::toggleBlackFast(); @@ -1060,15 +1067,37 @@ goInsideStructure( Player *p ) return tmp; } } - delete[] current; } + return this; } -void World::addHole(unsigned int start,unsigned int end){ - unsigned int i; - for(i=start;i<end;i++){ +void World:: +addHole( unsigned int start, unsigned int end ) +{ + for ( unsigned int i = end; i-- > start; ) worldData[i].groundHeight = 0; +} + +void World:: +addHill( const ivec2 peak, const unsigned int width ) +{ + int start = peak.x - width / 2, end = start + width, offset; + const float thing = peak.y - worldData[start].groundHeight; + const float period = PI / width; + + if ( start < 0 ) { + offset = -start; + start = 0; + } + + if ( end > (signed)worldData.size() ) + end = worldData.size(); + + for ( int i = start; i < end; i++ ) { + worldData[i].groundHeight += thing * sin((i - start + offset) * period); + if ( worldData[i].groundHeight > peak.y ) + worldData[i].groundHeight = peak.y; } } @@ -1081,38 +1110,32 @@ getTheWidth( void ) const void World::save(void){ std::string data; - std::cout << "Setting save" << std::endl; std::string save = (std::string)currentXML + ".dat"; std::ofstream out (save,std::ios::out | std::ios::binary); std::cout<<"Saving to "<<save<<" ..."<<std::endl; - std::cout << "Saving npcs" << std::endl; for(auto &n : npc){ data.append(std::to_string(n->dialogIndex) + "\n"); data.append(std::to_string((int)n->loc.x) + "\n"); data.append(std::to_string((int)n->loc.y) + "\n"); } - std::cout << "Saving buildings" << std::endl; for(auto &b : build){ data.append(std::to_string((int)b->loc.x) + "\n"); data.append(std::to_string((int)b->loc.y) + "\n"); } - std::cout << "Saving mobs" << std::endl; for(auto &m : mob){ data.append(std::to_string((int)m->loc.x) + "\n"); data.append(std::to_string((int)m->loc.y) + "\n"); data.append(std::to_string((int)m->alive) + "\n"); } - std::cout << "Ending file" << std::endl; data.append("dOnE\0"); std::cout << "Writing to the file" << std::endl; out.write(data.c_str(),data.size()); - std::cout << "Closing file" << std::endl; out.close(); std::cout << "Done saving" << std::endl; } @@ -1374,18 +1397,18 @@ loadWorldFromXMLNoSave( std::string path ) { while(wxml){ name = wxml->Name(); - if(name == "link"){ + if ( name == "link" ) { if((ptr = wxml->Attribute("left"))) tmp->setToLeft(ptr); else if((ptr = wxml->Attribute("right"))) tmp->setToRight(ptr); else abort(); - }else if(name == "style"){ + } else if ( name == "style" ) { tmp->setStyle(wxml->StrAttribute("folder")); tmp->setBackground((WorldBGType)wxml->UnsignedAttribute("background")); tmp->setBGM(wxml->StrAttribute("bgm")); - }else if(name == "generation"){ + } else if ( name == "generation" ) { if(!strcmp(wxml->Attribute("type"),"Random")){ if(Indoor) ((IndoorWorld *)tmp)->generate(wxml->UnsignedAttribute("width")); @@ -1395,7 +1418,7 @@ loadWorldFromXMLNoSave( std::string path ) { } }else if(Indoor) abort(); - }else if(name == "mob"){ + } else if ( name == "mob" ) { unsigned int type; type = wxml->UnsignedAttribute("type"); if(wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR) @@ -1405,7 +1428,7 @@ loadWorldFromXMLNoSave( std::string path ) { if(wxml->QueryBoolAttribute("aggressive",&dialog) == XML_NO_ERROR) tmp->mob.back()->aggressive = dialog; - }else if(name == "npc"){ + } else if ( name == "npc" ) { const char *npcname; if(wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR) @@ -1425,7 +1448,7 @@ loadWorldFromXMLNoSave( std::string path ) { tmp->npc.back()->addAIFunc(commonAIFunc,false); else tmp->npc.back()->dialogIndex = 9999; - }else if(name == "structure"){ + } else if ( name == "structure" ) { tmp->addStructure((BUILD_SUB)wxml->UnsignedAttribute("type"), wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR ? getRand() % tmp->getTheWidth() / 2.0f : @@ -1433,10 +1456,17 @@ loadWorldFromXMLNoSave( std::string path ) { 100, wxml->StrAttribute("texture"), wxml->StrAttribute("inside")); - }else if(name == "trigger"){ + } else if ( name == "trigger" ) { tmp->addMob(MS_TRIGGER,wxml->FloatAttribute("x"),0,commonTriggerFunc); tmp->mob.back()->heyid = wxml->Attribute("id"); - } + } else if ( name == "page" ) { + tmp->addMob( MS_PAGE, wxml->FloatAttribute("x"), 0, commonPageFunc ); + tmp->mob.back()->heyid = wxml->Attribute("id"); + } else if ( name == "hill" ) { + tmp->addHill( ivec2 { wxml->IntAttribute("peakx"), wxml->IntAttribute("peaky") }, wxml->UnsignedAttribute("width") ); + } else if ( name == "time") { + tickCount = std::stoi( wxml->GetText() ); + } wxml = wxml->NextSiblingElement(); } @@ -1459,13 +1489,13 @@ loadWorldFromXMLNoSave( std::string path ) { * READS DATA ABOUT STRUCTURE CONTAINED IN VILLAGE */ - if(name == "structure"){ + if ( name == "structure" ) { tmp->addStructure((BUILD_SUB)vil->UnsignedAttribute("type"), vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? randx : spawnx, 100, vil->StrAttribute("texture"), vil->StrAttribute("inside")); - }else if(name == "stall"){ + }else if ( name == "stall" ) { if(!strcmp(vil->Attribute("type"),"market")){ std::cout << "Market" << std::endl; tmp->addStructure((BUILD_SUB)70, diff --git a/xml/playerSpawnHill1.xml b/xml/playerSpawnHill1.xml index 2e8b2aa..86ee397 100644 --- a/xml/playerSpawnHill1.xml +++ b/xml/playerSpawnHill1.xml @@ -2,14 +2,20 @@ <World> <style background="0" bgm="assets/music/embark.wav" folder="assets/style/classic/" /> <generation type="Random" width="500" /> - <link left="playerSpawnHill2.xml" /> - - <mob x="300" type="1" aggressive="true" /> - - <trigger x="-300" id="Test" /> - + <link right="playerSpawnHill2.xml" /> + <time>12000</time> + + <hill peakx="0" peaky="1000" width="50" /> + + <mob x="300" type="1" aggressive="false" /> + + <!--<trigger x="-300" id="Test" />--> + <npc name="Ralph" hasDialog="true" /> <npc name="Johnny" hasDialog="false" /> + + <page x="-200" id="assets/pages/gootaGoFast.png" /> + <village name="the Cranmore Tubing Park"> <structure type="0" x="-300" inside="playerSpawnHill1_Building1.xml"/> <structure type="5" x="-500" inside="playerSpawnHill1_Building1.xml"/> @@ -29,20 +35,20 @@ And it wasn't stormy. ...</Trigger> <Dialog name="Ralph"> - + <text id="0" nextid="1" > Hello there! My name is Ralph. </text> - + <text id="1" nextid="2" call="Johnny" callid="0" pause="true" > You should go talk to my friend Johnny. He's a pretty chill dude. </text> - + <text id="2" > Niice. <quest check="Your First Quest" fail="3" /> </text> - + <text id="3"> Go check out Johnny. He's cool. </text> @@ -56,7 +62,7 @@ And it wasn't stormy. Wood Sword,1 </quest> </text> - + <text id="1" nextid="1" pause="true" > Broooooooooooooo... </text> diff --git a/xml/playerSpawnHill1_Building1.xml b/xml/playerSpawnHill1_Building1.xml index 67695c7..f0c8a21 100644 --- a/xml/playerSpawnHill1_Building1.xml +++ b/xml/playerSpawnHill1_Building1.xml @@ -2,7 +2,7 @@ <IndoorWorld> <style background="1" bgm="assets/music/theme_jazz.wav" /> <generation type="Random" width="300" /> - + <npc name="Bob" hasDialog="true" /> </IndoorWorld> @@ -12,23 +12,23 @@ Hey. Have a Dank MayMay :) <give id="Dank MayMay" count="1" /> </text> - + <text id="1" nextid="2"> What? You want another Dank MayMay? </text> - + <text id="2" nextid="3" pause="true"> K. <give id="Dank MayMay" count="1" /> </text> - + <text id="3" nextid="4"> Well... I'm out of Dank MayMays. </text> - + <text id="4"> Have a sword though. <give id="Wood Sword" count="1" /> </text> - + </Dialog> diff --git a/xml/playerSpawnHill2.xml b/xml/playerSpawnHill2.xml index c46dad3..8d3d328 100644 --- a/xml/playerSpawnHill2.xml +++ b/xml/playerSpawnHill2.xml @@ -3,7 +3,7 @@ <style background="0" bgm="assets/music/embark.wav" folder="assets/style/rustic/"/> <generation type="Random" width="1000" /> <structure type="5" inside="playerSpawnHill1_Building1.xml"/> - - <link right="playerSpawnHill1.xml" /> + + <link left="playerSpawnHill1.xml" /> </World> |