aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordrumsetmonkey <abelleisle@roadrunner.com>2016-02-26 08:28:48 -0500
committerdrumsetmonkey <abelleisle@roadrunner.com>2016-02-26 08:28:48 -0500
commit4df411931dd63f22258be76911e0648c3cdc3936 (patch)
tree878df1b96322d7f9c25151f0882606df2571e57c
parent0396f428411eb015f796643f9e7e38ca97f8fd42 (diff)
Merchants kinda work...
-rw-r--r--include/common.h3
-rw-r--r--include/entities.h30
-rw-r--r--include/ui.h7
-rw-r--r--include/world.h8
-rw-r--r--main.cpp24
-rw-r--r--src/config.cpp1
-rw-r--r--src/entities.cpp49
-rw-r--r--src/gameplay.cpp3
-rw-r--r--src/ui.cpp116
-rw-r--r--src/world.cpp42
-rw-r--r--xml/playerSpawnHill1.xml11
11 files changed, 265 insertions, 29 deletions
diff --git a/include/common.h b/include/common.h
index a99e352..cbfc507 100644
--- a/include/common.h
+++ b/include/common.h
@@ -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.
diff --git a/include/entities.h b/include/entities.h
index 926eeae..6c8e658 100644
--- a/include/entities.h
+++ b/include/entities.h
@@ -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;
diff --git a/include/ui.h b/include/ui.h
index 6a81ff8..0499570 100644
--- a/include/ui.h
+++ b/include/ui.h
@@ -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);
/*
diff --git a/include/world.h b/include/world.h
index f9e952e..7338097 100644
--- a/include/world.h
+++ b/include/world.h
@@ -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.
diff --git a/main.cpp b/main.cpp
index 97f788c..cb28bcc 100644
--- 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++)
diff --git a/src/config.cpp b/src/config.cpp
index 72a071d..45bab3f 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -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));
diff --git a/src/entities.cpp b/src/entities.cpp
index 6c2da81..afcc9ad 100644
--- a/src/entities.cpp
+++ b/src/entities.cpp
@@ -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;
diff --git a/src/gameplay.cpp b/src/gameplay.cpp
index 4bbc672..1c77309 100644
--- a/src/gameplay.cpp
+++ b/src/gameplay.cpp
@@ -217,8 +217,7 @@ void commonTriggerFunc(Mob *callee){
XMLDocument xml;
XMLElement *exml;
- char *text,*pch;
-
+ char *text,*pch;
if(!lock){
lock = true;
diff --git a/src/ui.cpp b/src/ui.cpp
index 6e616a7..836a98e 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -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;
diff --git a/src/world.cpp b/src/world.cpp
index 2df0712..306933d 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -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;
}
diff --git a/xml/playerSpawnHill1.xml b/xml/playerSpawnHill1.xml
index 269b393..d84d291 100644
--- a/xml/playerSpawnHill1.xml
+++ b/xml/playerSpawnHill1.xml
@@ -11,9 +11,16 @@
<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>