]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
action menu?
authorClyne Sullivan <tullivan99@gmail.com>
Sat, 16 Apr 2016 17:55:31 +0000 (13:55 -0400)
committerClyne Sullivan <tullivan99@gmail.com>
Sat, 16 Apr 2016 17:55:31 +0000 (13:55 -0400)
12 files changed:
include/common.hpp
include/ui.hpp
include/ui_action.hpp [new file with mode: 0644]
include/ui_menu.hpp
include/world.hpp
main.cpp
src/entities.cpp
src/inventory.cpp
src/ui.cpp
src/ui_action.cpp [new file with mode: 0644]
src/world.cpp
xml/playerSpawnHill1.xml

index 65ac47b9de982d8cb2c968d20cfcbb18e0caf8bc..a7ad6ec2a9bd8d5adcfb24c6884a62f90a01cf19 100644 (file)
@@ -160,6 +160,8 @@ extern std::mutex mtx;
  *
  */
 
+#define HLINES(n) (HLINE * n)
+
 extern unsigned int HLINE;
 
 extern float VOLUME_MASTER;
index 5281d3182fd3b02764d03bb7291660bbfbbf1c2f..5ddf165a9828282be18936e821c5c51b693cb197 100644 (file)
@@ -11,7 +11,9 @@
 
 #include <config.hpp>
 #include <world.hpp>
+
 #include <ui_menu.hpp>
+#include <ui_action.hpp>
 
 #include <ft2build.h>
 #include <SDL2/SDL_opengl.h>
