]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
Merchants kinda work...
authordrumsetmonkey <abelleisle@roadrunner.com>
Fri, 26 Feb 2016 13:28:48 +0000 (08:28 -0500)
committerdrumsetmonkey <abelleisle@roadrunner.com>
Fri, 26 Feb 2016 13:28:48 +0000 (08:28 -0500)
include/common.h
include/entities.h
include/ui.h
include/world.h
main.cpp
src/config.cpp
src/entities.cpp
src/gameplay.cpp
src/ui.cpp
src/world.cpp
xml/playerSpawnHill1.xml

index a99e3529421c3a9e179ec449275f7b46eb30805c..cbfc50793f4d7f169f2ef8ac6604102f52f7d786 100644 (file)
@@ -18,6 +18,7 @@
 #include <thread>
 #include <mutex>
 #include <future>
+#include <threadpool.h>
 
 #define GLEW_STATIC
 #include <GL/glew.h>
@@ -113,6 +114,8 @@ extern unsigned int SCREEN_WIDTH;
 extern unsigned int SCREEN_HEIGHT;
 
 extern bool FULLSCREEN;
+extern bool uiLoop;
+extern std::mutex mtx;
 
 /**
  * Define the length of a single HLINE.
index 926eeae4b8bc4b26f8ddd1e703c915bf0aa1847c..6c8e6586b1b96719683d0c77fc3f2d76c2f29d72 100644 (file)
@@ -22,13 +22,13 @@ enum _TYPE {
        STRUCTURET,
        PLAYERT,
        NPCT,
+       MERCHT,
        MOBT
 };
 
 enum GENDER{
        MALE,
-       FEMALE,
-       TRANSBULLSHIT
+       FEMALE
 };
 
 enum MOB_SUB {
@@ -47,7 +47,9 @@ enum BUILD_SUB{
        HOUSE4 = 4,
        FOUNTAIN = 5,
        LAMP_POST = 6,
-       FIRE_PIT = 7
+       FIRE_PIT = 7,
+       STALL_MARKET = 70,
+       STALL_TRADER = 71
 };
 
 class World;
@@ -191,10 +193,30 @@ public:
        
        void addAIFunc(int (*func)(NPC *),bool preload);
        void clearAIFunc(void);
-       void interact();
+       virtual void interact();
        void wander(int);
 };
 
+class Merchant : public NPC{
+public:
+       union BSINV{
+               struct EQUAL{
+                       std::string item1;
+                       std::string item2;
+               };
+
+               struct COST{
+                       std::string item;
+                       int price;
+               };
+       };
+       std::vector<BSINV>bsinv;
+       void interact();
+
+       Merchant();
+       ~Merchant();
+};
+
 class Structures : public Entity{
 public:
        BUILD_SUB bsubtype;
index 6a81ff8e360ca365171d5456531ae4c7ea082392..04995705005612fd8f0e48056342bbf919856c7c 100644 (file)
@@ -108,9 +108,9 @@ namespace ui {
        extern bool posFlag;
        
        extern unsigned char dialogOptChosen;
-       extern bool dialogBoxExists;
-       extern bool dialogImportant;
-       extern bool dialogPassive;
+       extern bool              dialogBoxExists;
+       extern bool              dialogImportant;
+       extern bool              dialogPassive;
 
        extern unsigned int textWrapLimit;
 
@@ -148,6 +148,7 @@ namespace ui {
        */
        
        void dialogBox(const char *name,const char *opt,bool passive,const char *text,...);
+       void merchantBox(const char *name,const char *opt,bool passive,const char *text,...);
        void waitForDialog(void);
        
        /*
index f9e952e7d5fe3fe35b282b420b44f1416febcdac..7338097c83cc9b68e9e7a1109c89d87a0fcebbbd 100644 (file)
@@ -101,6 +101,8 @@ struct Village{
        }
 };
 
+extern Player *player;
+
 /**
  * The world class. This class does everything a world should do.
  */
@@ -215,6 +217,10 @@ public:
        
        char *setToRight(const char *file);
 
+       void callUpdate(){
+               this->update(player,deltaTime);
+       }
+
 
        /**
         * A vector of pointers to every NPC, Structure, Mob, and Object in this
@@ -228,6 +234,7 @@ public:
         */
 
        std::vector<NPC                 *>      npc;
+       std::vector<Merchant    *>  merchant;
        
        /**
         * A vector of all Structures in this world.
@@ -310,6 +317,7 @@ public:
         */
        
        void addNPC(float x,float y);
