aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authordrumsetmonkey <abelleisle@roadrunner.com>2016-03-21 08:04:33 -0400
committerdrumsetmonkey <abelleisle@roadrunner.com>2016-03-21 08:04:33 -0400
commitbbdc924d409f74594bd8c8b0d4bf55d5e5f32209 (patch)
tree6bbe247053be8686ed0223225f4d2be76f75fed9 /src
parent569d23b5d4577fce1473a82ae7f8977205ff7f0f (diff)
Created currency and new inventory
Diffstat (limited to 'src')
-rw-r--r--src/gameplay.cpp122
-rw-r--r--src/inventory.cpp292
-rw-r--r--src/ui.cpp376
-rw-r--r--src/world.cpp437
4 files changed, 715 insertions, 512 deletions
diff --git a/src/gameplay.cpp b/src/gameplay.cpp
index 0624067..7d52629 100644
--- a/src/gameplay.cpp
+++ b/src/gameplay.cpp
@@ -30,33 +30,33 @@ void segFault(){
int commonAIFunc(NPC *speaker){
XMLDocument xml;
XMLElement *exml,*oxml;
-
+
static unsigned int oldidx = 9999;
-
+
const char *name;
unsigned int idx = 0;
bool stop = false;
-
+
/*
* Load the current world's XML file into memory for reading.
*/
-
+
xml.LoadFile(currentXML.c_str());
exml = xml.FirstChildElement("Dialog");
-
+
/*
* Search for the correct dialog block.
*/
-
+
while(strcmp(exml->Attribute("name"),speaker->name))
exml = exml->NextSiblingElement();
-
+
exml = exml->FirstChildElement();
-
+
/*
* Search for which text block should be used.
*/
-
+
do{
if(!strcmp(exml->Name(),"text")){
if(exml->UnsignedAttribute("id") == (unsigned)speaker->dialogIndex){
@@ -64,10 +64,10 @@ int commonAIFunc(NPC *speaker){
/*
* Handle any quest tags
*/
-
+
if((oxml = exml->FirstChildElement("quest"))){
std::string qname;
-
+
while ( oxml ) {
if ( !(qname = oxml->StrAttribute("assign")).empty() )
player->qh.assign(qname,"None",(std::string)oxml->GetText());
@@ -79,8 +79,8 @@ int commonAIFunc(NPC *speaker){
speaker->dialogIndex = oxml->UnsignedAttribute("fail");
return commonAIFunc(speaker);
}
- }
-
+ }
+
oxml = oxml->NextSiblingElement();
}
}
@@ -90,68 +90,68 @@ CONT:
/*
* Handle any 'give' requests.
*/
-
+
if((oxml = exml->FirstChildElement("give"))){
while(oxml){
player->inv->addItem(oxml->Attribute("id"),oxml->UnsignedAttribute("count"));
oxml = oxml->NextSiblingElement();
}
}
-
+
/*
* Handle any 'take' requests.
*/
-
+
if((oxml = exml->FirstChildElement("take"))){
while(oxml){
player->inv->takeItem(oxml->Attribute("id"),oxml->UnsignedAttribute("count"));
oxml = oxml->NextSiblingElement();
}
}
-
+
/*
* Handle dialog options.
*/
-
+
if((oxml = exml->FirstChildElement("option"))){
-
+
/*
* Convert the list of options into a single colon-separated string.
*/
-
+
std::string optstr;
while(oxml){
-
+
/*
* Create a buffer big enough for the next option.
*/
-
+
optstr.append((std::string)":" + oxml->Attribute("text"));
-
+
/*
* Append the next option.
*/
-
+
dopt.push_back(oxml);
-
+
oxml = oxml->NextSiblingElement();
}
-
+
/*
* Get the player's choice, then set the XMLElement to the option's block.
*/
-
+
ui::dialogBox(speaker->name,optstr.c_str(),false,exml->GetText()+1);
ui::waitForDialog();
-
+
if(ui::dialogOptChosen)
exml = dopt[ui::dialogOptChosen-1];
-
+
while(!dopt.empty())
dopt.pop_back();
}else{
-
+
/*
* No options - simply print the text.
*/
@@ -159,11 +159,11 @@ CONT:
ui::dialogBox(speaker->name,NULL,false,exml->GetText());
ui::waitForDialog();
}
-
+
/*
* Give another NPC dialog if requested.
*/
-
+
if((name = exml->Attribute("call"))){
for(auto &n : currentWorld->npc){
if(!strcmp(n->name,name)){
@@ -174,14 +174,14 @@ CONT:
}
}
}
-
+
/*
* Handle the next dialog block if this one leads to another.
*/
-
+
if(exml->QueryUnsignedAttribute("nextid",&idx) == XML_NO_ERROR){
speaker->dialogIndex = idx;
-
+
if(exml->QueryBoolAttribute("stop",&stop) == XML_NO_ERROR && stop){
speaker->dialogIndex = 9999;
return 0;
@@ -202,11 +202,11 @@ CONT:
//return 1;
}
}
-
+
exml = exml->NextSiblingElement();
-
+
}while(exml);
-
+
return 0;
}
@@ -214,37 +214,37 @@ void commonTriggerFunc(Mob *callee){
static bool lock = false;
XMLDocument xml;
XMLElement *exml;
-
- char *text,*pch;
+
+ char *text,*pch;
if(!lock){
lock = true;
-
+
xml.LoadFile(currentXML.c_str());
exml = xml.FirstChildElement("Trigger");
-
+
while(strcmp(exml->Attribute("id"),callee->heyid.c_str()))
exml = exml->NextSiblingElement();
-
+
player->vel.x = 0;
ui::toggleBlackFast();
ui::waitForCover();
-
+
text = new char[256];
strcpy(text,exml->GetText());
pch = strtok(text,"\n");
-
+
while(pch){
ui::importantText(pch);
ui::waitForDialog();
-
+
pch = strtok(NULL,"\n");
}
-
+
delete[] text;
-
+
ui::toggleBlackFast();
-
+
callee->alive = false;
lock = false;
}
@@ -253,38 +253,38 @@ void commonTriggerFunc(Mob *callee){
void initEverything(void){
std::vector<std::string> xmlFiles;
XMLDocument xml;
-
+
/*
* Read the XML directory into an array.
*/
-
+
if(getdir("./xml/",xmlFiles)){
std::cout<<"Error reading XML files!!!1"<<std::endl;
abort();
}
-
+
/*
* Sort the files alphabetically.
*/
-
+
strVectorSortAlpha(&xmlFiles);
-
+
/*
* Load the first file found as currentWorld.
*/
-
+
for(unsigned int i=0;i<xmlFiles.size();i++){
if(xmlFiles[i] != "." && xmlFiles[i] != ".." && strcmp(xmlFiles[i].c_str()+xmlFiles[i].size()-3,"dat")){
-
+
/*
* Read in the XML file.
*/
-
+
currentWorld = loadWorldFromXML(xmlFiles[i]);
break;
}
}
-
+
pauseMenu.items.push_back(ui::createParentButton({-256/2,0},{256,75},{0.0f,0.0f,0.0f}, "Resume"));
pauseMenu.items.push_back(ui::createChildButton({-256/2,-100},{256,75},{0.0f,0.0f,0.0f}, "Options"));
pauseMenu.items.push_back(ui::createButton({-256/2,-200},{256,75},{0.0f,0.0f,0.0f}, "Save and Quit", ui::quitGame));
@@ -299,7 +299,7 @@ void initEverything(void){
optionsMenu.child = NULL;
optionsMenu.parent = &pauseMenu;
// optionsMenu.push_back(ui::createButton({-256/2,-200},{256,75},{0.0f,0.0f,0.0f}, (const char*)("Save and Quit"), );
-
+
/*
* Spawn the player and begin the game.
*/
@@ -313,9 +313,9 @@ void initEverything(void){
void destroyEverything(void){
currentWorld->save();
- delete currentWorld;
+ //delete currentWorld;
//delete[] currentXML;
-
+
while(!AIpreload.empty())
AIpreload.pop_back();
while(!AIpreaddr.empty())
diff --git a/src/inventory.cpp b/src/inventory.cpp
index e82d99e..1390719 100644
--- a/src/inventory.cpp
+++ b/src/inventory.cpp
@@ -11,6 +11,7 @@ static float hangle = 0.0f;
static bool swing = false;
//static float xc,yc;
static vec2 itemLoc;
+static const unsigned char numSlot = 7;
Mix_Chunk* swordSwing;
static std::vector<Item *> itemMap;
@@ -23,18 +24,18 @@ void items(void){
xml.LoadFile("config/items.xml");
exml = xml.FirstChildElement("item");
while(exml){
-
+
itemMap.push_back(new Item());
itemMap.back()->width = exml->FloatAttribute("width") * HLINE;
itemMap.back()->height = exml->FloatAttribute("height") * HLINE;
itemMap.back()->maxStackSize = exml->UnsignedAttribute("maxstack");
-
+
itemMap.back()->name = exml->Attribute("name");
itemMap.back()->type = exml->Attribute("type");
itemMap.back()->texloc = exml->Attribute("sprite");
exml = exml->NextSiblingElement();
- }
+ }
}
int Inventory::addItem(std::string name,uint count){
@@ -55,25 +56,25 @@ int Inventory::addItem(std::string name,uint count){
int Inventory::takeItem(std::string name,uint count){
unsigned int id = 999999;
-
+
/*
* Name to ID lookup
*/
-
+
for(unsigned int i=0;i<itemMap.size();i++){
if(itemMap[i]->name == name){
id = i;
break;
}
}
-
+
if(id == 999999)
return -1; //if no such item exists
-
+
/*
* Inventory lookup
*/
-
+
for(unsigned int i=0;i<items.size();i++){
if(items[i].id == id){
if(count > items[i].count)
@@ -98,7 +99,7 @@ int Inventory::hasItem(std::string name){
break;
}
}
-
+
if(id == 999999)
return 0;
@@ -106,15 +107,15 @@ int Inventory::hasItem(std::string name){
if(i.id == id)
return i.count;
}
-
+
return 0;
}
void initInventorySprites(void){
-
+
items();
itemtex = new GLuint[itemMap.size()];
-
+
for(unsigned int i = 0;i<itemMap.size();i++){
itemtex[i] = Texture::loadTexture(getItemTexturePath(itemMap[i]->name));
}
@@ -124,12 +125,12 @@ void initInventorySprites(void){
}
void destroyInventory(void){
-
+
while(!itemMap.empty()){
delete itemMap.front();
itemMap.erase(itemMap.begin());
}
-
+
Mix_FreeChunk(swordSwing);
}
@@ -178,27 +179,71 @@ void Inventory::setSelection(unsigned int s){
sel=s;
}
+void Inventory::setSelectionUp(){
+ if(!sel--)sel++;
+}
+
+void Inventory::setSelectionDown(){
+ sel++;
+ if(sel>=numSlot)sel=numSlot-1;
+}
+
void Inventory::draw(void){
static unsigned int lop = 0;
- const unsigned int numSlot = 7;
+ //const unsigned int numSlot = 7;
static std::vector<int>dfp(numSlot);
static std::vector<Ray>iray(numSlot);
static std::vector<vec2>curCoord(numSlot);
static int range = 200;
+
+ static std::vector<int>curdfp(4);
+ static std::vector<Ray>curRay(4);
+ static std::vector<vec2>curCurCoord(4);
+ static int curRange = 100;
+
+ static std::vector<int>massDfp(32);
+ static std::vector<vec2>massRay(32);
+ static std::vector<int>massOrder = {9,10,11,12,13,14,22,21,20,19,18,17,16,8,0,1,2,3,4,5,6,7,15,23,31,30,29,28,27,26,25,24};
+ static std::vector<int>massOrderClosing = {31,30,23,29,22,15,28,21,14,7,27,20,13,6,26,19,12,5,25,18,11,4,24,17,10,3,16,9,2,8,1,0};
+ static int massRange = 200;
+
static int itemWide = 45;
float angleB = (float)180/(float)numSlot;
float angle = float(angleB/2.0f);
unsigned int a = 0;
- unsigned int end = 0;
+ static bool end = false;
static vec2 mouseStart = {0,0};
-
+
for(auto &r : iray){
r.start.x = player->loc.x + (player->width/2);
r.start.y = player->loc.y + (player->height/2);
curCoord[a++] = r.start;
}a=0;
-
- if(invOpening){
+
+ for(auto &cr : curRay){
+ cr.start.x = (offset.x + SCREEN_WIDTH/2);
+ cr.start.y = offset.y - (a*itemWide*1.5);
+ curCurCoord[a++] = cr.start;
+ }a=0;
+
+ for(int r = 0; r < 4; r++){
+ for(int c = 0; c < 8; c++){
+ //std::cout << a << ",";
+ massRay[a].x = ((offset.x - SCREEN_WIDTH/2) + itemWide) + c*itemWide*1.5;
+ massRay[a++].y = ((offset.y + SCREEN_HEIGHT/2) - itemWide*1.5) - r*itemWide*1.5;
+ //std::cout << massRay[a-1].x << "," << massRay[a-1].y << " " << std::endl;
+ }
+ //std::cout << std::endl;
+ }a=0;
+ //std::cout << std::endl;
+
+ ui::fontTransInv = 255*(averagef(dfp)/range);
+ if(ui::fontTransInv > 255)
+ ui::fontTransInv = 255;
+ if(ui::fontTransInv < 0)
+ ui::fontTransInv = 0;
+
+ if(invOpening){
for(auto &d : dfp){
if(!a || dfp[a - 1] > 50)
d += 1.65 * deltaTime;
@@ -206,24 +251,87 @@ void Inventory::draw(void){
d = range;
a++;
}a=0;
-
+ for(auto &cd : curdfp){
+ if(!a || curdfp[a-1] > 90)
+ cd += 1.5 * deltaTime;
+ if(cd >= curRange)
+ cd = curRange;
+ a++;
+ }a=0;
+ for(uint i = 0; i < massOrder.size();i++){
+ if(!a || massDfp[massOrder[a-1]] > massRange*.75)
+ massDfp[massOrder[a]] += 5.00 * deltaTime;
+ if(massDfp[massOrder[a]] >= massRange)
+ massDfp[massOrder[a]] = massRange;
+ a++;
+ }a=0;
+
if(numSlot > 0)invOpen=true;
}else{
for(auto &d : dfp){
if(d > 0){
d -= 1.65 * deltaTime;
- }else end++;
+ }
}
- if(end >= numSlot)
+ for(auto &cd : curdfp){
+ if(cd > 0){
+ cd -= 1.0 * deltaTime;
+ }
+ }
+
+ for(uint i = 0; i < massRay.size();i++){
+ if(!a || massDfp[massOrderClosing[a-1]] <= 0)
+ massDfp[massOrderClosing[a]] -= 10.0f * deltaTime;
+ if(massDfp[massOrderClosing[a-1]] <= 0){
+ massDfp[massOrderClosing[a-1]] = 0;
+ }
+ a++;
+ }a=0;
+ end = std::all_of(std::begin(massDfp),std::end(massDfp),[](auto d){return d <= 0;});
+
+ if(end){
invOpen = false;
+ for(auto &md : massDfp){
+ if(md < 0){
+ md = 0;
+ }
+ }
+ }
+
}
-
+
/*
* a = 0
*/
-
+
if(invOpen){
-
+
+ for(auto &mr : massRay){
+ glColor4f(0.0f,0.0f,0.0f, ((float)massDfp[a]/(float)massRange)*.5f);
+ glBegin(GL_QUADS);
+ glVertex2i(mr.x-(itemWide/2), mr.y-(itemWide/2));
+ glVertex2i(mr.x-(itemWide/2)+itemWide,mr.y-(itemWide/2));
+ glVertex2i(mr.x-(itemWide/2)+itemWide,mr.y-(itemWide/2)+itemWide);
+ glVertex2i(mr.x-(itemWide/2), mr.y-(itemWide/2)+itemWide);
+ glEnd();
+ a++;
+ }a=0;
+
+ for(auto &cr : curRay){
+ curCurCoord[a].x -= float((curdfp[a]) * cos(-1));
+ curCurCoord[a].y += float((curdfp[a]) * sin(0));
+ cr.end = curCurCoord[a];
+
+ glColor4f(0.0f, 0.0f, 0.0f, ((float)curdfp[a]/(float)(curRange?curRange:1))*0.5f);
+ glBegin(GL_QUADS);
+ glVertex2i(cr.end.x-(itemWide/2), cr.end.y-(itemWide/2));
+ glVertex2i(cr.end.x-(itemWide/2)+itemWide,cr.end.y-(itemWide/2));
+ glVertex2i(cr.end.x-(itemWide/2)+itemWide,cr.end.y-(itemWide/2)+itemWide);
+ glVertex2i(cr.end.x-(itemWide/2), cr.end.y-(itemWide/2)+itemWide);
+ glEnd();
+ a++;
+ }a=0;
+
for(auto &r : iray){
angle = 180 - (angleB * a) - angleB / 2.0f;
curCoord[a].x += float((dfp[a]) * cos(angle*PI/180));
@@ -260,16 +368,47 @@ void Inventory::draw(void){
ui::putText(r.end.x-(itemWide/2)+(itemWide*.85),r.end.y-(itemWide/2),"%d",items[a].count);
}
- a++;
-
- if(sel == a - 1){
- glBegin(GL_LINES);
- glColor4f(1.0f, 0.0f, 0.0f, 0.0f);
- glVertex2i(r.start.x,r.start.y);
- glColor4f(1.0f, 0.0f, 0.0f, 0.8f);
- glVertex2i(r.end.x+20, r.end.y-20);
+ if(sel == a){
+ static float sc = 1;
+ static bool up;
+ up ? sc += .01 : sc -= .01;
+ if(sc > 1.2){
+ up = false;
+ sc = 1.2;
+ }
+ if(sc < 1.0){
+ up = true;
+ sc = 1.0;
+ }
+ glPushMatrix();
+ glLoadIdentity();
+ //glTranslatef(-sc, -sc, 0);
+ //glScalef(sc,sc,0.0f);
+ glBegin(GL_QUADS);
+ glColor4f(1.0f, 1.0f, 1.0f, ((float)dfp[a]/(float)(range?range:1)));
+ glVertex2f(r.end.x - (itemWide*sc)/2 - (itemWide*sc)*.09,r.end.y - (itemWide*sc)/2 - (itemWide*sc)*.09);
+ glVertex2f(r.end.x + (itemWide*sc)/2 + (itemWide*sc)*.09,r.end.y - (itemWide*sc)/2 - (itemWide*sc)*.09);
+ glVertex2f(r.end.x + (itemWide*sc)/2 + (itemWide*sc)*.09,r.end.y - (itemWide*sc)/2);
+ glVertex2f(r.end.x - (itemWide*sc)/2 - (itemWide*sc)*.09,r.end.y - (itemWide*sc)/2);
+
+ glVertex2f(r.end.x - (itemWide*sc)/2 - (itemWide*sc)*.09,r.end.y + (itemWide*sc)/2 + (itemWide*sc)*.09);
+ glVertex2f(r.end.x + (itemWide*sc)/2 + (itemWide*sc)*.09,r.end.y + (itemWide*sc)/2 + (itemWide*sc)*.09);
+ glVertex2f(r.end.x + (itemWide*sc)/2 + (itemWide*sc)*.09,r.end.y + (itemWide*sc)/2);
+ glVertex2f(r.end.x - (itemWide*sc)/2 - (itemWide*sc)*.09,r.end.y + (itemWide*sc)/2);
+
+ glVertex2f(r.end.x - (itemWide*sc)/2 - (itemWide*sc)*.09,r.end.y - (itemWide*sc)/2 - (itemWide*sc)*.09);
+ glVertex2f(r.end.x - (itemWide*sc)/2 ,r.end.y - (itemWide*sc)/2 - (itemWide*sc)*.09);
+ glVertex2f(r.end.x - (itemWide*sc)/2 ,r.end.y + (itemWide*sc)/2 + (itemWide*sc)*.09);
+ glVertex2f(r.end.x - (itemWide*sc)/2 - (itemWide*sc)*.09,r.end.y + (itemWide*sc)/2 + (itemWide*sc)*.09);
+
+ glVertex2f(r.end.x + (itemWide*sc)/2 ,r.end.y - (itemWide*sc)/2 - (itemWide*sc)*.09);
+ glVertex2f(r.end.x + (itemWide*sc)/2 + (itemWide*sc)*.09,r.end.y - (itemWide*sc)/2 - (itemWide*sc)*.09);
+ glVertex2f(r.end.x + (itemWide*sc)/2 + (itemWide*sc)*.09,r.end.y + (itemWide*sc)/2 + (itemWide*sc)*.09);
+ glVertex2f(r.end.x + (itemWide*sc)/2 ,r.end.y + (itemWide*sc)/2 + (itemWide*sc)*.09);
glEnd();
+ glPopMatrix();
}
+ a++;
}
}else if(invHover){
static unsigned int highlight = 0;
@@ -279,14 +418,23 @@ void Inventory::draw(void){
if(!mouseSel){
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;
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;
@@ -297,7 +445,7 @@ 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;
+ else highlight=sel-thing;
if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)){
sel = highlight;
mouseSel=false;
@@ -306,12 +454,17 @@ 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;
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;
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));
@@ -320,29 +473,36 @@ void Inventory::draw(void){
glVertex2i(r.end.x-(itemWide/2), r.end.y+(itemWide/2));
glEnd();
- 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);
- glBegin(GL_QUADS);
- if(itemMap[items[a].id]->height > itemMap[items[a].id]->width){
- 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));
- glTexCoord2i(0,0);glVertex2i(r.end.x-((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y+(itemWide/2));
- }else{
- glTexCoord2i(0,1);glVertex2i(r.end.x-(itemWide/2),r.end.y-(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
- glTexCoord2i(1,1);glVertex2i(r.end.x+(itemWide/2),r.end.y-(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
- glTexCoord2i(1,0);glVertex2i(r.end.x+(itemWide/2),r.end.y+(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
- glTexCoord2i(0,0);glVertex2i(r.end.x-(itemWide/2),r.end.y+(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
- }
- glEnd();
- glDisable(GL_TEXTURE_2D);
-
- a++;
+ std::cout << "Draw items" << std::endl;
+ if(!items.empty() && a < items.size() && items[a].count){
+ std::cout << "Jamie" << std::endl;
+ 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));
+ glTexCoord2i(0,0);glVertex2i(r.end.x-((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y+(itemWide/2));
+ }else{
+ glTexCoord2i(0,1);glVertex2i(r.end.x-(itemWide/2),r.end.y-(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
+ glTexCoord2i(1,1);glVertex2i(r.end.x+(itemWide/2),r.end.y-(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
+ glTexCoord2i(1,0);glVertex2i(r.end.x+(itemWide/2),r.end.y+(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
+ glTexCoord2i(0,0);glVertex2i(r.end.x-(itemWide/2),r.end.y+(itemWide/2)*((float)itemMap[items[a].id]->height/(float)itemMap[items[a].id]->width));
+ }
+ glEnd();
+ glDisable(GL_TEXTURE_2D);
+ std::cout << "Adding a" << std::endl;
+ a++;
+ }
}
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)
itemDraw(player,items[sel].id);
lop++;
@@ -352,9 +512,9 @@ void itemDraw(Player *p,uint id){
itemLoc.y = p->loc.y+(p->height/3);
itemLoc.x = p->left?p->loc.x:p->loc.x+p->width;
glPushMatrix();
-
+
if(!id)return;
-
+
if(itemMap[id]->type == "Sword"){
if(p->left){
if(hangle < 15){
@@ -368,7 +528,7 @@ void itemDraw(Player *p,uint id){
}
}
}else hangle = 0.0f;
-
+
glUseProgram(shaderProgram);
glUniform1i(glGetUniformLocation(shaderProgram, "sampler"), 0);
glTranslatef(itemLoc.x,itemLoc.y,0);
@@ -392,9 +552,9 @@ void itemDraw(Player *p,uint id){
int Inventory::useItem(void){
static bool up = false;
if(!invHover){
-
+
if(itemMap[items[sel].id]->type == "Sword"){
-
+
if(swing){
if(!player->left){
if(hangle==-15){up=true;Mix_PlayChannel(2,swordSwing,0);}
@@ -417,9 +577,10 @@ int Inventory::useItem(void){
bool Inventory::detectCollision(vec2 one, vec2 two){
(void)one;
(void)two;
- //float i = 0.0f;
-
- /*if(items.empty() || !items[sel].count)
+ float xc, yc;
+ float i = 0.0f;
+
+ if(items.empty() || !items[sel].count)
return false;
if(itemMap[items[sel].id]->type == "Sword"){
std::cout<<"Collision???"<<std::endl;
@@ -428,11 +589,11 @@ bool Inventory::detectCollision(vec2 one, vec2 two){
xc += float(i) * cos((hangle+90)*PI/180);
yc += float(i) * sin((hangle+90)*PI/180);
- *glColor4f(1.0f,1.0f,1.0f,1.0f);
+ /*glColor4f(1.0f,1.0f,1.0f,1.0f);
glBegin(GL_LINES);
glVertex2f(player->loc.x,player->loc.y+player->height/3);
glVertex2f(xc,yc);
- glEnd();*
+ glEnd();*/
if(xc >= one.x && xc <= two.x){
if(yc >= one.y && yc <= two.y){
@@ -442,7 +603,6 @@ bool Inventory::detectCollision(vec2 one, vec2 two){
i+=HLINE;
}
- }*/
+ }
return false;
}
-
diff --git a/src/ui.cpp b/src/ui.cpp
index ee29641..3b3f298 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -43,7 +43,7 @@ static vec2 ftexwh[93];
static vec2 ftexbl[93];
static vec2 ftexad[93];
-static unsigned char fontColor[3] = {255,255,255};
+static unsigned char fontColor[4] = {255,255,255,255};
/*
* Variables for dialog boxes / options.
@@ -100,13 +100,13 @@ void Menu::gotoChild(){
}
namespace ui {
-
+
/*
* Mouse coordinates.
*/
-
+
vec2 mouse;
- static vec2 premouse={0,0};
+ static vec2 premouse={0,0};
/*
* Variety of keydown bools
@@ -116,7 +116,7 @@ namespace ui {
/*
* Debugging flags.
*/
-
+
bool debug=false;
bool posFlag=false;
bool dialogPassive = false;
@@ -124,23 +124,25 @@ namespace ui {
int dialogPassiveTime = 0;
Trade merchTrade;
-
+ int fontTransInv = 255;
+
+
/*
* Dialog stuff that needs to be 'public'.
*/
-
+
bool dialogBoxExists = false;
bool dialogImportant = false;
unsigned char dialogOptChosen = 0;
unsigned char merchOptChosen = 0;
-
+
unsigned int textWrapLimit = 110;
-
+
/*
* Current font size. Changing this WILL NOT change the font size, see setFontSize() for
* actual font size changing.
*/
-
+
unsigned int fontSize;
/*
@@ -162,20 +164,20 @@ namespace ui {
sanic = Mix_LoadWAV("assets/sounds/sanic.wav");
//Mix_Volume(1,50);
}
-
+
void destroyFonts(void){
FT_Done_Face(ftf);
FT_Done_FreeType(ftl);
-
+
Mix_FreeChunk(dialogClick);
Mix_FreeChunk(battleStart);
Mix_FreeChunk(sanic);
}
-
+
/*
* Sets a new font family to use (*.ttf).
*/
-
+
void setFontFace(const char *ttf){
if(FT_New_Face(ftl,ttf,0,&ftf)){
std::cout<<"Error! Couldn't open "<<ttf<<"."<<std::endl;
@@ -185,56 +187,56 @@ namespace ui {
DEBUG_printf("Using font %s\n",ttf);
#endif // DEBUG
}
-
+
/*
* Sets a new font size (default: 12).
*/
-
+
void setFontSize(unsigned int size){
mtx.lock();
unsigned int i,j;
unsigned char *buf;
-
+
fontSize=size;
FT_Set_Pixel_Sizes(ftf,0,fontSize);
-
+
/*
* Pre-render 'all' the characters.
*/
-
+
glDeleteTextures(93,ftex); // delete[] any already-rendered textures
glGenTextures(93,ftex); // Generate new texture name/locations?
-
+
for(i=33;i<126;i++){
-
+
/*
* Load the character from the font family file.
*/
-
+
if(FT_Load_Char(ftf,i,FT_LOAD_RENDER)){
std::cout<<"Error! Unsupported character "<<(char)i<<" ("<<i<<")."<<std::endl;
abort();
}
-
+
/*
* Transfer the character's bitmap (?) to a texture for rendering.
*/
-
+
glBindTexture(GL_TEXTURE_2D,ftex[i-33]);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S ,GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T ,GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER ,GL_LINEAR );
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER ,GL_LINEAR );
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
-
+
/*
* The just-created texture will render red-on-black if we don't do anything to it, so
* here we create a buffer 4 times the size and transform the texture into an RGBA array,
* making it white-on-black.
*/
-
+
buf = new unsigned char[ftf->glyph->bitmap.width * ftf->glyph->bitmap.rows * 4];
-
+
for(j=0;j<ftf->glyph->bitmap.width*ftf->glyph->bitmap.rows;j++){
buf[j*4 ]=255;//fontColor[0];
buf[j*4+1]=255;//fontColor[1];
@@ -242,58 +244,66 @@ namespace ui {
buf[j*4+3]=ftf->glyph->bitmap.buffer[j] ? 255 : 0;
//buf[j*4+3]=ftf->glyph->bitmap.buffer[j];
}
-
+
ftexwh[i-33].x=ftf->glyph->bitmap.width;
ftexwh[i-33].y=ftf->glyph->bitmap.rows;
ftexbl[i-33].x=ftf->glyph->bitmap_left;
ftexbl[i-33].y=ftf->glyph->bitmap_top;
ftexad[i-33].x=ftf->glyph->advance.x>>6;
ftexad[i-33].y=ftf->glyph->advance.y>>6;
-
- glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,ftf->glyph->bitmap.width,ftf->glyph->bitmap.rows,0,GL_RGBA,GL_UNSIGNED_BYTE,buf);
-
+
+ glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,ftf->glyph->bitmap.width,ftf->glyph->bitmap.rows,0,GL_RGBA,GL_UNSIGNED_BYTE,buf);
+
delete[] buf; //free(buf);
}
mtx.unlock();
}
-
+
/*
* Set a color for font rendering (default: white).
*/
-
+
void setFontColor(unsigned char r,unsigned char g,unsigned char b){
fontColor[0]=r;
fontColor[1]=g;
fontColor[2]=b;
+ fontColor[3]=255;
}
-
+
+ void setFontColor(unsigned char r,unsigned char g,unsigned char b, unsigned char a){
+ fontColor[0]=r;
+ fontColor[1]=g;
+ fontColor[2]=b;
+ fontColor[3]=a;
+ }
+
/*
* Draws a character at the specified coordinates, aborting if the character is unknown.
*/
-
+
vec2 putChar(float xx,float yy,char c){
vec2 c1,c2;
int x = xx, y = yy;
-
+
/*
* Get the width and height of the rendered character.
*/
-
+
c1={(float)floor(x)+ftexbl[c-33].x,
(float)floor(y)+ftexbl[c-33].y};
c2=ftexwh[c-33];
-
+
/*
* Draw the character:
*/
-
+
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,ftex[c-33]);
glPushMatrix();
glTranslatef(0,-c2.y,0);
glBegin(GL_QUADS);
- glColor3ub(fontColor[0],fontColor[1],fontColor[2]);
+ glColor4ub(fontColor[0],fontColor[1],fontColor[2],fontColor[3]);
glTexCoord2f(0,1);glVertex2f(c1.x ,c1.y );
glTexCoord2f(1,1);glVertex2f(c1.x+c2.x,c1.y );
glTexCoord2f(1,0);glVertex2f(c1.x+c2.x,c1.y+c2.y);
@@ -301,28 +311,28 @@ namespace ui {
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
-
+
/*
* return the width.
*/
-
+
return ftexad[c-33];//(vec2){c2.x,ftexad[c-33].y};
}
-
+
/*
* Draw a string at the specified coordinates.
*/
-
+
float putString(const float x,const float y,const char *s){
unsigned int i=0;
float xo=x,yo=y;
vec2 add;
//vec2 off = { (float)floor(x), (float)floor(y) };
-
+
/*
* Loop on each character:
*/
-
+
do{
if(i && ((i / 110.0) == (i / 110))){
yo-=fontSize*1.05;
@@ -333,7 +343,7 @@ namespace ui {
if(i && (i / (float)textWrapLimit == i / textWrapLimit)){
yo -= fontSize * 1.05;
xo = x;
-
+
// skip a space if it's there since we just newline'd
if(s[i] == ' ')
i++;
@@ -355,14 +365,14 @@ namespace ui {
yo+=add.y;
}
}while(s[++i]);
-
+
return xo; // i.e. the string width
}
-
+
float putStringCentered(const float x,const float y,const char *s){
unsigned int i = 0;
float width = 0;
-
+
do{
if(s[i]=='\n'){ // Handle newlines
// TODO
@@ -375,11 +385,11 @@ namespace ui {
width+=ftexwh[i].x+fontSize*.1;
}
}while(s[++i]);
-
+
putString(floor(x-width/2),y,s);
return width;
}
-
+
/*
* Draw a string in a typewriter-esque fashion. Each letter is rendered as calls are made
* to this function. Passing a different string to the function will reset the counters.
@@ -391,20 +401,20 @@ namespace ui {
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
size=strlen(str); // Set the new target string size
@@ -412,58 +422,58 @@ namespace ui {
sinc=1;
typeOutDone = false;
}
-
+
/*
* Draw the next letter if necessary.
*/
-
+
if(typeOutDone)
return str;
else if(++sinc==2){
sinc=0;
-
+
strncpy(ret+linc,str+linc,1); // Get next character
-
+
if(linc<size)
linc++;
else
typeOutDone = true;
}
-
+
return ret; // The buffered string.
}
-
+
/*
* Draw a formatted string to the specified coordinates.
*/
-
+
float putText(const float x,const float y,const char *str,...){
va_list args;
char *buf;
float width;
-
+
/*
* Create a wimpy buffer.
*/
-
+
buf = new char[512]; //(char *)calloc(128,sizeof(char));
memset(buf,0,512*sizeof(char));
-
+
/*
* Handle the formatted string, printing it to the buffer.
*/
-
+
va_start(args,str);
vsnprintf(buf,512,str,args);
va_end(args);
-
+
/*
* Draw the string, free resources, return the width of the string.
*/
-
+
width=putString(x,y,buf);
delete[] buf; //free(buf);
-
+
return width;
}
void dialogBox(const char *name,const char *opt,bool passive,const char *text,...){
@@ -471,32 +481,32 @@ namespace ui {
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]);
@@ -508,30 +518,30 @@ namespace ui {
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.
+ * Tell draw() that the box is ready.
*/
-
+
dialogBoxExists = true;
dialogImportant = false;
-
+
if(ret)
ret[0] = '\0';
}
@@ -541,39 +551,39 @@ namespace ui {
std::cout << "Buying and selling on the bi-weekly!" << std::endl;
va_list dialogArgs;
size_t len;
-
+
dialogPassive = passive;
std::cout << "Market Trading: " << trade.quantity[0] << " " << trade.item[0] << " for " << trade.quantity[1] << " " << trade.item[1] << std::endl;
merchTrade = trade;
-
+
// clear the buffer
memset(dialogBoxText, '\0', 512);
-
+
// create the string
strcpy(dialogBoxText, name);
strcat(dialogBoxText, ": ");
-
+
len=strlen(dialogBoxText);
va_start(dialogArgs,text);
vsnprintf(dialogBoxText + len, 512 - len, text, dialogArgs);
va_end(dialogArgs);
-
+
// free old option text
while(dialogOptCount){
if(dialogOptText[dialogOptCount]){
delete[] dialogOptText[dialogOptCount];
dialogOptText[dialogOptCount] = NULL;
}
-
+
dialogOptCount--;
};
dialogOptChosen = 0;
merchOptChosen = 0;
memset(&dialogOptLoc, 0, sizeof(float) * 12);
-
+
// handle options if desired
if(opt){
//std::unique_ptr<char[]> soptbuf (new char[strlen(opt) + 1]);
@@ -587,27 +597,27 @@ namespace ui {
sopt = strtok(NULL,":");
}
}
-
+
// allow box to be displayed
dialogBoxExists = true;
dialogImportant = false;
dialogMerchant = true;
textWrapLimit = 50;
-
+
// kill the string created by typeOut if it contains something
if(ret)
*ret = '\0';
}
-
+
void merchantBox(){
textWrapLimit = 50;
dialogMerchant = true;
}
-
+
/**
* Wait for a dialog box to be dismissed.
*/
-
+
void waitForDialog(void){
do{
//std::thread(dialogAdvance);
@@ -663,11 +673,11 @@ namespace ui {
unsigned char i;
float x,y,tmp;
char *rtext;
-
+
if(dialogBoxExists){
-
+
rtext=typeOut(dialogBoxText);
-
+
if(dialogImportant){
setFontColor(255,255,255);
if(dialogPassive){
@@ -688,8 +698,8 @@ namespace ui {
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);
@@ -698,10 +708,10 @@ namespace ui {
glVertex2f(x-1,y-1-SCREEN_HEIGHT*.6);
glVertex2f(x-1,y+1);
glEnd();
-
+
glColor3ub(0,0,0);
glRectf(x,y,x+SCREEN_WIDTH/3,y-SCREEN_HEIGHT*.6);
-
+
// draw typeOut'd text
putString(x + HLINE, y - fontSize - HLINE, (rtext = typeOut(dialogBoxText)));
@@ -745,8 +755,8 @@ namespace ui {
merchAOptLoc[1][2] = offset.x + (SCREEN_WIDTH / 8.5);
for(i = 0; i < 2; i++){
- if(((merchAOptLoc[i][0] < merchAOptLoc[i][2]) ?
- (mouse.x > merchAOptLoc[i][0] && mouse.x < merchAOptLoc[i][2]) :
+ if(((merchAOptLoc[i][0] < merchAOptLoc[i][2]) ?
+ (mouse.x > merchAOptLoc[i][0] && mouse.x < merchAOptLoc[i][2]) :
(mouse.x < merchAOptLoc[i][0] && mouse.x > merchAOptLoc[i][2])) &&
mouse.y > merchAOptLoc[i][1] - 8 && mouse.y < merchAOptLoc[i][1] + 8){
glColor3ub(255,255, 0);
@@ -760,19 +770,19 @@ namespace ui {
glEnd();
}
-
+
// draw / handle dialog options if they exist
for(i = 0; i < dialogOptCount; i++){
setFontColor(255, 255, 255);
-
+
// draw option
tmp = putStringCentered(offset.x, dialogOptLoc[i][1], dialogOptText[i]);
-
+
// get coordinate information on option
dialogOptLoc[i][2] = offset.x + tmp;
dialogOptLoc[i][0] = offset.x - tmp;
dialogOptLoc[i][1] = y - SCREEN_HEIGHT / 2 - (fontSize + HLINE) * (i + 1);
-
+
// make text yellow if the mouse hovers over the text
if(mouse.x > dialogOptLoc[i][0] && mouse.x < dialogOptLoc[i][2] &&
mouse.y > dialogOptLoc[i][1] && mouse.y < dialogOptLoc[i][1] + 16 ){
@@ -780,13 +790,13 @@ namespace ui {
putStringCentered(offset.x, dialogOptLoc[i][1], dialogOptText[i]);
}
}
-
+
setFontColor(255, 255, 255);
}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);
@@ -797,14 +807,14 @@ namespace ui {
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);
-
+
rtext=typeOut(dialogBoxText);
-
+
putString(x+HLINE,y-fontSize-HLINE,rtext);
-
+
for(i=0;i<dialogOptCount;i++){
setFontColor(255,255,255);
tmp = putStringCentered(offset.x,dialogOptLoc[i][1],dialogOptText[i]);
@@ -821,17 +831,17 @@ namespace ui {
}
setFontColor(255,255,255);
}
-
+
if(strcmp(rtext,dialogBoxText)){
Mix_PlayChannel(1,dialogClick,0);
}
-
+
}if(!fadeIntensity){
vec2 hub = {
(SCREEN_WIDTH/2+offset.x)-fontSize*10,
(offset.y+SCREEN_HEIGHT/2)-fontSize
};
-
+
putText(hub.x,hub.y,"Health: %u/%u",player->health>0?(unsigned)player->health:0,
(unsigned)player->maxHealth
);
@@ -848,22 +858,34 @@ namespace ui {
hub.x+(player->health/player->maxHealth * 150),
hub.y+12);
}
-
+
/*
* Lists all of the quests the player is currently taking.
*/
-
+
+ setFontColor(255,255,255,fontTransInv);
if(player->inv->invOpen){
hub.y = player->loc.y + fontSize * 8;
hub.x = player->loc.x;// + player->width / 2;
-
+
putStringCentered(hub.x,hub.y,"Current Quests:");
-
+
for(auto &c : player->qh.current){
hub.y -= fontSize * 1.15;
putStringCentered(hub.x,hub.y,c.title.c_str());
- }
+ }
+
+ hub.y = offset.y + 40*1.2;
+ hub.x = offset.x + SCREEN_WIDTH/2 - 40*1.5;
+
+ putStringCentered(hub.x,hub.y,"Equipment:");
+
+ hub.y = offset.y + SCREEN_HEIGHT/2 - 20;
+ hub.x = offset.x - SCREEN_WIDTH/2 + 45*4*1.5;
+
+ putStringCentered(hub.x,hub.y,"Inventory:");
}
+ setFontColor(255,255,255,255);
}
}
@@ -875,7 +897,7 @@ namespace ui {
updateConfig();
saveConfig();
}
-
+
menuItem createButton(vec2 l, dim2 d, Color c, const char* t, menuFunc f){
menuItem temp;
temp.member = 0;
@@ -948,7 +970,7 @@ namespace ui {
setFontSize(24);
updateConfig();
SDL_Event e;
-
+
mouse.x=premouse.x+offset.x-(SCREEN_WIDTH/2);
mouse.y=(offset.y+SCREEN_HEIGHT/2)-premouse.y;
@@ -984,15 +1006,15 @@ namespace ui {
//draw the button background
glColor3f(m.button.color.red,m.button.color.green,m.button.color.blue);
- glRectf(offset.x+m.button.loc.x,
- offset.y+m.button.loc.y,
- offset.x+m.button.loc.x + m.button.dim.x,
+ glRectf(offset.x+m.button.loc.x,
+ offset.y+m.button.loc.y,
+ offset.x+m.button.loc.x + m.button.dim.x,
offset.y+m.button.loc.y + m.button.dim.y);
//draw the button text
putStringCentered(offset.x + m.button.loc.x + (m.button.dim.x/2),
(offset.y + m.button.loc.y + (m.button.dim.y/2)) - ui::fontSize/2,
m.button.text);
-
+
//tests if the mouse is over the button
if(mouse.x >= offset.x+m.button.loc.x && mouse.x <= offset.x+m.button.loc.x + m.button.dim.x){
if(mouse.y >= offset.y+m.button.loc.y && mouse.y <= offset.y+m.button.loc.y + m.button.dim.y){
@@ -1047,9 +1069,9 @@ namespace ui {
}
//draw the background of the slider
glColor4f(m.slider.color.red,m.slider.color.green,m.slider.color.blue, .5f);
- glRectf(offset.x+m.slider.loc.x,
- offset.y+m.slider.loc.y,
- offset.x+m.slider.loc.x + m.slider.dim.x,
+ glRectf(offset.x+m.slider.loc.x,
+ offset.y+m.slider.loc.y,
+ offset.x+m.slider.loc.x + m.slider.dim.x,
offset.y+m.slider.loc.y + m.slider.dim.y);
//draw the slider handle
@@ -1070,7 +1092,7 @@ namespace ui {
//draw the now combined slider text
putStringCentered(offset.x + m.slider.loc.x + (m.slider.dim.x/2), (offset.y + m.slider.loc.y + (m.slider.dim.y/2)) - ui::fontSize/2, outSV);
- }
+ }
//test if mouse is inside of the slider's borders
if(mouse.x >= offset.x+m.slider.loc.x && mouse.x <= offset.x+m.slider.loc.x + m.slider.dim.x){
if(mouse.y >= offset.y+m.slider.loc.y && mouse.y <= offset.y+m.slider.loc.y + m.slider.dim.y){
@@ -1109,18 +1131,18 @@ namespace ui {
*m.slider.var = (((mouse.y-offset.y) - m.slider.loc.y)/m.slider.dim.y)*100;
//draw a white box over the handle
glColor3f(1.0f,1.0f,1.0f);
- glRectf(offset.x+m.slider.loc.x,
- offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05),
- offset.x+m.slider.loc.x + sliderW,
+ glRectf(offset.x+m.slider.loc.x,
+ offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05),
+ offset.x+m.slider.loc.x + sliderW,
offset.y+m.slider.loc.y + (m.slider.sliderLoc * 1.05) + sliderH);
}else{
*m.slider.var = (((mouse.x-offset.x) - m.slider.loc.x)/m.slider.dim.x)*100;
//draw a white box over the handle
glColor3f(1.0f,1.0f,1.0f);
- glRectf(offset.x+m.slider.loc.x + m.slider.sliderLoc,
- offset.y+m.slider.loc.y,
- offset.x+m.slider.loc.x + (m.slider.sliderLoc + sliderW),
+ glRectf(offset.x+m.slider.loc.x + m.slider.sliderLoc,
+ offset.y+m.slider.loc.y,
+ offset.x+m.slider.loc.x + (m.slider.sliderLoc + sliderW),
offset.y+m.slider.loc.y + m.slider.dim.y);
}
}
@@ -1137,7 +1159,7 @@ namespace ui {
void takeScreenshot(GLubyte* pixels){
std::vector<GLubyte> bgr (SCREEN_WIDTH * SCREEN_HEIGHT * 3, 0);
-
+
for(uint x = 0; x < SCREEN_WIDTH*SCREEN_HEIGHT*3; x+=3){
bgr[x] = pixels[x+2];
bgr[x+1] = pixels[x+1];
@@ -1197,10 +1219,15 @@ namespace ui {
fwrite(&bgr, 1,3*SCREEN_WIDTH*SCREEN_HEIGHT,bmp);
delete[] pixels;
-
+
fclose(bmp);
}
+ void closeBox(){
+ dialogBoxExists = false;
+ dialogMerchant = false;
+ }
+
void dialogAdvance(void){
unsigned char i;
if(!typeOutDone){
@@ -1218,8 +1245,8 @@ namespace ui {
}
if(dialogMerchant){
for(i=0;i<2;i++){
- if(((merchAOptLoc[i][0] < merchAOptLoc[i][2]) ?
- (mouse.x > merchAOptLoc[i][0] && mouse.x < merchAOptLoc[i][2]) :
+ if(((merchAOptLoc[i][0] < merchAOptLoc[i][2]) ?
+ (mouse.x > merchAOptLoc[i][0] && mouse.x < merchAOptLoc[i][2]) :
(mouse.x < merchAOptLoc[i][0] && mouse.x > merchAOptLoc[i][2])) &&
mouse.y > merchAOptLoc[i][1] - 8 && mouse.y < merchAOptLoc[i][1] + 8){ // fontSize
merchOptChosen = i + 1;
@@ -1227,7 +1254,7 @@ namespace ui {
}
}
}
-
+
EXIT:
//if(!dialogMerchant)closeBox();
@@ -1246,28 +1273,29 @@ namespace ui {
void handleEvents(void){
static bool left=true,right=false;
static int heyOhLetsGo = 0;
+ static int mouseWheelUpCount = 0, mouseWheelDownCount = 0;
World *tmp;
vec2 oldpos,tmppos;
SDL_Event e;
-
+
// update mouse coords
mouse.x = premouse.x + offset.x - ( SCREEN_WIDTH / 2 );
mouse.y = ( offset.y + SCREEN_HEIGHT / 2 ) - premouse.y;
-
+
while(SDL_PollEvent(&e)){
switch(e.type){
-
+
// escape - quit game
case SDL_QUIT:
gameRunning=false;
break;
-
+
// mouse movement - update mouse vector
case SDL_MOUSEMOTION:
premouse.x=e.motion.x;
premouse.y=e.motion.y;
break;
-
+
// mouse clicks
case SDL_MOUSEBUTTONDOWN:
// right click advances dialog
@@ -1277,10 +1305,22 @@ namespace ui {
if ( ( e.button.button & SDL_BUTTON_LEFT ) && !dialogBoxExists )
player->inv->usingi = true;
break;
-
+ case SDL_MOUSEWHEEL:
+ if (e.wheel.y < 0){
+ if(mouseWheelUpCount++ && mouseWheelUpCount%5==0){
+ player->inv->setSelectionUp();
+ mouseWheelUpCount = 0;
+ }
+ }else{
+ if(mouseWheelDownCount-- && mouseWheelDownCount%5==0){
+ player->inv->setSelectionDown();
+ mouseWheelDownCount = 0;
+ }
+ }
+ break;
// key presses
case SDL_KEYDOWN:
-
+
// space - make player jump
if ( SDL_KEY == SDLK_SPACE ) {
if ( player->ground ) {
@@ -1309,11 +1349,11 @@ namespace ui {
if((tmp = currentWorld->goWorldLeft(player)) != currentWorld){
tmppos = player->loc;
player->loc = oldpos;
-
+
toggleBlackFast();
waitForCover();
player->loc = tmppos;
-
+
currentWorld = tmp;
toggleBlackFast();
}
@@ -1331,11 +1371,11 @@ namespace ui {
if((tmp = currentWorld->goWorldRight(player)) != currentWorld){
tmppos = player->loc;
player->loc = oldpos;
-
+
toggleBlackFast();
waitForCover();
player->loc = tmppos;
-
+
currentWorld = tmp;
toggleBlackFast();
}
@@ -1357,7 +1397,7 @@ namespace ui {
}
break;
case SDLK_i:
- /*currentWorld=currentWorld->goWorldBack(player); // Go back a layer if possible
+ /*currentWorld=currentWorld->goWorldBack(player); // Go back a layer if possible
if(tmp!=currentWorld){
currentWorld->detect(player);
player->vel.y=.2;
@@ -1415,7 +1455,7 @@ namespace ui {
/*
* KEYUP
*/
-
+
case SDL_KEYUP:
if(SDL_KEY == SDLK_ESCAPE){
//gameRunning = false;
@@ -1450,12 +1490,6 @@ namespace ui {
}
heyOhLetsGo = 0;
break;
- case SDLK_LEFT:
- if(player->inv->sel)player->inv->sel--;
- break;
- case SDLK_RIGHT:
- player->inv->sel++;
- break;
case SDLK_l:
player->light^=true;
break;
@@ -1494,16 +1528,16 @@ namespace ui {
default:
break;
}
-
+
if(!left&&!right)
player->vel.x=0;
-
+
break;
default:
break;
}
}
-
+
// Flush preloaded AI functions if necessary
if ( !dialogBoxExists && AIpreaddr.size() ) {
while ( !AIpreaddr.empty() ) {
@@ -1513,7 +1547,7 @@ namespace ui {
}
}
}
-
+
void toggleBlack(void){
fadeEnable ^= true;
fadeWhite = false;
@@ -1533,7 +1567,7 @@ namespace ui {
fadeEnable ^= true;
fadeWhite = true;
fadeFast = true;
-
+
Mix_PlayChannel( 1, battleStart, 0 );
}
}
diff --git a/src/world.cpp b/src/world.cpp
index 8af9e6a..c31f551 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -65,10 +65,10 @@ const std::string bgPaths[2][9]={
const std::string buildPaths[] = {
"townhall.png",
- "house1.png",
- "house2.png",
- "house1.png",
- "house1.png",
+ "house1.png",
+ "house2.png",
+ "house1.png",
+ "house1.png",
"fountain1.png",
"lampPost1.png",
"brazzier.png"
@@ -87,7 +87,7 @@ const float bgDraw[4][3]={
/**
* Sets the desired theme for the world's background.
- *
+ *
* The images chosen for the background layers are selected depending on the
* world's background type.
*/
@@ -100,7 +100,7 @@ setBackground( WorldBGType bgt )
case WorldBGType::Forest:
bgTex = new Texturec( bgFiles );
break;
-
+
case WorldBGType::WoodHouse:
bgTex = new Texturec( bgFilesIndoors );
break;
@@ -113,7 +113,7 @@ setBackground( WorldBGType bgt )
/**
* Sets the world's style.
- *
+ *
* The world's style will determine what sprites are used for things like\
* generic structures.
*/
@@ -122,25 +122,25 @@ void World::
setStyle( std::string pre )
{
unsigned int i;
-
+
// get folder prefix
std::string prefix = pre.empty() ? "assets/style/classic/" : pre;
-
+
for ( i = 0; i < arrAmt(buildPaths); i++ )
sTexLoc.push_back( prefix + buildPaths[i] );
-
+
prefix += "bg/";
-
+
for ( i = 0; i < arrAmt(bgPaths[0]); i++ )
bgFiles.push_back( prefix + bgPaths[0][i] );
-
+
for ( i = 0; i < arrAmt(bgPaths[1]); i++ )
bgFilesIndoors.push_back( prefix + bgPaths[1][i] );
}
/**
* Creates a world object.
- *
+ *
* Note that all this does is nullify pointers, to prevent as much disaster as
* possible. Functions like setBGM(), setStyle() and generate() should be called
* before the World is actually put into use.
@@ -150,14 +150,14 @@ World::
World( void )
{
bgmObj = NULL;
-
+
toLeft = NULL;
toRight = NULL;
}
/**
* The entity vector destroyer.
- *
+ *
* This function will free all memory used by all entities, and then empty the
* vectors they were stored in.
*/
@@ -176,25 +176,25 @@ deleteEntities( void )
delete npc.back();
npc.pop_back();
}
-
+
// free structures
while ( !build.empty() ) {
delete build.back();
build.pop_back();
}
-
+
// free objects
while ( !object.empty() ) {
delete object.back();
object.pop_back();
}
-
+
// clear entity array
entity.clear();
-
+
// free particles
particles.clear();
-
+
// clear light array
light.clear();
@@ -207,7 +207,7 @@ deleteEntities( void )
/**
* The world destructor.
- *
+ *
* This will free objects used by the world itself, then free the vectors of
* entity-related objects.
*/
@@ -218,9 +218,9 @@ World::
// sdl2_mixer's object
if(bgmObj)
Mix_FreeMusic(bgmObj);
-
+
delete bgTex;
-
+
delete[] toLeft;
delete[] toRight;
@@ -229,20 +229,20 @@ World::
/**
* Generates a world of the specified width.
- *
+ *
* This will mainly populate the WorldData array, mostly preparing the World
* object for usage.
*/
void World::
generate( unsigned int width )
-{
+{
// iterator for `for` loops
std::vector<WorldData>::iterator wditer;
-
+
// see below for description
float geninc = 0;
-
+
// check for valid width
if ( (int)width <= 0 )
UserError("Invalid world dimensions");
@@ -250,17 +250,17 @@ generate( unsigned int width )
// allocate space for world
worldData = std::vector<WorldData> (width + GROUND_HILLINESS, WorldData { false, {0,0}, 0, 0 });
lineCount = worldData.size();
-
+
// prepare for generation
worldData.front().groundHeight = GROUND_HEIGHT_INITIAL;
wditer = worldData.begin();
-
+
// give every GROUND_HILLINESSth entry a groundHeight value
for(unsigned int i = GROUND_HILLINESS; i < worldData.size(); i += GROUND_HILLINESS, wditer += GROUND_HILLINESS)
worldData[i].groundHeight = (*wditer).groundHeight + (randGet() % 8 - 4);
// create slopes from the points that were just defined, populate the rest of the WorldData structure
-
+
for(wditer = worldData.begin(); wditer != worldData.end(); wditer++){
if ((*wditer).groundHeight)
// wditer + GROUND_HILLINESS can go out of bounds (invalid read)
@@ -278,15 +278,15 @@ generate( unsigned int width )
(*wditer).groundHeight = GROUND_HEIGHT_MINIMUM;
else if ( (*wditer).groundHeight > GROUND_HEIGHT_MAXIMUM )
(*wditer).groundHeight = GROUND_HEIGHT_MAXIMUM;
-
+
if( (*wditer).groundHeight <= 0 )
(*wditer).groundHeight = GROUND_HEIGHT_MINIMUM;
}
-
+
// define x-coordinate of world's leftmost 'line'
worldStart = (width - GROUND_HILLINESS) * HLINE / 2 * -1;
-
+
// create empty star array, should be filled here as well...
star = std::vector<vec2> (100, vec2 { 0, 400 } );
for ( auto &s : star ) {
@@ -297,7 +297,7 @@ generate( unsigned int width )
/**
* Updates all entity and player coordinates with their velocities.
- *
+ *
* Also handles music fading, although that could probably be placed elsewhere.
*/
@@ -307,15 +307,15 @@ update( Player *p, unsigned int delta )
// update player coords
p->loc.y += p->vel.y * delta;
p->loc.x +=(p->vel.x * p->speed) * delta;
-
+
// update entity coords
for ( auto &e : entity ) {
e->loc.y += e->vel.y * delta;
-
+
// dont let structures move?
if ( e->type != STRUCTURET && e->canMove ) {
e->loc.x += e->vel.x * delta;
-
+
// update boolean directions
if ( e->vel.x < 0 )
e->left = true;
@@ -341,7 +341,7 @@ update( Player *p, unsigned int delta )
}
}
}
-
+
// handle music fades
if ( ui::dialogImportant )
Mix_FadeOutMusic(2000);
@@ -351,7 +351,7 @@ update( Player *p, unsigned int delta )
/**
* Set the world's BGM.
- *
+ *
* This will load a sound file to be played while the player is in this world.
* If no file is found, no music should play.
*/
@@ -365,7 +365,7 @@ setBGM( std::string path )
/**
* Toggle play/stop of the background music.
- *
+ *
* If new music is to be played a crossfade will occur, otherwise... uhm.
*/
@@ -387,7 +387,7 @@ bgmPlay( World *prev ) const
/**
* The world draw function.
- *
+ *
* This function will draw the background layers, entities, and player to the
* screen.
*/
@@ -397,34 +397,34 @@ draw( Player *p )
{
// iterators
int i, iStart, iEnd;
-
+
// shade value for draws -- may be unnecessary
int shadeBackground = -worldShade;
-
+
// player's offset in worldData[]
int pOffset;
-
+
// world width in pixels
int width = worldData.size() * HLINE;
-
+
// shade value for GLSL
float shadeAmbient = -worldShade / 50.0f + 0.5f; // -0.5f to 1.5f
if ( shadeAmbient < 0 )
shadeAmbient = 0;
else if ( shadeAmbient > 0.9f )
shadeAmbient = 1;
-
+
/*
* Draw background images.
*/
-
+
glEnable( GL_TEXTURE_2D );
-
+
// the sunny wallpaper is faded with the night depending on tickCount
-
+
bgTex->bind( 0 );
safeSetColorA( 255, 255, 255, 255 - worldShade * 4 );
-
+
glBegin( GL_QUADS );
glTexCoord2i( 0, 0 ); glVertex2i( worldStart, SCREEN_HEIGHT );
glTexCoord2i( 1, 0 ); glVertex2i( -worldStart, SCREEN_HEIGHT );
@@ -434,24 +434,24 @@ draw( Player *p )
bgTex->bindNext();
safeSetColorA( 255, 255, 255, worldShade * 4 );
-
+
glBegin( GL_QUADS );
glTexCoord2i( 0, 0 ); glVertex2i( worldStart, SCREEN_HEIGHT );
glTexCoord2i( 1, 0 ); glVertex2i( -worldStart, SCREEN_HEIGHT );
glTexCoord2i( 1, 1 ); glVertex2i( -worldStart, 0 );
glTexCoord2i( 0, 1 ); glVertex2i( worldStart, 0 );
glEnd();
-
+
glDisable( GL_TEXTURE_2D );
-
+
// draw the stars if the time deems it appropriate
-
+
//if (((( weather == WorldWeather::Dark ) & ( tickCount % DAY_CYCLE )) < DAY_CYCLE / 2) ||
// ((( weather == WorldWeather::Sunny ) & ( tickCount % DAY_CYCLE )) > DAY_CYCLE * .75) ){
- if ( worldShade > 0 ) {
+ if ( worldShade > 0 ) {
safeSetColorA( 255, 255, 255, 255 - (getRand() % 30 - 15) );
-
+
for ( i = 0; i < 100; i++ ) {
glRectf(star[i].x + offset.x * .9,
star[i].y,
@@ -459,15 +459,15 @@ draw( Player *p )
star[i].y + HLINE
);
}
- }
-
+ }
+
// draw remaining background items
-
+
glEnable( GL_TEXTURE_2D );
-
+
bgTex->bindNext();
safeSetColorA( 150 + shadeBackground * 2, 150 + shadeBackground * 2, 150 + shadeBackground * 2, 255 );
-
+
glBegin( GL_QUADS );
for ( i = 0; i <= (int)(worldData.size() * HLINE / 1920); i++ ) {
glTexCoord2i( 0, 1 ); glVertex2i( width / 2 * -1 + (1920 * i ) + offset.x * .85, GROUND_HEIGHT_MINIMUM );
@@ -476,11 +476,11 @@ draw( Player *p )
glTexCoord2i( 0, 0 ); glVertex2i( width / 2 * -1 + (1920 * i ) + offset.x * .85, GROUND_HEIGHT_MINIMUM + 1080 );
}
glEnd();
-
+
for ( i = 0; i < 4; i++ ) {
bgTex->bindNext();
safeSetColorA( bgDraw[i][0] + shadeBackground * 2, bgDraw[i][0] + shadeBackground * 2, bgDraw[i][0] + shadeBackground * 2, bgDraw[i][1] );
-
+
glBegin( GL_QUADS );
for( int j = worldStart; j <= -worldStart; j += 600 ){
glTexCoord2i( 0, 1 ); glVertex2i( j + offset.x * bgDraw[i][2], GROUND_HEIGHT_MINIMUM );
@@ -490,22 +490,22 @@ draw( Player *p )
}
glEnd();
}
-
+
glDisable( GL_TEXTURE_2D );
-
+
// draw black under backgrounds
-
+
glColor3ub( 0, 0, 0 );
glRectf( worldStart, GROUND_HEIGHT_MINIMUM, -worldStart, 0 );
-
+
pOffset = (offset.x + p->width / 2 - worldStart) / HLINE;
-
+
/*
* Prepare for world ground drawing.
*/
-
+
// only draw world within player vision
-
+
if ((iStart = pOffset - (SCREEN_WIDTH / 2 / HLINE) - GROUND_HILLINESS) < 0)
iStart = 0;
@@ -517,51 +517,51 @@ draw( Player *p )
// draw particles and buildings
std::for_each( particles.begin(), particles.end(), [](Particles part) { if ( part.behind ) part.draw(); });
-
+
for ( auto &b : build )
b->draw();
// draw light elements?
-
+
glEnable( GL_TEXTURE_2D );
-
+
glActiveTexture( GL_TEXTURE0 );
bgTex->bindNext();
-
+
std::unique_ptr<GLfloat[]> pointArrayBuf = std::make_unique<GLfloat[]> (2 * (light.size() + p->light));
auto pointArray = pointArrayBuf.get();
-
+
for ( i = 0; i < (int)light.size(); i++ ) {
pointArray[2 * i ] = light[i].loc.x - offset.x;
pointArray[2 * i + 1] = light[i].loc.y;
}
-
+
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
-
+
glUseProgram( shaderProgram );
glUniform1i( glGetUniformLocation( shaderProgram, "sampler"), 0 );
glUniform1f( glGetUniformLocation( shaderProgram, "amb" ), shadeAmbient );
-
+
if ( p->light ) {
pointArray[2 * (light.size() + 1) ] = (float)( p->loc.x + SCREEN_WIDTH / 2 );
pointArray[2 * (light.size() + 1) + 1] = (float)( p->loc.y );
}
-
+
if ( light.size() + (int)p->light == 0)
glUniform1i( glGetUniformLocation( shaderProgram, "numLight"), 0);
else {
glUniform1i ( glGetUniformLocation( shaderProgram, "numLight" ), light.size() + (int)p->light );
- glUniform2fv( glGetUniformLocation( shaderProgram, "lightLocation"), light.size() + (int)p->light, pointArray );
+ glUniform2fv( glGetUniformLocation( shaderProgram, "lightLocation"), light.size() + (int)p->light, pointArray );
glUniform3f ( glGetUniformLocation( shaderProgram, "lightColor" ), 1.0f, 1.0f, 1.0f );
}
-
+
/*
* Draw the dirt.
*/
-
+
glBegin( GL_QUADS );
-
+
// faulty
/*glTexCoord2i(0 ,0);glVertex2i(pOffset - (SCREEN_WIDTH / 1.5),0);
glTexCoord2i(64,0);glVertex2i(pOffset + (SCREEN_WIDTH / 1.5),0);
@@ -577,50 +577,50 @@ draw( Player *p )
glTexCoord2i( 0, 0 ); glVertex2i(worldStart + i * HLINE , worldData[i].groundHeight - GRASS_HEIGHT );
glTexCoord2i( 1, 0 ); glVertex2i(worldStart + i * HLINE + HLINE , worldData[i].groundHeight - GRASS_HEIGHT );
-
+
glTexCoord2i( 1, (int)(worldData[i].groundHeight / 64) + worldData[i].groundColor ); glVertex2i(worldStart + i * HLINE + HLINE, 0 );
glTexCoord2i( 0, (int)(worldData[i].groundHeight / 64) + worldData[i].groundColor ); glVertex2i(worldStart + i * HLINE , 0 );
-
+
if ( worldData[i].groundHeight == GROUND_HEIGHT_MINIMUM - 1 )
worldData[i].groundHeight = 0;
}
-
+
glEnd();
-
+
glUseProgram(0);
glDisable(GL_TEXTURE_2D);
-
+
/*
* Draw the grass/the top of the ground.
*/
glEnable( GL_TEXTURE_2D );
-
+
glActiveTexture( GL_TEXTURE0 );
bgTex->bindNext();
-
+
glUseProgram( shaderProgram );
glUniform1i( glGetUniformLocation( shaderProgram, "sampler"), 0);
float cgh[2];
for ( i = iStart; i < iEnd - GROUND_HILLINESS; i++ ) {
-
+
// load the current line's grass values
if ( worldData[i].groundHeight )
memcpy( cgh, worldData[i].grassHeight, 2 * sizeof( float ));
else
memset( cgh, 0 , 2 * sizeof( float ));
-
+
// flatten the grass if the player is standing on it.
if( !worldData[i].grassUnpressed ){
cgh[0] /= 4;
cgh[1] /= 4;
}
-
+
// actually draw the grass.
-
+
safeSetColorA( 255, 255, 255, 255 );
-
+
glBegin( GL_QUADS );
glTexCoord2i( 0, 0 ); glVertex2i( worldStart + i * HLINE , worldData[i].groundHeight + cgh[0] );
glTexCoord2i( 1, 0 ); glVertex2i( worldStart + i * HLINE + HLINE / 2, worldData[i].groundHeight + cgh[0] );
@@ -639,9 +639,9 @@ draw( Player *p )
/*
* Draw remaining entities.
*/
-
+
std::for_each( particles.begin(), particles.end(), [](Particles part) { if ( !part.behind ) part.draw(); });
-
+
for ( auto &n : npc )
n->draw();
@@ -650,11 +650,11 @@ draw( Player *p )
for ( auto &o : object )
o->draw();
-
+
/*
* Handle grass-squishing.
*/
-
+
// calculate the line that the player is on
int ph = ( p->loc.x + p->width / 2 - worldStart ) / HLINE;
@@ -670,13 +670,13 @@ draw( Player *p )
/*
* Draw the player.
*/
-
+
p->draw();
}
/**
* Handles physics and such for a single entity.
- *
+ *
* This function is kept private, as World::detect() should be used instead to
* handle stuffs for all entities at once.
*/
@@ -687,11 +687,11 @@ singleDetect( Entity *e )
std::string killed;
unsigned int i,j;
int l;
-
+
/*
* Kill any dead entities.
*/
-
+
if ( !e->alive || e->health <= 0 ) {
for ( i = 0; i < entity.size(); i++) {
if ( entity[i] == e ){
@@ -747,71 +747,71 @@ singleDetect( Entity *e )
std::cout<<"RIP "<<e->name<<"."<<std::endl;
exit(0);
}
-
+
/*
* Handle only living entities.
*/
-
+
if(e->alive){
-
+
if ( e->type == MOBT && Mobp(e)->subtype == MS_TRIGGER )
return;
-
+
/*
* Calculate the line that this entity is currently standing on.
*/
-
+
l=(e->loc.x + e->width / 2 - worldStart) / HLINE;
if(l < 0) l=0;
i = l;
if(i > lineCount-1) i=lineCount-1;
-
+
/*
* If the entity is under the world/line, pop it back to the surface.
*/
-
+
if ( e->loc.y < worldData[i].groundHeight ) {
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;
-
+
}
-
+
/*
* Insure that the entity doesn't fall off either edge of the world.
*/
if(e->loc.x < worldStart){ // Left bound
-
+
e->vel.x=0;
e->loc.x=(float)worldStart + HLINE / 2;
-
+
}else if(e->loc.x + e->width + HLINE > worldStart + worldStart * -2){ // Right bound
-
+
e->vel.x=0;
e->loc.x=worldStart + worldStart * -2 - e->width - HLINE;
-
+
}
}
}
/**
* Handle entity logic for the world.
- *
+ *
* This function runs World::singleDetect() for the player and every entity
* currently in a vector of this world. Particles and village entrance/exiting
* are also handled here.
@@ -821,20 +821,20 @@ void World::
detect( Player *p )
{
int l;
-
+
// handle the player
std::thread( &World::singleDetect, this, p).detach();
-
+
// handle other entities
for ( auto &e : entity )
std::thread(&World::singleDetect,this,e).detach();
-
+
// handle particles
for ( auto &part : particles ) {
-
+
// get particle's current world line
l = (part.loc.x + part.width / 2 - worldStart) / HLINE;
-
+
if ( l < 0 )
l = 0;
@@ -850,7 +850,7 @@ detect( Player *p )
} else if ( part.gravity && part.vely > -2 )
part.vely -= .003 * deltaTime;
}
-
+
// handle particle creation
for ( auto &b : build ) {
switch ( b->bsubtype ) {
@@ -869,7 +869,7 @@ detect( Player *p )
particles.back().fountain = true;
}
break;
-
+
case FIRE_PIT:
for(unsigned int r = (randGet() % 20) + 11; r--; ) {
addParticle(randGet() % (int)(b->width / 2) + b->loc.x + b->width / 4, // x
@@ -908,18 +908,18 @@ void World::addStructure(BUILD_SUB sub, float x,float y, std::string tex, std::s
build.push_back(new Structures());
build.back()->inWorld = this;
build.back()->textureLoc = tex;
-
+
build.back()->spawn(sub,x,y);
-
+
build.back()->inside = inside;
-
+
entity.push_back(build.back());
}
void World::addMob(int t,float x,float y){
mob.push_back(new Mob(t));
mob.back()->spawn(x,y);
-
+
entity.push_back(mob.back());
}
@@ -927,14 +927,14 @@ void World::addMob(int t,float x,float y,void (*hey)(Mob *)){
mob.push_back(new Mob(t));
mob.back()->spawn(x,y);
mob.back()->hey = hey;
-
+
entity.push_back(mob.back());
}
void World::addNPC(float x,float y){
npc.push_back(new NPC());
npc.back()->spawn(x,y);
-
+
entity.push_back(npc.back());
}
@@ -974,7 +974,7 @@ char *World::setToLeft(const char *file){
delete[] toLeft;
if(!file)
return (toLeft = NULL);
-
+
strcpy((toLeft = new char[strlen(file) + 1]),file);
return toLeft;
}
@@ -983,40 +983,41 @@ char *World::setToRight(const char *file){
delete[] toRight;
if(!file)
return (toRight = NULL);
-
+
strcpy((toRight = new char[strlen(file) + 1]),file);
return toRight;
}
+//what is this clyne why are they differnet
World *World::
goWorldLeft( Player *p )
{
World *tmp;
-
+
// check if player is at world edge
if(toLeft && p->loc.x < worldStart + HLINE * 15.0f){
-
+
// load world (`toLeft` conditional confirms existance)
tmp = loadWorldFromXML(toLeft);
-
+
// adjust player location
- p->loc.x = tmp->worldStart - HLINE * -10.0f;
+ p->loc.x = -tmp->worldStart - (int)HLINE * -10.0f;
p->loc.y = tmp->worldData[tmp->lineCount - 1].groundHeight;
-
+
return tmp;
}
return this;
-}
+}
World *World::goWorldRight(Player *p){
World *tmp;
-
+
if(toRight && p->loc.x + p->width > -worldStart - HLINE * 15){
tmp = loadWorldFromXML(toRight);
-
- p->loc.x = tmp->worldStart + HLINE * 10;
+
+ p->loc.x = tmp->worldStart + (int)HLINE * 10;
p->loc.y = GROUND_HEIGHT_MINIMUM;
-
+
return tmp;
}
return this;
@@ -1032,13 +1033,13 @@ goInsideStructure( Player *p )
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));
-
+
tmp = loadWorldFromXML(b->inside.c_str());
-
+
ui::toggleBlackFast();
ui::waitForCover();
ui::toggleBlackFast();
-
+
return tmp;
}
}
@@ -1051,11 +1052,11 @@ goInsideStructure( Player *p )
ui::toggleBlackFast();
ui::waitForCover();
-
+
p->loc.x = b->loc.x + (b->width / 2);
-
+
ui::toggleBlackFast();
-
+
return tmp;
}
}
@@ -1079,51 +1080,59 @@ 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;
}
void World::load(void){
std::string save,data,line;
const char *filedata;
-
+
save = (std::string)currentXML + ".dat";
filedata = readFile(save.c_str());
data = filedata;
std::istringstream iss (data);
-
+
for(auto &n : npc){
std::getline(iss,line);
if(line == "dOnE")return;
if((n->dialogIndex = std::stoi(line)) != 9999)
n->addAIFunc(commonAIFunc,false);
else n->clearAIFunc();
-
+
std::getline(iss,line);
if(line == "dOnE")return;
n->loc.x = std::stoi(line);
@@ -1131,7 +1140,7 @@ void World::load(void){
if(line == "dOnE")return;
n->loc.y = std::stoi(line);
}
-
+
for(auto &b : build){
std::getline(iss,line);
if(line == "dOnE")return;
@@ -1140,7 +1149,7 @@ void World::load(void){
if(line == "dOnE")return;
b->loc.y = std::stoi(line);
}
-
+
for(auto &m : mob){
std::getline(iss,line);
if(line == "dOnE")return;
@@ -1152,12 +1161,12 @@ void World::load(void){
if(line == "dOnE")return;
m->alive = std::stoi(line);
}
-
+
while(std::getline(iss,line)){
if(line == "dOnE")
break;
}
-
+
delete[] filedata;
}
@@ -1166,16 +1175,16 @@ IndoorWorld::IndoorWorld(void){
IndoorWorld::~IndoorWorld(void){
delete bgTex;
-
+
deleteEntities();
}
void IndoorWorld::generate(unsigned int width){ // Generates a flat area of width 'width'
lineCount=width+GROUND_HILLINESS; // Sets line count to the desired width plus GEN_INC to remove incorrect line calculations.
if(lineCount<=0)abort();
-
+
worldData = std::vector<WorldData> (lineCount, WorldData { false, {0,0}, INDOOR_FLOOR_HEIGHT, 0 });
-
+
worldStart = (width - GROUND_HILLINESS) * HLINE / 2 * -1;
}
@@ -1183,71 +1192,71 @@ void IndoorWorld::draw(Player *p){
unsigned int i,ie;
//int j,x,v_offset;
int x;
-
+
/*
* Draw the background.
*/
-
+
glEnable(GL_TEXTURE_2D);
-
+
std::unique_ptr<GLfloat[]> pointArrayBuf = std::make_unique<GLfloat[]> (2 * (light.size() + p->light));
auto pointArray = pointArrayBuf.get();
-
+
for ( i = 0; i < light.size(); i++ ) {
pointArray[2 * i ] = light[i].loc.x - offset.x;
pointArray[2 * i + 1] = light[i].loc.y;
}
-
+
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
-
+
glUseProgram( shaderProgram );
glUniform1i( glGetUniformLocation( shaderProgram, "sampler"), 0 );
glUniform1f( glGetUniformLocation( shaderProgram, "amb" ), 0.3f );
-
+
if ( p->light ) {
pointArray[2 * (light.size() + 1) ] = (float)( p->loc.x + SCREEN_WIDTH / 2 );
pointArray[2 * (light.size() + 1) + 1] = (float)( p->loc.y );
}
-
+
if ( light.size() + (int)p->light == 0)
glUniform1i( glGetUniformLocation( shaderProgram, "numLight"), 0);
else {
glUniform1i ( glGetUniformLocation( shaderProgram, "numLight" ), light.size() + (int)p->light );
- glUniform2fv( glGetUniformLocation( shaderProgram, "lightLocation"), light.size() + (int)p->light, pointArray );
+ glUniform2fv( glGetUniformLocation( shaderProgram, "lightLocation"), light.size() + (int)p->light, pointArray );
glUniform3f ( glGetUniformLocation( shaderProgram, "lightColor" ), 1.0f, 1.0f, 1.0f );
}
-
+
bgTex->bind(0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //for the s direction
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //for the t direction
glColor4ub(255,255,255,255);
-
+
glBegin(GL_QUADS);
glTexCoord2i(0,1); glVertex2i( worldStart - SCREEN_WIDTH / 2,0);
glTexCoord2i((-worldStart*2+SCREEN_WIDTH)/512,1);glVertex2i(-worldStart + SCREEN_WIDTH / 2,0);
glTexCoord2i((-worldStart*2+SCREEN_WIDTH)/512,0);glVertex2i(-worldStart + SCREEN_WIDTH / 2,SCREEN_HEIGHT);
glTexCoord2i(0,0); glVertex2i( worldStart - SCREEN_WIDTH / 2,SCREEN_HEIGHT);
glEnd();
-
+
glUseProgram(0);
glDisable(GL_TEXTURE_2D);
-
+
/*
* Calculate the starting and ending points to draw the ground from.
*/
-
+
/*v_offset = (p->loc.x - x_start) / HLINE;
j = v_offset - (SCREEN_WIDTH / 2 / HLINE) - GEN_INC;
if(j < 0)j = 0;
i = j;
-
+
ie = v_offset + (SCREEN_WIDTH / 2 / HLINE) - GEN_INC;
if(ie > lineCount)ie = lineCount;*/
-
+
i = 0;
ie = lineCount;
-
+
/*
* Draw the ground.
*/
@@ -1256,7 +1265,7 @@ void IndoorWorld::draw(Player *p){
glBegin(GL_QUADS);
for(;i < ie - GROUND_HILLINESS;i++){
safeSetColor(150,100,50);
-
+
x = worldStart + i * HLINE;
glVertex2i(x ,worldData[i].groundHeight);
glVertex2i(x + HLINE,worldData[i].groundHeight);
@@ -1265,11 +1274,11 @@ void IndoorWorld::draw(Player *p){
}
glEnd();
glUseProgram(0);
-
+
/*
* Draw all entities.
*/
-
+
for ( auto &part : particles )
part.draw();
@@ -1282,14 +1291,14 @@ void IndoorWorld::draw(Player *p){
Arena::Arena(World *leave,Player *p,Mob *m){
generate(800);
addMob(MS_DOOR,100,100);
-
+
inBattle = true;
mmob = m;
mmob->aggressive = false;
-
+
mob.push_back(m);
entity.push_back(m);
-
+
battleNest.push_back(leave);
battleNestLoc.push_back(p->loc);
}
@@ -1304,17 +1313,17 @@ World *Arena::exitArena(Player *p){
p->loc.x + p->width / 2 < mob[0]->loc.x + HLINE * 12 ){
tmp = battleNest.front();
battleNest.erase(battleNest.begin());
-
+
inBattle = !battleNest.empty();
ui::toggleBlackFast();
ui::waitForCover();
-
+
p->loc = battleNestLoc.back();
battleNestLoc.pop_back();
-
+
mob.clear();
mmob->alive = false;
-
+
return tmp;
}else{
return this;
@@ -1337,14 +1346,14 @@ loadWorldFromXMLNoSave( std::string path ) {
XMLDocument xml;
XMLElement *wxml;
XMLElement *vil;
-
+
World *tmp;
float spawnx, randx;
bool dialog,Indoor;
-
+
const char *ptr;
std::string name;
-
+
currentXML = (std::string)"xml/" + path;
xml.LoadFile(currentXML.c_str());
@@ -1361,10 +1370,10 @@ loadWorldFromXMLNoSave( std::string path ) {
Indoor = true;
tmp = new IndoorWorld();
}
-
+
while(wxml){
name = wxml->Name();
-
+
if(name == "link"){
if((ptr = wxml->Attribute("left")))
tmp->setToLeft(ptr);
@@ -1381,7 +1390,7 @@ loadWorldFromXMLNoSave( std::string path ) {
if(Indoor)
((IndoorWorld *)tmp)->generate(wxml->UnsignedAttribute("width"));
else {
-
+
tmp->generate(wxml->UnsignedAttribute("width"));
}
}else if(Indoor)
@@ -1395,7 +1404,7 @@ loadWorldFromXMLNoSave( std::string path ) {
tmp->addMob(type,spawnx,wxml->FloatAttribute("y"));
if(wxml->QueryBoolAttribute("aggressive",&dialog) == XML_NO_ERROR)
tmp->mob.back()->aggressive = dialog;
-
+
}else if(name == "npc"){
const char *npcname;
@@ -1403,23 +1412,23 @@ loadWorldFromXMLNoSave( std::string path ) {
tmp->addNPC(0,100);
else
tmp->addNPC(spawnx,wxml->FloatAttribute("y"));
-
-
+
+
if((npcname = wxml->Attribute("name"))){
delete[] tmp->npc.back()->name;
tmp->npc.back()->name = new char[strlen(npcname) + 1];
strcpy(tmp->npc.back()->name,npcname);
}
-
+
dialog = false;
if(wxml->QueryBoolAttribute("hasDialog",&dialog) == XML_NO_ERROR && dialog)
tmp->npc.back()->addAIFunc(commonAIFunc,false);
else tmp->npc.back()->dialogIndex = 9999;
-
+
}else if(name == "structure"){
tmp->addStructure((BUILD_SUB)wxml->UnsignedAttribute("type"),
- wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR ?
- getRand() % tmp->getTheWidth() / 2.0f :
+ wxml->QueryFloatAttribute("x",&spawnx) != XML_NO_ERROR ?
+ getRand() % tmp->getTheWidth() / 2.0f :
spawnx,
100,
wxml->StrAttribute("texture"),
@@ -1449,7 +1458,7 @@ loadWorldFromXMLNoSave( std::string path ) {
/**
* READS DATA ABOUT STRUCTURE CONTAINED IN VILLAGE
*/
-
+
if(name == "structure"){
tmp->addStructure((BUILD_SUB)vil->UnsignedAttribute("type"),
vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ? randx : spawnx,
@@ -1460,7 +1469,7 @@ loadWorldFromXMLNoSave( std::string path ) {
if(!strcmp(vil->Attribute("type"),"market")){
std::cout << "Market" << std::endl;
tmp->addStructure((BUILD_SUB)70,
- vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ?
+ vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ?
randx : spawnx,
100,
vil->StrAttribute("texture"),
@@ -1484,20 +1493,20 @@ loadWorldFromXMLNoSave( std::string path ) {
}else if(!strcmp(vil->Attribute("type"),"trader")){
std::cout << "Trader" << std::endl;
tmp->addStructure((BUILD_SUB)71,
- vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ?
+ vil->QueryFloatAttribute("x", &spawnx) != XML_NO_ERROR ?
randx : spawnx,
100,
vil->StrAttribute("texture"),
vil->StrAttribute("inside"));
}
}
-
+
vptr->build.push_back(tmp->build.back());
-
+
if(vptr->build.back()->loc.x < vptr->start.x){
vptr->start.x = vptr->build.back()->loc.x;
}
-
+
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;
}
@@ -1505,7 +1514,7 @@ loadWorldFromXMLNoSave( std::string path ) {
//go to the next element in the village block
vil = vil->NextSiblingElement();
}
-
+
std::ifstream dat (((std::string)currentXML + ".dat").c_str());
if(dat.good()){
dat.close();