@@ -109,6 +111,7 @@ namespace ui {
         *      limited until a right click is given, closing the box.
        */
 
+       void drawBox(vec2 c1, vec2 c2);
        void dialogBox(const char *name,const char *opt,bool passive,const char *text,...);
        void merchantBox(const char *name,Trade trade,const char *opt,bool passive,const char *text,...);
        void merchantBox();
diff --git a/include/ui_action.hpp b/include/ui_action.hpp
new file mode 100644 (file)
index 0000000..a275ab3
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef ACTION_H_
+#define ACTION_H_
+
+#include <common.hpp>
+#include <ui.hpp>
+
+namespace ui {
+    namespace action {
+        extern bool make;
+
+        // enables the action ui
+        void enable(void);
+        // disables the action ui
+        void disable(void);
+
+        // draws the action ui
+        void draw(vec2 loc);
+    }
+}
+
+#endif // ACTION_H_
index bfeecba5246dca5ba02194ae1f527ee661a07157..621676a11aac38591c5acd623ba89e0959342581 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <common.hpp>
 #include <config.hpp>
+#include <ui.hpp>
 
 typedef void (*menuFunc)(void);
 
@@ -13,7 +14,7 @@ struct menuItem {
                        vec2 loc;
                        dim2 dim;
                        Color color;
-            
+
                        const char *text;
                        menuFunc func;
                } button;
@@ -21,11 +22,11 @@ struct menuItem {
                        vec2 loc;
                        dim2 dim;
                        Color color;
-            
+
                        float minValue;
                        float maxValue;
             float sliderLoc;
-            
+
                        const char *text;
                        float *var;
                } slider;
@@ -36,7 +37,7 @@ class Menu {
 public:
        std::vector<menuItem> items;
        Menu *child, *parent;
-    
+
        ~Menu() {
         // TODO you CANNOT delete null pointers!
                /*child = NULL;
@@ -55,7 +56,7 @@ namespace ui {
         menuItem createChildButton(vec2 l, dim2 d, Color c, const char* t);
         menuItem createParentButton(vec2 l, dim2 d, Color c, const char* t);
         menuItem createSlider(vec2 l, dim2 d, Color c, float min, float max, const char* t, float* v);
-        
+
         void draw(void);
     }
 }
index bee2bcf7caf391d9d5f9297cdcb282bf58b21ecc..5608acc20941bad6a3aa21ebf465aebc57a4260e 100644 (file)
@@ -134,7 +134,6 @@ public:
        vec2 start;
        vec2 end;
        bool in;
-       std::vector<Structures *> build;
 
        Village(const char *meme, World *w);
        ~Village(void){}
@@ -251,16 +250,19 @@ protected:
 
        std::vector<std::string> sTexLoc;
 
-       std::vector<Light>     light;
-       std::vector<Village>   village;
-       std::vector<Particles> particles;
-       std::vector<Object>        object;
-       std::vector<Mob>       mob;
+       std::vector<Light>        light;
+       std::vector<Village>      village;
+       std::vector<Particles>    particles;
+       std::vector<Object>           object;
+       std::vector<Mob *>        mob;
+       std::vector<Structures *> build;
 
 public:
 
        Light *getLastLight(void);
        Mob   *getLastMob(void);
+       Entity *getNearInteractable(Entity e);
+       vec2 getStructurePos(int index);
 
        std::string getSTextureLocation(unsigned int index) const;
 
@@ -280,20 +282,9 @@ public:
         * world.
         */
 
-       std::vector<Entity              *>      entity;
-
-       /**
-        * A vector of all NPCs in this world.
-        */
-
-       std::vector<NPC                 *>      npc;
-       std::vector<Merchant    *>  merchant;
-
-       /**
-        * A vector of all Structures in this world.
-        */
-
-       std::vector<Structures  *>      build;
+       std::vector<Entity *> entity;
+       std::vector<NPC *> npc;
+       std::vector<Merchant *> merchant;
 
        /**
         * NULLifies pointers and allocates necessary memory. This should be
@@ -309,63 +300,17 @@ public:
 
        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);
+       void     addLight(vec2 xy, Color color);
+       void     addMerchant(float x, float y, bool housed);
+       void     addMob(int type,float x,float y);
+       void     addMob(int t,float x,float y,void (*hey)(Mob *));
+       void     addNPC(float x,float y);
+       void     addObject(std::string in, std::string pickupDialog, float x, float y);
+       void     addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int d);
+       void     addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int d, unsigned char flags);
+       void     addStructure(BUILD_SUB subtype,float x,float y, std::string tex, std::string inside);
        Village *addVillage(std::string name, World *world);
 
-       /**
-        * 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 d);
-       void addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int d, unsigned char flags);
-
-       /**
-        * 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.
index 2be34ca7e534920542f4bb45b0c0c4391c27f835..3037c77a045e5f8077f49a09da3f1f662b04bf77 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -3,14 +3,6 @@
  *     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.
  */
 
-/*
- * Standard library includes
- */
-
-#include <fstream>
-#include <istream>
-#include <thread>
-
 #include <tinyxml2.h>
 using namespace tinyxml2;
 
@@ -18,52 +10,24 @@ using namespace tinyxml2;
  * Game includes
  */
 
-#include <config.hpp>
 #include <common.hpp>
+#include <config.hpp>
+#include <entities.hpp>
 #include <world.hpp>
 #include <ui.hpp>
-#include <entities.hpp>
-
-/**
- * The window object returned by SDL when we create the main window.
- */
 
+// SDL's window object
 SDL_Window *window = NULL;
 
-/**
- * Determines when the game should exit. This variable is set to true right
- * before the main loop is entered, once set to false the game will exit/
- * free resources.
- */
-
+// main loop runs based on this variable's value
 bool gameRunning;
 
-/**
- * TODO
- */
-
-GLuint invUI;
-
-/**
- * Contains an angle based off of the player's location and the mouse's
- * location.
- */
-
-float handAngle;
-
-/**
- * Contains a pointer to the world that the player is currently in. All render/
- * logic operations have to go access members of this object in order to work.
- */
-
+// world objects for the current world and the two that are adjacent
 World *currentWorld        = NULL,
          *currentWorldToLeft  = NULL,
          *currentWorldToRight = NULL;
 
-/**
- * The player object.
- */
-
+// the player object
 Player *player;
 
 /**
@@ -397,7 +361,6 @@ int main(int argc, char *argv[]){
         * Load sprites used in the inventory menu. See src/inventory.cpp
         */
 
-       invUI = Texture::loadTexture("assets/invUI.png" );
        mouseTex = Texture::loadTexture("assets/mouse.png");
 
        initInventorySprites();
@@ -616,22 +579,6 @@ void render() {
 
        currentWorld->draw(player);
 
-       /*
-        * Calculate the player's hand angle.
-        */
-
-       handAngle = atan((ui::mouse.y - (player->loc.y + player->height/2)) / (ui::mouse.x - player->loc.x + player->width/2))*180/PI;
-       if(ui::mouse.x < player->loc.x){
-               if(handAngle <= 0)
-                       handAngle+=180;
-               if(ui::mouse.y < player->loc.y + player->height/2){
-                       handAngle+=180;
-               }
-       }
-
-       if(ui::mouse.x > player->loc.x && ui::mouse.y < player->loc.y+player->height/2 && handAngle <= 0)
-               handAngle = 360 + handAngle;
-
        /*
         * Draw the player's inventory.
         */
@@ -669,7 +616,7 @@ void render() {
 
                ui::putText(offset.x-SCREEN_WIDTH/2,
                                        (offset.y+SCREEN_HEIGHT/2)-ui::fontSize,
-                                       "FPS: %d\nG:%d\nRes: %ux%u\nE: %d\nPOS: (x)%+.2f\n     (y)%+.2f\nTc: %u\nHA: %+.2f\nVol: %f\nWea: %s",
+                                       "fps: %d\ngrounded:%d\nresolution: %ux%u\nentity cnt: %d\nloc: (%+.2f, %+.2f)\nticks: %u\nvolume: %f\nweather: %s",
                                        fps,
                                        player->ground,
                                        SCREEN_WIDTH,                           // Window dimensions
@@ -678,7 +625,6 @@ void render() {
                                        player->loc.x,                          // The player's x coordinate
                                        debugY,                                         // The player's y coordinate
                                        tickCount,
-                                       handAngle,
                                        VOLUME_MASTER,
                                        getWorldWeatherStr(weather).c_str()
                                        );
@@ -792,6 +738,8 @@ void logic(){
                                } else
                                        e->near = false;
                        } else if (e->type == MOBT) {
+                               e->near = player->isNear(*e);
+
                                switch (e->subtype) {
                                case MS_RABBIT:
                                case MS_BIRD:
index 02be6fee2d9316af1b0aa1b0aff2fe882b271a84..daf4cc96474eafa023291e2b84947f7d5782deb6 100644 (file)
@@ -114,7 +114,10 @@ void Entity::spawn(float x, float y){      //spawns the entity you pass to it based o
        }
 
        name = new char[32];
-       getRandomName(this);
+       if (type == MOBT)
+               name[0] = '\0';
+       else
+               getRandomName(this);
 
        followee = NULL;
 }
@@ -382,14 +385,7 @@ void Entity::draw(void){           //draws the entities
                }
                break;
        case STRUCTURET:
-               for(auto &strt : currentWorld->build){
-                       if(this == strt){
-                               glActiveTexture(GL_TEXTURE0);
-                               tex->bind(0);
-                               break;
-                       }
-               }
-               break;
+               /* fall through */
        default:
                glActiveTexture(GL_TEXTURE0);
                tex->bind(0);
@@ -414,7 +410,7 @@ NOPE:
        glDisable(GL_TEXTURE_2D);
        glMatrixMode(GL_MODELVIEW);
        glPopMatrix();
-       if (near)
+       if (near && type != MOBT)
                ui::putStringCentered(loc.x+width/2,loc.y-ui::fontSize-HLINE/2,name);
        if (health != maxHealth) {
                glColor3ub(150,0,0); glRectf(loc.x, loc.y + height, loc.x + width, loc.y + height + HLINE * 2);
index 1b2d37825c3944a88d617c388cebc2f8e356e74c..84f88711408dddfa5ea80675d46c0f193bacbd36 100644 (file)
@@ -425,31 +425,21 @@ void Inventory::draw(void){
                        a++;
                }
                C("Done drawing standard inv");
-       }else if(invHover){
+       } else if (invHover) {
                static unsigned int highlight = 0;
                static unsigned int thing = 0;
 
-               std::cout<<"Inventory2???"<<std::endl;
-
-               if(!mouseSel){
+               if (!mouseSel) {
+                       // setup?
                        mouseStart.x = ui::mouse.x - offset.x;
-                       std::cout << "Setting highlight" << std::endl;
                        highlight = sel;
-                       std::cout << "Setting thing" << std::endl;
                        thing = sel;
-                       std::cout << "Setting mouseSel" << std::endl;
-                       mouseSel=true;
-                       std::cout << "Done" << std::endl;
-               }else{
-                       std::cout << "Is mousex greater than the start" << std::endl;
+                       mouseSel = true;
+               } else {
                        if((ui::mouse.x - offset.x) >= mouseStart.x){
-                               std::cout << "Thing" << std::endl;
                                thing = (ui::mouse.x - offset.x - mouseStart.x)/80;
-                               std::cout << "Highlight" << std::endl;
                                highlight=sel+thing;
-                               std::cout << "Highlight Check" << std::endl;
                                if(highlight>numSlot-1)highlight=numSlot-1;
-                               std::cout << "Left Click" << std::endl;
                                if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)){
                                        sel = highlight;
                                        mouseSel=false;
@@ -459,8 +449,10 @@ void Inventory::draw(void){
                        }
                        if((ui::mouse.x - offset.x) < mouseStart.x){
                                thing = (mouseStart.x - (ui::mouse.x - offset.x))/80;
-                               if((int)sel-(int)thing<0)highlight=0;
-                               else highlight=sel-thing;
+                               if ((int)sel - (int)thing < 0)
+                                       highlight = 0;
+                               else
+                                       highlight = sel - thing;
                                if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)){
                                        sel = highlight;
                                        mouseSel=false;
@@ -469,17 +461,16 @@ void Inventory::draw(void){
                                }
                        }
                }
-               std::cout << "Rays" << std::endl;
-               for(auto &r : iray){
-                       std::cout << "Setting angle" << std::endl;
-                       angle=180-(angleB*a) - angleB/2.0f;
-                       std::cout << "Currcourd" << std::endl;
+
+               a = 0;
+               for (auto &r : iray) {
+                       angle = 180 - (angleB * a) - angleB / 2.0f;
+
                        curCoord[a].x += float(range) * cos(angle*PI/180);
                        curCoord[a].y += float(range) * sin(angle*PI/180);
-                       std::cout << "Ray.end" << std::endl;
                        r.end = curCoord[a];
 
-                       std::cout << "Draw" << std::endl;
+                       // square drawing
                        glColor4f(0.0f, 0.0f, 0.0f, a == highlight ? 0.5f : 0.1f);
                        glBegin(GL_QUADS);
                                glVertex2i(r.end.x-(itemWide/2),        r.end.y-(itemWide/2));
@@ -488,17 +479,12 @@ void Inventory::draw(void){
                                glVertex2i(r.end.x-(itemWide/2),        r.end.y+(itemWide/2));
                        glEnd();
 
-                       std::cout << "Draw items" << std::endl;
-                       if(!items.empty() && a < items.size() && items[a].count){
-                               std::cout << "Jamie" << std::endl;
+                       if (a < items.size() && items[a].count) {
                                glEnable(GL_TEXTURE_2D);
                                glBindTexture(GL_TEXTURE_2D, itemtex[items[a].id]);
                                glColor4f(1.0f, 1.0f, 1.0f, a == highlight ? 0.8f : 0.2f);
-                               std::cout << "Done Binding" << std::endl;
                                glBegin(GL_QUADS);
-                               std::cout << "jdjdjd" << std::endl;
                                        if(itemMap[items[a].id]->height > itemMap[items[a].id]->width){
-                                               std::cout << "map" << std::endl;
                                                glTexCoord2i(0,1);glVertex2i(r.end.x-((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y-(itemWide/2));
                                                glTexCoord2i(1,1);glVertex2i(r.end.x+((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y-(itemWide/2));
                                                glTexCoord2i(1,0);glVertex2i(r.end.x+((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y+(itemWide/2));
@@ -511,11 +497,16 @@ void Inventory::draw(void){
                                        }
                                glEnd();
                                glDisable(GL_TEXTURE_2D);
-                               std::cout << "Adding a" << std::endl;
-                               a++;
                        }
+                       a++;
+               }
+
+               if (highlight < items.size()) {
+                       ui::putStringCentered(player->loc.x + player->width / 2,
+                                             player->loc.y + range * 0.75f,
+                                                             itemMap[items[highlight].id]->name.c_str()
+                                                        );
                }
-               ui::putStringCentered(player->loc.x+player->width/2, player->loc.y + range*.75,itemMap[items[highlight].id]->name.c_str());
        }
 
        if(!items.empty() && items.size() > sel && items[sel].count)
index a78686c7e72c701dd45cdd1ee7a75900c2a5ab67..f6f7b9456afc5c246bc8cde8c2b73205ee70fe08 100644 (file)
@@ -615,11 +615,30 @@ namespace ui {
                pageTexReady = true;
        }
 
+       void drawBox(vec2 c1, vec2 c2) {
+               // draw black body
+               glColor3ub(0, 0, 0);
+               glRectf(c1.x, c1.y, c2.x, c2.y);
+
+               // draw white border
+               glColor3ub(255, 255, 255);
+               glBegin(GL_LINE_STRIP);
+                       glVertex2i(c1.x    , c1.y);
+                       glVertex2i(c2.x + 1, c1.y);
+                       glVertex2i(c2.x + 1, c2.y);
+                       glVertex2i(c1.x - 1, c2.y);
+                       glVertex2i(c1.x    , c1.y);
+               glEnd();
+       }
+
        void draw(void){
                unsigned char i;
                float x,y,tmp;
                std::string rtext;
 
+               // will return if not toggled
+               action::draw(vec2 {player->loc.x + player->width / 2, player->loc.y + player->height + HLINE});
+
                if (pageTexReady) {
                        glEnable(GL_TEXTURE_2D);
                        glBindTexture(GL_TEXTURE_2D, pageTex);
@@ -654,38 +673,24 @@ namespace ui {
                                x=offset.x-SCREEN_WIDTH/6;
                                y=(offset.y+SCREEN_HEIGHT/2)-HLINE*8;
 
-                               // draw the box border
-                               glColor3ub(255,255,255);
-                               glBegin(GL_LINE_STRIP);
-                                       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);
-                               glEnd();
-
-                               // draw the box
-                               glColor3ub(0,0,0);
-                               glRectf(x,y,x+SCREEN_WIDTH/3,y-SCREEN_HEIGHT*.6);
+                               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)));
 
-                               std::string itemString1 = std::to_string(merchTrade.quantity[0]);
-                               itemString1 += "x";
-
-                               std::string itemString2 = std::to_string(merchTrade.quantity[1]);
-                               itemString2 += "x";
+                               std::string itemString1 = std::to_string(merchTrade.quantity[0]) + "x",
+                                           itemString2 = std::to_string(merchTrade.quantity[1]) + "x";
 
-                               putStringCentered(offset.x - (SCREEN_WIDTH / 10) + 20, offset.y + (SCREEN_HEIGHT / 5) + 40 + (fontSize*2), itemString1.c_str());
-                               putStringCentered(offset.x - (SCREEN_WIDTH / 10) + 20, offset.y + (SCREEN_HEIGHT / 5) + 40 + fontSize, merchTrade.item[0].c_str());
+                               vec2 merchBase = {offset.x, offset.y + SCREEN_HEIGHT / 5};
 
-                               putStringCentered(offset.x + (SCREEN_WIDTH / 10) - 20, offset.y + (SCREEN_HEIGHT / 5) + 40 + (fontSize*2), itemString2.c_str());
-                               putStringCentered(offset.x + (SCREEN_WIDTH / 10) - 20, offset.y + (SCREEN_HEIGHT / 5) + 40 + fontSize, merchTrade.item[1].c_str());
-
-                               putStringCentered(offset.x,offset.y + (SCREEN_HEIGHT / 5) + 60, "for");
+                               putStringCentered(merchBase.x + SCREEN_WIDTH / 10 - 20, merchBase.y + 40 + fontSize * 2, itemString1.c_str());
+                               putStringCentered(merchBase.x + SCREEN_WIDTH / 10 - 20, merchBase.y + 40 + fontSize    , merchTrade.item[0].c_str());
+                               putStringCentered(merchBase.x - SCREEN_WIDTH / 10     , merchBase.y + 40 + fontSize * 2, itemString2.c_str());
+                               putStringCentered(merchBase.x - SCREEN_WIDTH / 10     , merchBase.y + 40 + fontSize    , merchTrade.item[1].c_str());
+                               putStringCentered(offset.x, merchBase.y + 60, "for");
 
                                glEnable(GL_TEXTURE_2D);
+
                                glBindTexture(GL_TEXTURE_2D, getItemTexture(merchTrade.item[0]));
                                glBegin(GL_QUADS);
                                        glTexCoord2d(0,1);glVertex2f(offset.x - (SCREEN_WIDTH / 10)     ,offset.y + (SCREEN_HEIGHT/5));
@@ -701,6 +706,7 @@ namespace ui {
                                        glTexCoord2d(1,0);glVertex2f(offset.x + (SCREEN_WIDTH / 10)     ,offset.y + (SCREEN_HEIGHT/5) + 40);
                                        glTexCoord2d(0,0);glVertex2f(offset.x + (SCREEN_WIDTH / 10) - 40,offset.y + (SCREEN_HEIGHT/5) + 40);
                                glEnd();
+
                                glDisable(GL_TEXTURE_2D);
 
                                merchArrowLoc[0].x = offset.x - (SCREEN_WIDTH / 8.5) - 16;
@@ -748,24 +754,12 @@ namespace ui {
                                }
 
                                setFontColor(255, 255, 255);
-                       }else{ //normal dialog box
+                       } else { //normal dialog box
 
-                               x=offset.x-SCREEN_WIDTH/2+HLINE*8;
-                               y=(offset.y+SCREEN_HEIGHT/2)-HLINE*8;
-
-                               // draw white border
-                               glColor3ub(255, 255, 255);
+                               x = offset.x - SCREEN_WIDTH / 2  + HLINE * 8;
+                               y = offset.y + SCREEN_HEIGHT / 2 - HLINE * 8;
 
-                               glBegin(GL_LINE_STRIP);
-                                       glVertex2i(x-1                                          ,y+1);
-                                       glVertex2i(x+1+SCREEN_WIDTH-HLINE*16,y+1);
-                                       glVertex2i(x+1+SCREEN_WIDTH-HLINE*16,y-1-SCREEN_HEIGHT/4);
-                                       glVertex2i(x-1                                          ,y-1-SCREEN_HEIGHT/4);
-                                       glVertex2i(x-1                                          ,y+1);
-                               glEnd();
-
-                               glColor3ub(0,0,0);
-                               glRectf(x,y,x+SCREEN_WIDTH-HLINE*16,y-SCREEN_HEIGHT/4);
+                               drawBox(vec2 {x, y}, vec2 {x + SCREEN_WIDTH - HLINE * 16, y - SCREEN_HEIGHT / 4});
 
                                rtext = typeOut(dialogBoxText);
 
@@ -956,16 +950,22 @@ EXIT:
                        // mouse clicks
                        case SDL_MOUSEBUTTONDOWN:
 
-                               // right click advances dialog
-                               if ((e.button.button & SDL_BUTTON_RIGHT) && (dialogBoxExists | pageTexReady))
-                                       dialogAdvance();
+                               // run actions?
+                               if ((action::make = e.button.button & SDL_BUTTON_RIGHT))
+                                       /*player->inv->invHover =*/ edown = false;
 
-                               // left click uses item
-                               if ((e.button.button & SDL_BUTTON_LEFT) && !dialogBoxExists)
-                                       player->inv->usingi = true;
+                               if (dialogBoxExists || pageTexReady) {
+                                       // right click advances dialog
+                                       if ((e.button.button & SDL_BUTTON_RIGHT))
+                                               dialogAdvance();
+                               } else {
+                                       // left click uses item
+                                       if (e.button.button & SDL_BUTTON_LEFT)
+                                               player->inv->usingi = true;
+                               }
 
                                if(mouse.x > player->loc.x && mouse.x < player->loc.x + player->width &&
-                                       mouse.y > player->loc.y && mouse.y < player->loc.y + player->height) {
+                                  mouse.y > player->loc.y && mouse.y < player->loc.y + player->height) {
                                        player->vel.y = .05;
                                        fr = mouse;
                                        ig = player;
@@ -1054,8 +1054,6 @@ EXIT:
                                                        }
                                                }
                                                break;
-                                       case SDLK_s:
-                                               break;
                                        case SDLK_w:
                                                if (inBattle) {
                                                        tmp = currentWorld;
@@ -1066,32 +1064,43 @@ EXIT:
                                                        currentWorld = tmp;
                                                break;
                                        case SDLK_LSHIFT:
-                                               if(debug){
-                                                       Mix_PlayChannel(1,sanic,-1);
+                                               if (debug) {
+                                                       Mix_PlayChannel(1, sanic, -1);
                                                        player->speed = 4.0f;
-                                               }else
+                                               } else
                                                        player->speed = 2.0f;
                                                break;
                                        case SDLK_LCTRL:
                                                player->speed = .5;
                                                break;
                                        case SDLK_e:
-                                               edown=true;
-                                               if(!heyOhLetsGo){
+                                               edown = true;
+
+                                               // start hover counter?
+                                               if (!heyOhLetsGo) {
                                                        heyOhLetsGo = loops;
                                                        player->inv->mouseSel = false;
                                                }
-                                               if(loops - heyOhLetsGo >= 2 && !(player->inv->invOpen) && !(player->inv->selected))
-                                                       player->inv->invHover=true;
+
+                                               // run hover thing
+                                               if (loops - heyOhLetsGo >= 2 && !(player->inv->invOpen) && !(player->inv->selected)) {
+                                                       player->inv->invHover = true;
+
+                                                       // enable action ui
+                                                       action::enable();
+                                               }
+
                                                break;
                                        default:
                                                break;
                                        }
-                                       if(tmp != currentWorld){
-                                               std::swap(tmp,currentWorld);
+
+                                       // handle world switches?
+                                       if (tmp != currentWorld) {
+                                               std::swap(tmp, currentWorld);
                                                toggleBlackFast();
                                                waitForCover();
-                                               std::swap(tmp,currentWorld);
+                                               std::swap(tmp, currentWorld);
                                                toggleBlackFast();
                                        }
                                }
@@ -1149,6 +1158,10 @@ EXIT:
                                                else player->inv->selected = false;
                                                player->inv->mouseSel = false;
                                        }
+
+                                       // disable action ui
+                                       action::disable();
+
                                        heyOhLetsGo = 0;
                                        break;
                                case SDLK_l:
@@ -1165,7 +1178,7 @@ EXIT:
                                        else {
                                                currentWorld->addStructure(FIRE_PIT, player->loc.x, player->loc.y, "", "");
                                                currentWorld->addLight({player->loc.x + SCREEN_WIDTH/2, player->loc.y},{1.0f,1.0f,1.0f});
-                                               currentWorld->getLastLight()->follow(currentWorld->build.back());
+                                               //currentWorld->getLastLight()->follow(currentWorld->build.back());
                                                currentWorld->getLastLight()->makeFlame();
                                        }
                                        break;
diff --git a/src/ui_action.cpp b/src/ui_action.cpp
new file mode 100644 (file)
index 0000000..66fea19
--- /dev/null
@@ -0,0 +1,142 @@
+#include <ui_action.hpp>
+
+extern World *currentWorld;
+extern Player *player;
+extern bool inBattle;
+
+static std::vector<std::pair<std::string, vec3>> actionText = {
+    {"Attack", vec3 {0, 0, 0}},
+    {"Action", vec3 {0, 0, 0}},
+    {"Umm"   , vec3 {0, 0, 0}}
+};
+
+void actionAttack(void);
+void actionAction(void);
+
+static std::vector<void (*)(void)> actionFunc = {
+    actionAttack,
+    actionAction,
+    nullptr,
+};
+
+static bool actionToggle = false;
+static unsigned int actionHover = 0;
+static Entity *nearEntity = nullptr, *lastEntity = nullptr;
+
+namespace ui {
+    namespace action {
+        bool make = false;
+
+        // enables action ui
+        void enable(void) {
+            actionToggle = true;
+        }
+
+        // disables action ui
+        void disable(void) {
+            actionToggle = false;
+
+            if (lastEntity != nullptr)
+                lastEntity->canMove = true;
+        }
+
+        // draws the action ui
+        void draw(vec2 loc) {
+            static bool second = false;
+            unsigned int i = 1;
+            float y = loc.y;
+
+            if (!actionToggle)
+                return;
+
+            nearEntity = currentWorld->getNearInteractable(*player);
+
+            if (nearEntity == nullptr) {
+                if (lastEntity != nullptr) {
+                    lastEntity->canMove = true;
+                    lastEntity = nullptr;
+                }
+                return;
+            } else if (nearEntity != lastEntity) {
+                if (lastEntity != nullptr)
+                    lastEntity->canMove = true;
+                lastEntity = nearEntity;;
+            }
+
+            if (make) {
+                if (!actionHover) {
+                    make = false;
+                    return;
+                }
+
+                if (!second)
+                    second = true;
+                else {
+                    second = false;
+                    return;
+                }
+
+                if (actionFunc[actionHover - 1] != nullptr)
+                    std::thread(actionFunc[actionHover - 1]).detach();
+
+                actionHover = 0;
+                make = false;
+                return;
+            } else {
+                nearEntity->canMove = false;
+                ui::drawBox(vec2 {loc.x - HLINES(11), loc.y}, vec2 {loc.x + HLINES(12), loc.y + actionText.size() * HLINES(8)});
+
+                for (auto &s : actionText) {
+                    s.second.z = ui::putStringCentered((s.second.x = loc.x), (s.second.y = (y += fontSize * 1.15f)), s.first) / 2;
+
+                    if (ui::mouse.x > s.second.x - s.second.z && ui::mouse.x < s.second.x + s.second.z &&
+                        ui::mouse.y > s.second.y && ui::mouse.y < s.second.y + ui::fontSize) {
+                        actionHover = i;
+                        ui::setFontColor(255, 100, 100, 255);
+                        ui::putStringCentered(s.second.x, s.second.y, s.first);
+                        ui::setFontColor(255, 255, 255, 255);
+                    }
+                    i++;
+                }
+
+                ui::putStringCentered(loc.x, y + fontSize * 1.2f, nearEntity->name);
+            }
+
+            if (i == actionText.size())
+                actionHover = 0;
+
+            ui::setFontColor(255, 255, 255, 255);
+        }
+    }
+}
+
+void actionAttack(void)
+{
+    auto m = currentWorld->getNearInteractable(*player);
+
+    if (m->type == MOBT) {
+        if (!inBattle && m != nullptr) {
+            Arena *a = new Arena(currentWorld, player, Mobp(m));
+            a->setStyle("");
+            a->setBackground(WorldBGType::Forest);
+            a->setBGM("assets/music/embark.wav");
+
+            ui::toggleWhiteFast();
+            ui::waitForCover();
+            currentWorld = a;
+            ui::toggleWhiteFast();
+        }
+    } else {
+        ui::dialogBox(player->name, "", false, "%s doesn't appear to be in the mood for fighting...", m->name);
+    }
+}
+
+void actionAction(void)
+{
+    auto e = currentWorld->getNearInteractable(*player);
+
+    if (e->type == NPCT) {
+        if (!NPCp(e)->aiFunc.empty())
+            e->interact();
+    }
+}
index 434f61979edfdf68564307f7f4afad80ee3f18c9..df6c556a42db68dd4bb48320f018e84ce7020c94 100644 (file)
@@ -168,7 +168,10 @@ void World::
 deleteEntities(void)
 {
     // free mobs
-       mob.clear();
+    while(!mob.empty()){
+               delete mob.back();
+               mob.pop_back();
+       }
 
        merchant.clear();
        while(!npc.empty()){
@@ -696,7 +699,7 @@ void World::draw(Player *p){
     }
 
        for (auto &m : mob)
-               m.draw();
+               m->draw();
 
        for (auto &o : object)
                o.draw();
@@ -969,18 +972,18 @@ addVillage(std::string name, World *world)
 }
 
 void World::addMob(int t,float x,float y){
-       mob.emplace_back(t);
-       mob.back().spawn(x,y);
+       mob.push_back(new Mob(t));
+       mob.back()->spawn(x,y);
 
-       entity.push_back(&mob.back());
+       entity.push_back(mob.back());
 }
 
 void World::addMob(int t,float x,float y,void (*hey)(Mob *)){
-       mob.emplace_back(t);
-       mob.back().spawn(x,y);
-       mob.back().hey = hey;
+       mob.push_back(new Mob(t));
+       mob.back()->spawn(x,y);
+       mob.back()->hey = hey;
 
-       entity.push_back(&mob.back());
+       entity.push_back(mob.back());
 }
 
 void World::addNPC(float x,float y){
@@ -990,10 +993,13 @@ void World::addNPC(float x,float y){
        entity.push_back(npc.back());
 }
 
-void World::addMerchant(float x, float y){
+void World::addMerchant(float x, float y, bool housed){
        merchant.push_back(new Merchant());
        merchant.back()->spawn(x,y);
 
+    if (housed)
+        merchant.back()->inside = build.back();
+
        npc.push_back(merchant.back());
        entity.push_back(npc.back());
 }
@@ -1037,7 +1043,20 @@ getLastLight(void)
 Mob *World::
 getLastMob(void)
 {
-    return &mob.back();
+    return mob.back();
+}
+
+Entity *World::
+getNearInteractable(Entity e)
+{
+    for (auto &n : entity) {
+        if (n->type == MOBT || n->type == NPCT || n->type == MERCHT) {
+            if (e.isNear(*n) && (e.left ? n->loc.x < e.loc.x : n->loc.x > e.loc.x))
+                return n;
+        }
+    }
+
+    return nullptr;
 }
 
 std::string World::
@@ -1049,6 +1068,17 @@ getSTextureLocation(unsigned int index) const
     return sTexLoc[ index ];
 }
 
+vec2 World::
+getStructurePos(int index)
+{
+    if (index < 0)
+        return build.back()->loc;
+    else if ((unsigned)index >= build.size())
+        return vec2{0, 0};
+
+    return build[index]->loc;
+}
+
 std::string World::
 setToLeft(std::string file)
 {
@@ -1193,7 +1223,9 @@ addHole(unsigned int start, unsigned int end)
 void World::
 addHill(const ivec2 peak, const unsigned int width)
 {
-       int start = peak.x - width / 2, end = start + width, offset = 0;
+       int start  = peak.x - width / 2,
+        end    = start + width,
+        offset = 0;
        const float thing = peak.y - worldData[start].groundHeight;
     const float period = PI / width;
 
@@ -1238,9 +1270,9 @@ void World::save(void){
        }
 
        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");
+               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");
        }
 
        data.append("dOnE\0");
@@ -1284,13 +1316,13 @@ void World::load(void){
        for(auto &m : mob){
                std::getline(iss,line);
                if(line == "dOnE")return;
-               m.loc.x = std::stoi(line);
+               m->loc.x = std::stoi(line);
                std::getline(iss,line);
                if(line == "dOnE")return;
-               m.loc.y = std::stoi(line);
+               m->loc.y = std::stoi(line);
                std::getline(iss,line);
                if(line == "dOnE")return;
-               m.alive = std::stoi(line);
+               m->alive = std::stoi(line);
        }
 
        while(std::getline(iss,line)){
@@ -1530,8 +1562,8 @@ Arena::Arena(World *leave,Player *p,Mob *m){
        mmob = m;
        mmob->aggressive = false;
 
-       mob.push_back(*m);
-       entity.push_back(&mob.back());
+       mob.push_back(m);
+       entity.push_back(mob.back());
 
        battleNest.push_back(leave);
        battleNestLoc.push_back(p->loc);
@@ -1544,8 +1576,8 @@ Arena::~Arena(void){
 World *Arena::exitArena(Player *p){
        World *tmp;
        if (!mmob->alive &&
-         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 &&
+            p->loc.x + p->width / 2 < mob[0]->loc.x + HLINE * 12) {
                tmp = battleNest.front();
                battleNest.erase(battleNest.begin());
 
@@ -1843,9 +1875,7 @@ loadWorldFromXMLNoSave(std::string path) {
                                                               vil->StrAttribute("texture"),
                                                               vil->StrAttribute("inside")
                    );
-                               tmp->addMerchant(0, 100);
-
-                tmp->merchant.back()->inside = tmp->build.back();
+                               tmp->addMerchant(0, 100, true);
             }
 
             // handle traders
@@ -1880,15 +1910,13 @@ loadWorldFromXMLNoSave(std::string path) {
                        }
                }
 
-               vptr->build.push_back(tmp->build.back());
+        float buildx = tmp->getStructurePos(-1).x;
 
-               if(vptr->build.back()->loc.x < vptr->start.x){
-                       vptr->start.x = vptr->build.back()->loc.x;
-               }
+               if (buildx < vptr->start.x)
+                       vptr->start.x = buildx;
 
-               if(vptr->build.back()->loc.x + vptr->build.back()->width > vptr->end.x){
-                       vptr->end.x = vptr->build.back()->loc.x + vptr->build.back()->width;
-               }
+               if (buildx > vptr->end.x)
+                       vptr->end.x = buildx;
 
                //go to the next element in the village block
                vil = vil->NextSiblingElement();
index 53f5ad20a67128c7ce25ab5208b597799d4d5643..622a4e6883cb388819f50e0c01dabcfcd2cd22c7 100644 (file)
@@ -7,7 +7,7 @@
 
        <hill peakx="0" peaky="1000" width="50" />
 
-       <mob x="300" type="1" aggressive="false" health="1000" />
+       <mob x="300" type="1" aggressive="false" health="100" />
 
        <!--<trigger x="-300" id="Test" />-->