+       void addMerchant(float x, float y);
        
        /**
         * Adds an object to the world with the specified item id and coordinates.
index 97f788cef1acaada1bcb7dd4ea04e72e4a0b78d1..cb28bcc9f7ce5198e052b581347160a8386e3d66 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -124,6 +124,10 @@ GLuint shaderProgram;
 GLuint colorIndex;
 GLuint mouseTex;
 
+bool uiLoop = false;
+std::mutex mtx;
+std::condition_variable cv;
+
 /*
  *     loops is used for texture animation. It is believed to be passed to entity
  *     draw functions, although it may be externally referenced instead.
@@ -131,6 +135,8 @@ GLuint mouseTex;
 
 unsigned int loops = 0;        // Used for texture animation
 
+ThreadPool pool(10);
+
 /*
  *     initEverything
  *
@@ -469,14 +475,16 @@ void mainLoop(void){
         */
 
        prev = currentWorld;
-       ui::handleEvents();
-       
+       pool.Enqueue(ui::handleEvents);
+       //ui::handleEvents();
+
        if(prev != currentWorld){
                currentWorld->bgmPlay(prev);
                ui::dialogBoxExists = false;
        }
        
        if(prevPrevTime + MSEC_PER_TICK <= currentTime){
+               //pool.Enqueue(logic);
                logic();
                prevPrevTime = currentTime;
        }
