*
*/
+#define HLINES(n) (HLINE * n)
+
extern unsigned int HLINE;
extern float VOLUME_MASTER;
#include <config.hpp>
#include <world.hpp>
+
#include <ui_menu.hpp>
+#include <ui_action.hpp>
#include <ft2build.h>
#include <SDL2/SDL_opengl.h>
* limited until a right click is given, closing the box.
*/
+ void drawBox(vec2 c1, vec2 c2);
void dialogBox(const char *name,const char *opt,bool passive,const char *text,...);
void merchantBox(const char *name,Trade trade,const char *opt,bool passive,const char *text,...);
void merchantBox();
--- /dev/null
+#ifndef ACTION_H_
+#define ACTION_H_
+
+#include <common.hpp>
+#include <ui.hpp>
+
+namespace ui {
+ namespace action {
+ extern bool make;
+
+ // enables the action ui
+ void enable(void);
+ // disables the action ui
+ void disable(void);
+
+ // draws the action ui
+ void draw(vec2 loc);
+ }
+}
+
+#endif // ACTION_H_
#include <common.hpp>
#include <config.hpp>
+#include <ui.hpp>
typedef void (*menuFunc)(void);
vec2 loc;
dim2 dim;
Color color;
-
+
const char *text;
menuFunc func;
} button;
vec2 loc;
dim2 dim;
Color color;
-
+
float minValue;
float maxValue;
float sliderLoc;
-
+
const char *text;
float *var;
} slider;
public:
std::vector<menuItem> items;
Menu *child, *parent;
-
+
~Menu() {
// TODO you CANNOT delete null pointers!
/*child = NULL;
menuItem createChildButton(vec2 l, dim2 d, Color c, const char* t);
menuItem createParentButton(vec2 l, dim2 d, Color c, const char* t);
menuItem createSlider(vec2 l, dim2 d, Color c, float min, float max, const char* t, float* v);
-
+
void draw(void);
}
}
vec2 start;
vec2 end;
bool in;
- std::vector<Structures *> build;
Village(const char *meme, World *w);
~Village(void){}
std::vector<std::string> sTexLoc;
- std::vector<Light> light;
- std::vector<Village> village;
- std::vector<Particles> particles;
- std::vector<Object> object;
- std::vector<Mob> mob;
+ std::vector<Light> light;
+ std::vector<Village> village;
+ std::vector<Particles> particles;
+ std::vector<Object> object;
+ std::vector<Mob *> mob;
+ std::vector<Structures *> build;
public:
Light *getLastLight(void);
Mob *getLastMob(void);
+ Entity *getNearInteractable(Entity e);
+ vec2 getStructurePos(int index);
std::string getSTextureLocation(unsigned int index) const;
* world.
*/
- std::vector<Entity *> entity;
-
- /**
- * A vector of all NPCs in this world.
- */
-
- std::vector<NPC *> npc;
- std::vector<Merchant *> merchant;
-
- /**
- * A vector of all Structures in this world.
- */
-
- std::vector<Structures *> build;
+ std::vector<Entity *> entity;
+ std::vector<NPC *> npc;
+ std::vector<Merchant *> merchant;
/**
* NULLifies pointers and allocates necessary memory. This should be
virtual ~World(void);
- /**
- * Adds a structure to the world, with the specified subtype and
- * coordinates. `inside` is a file name for the IndoorWorld XML file that
- * this structure will lead to; if NULL the player won't be able to enter
- * the structure.
- */
-
- void addStructure(BUILD_SUB subtype,float x,float y, std::string tex, std::string inside);
+ void addLight(vec2 xy, Color color);
+ void addMerchant(float x, float y, bool housed);
+ void addMob(int type,float x,float y);
+ void addMob(int t,float x,float y,void (*hey)(Mob *));
+ void addNPC(float x,float y);
+ void addObject(std::string in, std::string pickupDialog, float x, float y);
+ void addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int d);
+ void addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int d, unsigned char flags);
+ void addStructure(BUILD_SUB subtype,float x,float y, std::string tex, std::string inside);
Village *addVillage(std::string name, World *world);
- /**
- * Adds a Mob to the world with the specified type and coordinates.
- */
-
- void addMob(int type,float x,float y);
-
- /**
- * Adds a Mob to the world with a handler function that can be called by
- * certain mobs to trigger events.
- */
-
- void addMob(int t,float x,float y,void (*hey)(Mob *));
-
- /**
- * Adds an NPC to the world with the specified coordinates.
- */
-
- void addNPC(float x,float y);
-
- /**
- * Adds a Merchant to the world at the specified coordinates.
- */
-
- void addMerchant(float x, float y);
-
- /**
- * Adds an object to the world with the specified item id and coordinates.
- * If `pickupDialog` is not NULL, that string will display in a dialog box
- * upon object interaction.
- */
-
- void addObject(std::string in, std::string pickupDialog, float x, float y);
-
- /**
- * Adds a particle to the world with the specified coordinates, dimensions,
- * velocity, color and duration (time to live).
- */
-
- void addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int d);
- void addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int d, unsigned char flags);
-
- /**
- * Adds a light to the world with the specified coordinates and color.
- */
-
- void addLight(vec2 xy, Color color);
-
/**
* Updates the coordinates of everything in the world that has coordinates
* and a velocity. The provided delta time is used for smoother updating.
* The main game loop contains all of the global variables the game uses, and it runs the main game loop, the render loop, and the logic loop that control all of the entities.
*/
-/*
- * Standard library includes
- */
-
-#include <fstream>
-#include <istream>
-#include <thread>
-
#include <tinyxml2.h>
using namespace tinyxml2;
* Game includes
*/
-#include <config.hpp>
#include <common.hpp>
+#include <config.hpp>
+#include <entities.hpp>
#include <world.hpp>
#include <ui.hpp>
-#include <entities.hpp>
-
-/**
- * The window object returned by SDL when we create the main window.
- */
+// SDL's window object
SDL_Window *window = NULL;
-/**
- * Determines when the game should exit. This variable is set to true right
- * before the main loop is entered, once set to false the game will exit/
- * free resources.
- */
-
+// main loop runs based on this variable's value
bool gameRunning;
-/**
- * TODO
- */
-
-GLuint invUI;
-
-/**
- * Contains an angle based off of the player's location and the mouse's
- * location.
- */
-
-float handAngle;
-
-/**
- * Contains a pointer to the world that the player is currently in. All render/
- * logic operations have to go access members of this object in order to work.
- */
-
+// world objects for the current world and the two that are adjacent
World *currentWorld = NULL,
*currentWorldToLeft = NULL,
*currentWorldToRight = NULL;
-/**
- * The player object.
- */
-
+// the player object
Player *player;
/**
* Load sprites used in the inventory menu. See src/inventory.cpp
*/
- invUI = Texture::loadTexture("assets/invUI.png" );
mouseTex = Texture::loadTexture("assets/mouse.png");
initInventorySprites();
currentWorld->draw(player);
- /*
- * Calculate the player's hand angle.
- */
-
- handAngle = atan((ui::mouse.y - (player->loc.y + player->height/2)) / (ui::mouse.x - player->loc.x + player->width/2))*180/PI;
- if(ui::mouse.x < player->loc.x){
- if(handAngle <= 0)
- handAngle+=180;
- if(ui::mouse.y < player->loc.y + player->height/2){
- handAngle+=180;
- }
- }
-
- if(ui::mouse.x > player->loc.x && ui::mouse.y < player->loc.y+player->height/2 && handAngle <= 0)
- handAngle = 360 + handAngle;
-
/*
* Draw the player's inventory.
*/
ui::putText(offset.x-SCREEN_WIDTH/2,
(offset.y+SCREEN_HEIGHT/2)-ui::fontSize,
- "FPS: %d\nG:%d\nRes: %ux%u\nE: %d\nPOS: (x)%+.2f\n (y)%+.2f\nTc: %u\nHA: %+.2f\nVol: %f\nWea: %s",
+ "fps: %d\ngrounded:%d\nresolution: %ux%u\nentity cnt: %d\nloc: (%+.2f, %+.2f)\nticks: %u\nvolume: %f\nweather: %s",
fps,
player->ground,
SCREEN_WIDTH, // Window dimensions
player->loc.x, // The player's x coordinate
debugY, // The player's y coordinate
tickCount,
- handAngle,
VOLUME_MASTER,
getWorldWeatherStr(weather).c_str()
);
} else
e->near = false;
} else if (e->type == MOBT) {
+ e->near = player->isNear(*e);
+
switch (e->subtype) {
case MS_RABBIT:
case MS_BIRD:
}
name = new char[32];
- getRandomName(this);
+ if (type == MOBT)
+ name[0] = '\0';
+ else
+ getRandomName(this);
followee = NULL;
}
}
break;
case STRUCTURET:
- for(auto &strt : currentWorld->build){
- if(this == strt){
- glActiveTexture(GL_TEXTURE0);
- tex->bind(0);
- break;
- }
- }
- break;
+ /* fall through */
default:
glActiveTexture(GL_TEXTURE0);
tex->bind(0);
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
- if (near)
+ if (near && type != MOBT)
ui::putStringCentered(loc.x+width/2,loc.y-ui::fontSize-HLINE/2,name);
if (health != maxHealth) {
glColor3ub(150,0,0); glRectf(loc.x, loc.y + height, loc.x + width, loc.y + height + HLINE * 2);
a++;
}
C("Done drawing standard inv");
- }else if(invHover){
+ } else if (invHover) {
static unsigned int highlight = 0;
static unsigned int thing = 0;
- std::cout<<"Inventory2???"<<std::endl;
-
- if(!mouseSel){
+ if (!mouseSel) {
+ // setup?
mouseStart.x = ui::mouse.x - offset.x;
- std::cout << "Setting highlight" << std::endl;
highlight = sel;
- std::cout << "Setting thing" << std::endl;
thing = sel;
- std::cout << "Setting mouseSel" << std::endl;
- mouseSel=true;
- std::cout << "Done" << std::endl;
- }else{
- std::cout << "Is mousex greater than the start" << std::endl;
+ mouseSel = true;
+ } else {
if((ui::mouse.x - offset.x) >= mouseStart.x){
- std::cout << "Thing" << std::endl;
thing = (ui::mouse.x - offset.x - mouseStart.x)/80;
- std::cout << "Highlight" << std::endl;
highlight=sel+thing;
- std::cout << "Highlight Check" << std::endl;
if(highlight>numSlot-1)highlight=numSlot-1;
- std::cout << "Left Click" << std::endl;
if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)){
sel = highlight;
mouseSel=false;
}
if((ui::mouse.x - offset.x) < mouseStart.x){
thing = (mouseStart.x - (ui::mouse.x - offset.x))/80;
- if((int)sel-(int)thing<0)highlight=0;
- else highlight=sel-thing;
+ if ((int)sel - (int)thing < 0)
+ highlight = 0;
+ else
+ highlight = sel - thing;
if(SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT)){
sel = highlight;
mouseSel=false;
}
}
}
- std::cout << "Rays" << std::endl;
- for(auto &r : iray){
- std::cout << "Setting angle" << std::endl;
- angle=180-(angleB*a) - angleB/2.0f;
- std::cout << "Currcourd" << std::endl;
+
+ a = 0;
+ for (auto &r : iray) {
+ angle = 180 - (angleB * a) - angleB / 2.0f;
+
curCoord[a].x += float(range) * cos(angle*PI/180);
curCoord[a].y += float(range) * sin(angle*PI/180);
- std::cout << "Ray.end" << std::endl;
r.end = curCoord[a];
- std::cout << "Draw" << std::endl;
+ // square drawing
glColor4f(0.0f, 0.0f, 0.0f, a == highlight ? 0.5f : 0.1f);
glBegin(GL_QUADS);
glVertex2i(r.end.x-(itemWide/2), r.end.y-(itemWide/2));
glVertex2i(r.end.x-(itemWide/2), r.end.y+(itemWide/2));
glEnd();
- std::cout << "Draw items" << std::endl;
- if(!items.empty() && a < items.size() && items[a].count){
- std::cout << "Jamie" << std::endl;
+ if (a < items.size() && items[a].count) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, itemtex[items[a].id]);
glColor4f(1.0f, 1.0f, 1.0f, a == highlight ? 0.8f : 0.2f);
- std::cout << "Done Binding" << std::endl;
glBegin(GL_QUADS);
- std::cout << "jdjdjd" << std::endl;
if(itemMap[items[a].id]->height > itemMap[items[a].id]->width){
- std::cout << "map" << std::endl;
glTexCoord2i(0,1);glVertex2i(r.end.x-((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y-(itemWide/2));
glTexCoord2i(1,1);glVertex2i(r.end.x+((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y-(itemWide/2));
glTexCoord2i(1,0);glVertex2i(r.end.x+((itemWide/2)*((float)itemMap[items[a].id]->width/(float)itemMap[items[a].id]->height)),r.end.y+(itemWide/2));
}
glEnd();
glDisable(GL_TEXTURE_2D);
- std::cout << "Adding a" << std::endl;
- a++;
}
+ a++;
+ }
+
+ if (highlight < items.size()) {
+ ui::putStringCentered(player->loc.x + player->width / 2,
+ player->loc.y + range * 0.75f,
+ itemMap[items[highlight].id]->name.c_str()
+ );
}
- ui::putStringCentered(player->loc.x+player->width/2, player->loc.y + range*.75,itemMap[items[highlight].id]->name.c_str());
}
if(!items.empty() && items.size() > sel && items[sel].count)
pageTexReady = true;
}
+ void drawBox(vec2 c1, vec2 c2) {
+ // draw black body
+ glColor3ub(0, 0, 0);
+ glRectf(c1.x, c1.y, c2.x, c2.y);
+
+ // draw white border
+ glColor3ub(255, 255, 255);
+ glBegin(GL_LINE_STRIP);
+ glVertex2i(c1.x , c1.y);
+ glVertex2i(c2.x + 1, c1.y);
+ glVertex2i(c2.x + 1, c2.y);
+ glVertex2i(c1.x - 1, c2.y);
+ glVertex2i(c1.x , c1.y);
+ glEnd();
+ }
+
void draw(void){
unsigned char i;
float x,y,tmp;
std::string rtext;
+ // will return if not toggled
+ action::draw(vec2 {player->loc.x + player->width / 2, player->loc.y + player->height + HLINE});
+
if (pageTexReady) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, pageTex);
x=offset.x-SCREEN_WIDTH/6;
y=(offset.y+SCREEN_HEIGHT/2)-HLINE*8;
- // draw the box border
- glColor3ub(255,255,255);
- glBegin(GL_LINE_STRIP);
- glVertex2f(x-1 ,y+1);
- glVertex2f(x+1+(SCREEN_WIDTH/3),y+1);
- glVertex2f(x+1+(SCREEN_WIDTH/3),y-1-SCREEN_HEIGHT*.6);
- glVertex2f(x-1,y-1-SCREEN_HEIGHT*.6);
- glVertex2f(x - 1,y+1);
- glEnd();
-
- // draw the box
- glColor3ub(0,0,0);
- glRectf(x,y,x+SCREEN_WIDTH/3,y-SCREEN_HEIGHT*.6);
+ drawBox(vec2 {x, y}, vec2 {x + SCREEN_WIDTH / 3, y - SCREEN_HEIGHT * 0.6f});
// draw typeOut'd text
putString(x + HLINE, y - fontSize - HLINE, (rtext = typeOut(dialogBoxText)));
- std::string itemString1 = std::to_string(merchTrade.quantity[0]);
- itemString1 += "x";
-
- std::string itemString2 = std::to_string(merchTrade.quantity[1]);
- itemString2 += "x";
+ std::string itemString1 = std::to_string(merchTrade.quantity[0]) + "x",
+ itemString2 = std::to_string(merchTrade.quantity[1]) + "x";
- putStringCentered(offset.x - (SCREEN_WIDTH / 10) + 20, offset.y + (SCREEN_HEIGHT / 5) + 40 + (fontSize*2), itemString1.c_str());
- putStringCentered(offset.x - (SCREEN_WIDTH / 10) + 20, offset.y + (SCREEN_HEIGHT / 5) + 40 + fontSize, merchTrade.item[0].c_str());
+ vec2 merchBase = {offset.x, offset.y + SCREEN_HEIGHT / 5};
- putStringCentered(offset.x + (SCREEN_WIDTH / 10) - 20, offset.y + (SCREEN_HEIGHT / 5) + 40 + (fontSize*2), itemString2.c_str());
- putStringCentered(offset.x + (SCREEN_WIDTH / 10) - 20, offset.y + (SCREEN_HEIGHT / 5) + 40 + fontSize, merchTrade.item[1].c_str());
-
- putStringCentered(offset.x,offset.y + (SCREEN_HEIGHT / 5) + 60, "for");
+ putStringCentered(merchBase.x + SCREEN_WIDTH / 10 - 20, merchBase.y + 40 + fontSize * 2, itemString1.c_str());
+ putStringCentered(merchBase.x + SCREEN_WIDTH / 10 - 20, merchBase.y + 40 + fontSize , merchTrade.item[0].c_str());
+ putStringCentered(merchBase.x - SCREEN_WIDTH / 10 , merchBase.y + 40 + fontSize * 2, itemString2.c_str());
+ putStringCentered(merchBase.x - SCREEN_WIDTH / 10 , merchBase.y + 40 + fontSize , merchTrade.item[1].c_str());
+ putStringCentered(offset.x, merchBase.y + 60, "for");
glEnable(GL_TEXTURE_2D);
+
glBindTexture(GL_TEXTURE_2D, getItemTexture(merchTrade.item[0]));
glBegin(GL_QUADS);
glTexCoord2d(0,1);glVertex2f(offset.x - (SCREEN_WIDTH / 10) ,offset.y + (SCREEN_HEIGHT/5));
glTexCoord2d(1,0);glVertex2f(offset.x + (SCREEN_WIDTH / 10) ,offset.y + (SCREEN_HEIGHT/5) + 40);
glTexCoord2d(0,0);glVertex2f(offset.x + (SCREEN_WIDTH / 10) - 40,offset.y + (SCREEN_HEIGHT/5) + 40);
glEnd();
+
glDisable(GL_TEXTURE_2D);
merchArrowLoc[0].x = offset.x - (SCREEN_WIDTH / 8.5) - 16;
}
setFontColor(255, 255, 255);
- }else{ //normal dialog box
+ } else { //normal dialog box
- x=offset.x-SCREEN_WIDTH/2+HLINE*8;
- y=(offset.y+SCREEN_HEIGHT/2)-HLINE*8;
-
- // draw white border
- glColor3ub(255, 255, 255);
+ x = offset.x - SCREEN_WIDTH / 2 + HLINE * 8;
+ y = offset.y + SCREEN_HEIGHT / 2 - HLINE * 8;
- glBegin(GL_LINE_STRIP);
- glVertex2i(x-1 ,y+1);
- glVertex2i(x+1+SCREEN_WIDTH-HLINE*16,y+1);
- glVertex2i(x+1+SCREEN_WIDTH-HLINE*16,y-1-SCREEN_HEIGHT/4);
- glVertex2i(x-1 ,y-1-SCREEN_HEIGHT/4);
- glVertex2i(x-1 ,y+1);
- glEnd();
-
- glColor3ub(0,0,0);
- glRectf(x,y,x+SCREEN_WIDTH-HLINE*16,y-SCREEN_HEIGHT/4);
+ drawBox(vec2 {x, y}, vec2 {x + SCREEN_WIDTH - HLINE * 16, y - SCREEN_HEIGHT / 4});
rtext = typeOut(dialogBoxText);
// mouse clicks
case SDL_MOUSEBUTTONDOWN:
- // right click advances dialog
- if ((e.button.button & SDL_BUTTON_RIGHT) && (dialogBoxExists | pageTexReady))
- dialogAdvance();
+ // run actions?
+ if ((action::make = e.button.button & SDL_BUTTON_RIGHT))
+ /*player->inv->invHover =*/ edown = false;
- // left click uses item
- if ((e.button.button & SDL_BUTTON_LEFT) && !dialogBoxExists)
- player->inv->usingi = true;
+ if (dialogBoxExists || pageTexReady) {
+ // right click advances dialog
+ if ((e.button.button & SDL_BUTTON_RIGHT))
+ dialogAdvance();
+ } else {
+ // left click uses item
+ if (e.button.button & SDL_BUTTON_LEFT)
+ player->inv->usingi = true;
+ }
if(mouse.x > player->loc.x && mouse.x < player->loc.x + player->width &&
- mouse.y > player->loc.y && mouse.y < player->loc.y + player->height) {
+ mouse.y > player->loc.y && mouse.y < player->loc.y + player->height) {
player->vel.y = .05;
fr = mouse;
ig = player;
}
}
break;
- case SDLK_s:
- break;
case SDLK_w:
if (inBattle) {
tmp = currentWorld;
currentWorld = tmp;
break;
case SDLK_LSHIFT:
- if(debug){
- Mix_PlayChannel(1,sanic,-1);
+ if (debug) {
+ Mix_PlayChannel(1, sanic, -1);
player->speed = 4.0f;
- }else
+ } else
player->speed = 2.0f;
break;
case SDLK_LCTRL:
player->speed = .5;
break;
case SDLK_e:
- edown=true;
- if(!heyOhLetsGo){
+ edown = true;
+
+ // start hover counter?
+ if (!heyOhLetsGo) {
heyOhLetsGo = loops;
player->inv->mouseSel = false;
}
- if(loops - heyOhLetsGo >= 2 && !(player->inv->invOpen) && !(player->inv->selected))
- player->inv->invHover=true;
+
+ // run hover thing
+ if (loops - heyOhLetsGo >= 2 && !(player->inv->invOpen) && !(player->inv->selected)) {
+ player->inv->invHover = true;
+
+ // enable action ui
+ action::enable();
+ }
+
break;
default:
break;
}
- if(tmp != currentWorld){
- std::swap(tmp,currentWorld);
+
+ // handle world switches?
+ if (tmp != currentWorld) {
+ std::swap(tmp, currentWorld);
toggleBlackFast();
waitForCover();
- std::swap(tmp,currentWorld);
+ std::swap(tmp, currentWorld);
toggleBlackFast();
}
}
else player->inv->selected = false;
player->inv->mouseSel = false;
}
+
+ // disable action ui
+ action::disable();
+
heyOhLetsGo = 0;
break;
case SDLK_l:
else {
currentWorld->addStructure(FIRE_PIT, player->loc.x, player->loc.y, "", "");
currentWorld->addLight({player->loc.x + SCREEN_WIDTH/2, player->loc.y},{1.0f,1.0f,1.0f});
- currentWorld->getLastLight()->follow(currentWorld->build.back());
+ //currentWorld->getLastLight()->follow(currentWorld->build.back());
currentWorld->getLastLight()->makeFlame();
}
break;
--- /dev/null
+#include <ui_action.hpp>
+
+extern World *currentWorld;
+extern Player *player;
+extern bool inBattle;
+
+static std::vector<std::pair<std::string, vec3>> actionText = {
+ {"Attack", vec3 {0, 0, 0}},
+ {"Action", vec3 {0, 0, 0}},
+ {"Umm" , vec3 {0, 0, 0}}
+};
+
+void actionAttack(void);
+void actionAction(void);
+
+static std::vector<void (*)(void)> actionFunc = {
+ actionAttack,
+ actionAction,
+ nullptr,
+};
+
+static bool actionToggle = false;
+static unsigned int actionHover = 0;
+static Entity *nearEntity = nullptr, *lastEntity = nullptr;
+
+namespace ui {
+ namespace action {
+ bool make = false;
+
+ // enables action ui
+ void enable(void) {
+ actionToggle = true;
+ }
+
+ // disables action ui
+ void disable(void) {
+ actionToggle = false;
+
+ if (lastEntity != nullptr)
+ lastEntity->canMove = true;
+ }
+
+ // draws the action ui
+ void draw(vec2 loc) {
+ static bool second = false;
+ unsigned int i = 1;
+ float y = loc.y;
+
+ if (!actionToggle)
+ return;
+
+ nearEntity = currentWorld->getNearInteractable(*player);
+
+ if (nearEntity == nullptr) {
+ if (lastEntity != nullptr) {
+ lastEntity->canMove = true;
+ lastEntity = nullptr;
+ }
+ return;
+ } else if (nearEntity != lastEntity) {
+ if (lastEntity != nullptr)
+ lastEntity->canMove = true;
+ lastEntity = nearEntity;;
+ }
+
+ if (make) {
+ if (!actionHover) {
+ make = false;
+ return;
+ }
+
+ if (!second)
+ second = true;
+ else {
+ second = false;
+ return;
+ }
+
+ if (actionFunc[actionHover - 1] != nullptr)
+ std::thread(actionFunc[actionHover - 1]).detach();
+
+ actionHover = 0;
+ make = false;
+ return;
+ } else {
+ nearEntity->canMove = false;
+ ui::drawBox(vec2 {loc.x - HLINES(11), loc.y}, vec2 {loc.x + HLINES(12), loc.y + actionText.size() * HLINES(8)});
+
+ for (auto &s : actionText) {
+ s.second.z = ui::putStringCentered((s.second.x = loc.x), (s.second.y = (y += fontSize * 1.15f)), s.first) / 2;
+
+ if (ui::mouse.x > s.second.x - s.second.z && ui::mouse.x < s.second.x + s.second.z &&
+ ui::mouse.y > s.second.y && ui::mouse.y < s.second.y + ui::fontSize) {
+ actionHover = i;
+ ui::setFontColor(255, 100, 100, 255);
+ ui::putStringCentered(s.second.x, s.second.y, s.first);
+ ui::setFontColor(255, 255, 255, 255);
+ }
+ i++;
+ }
+
+ ui::putStringCentered(loc.x, y + fontSize * 1.2f, nearEntity->name);
+ }
+
+ if (i == actionText.size())
+ actionHover = 0;
+
+ ui::setFontColor(255, 255, 255, 255);
+ }
+ }
+}
+
+void actionAttack(void)
+{
+ auto m = currentWorld->getNearInteractable(*player);
+
+ if (m->type == MOBT) {
+ if (!inBattle && m != nullptr) {
+ Arena *a = new Arena(currentWorld, player, Mobp(m));
+ a->setStyle("");
+ a->setBackground(WorldBGType::Forest);
+ a->setBGM("assets/music/embark.wav");
+
+ ui::toggleWhiteFast();
+ ui::waitForCover();
+ currentWorld = a;
+ ui::toggleWhiteFast();
+ }
+ } else {
+ ui::dialogBox(player->name, "", false, "%s doesn't appear to be in the mood for fighting...", m->name);
+ }
+}
+
+void actionAction(void)
+{
+ auto e = currentWorld->getNearInteractable(*player);
+
+ if (e->type == NPCT) {
+ if (!NPCp(e)->aiFunc.empty())
+ e->interact();
+ }
+}
deleteEntities(void)
{
// free mobs
- mob.clear();
+ while(!mob.empty()){
+ delete mob.back();
+ mob.pop_back();
+ }
merchant.clear();
while(!npc.empty()){
}
for (auto &m : mob)
- m.draw();
+ m->draw();
for (auto &o : object)
o.draw();
}
void World::addMob(int t,float x,float y){
- mob.emplace_back(t);
- mob.back().spawn(x,y);
+ mob.push_back(new Mob(t));
+ mob.back()->spawn(x,y);
- entity.push_back(&mob.back());
+ entity.push_back(mob.back());
}
void World::addMob(int t,float x,float y,void (*hey)(Mob *)){
- mob.emplace_back(t);
- mob.back().spawn(x,y);
- mob.back().hey = hey;
+ mob.push_back(new Mob(t));
+ mob.back()->spawn(x,y);
+ mob.back()->hey = hey;
- entity.push_back(&mob.back());
+ entity.push_back(mob.back());
}
void World::addNPC(float x,float y){
entity.push_back(npc.back());
}
-void World::addMerchant(float x, float y){
+void World::addMerchant(float x, float y, bool housed){
merchant.push_back(new Merchant());
merchant.back()->spawn(x,y);
+ if (housed)
+ merchant.back()->inside = build.back();
+
npc.push_back(merchant.back());
entity.push_back(npc.back());
}
Mob *World::
getLastMob(void)
{
- return &mob.back();
+ return mob.back();
+}
+
+Entity *World::
+getNearInteractable(Entity e)
+{
+ for (auto &n : entity) {
+ if (n->type == MOBT || n->type == NPCT || n->type == MERCHT) {
+ if (e.isNear(*n) && (e.left ? n->loc.x < e.loc.x : n->loc.x > e.loc.x))
+ return n;
+ }
+ }
+
+ return nullptr;
}
std::string World::
return sTexLoc[ index ];
}
+vec2 World::
+getStructurePos(int index)
+{
+ if (index < 0)
+ return build.back()->loc;
+ else if ((unsigned)index >= build.size())
+ return vec2{0, 0};
+
+ return build[index]->loc;
+}
+
std::string World::
setToLeft(std::string file)
{
void World::
addHill(const ivec2 peak, const unsigned int width)
{
- int start = peak.x - width / 2, end = start + width, offset = 0;
+ int start = peak.x - width / 2,
+ end = start + width,
+ offset = 0;
const float thing = peak.y - worldData[start].groundHeight;
const float period = PI / width;
}
for(auto &m : mob){
- data.append(std::to_string((int)m.loc.x) + "\n");
- data.append(std::to_string((int)m.loc.y) + "\n");
- data.append(std::to_string((int)m.alive) + "\n");
+ data.append(std::to_string((int)m->loc.x) + "\n");
+ data.append(std::to_string((int)m->loc.y) + "\n");
+ data.append(std::to_string((int)m->alive) + "\n");
}
data.append("dOnE\0");
for(auto &m : mob){
std::getline(iss,line);
if(line == "dOnE")return;
- m.loc.x = std::stoi(line);
+ m->loc.x = std::stoi(line);
std::getline(iss,line);
if(line == "dOnE")return;
- m.loc.y = std::stoi(line);
+ m->loc.y = std::stoi(line);
std::getline(iss,line);
if(line == "dOnE")return;
- m.alive = std::stoi(line);
+ m->alive = std::stoi(line);
}
while(std::getline(iss,line)){
mmob = m;
mmob->aggressive = false;
- mob.push_back(*m);
- entity.push_back(&mob.back());
+ mob.push_back(m);
+ entity.push_back(mob.back());
battleNest.push_back(leave);
battleNestLoc.push_back(p->loc);
World *Arena::exitArena(Player *p){
World *tmp;
if (!mmob->alive &&
- p->loc.x + p->width / 2 > mob[0].loc.x &&
- p->loc.x + p->width / 2 < mob[0].loc.x + HLINE * 12) {
+ p->loc.x + p->width / 2 > mob[0]->loc.x &&
+ p->loc.x + p->width / 2 < mob[0]->loc.x + HLINE * 12) {
tmp = battleNest.front();
battleNest.erase(battleNest.begin());
vil->StrAttribute("texture"),
vil->StrAttribute("inside")
);
- tmp->addMerchant(0, 100);
-
- tmp->merchant.back()->inside = tmp->build.back();
+ tmp->addMerchant(0, 100, true);
}
// handle traders
}
}
- vptr->build.push_back(tmp->build.back());
+ float buildx = tmp->getStructurePos(-1).x;
- if(vptr->build.back()->loc.x < vptr->start.x){
- vptr->start.x = vptr->build.back()->loc.x;
- }
+ if (buildx < vptr->start.x)
+ vptr->start.x = buildx;
- if(vptr->build.back()->loc.x + vptr->build.back()->width > vptr->end.x){
- vptr->end.x = vptr->build.back()->loc.x + vptr->build.back()->width;
- }
+ if (buildx > vptr->end.x)
+ vptr->end.x = buildx;
//go to the next element in the village block
vil = vil->NextSiblingElement();
<hill peakx="0" peaky="1000" width="50" />
- <mob x="300" type="1" aggressive="false" health="1000" />
+ <mob x="300" type="1" aggressive="false" health="100" />
<!--<trigger x="-300" id="Test" />-->