@@ -485,6 +493,9 @@ void mainLoop(void){
         * Update player and entity coordinates.
         */
        
+       /*pool.Enqueue([](){
+               currentWorld->update(player,deltaTime);
+       });*/
        currentWorld->update(player,deltaTime);
        
        /*
@@ -646,7 +657,7 @@ void render(){
                                offset.y+SCREEN_HEIGHT/2);
        }else if(ui::fontSize != 16)
                ui::setFontSize(16);
-       
+
        /*
         * Draw UI elements. This includes the player's health bar and the dialog box.
         */
@@ -764,19 +775,12 @@ void logic(){
                         *      that the NPC doesn't move when it talks to the player.
                         */
 
-/*<<<<<<< HEAD
-                       if(n->canMove) n->wander((rand() % 120 + 30));
-
-                       if(!player->inv->usingi) n->hit = false;
-                       if(player->inv->usingi && !n->hit && player->inv->detectCollision(vec2{n->loc.x, n->loc.y},vec2{n->loc.x+n->width,n->loc.y+n->height})){
-=======*/
                        if(n->canMove)
                                n->wander((rand() % 120 + 30));
                        
                        /*if(!player->inv->usingi) n->hit = false;
                        
                        if(player->inv->usingi && !n->hit && player->inv->detectCollision((vec2){n->loc.x, n->loc.y},(vec2){n->loc.x+n->width,n->loc.y+n->height})){
->>>>>>> 7ab072caaaec09720ad79cfed5738e89bc60c44f
                                n->health -= 25;
                                n->hit = true;
                                for(int r = 0; r < (rand()%5);r++)
index 72a071d72c6a16b11fc2f06971e325e5bd321e53..45bab3f45a3845f0c7099398bbf69008f6cab56a 100644 (file)
@@ -56,6 +56,7 @@ void readConfig(){
 }
 
 void updateConfig(){
+
        Mix_Volume(0,VOLUME_MASTER);
        Mix_Volume(1,VOLUME_SFX * (VOLUME_MASTER/100.0f));
        Mix_VolumeMusic(VOLUME_MUSIC * (VOLUME_MASTER/100.0f));
index 6c2da81d8a38688afe0904daf666632ab886e2ea..afcc9adf91215ebfc8df7a2643705ad6abfc673e 100644 (file)
@@ -3,7 +3,7 @@
 
 #include <istream>
 
-#define RAND_DIALOG_COUNT 13
+#define RAND_DIALOG_COUNT 14
 
 extern std::istream *names;
 extern unsigned int loops;
@@ -125,6 +125,7 @@ NPC::NPC(){ //sets all of the NPC specific traits on object creation
        randDialog = rand() % RAND_DIALOG_COUNT - 1;
        dialogIndex = 0;
 }
+
 NPC::~NPC(){
        while(!aiFunc.empty()){
                aiFunc.pop_back();
@@ -135,6 +136,36 @@ NPC::~NPC(){
        delete[] name;
 }
 
+Merchant::Merchant(){  //sets all of the Merchant specific traits on object creation
+       width = HLINE * 10;
+       height = HLINE * 16;
+       
+       type    = MERCHT; //sets type to merchant
+       subtype = 0;
+
+       health = maxHealth = 100;
+       
+       maxHealth = health = 100;
+       canMove = true;
+       
+       //tex = new Texturec(1,"assets/NPC.png");
+       //inv = new Inventory(NPC_INV_SIZE);
+       inv = NULL;
+
+       //randDialog = rand() % RAND_DIALOG_COUNT - 1;
+       dialogIndex = 0;
+}
+
+Merchant::~Merchant(){
+       while(!aiFunc.empty()){
+               aiFunc.pop_back();
+       }
+       
+       delete inv;
+       delete tex;
+       delete[] name;
+}
+
 Structures::Structures(){ //sets the structure type
        health = maxHealth = 1;
        
@@ -143,7 +174,7 @@ Structures::Structures(){ //sets the structure type
        
        name = NULL;
        
-       inv = NULL;
+       //inv = NULL;
        canMove = false;
 }
 Structures::~Structures(){
@@ -401,7 +432,8 @@ const char *randomDialog[RAND_DIALOG_COUNT] = {
        "I want to have the wallpaper in our house changed. It doesn\'t really fit the environment.",
        "Frig.",
        "The sine of theta equals the opposite over the hypotenuese.",
-       "Did you know the developers spelt brazier as brazzier."
+       "Did you know the developers spelt brazier as brazzier.",
+       "My dad once said to me, \"Boy, you are in a game.\" I never knew what he meant by that."
 };
 
 void NPC::interact(){ //have the npc's interact back to the player
@@ -425,6 +457,10 @@ void NPC::interact(){ //have the npc's interact back to the player
        canMove=true;
 }
 
+void Merchant::interact(){
+       ui::merchantBox(name, ":Accept:Good Bye", false, "Welcome to smithy\'s. Buy your sausages here you freaking mean lording screw-face");
+}
+
 void Object::interact(void){
        if(questObject && alive){
                ui::dialogBox(player->name,":Yes:No",false,pickupDialog);               
@@ -468,11 +504,18 @@ unsigned int Structures::spawn(BUILD_SUB sub, float x, float y){
 
        //unsigned int tempN = (getRand() % 5 + 2);
        switch(sub){
+               case STALL_MARKET:
+                       tex = new Texturec(1, textureLoc ? textureLoc : inWorld->sTexLoc[sub].c_str());
+                       dim = Texture::imageDim(textureLoc ? textureLoc : inWorld->sTexLoc[sub].c_str());
+                       width = dim.x;
+                       height = dim.y;
+                       break;
                default:
                        tex = new Texturec(1, textureLoc ? textureLoc : inWorld->sTexLoc[sub].c_str());
                        dim = Texture::imageDim(textureLoc ? textureLoc : inWorld->sTexLoc[sub].c_str());
                        width = dim.x;
                        height = dim.y;
+                       inv = NULL;
                        break;
        }
        return 0;
index 4bbc672c36d1fd4b729d2f18162d2431cac9a6ec..1c7730943f7985b5aac9aa46fdb1708fad1ad11b 100644 (file)
@@ -217,8 +217,7 @@ void commonTriggerFunc(Mob *callee){
        XMLDocument xml;
        XMLElement *exml;
        
-       char *text,*pch;
-       
+       char *text,*pch;        
        if(!lock){
                lock = true;
        
index 6e616a7576908df733b0307d68b55843c1c4d6e4..836a98eb0ac1758a0f8bd0e22e871bbf4c65415d 100644 (file)
@@ -114,6 +114,7 @@ namespace ui {
        bool debug=false;
        bool posFlag=false;
        bool dialogPassive = false;
+       bool dialogMerchant = false;
        int dialogPassiveTime = 0;
 
        
@@ -182,10 +183,12 @@ namespace ui {
        */
        
        void setFontSize(unsigned int size){
+               mtx.lock();
                unsigned int i,j;
                char *buf;
                
                fontSize=size;
+
                FT_Set_Pixel_Sizes(ftf,0,fontSize);
                
                /*
@@ -200,7 +203,7 @@ namespace ui {
                        /*
                         *      Load the character from the font family file.
                        */
-               
+                       //uiLoop ? std::cout << "Loop while render\n" : std::cout << "No loop while render\n";          
                        if(FT_Load_Char(ftf,i,FT_LOAD_RENDER)){
                                std::cout<<"Error! Unsupported character "<<(char)i<<" ("<<i<<")."<<std::endl;
                                abort();
@@ -244,6 +247,7 @@ namespace ui {
                        
                        delete[] buf;   //free(buf);
                }
+               mtx.unlock();
        }
        
        /*
@@ -514,6 +518,76 @@ namespace ui {
                if(ret)
                        ret[0] = '\0';
        }
+       void merchantBox(const char *name,const char *opt,bool passive,const char *text,...){
+               std::cout << "Buying and selling on the bi-weekly!" << std::endl;
+               va_list dialogArgs;
+               unsigned int len;
+               char *sopt,*soptbuf;
+               
+               dialogPassive = passive;
+               
+               /*
+                *      Set up the text buffer.
+               */
+               
+               memset(dialogBoxText,0,512);
+               
+               /*
+                *      Get the text ready for rendering.
+               */
+               
+               len=strlen(name);
+               strcpy(dialogBoxText    ,name);
+               strcpy(dialogBoxText+len,": ");
+               len+=2;
+               
+               va_start(dialogArgs,text);
+               vsnprintf(dialogBoxText+len,512-len,text,dialogArgs);
+               va_end(dialogArgs);
+                               
+               /*
+                *      Set up option text.
+               */
+               
+               while(dialogOptCount){
+                       if(dialogOptText[dialogOptCount]){
+                               delete[] dialogOptText[dialogOptCount]; //free(dialogOptText[dialogOptCount]);
+                               dialogOptText[dialogOptCount] = NULL;
+                       }
+                       dialogOptCount--;
+               };
+
+               dialogOptCount = 0;
+               dialogOptChosen = 0;
+               memset(&dialogOptLoc,0,sizeof(float)*12);
+               
+               if(opt != NULL){
+                       
+                       soptbuf = new char[strlen(opt)+1];
+                       strcpy(soptbuf,opt);
+                       
+                       sopt=strtok(soptbuf,":");
+                       while(sopt != NULL){
+                               dialogOptText[dialogOptCount] = new char[strlen(sopt)+1];       //(char *)malloc(strlen(sopt));
+                               strcpy(dialogOptText[dialogOptCount++],sopt);
+                               sopt=strtok(NULL,":");
+                       }
+                       
+                       delete[] soptbuf;
+
+               }
+               
+               /*
+                *      Tell draw() that the box is ready. 
+               */
+               
+               dialogBoxExists = true;
+               dialogImportant = false;
+               dialogMerchant = true;
+               
+               if(ret)
+                       ret[0] = '\0';
+       }
        void waitForDialog(void){
                do{
                        mainLoop();
@@ -565,6 +639,7 @@ namespace ui {
 
 
        void draw(void){
+               uiLoop = true;
                unsigned char i;
                float x,y,tmp;
                char *rtext;
@@ -588,6 +663,42 @@ namespace ui {
                                        putStringCentered(offset.x,offset.y,rtext);
                                        setFontSize(16);
                                }
+                       }else if(dialogMerchant){
+                               /*static std::string merchOpt[3] = {"Accept",
+                                                                                                 "Cancel"};*/
+
+                               x=offset.x-SCREEN_WIDTH/6;
+                               y=(offset.y+SCREEN_HEIGHT/2)-HLINE*8;
+                       
+                       
+                               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,y+1);
+                               glEnd();
+                       
+                               glColor3ub(0,0,0);
+                               glRectf(x,y,x+SCREEN_WIDTH/3,y-SCREEN_HEIGHT*.6);
+                               
+                               for(i=0;i<dialogOptCount;i++){
+                                       dialogOptLoc[i][1] = (y-SCREEN_HEIGHT*.55) - i*fontSize;
+                                       setFontColor(255,255,255);
+                                       tmp = putStringCentered(offset.x,dialogOptLoc[i][1],dialogOptText[i]);
+                                       dialogOptLoc[i][2] = offset.x + tmp;
+                                       dialogOptLoc[i][0] = offset.x - tmp;
+                                       //merchOptLoc[i][1] = y - SCREEN_HEIGHT / 4 + (fontSize + HLINE) * (i + 1);
+                                       if(mouse.x > dialogOptLoc[i][0] &&
+                                          mouse.x < dialogOptLoc[i][2] &&
+                                          mouse.y > dialogOptLoc[i][1] &&
+                                          mouse.y < dialogOptLoc[i][1] + fontSize){ // fontSize
+                                                 setFontColor(255,255,0);
+                                                 putStringCentered(offset.x,dialogOptLoc[i][1],dialogOptText[i]);
+                                       }
+                               }
+                               setFontColor(255,255,255);      
                        }else{
                        
                                x=offset.x-SCREEN_WIDTH/2+HLINE*8;
@@ -670,6 +781,7 @@ namespace ui {
                                }       
                        }
                }
+               uiLoop = false;
        }
 
        void quitGame(){
@@ -1030,8 +1142,10 @@ DONE:
                /*if(ui::fontSize != 16)
                        setFontSize(16);*/
 
+               if(dialogMerchant) dialogMerchant = false;
                dialogBoxExists = false;
        }
+
        void handleEvents(void){
                static bool left=true,right=false;
                static int heyOhLetsGo = 0;
index 2df0712df9ed00ad02c30b5639d041964dd04dd9..306933d5cd5769743d998adeab5e1bd473b36148 100644 (file)
@@ -122,6 +122,10 @@ void World::deleteEntities(void){
                delete npc.back();
                npc.pop_back();
        }
+       while(!merchant.empty()){
+               delete merchant.back();
+               merchant.pop_back();
+       }
        while(!build.empty()){
                delete build.back();
                build.pop_back();
@@ -945,7 +949,8 @@ void World::detect(Player *p){
        */
        
        //auto pl = std::async(&World::singleDetect,this,p);
-       std::thread(&World::singleDetect,this, p).detach();
+       //std::thread(&World::singleDetect,this, p).detach();
+        singleDetect(p);
                
        /*
         *      Handle all remaining entities in this world. 
@@ -953,8 +958,8 @@ void World::detect(Player *p){
        
 //LOOOOP:
        for(auto &e : entity)
-               std::thread(&World::singleDetect,this,e).detach();
-               //hey->singleDetect(e);
+               //std::thread(&World::singleDetect,this,e).detach();
+               singleDetect(e);
        for(auto &part : particles){
                int l;
                unsigned int i;
@@ -1070,6 +1075,14 @@ void World::addNPC(float x,float y){
        entity.push_back(npc.back());
 }
 
+void World::addMerchant(float x, float y){
+       merchant.push_back(new Merchant());
+       merchant.back()->spawn(x,y);
+
+       npc.push_back(merchant.back());
+       entity.push_back(npc.back());
+}
+
 void World::addObject(/*ITEM_ID i*/std::string in,const char *p, float x, float y){
        object.push_back(new Object(in,p));
        object.back()->spawn(x,y);
@@ -1636,8 +1649,29 @@ World *loadWorldFromXMLNoSave(const char *path){
                                                           (char*)vil->Attribute("texture"),
                                                           ptr);
 
-                       tmp->village.back().build.push_back(tmp->build.back());
+               }else if(!strcmp(name, "stall")){
+                       if(!strcmp(vil->Attribute("type"),"market")){
+                               std::cout << "Market" << std::endl;
+                               tmp->addStructure((BUILD_SUB)70,
+                                                          vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? 
+                                                          randx : spawnx,
+                                                          100,
+                                                          (char*)vil->Attribute("texture"),
+                                                          ptr);
+                               tmp->addMerchant(0,100);
+                               strcpy(tmp->merchant.back()->name,"meme");
+
+                       }else if(!strcmp(vil->Attribute("type"),"trader")){
+                               std::cout << "Trader" << std::endl;
+                               tmp->addStructure((BUILD_SUB)71,
+                                                          vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? 
+                                                          randx : spawnx,
+                                                          100,
+                                                          (char*)vil->Attribute("texture"),
+                                                          ptr);
+                       }
                }
+               tmp->village.back().build.push_back(tmp->build.back());
                if(tmp->village.back().build.back()->loc.x < tmp->village.back().start.x){
                        tmp->village.back().start.x = tmp->village.back().build.back()->loc.x;
                }
index 269b393ffe0c6969ab399ae57a5c015e9ea238ca..d84d291a4c1d7b91e6834b0b0900abbb59339018 100644 (file)
        <npc name="Ralph" hasDialog="true" />
        <npc name="Johnny" hasDialog="false" />
        <!-- <structure type="5" inside="playerSpawnHill1_Building1.xml" /> -->
-       <village name="Meme-Town">
-               <structure type="0" x="-100" inside="playerSpawnHill1_Building1.xml"/>
+       <village name="the Cranmore Tubing Park">
+               <structure type="0" x="-300" inside="playerSpawnHill1_Building1.xml"/>
                <structure type="5" x="-500" inside="playerSpawnHill1_Building1.xml"/>
+               <stall type="market" texture="assets/style/classic/stall.png">
+                       <buy item="Dank MayMay" cost="420"/>
+                       <sell item="Dank MayMay" cost="666"/>
+               </stall>
+               <stall type="trader" texture="assets/style/classic/stall.png">
+                       <trade item="Dank MayMay" item1="Sword"/>
+               </stall>
        </village>
 
 </World>