aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog6
-rw-r--r--include/entities.hpp3
-rw-r--r--include/world.hpp337
-rw-r--r--main.cpp9
-rw-r--r--src/entities.cpp43
-rw-r--r--src/ui.cpp20
-rw-r--r--src/world.cpp85
7 files changed, 384 insertions, 119 deletions
diff --git a/Changelog b/Changelog
index 2d11496..bd4fb68 100644
--- a/Changelog
+++ b/Changelog
@@ -991,3 +991,9 @@
- fixed important bugs/memory leaks, few segfaults happen now
- new rendering almost complete
- brice stuff almost done
+
+5/13/2016:
+==========
+
+ - NPCs and mobs can gracefully walk between worlds, carry dialog
+ - began more work on combat stuffs
diff --git a/include/entities.hpp b/include/entities.hpp
index ce2e14d..7487bbe 100644
--- a/include/entities.hpp
+++ b/include/entities.hpp
@@ -207,6 +207,9 @@ public:
// tells direction entity is facing
bool right, left;
+ // tells if the entity is from another world
+ char outnabout;
+
// set to 1 if entity is on the ground, 0 if in the air
unsigned char ground;
diff --git a/include/world.hpp b/include/world.hpp
index c40f5f5..74f9cb7 100644
--- a/include/world.hpp
+++ b/include/world.hpp
@@ -1,24 +1,15 @@
-/* ----------------------------------------------------------------------------
-** The world stuffs.
-**
-** This file contains the classes and variables necessary to create an in-game
-** world... "and stuffs".
-** --------------------------------------------------------------------------*/
#ifndef WORLD_H
#define WORLD_H
-/* ----------------------------------------------------------------------------
-** Includes section
-** --------------------------------------------------------------------------*/
+/**
+ * @file world.hpp
+ * @brief The world system
+ */
// local game includes
#include <common.hpp>
#include <entities.hpp>
-/* ----------------------------------------------------------------------------
-** Structures section
-** --------------------------------------------------------------------------*/
-
/**
* The background type enum.
* This enum contains all different possibilities for world backgrounds; used
@@ -47,164 +38,363 @@ enum class WorldWeather : unsigned char {
* lines. Dirt color and grass properties are also kept track of here.
*/
typedef struct {
- bool grassUnpressed;
- float grassHeight[2];
- float groundHeight;
- unsigned char groundColor;
+ bool grassUnpressed; /**< squishes grass if false */
+ float grassHeight[2]; /**< height of the two grass blades */
+ float groundHeight; /**< height of the 'line' */
+ unsigned char groundColor; /**< a value that affects the ground's color */
} WorldData;
+/**
+ * Contains info necessary for switching worlds.
+ * This pair contains a pointer to the new world, and the new set of
+ * coordinates the player should be at in that world.
+ */
typedef std::pair<World *, vec2> WorldSwitchInfo;
-/* ----------------------------------------------------------------------------
-** Variables section
-** --------------------------------------------------------------------------*/
-
-// affects brightness of world elements when drawn
+/**
+ * Alters how bright world elements are drawn.
+ * This value is based off of the current time of day (tick count), set in
+ * main.cpp.
+ */
extern int worldShade;
-// the path to the currently loaded XML file.
+/**
+ * The file path to the currently loaded XML file.
+ */
extern std::string currentXML;
-// defines how many game ticks it takes for a day to elapse
+/**
+ * Defines how many game ticks it takes to go from day to night or vice versa.
+ */
constexpr const unsigned int DAY_CYCLE = 12000;
-// velocity of player when moved by user
+/**
+ * Defines the velocity of player when moved by the keyboard
+ */
constexpr const float PLAYER_SPEED_CONSTANT = 0.15f;
-// maximum pull of gravity in one game tick
+/**
+ * Defines the strongest pull gravity can have on an entity.
+ * This is the most that can be subtracted from an entity's velocity in one
+ * game tick.
+ */
constexpr const float GRAVITY_CONSTANT = 0.001f;
-// height of the floor in an indoor world
+/**
+ * Defines the thickness of the floor in an indoor world.
+ */
constexpr const unsigned int INDOOR_FLOOR_THICKNESS = 50;
+
+/**
+ * Defines how far each floor can be from the next (height).
+ */
constexpr const unsigned int INDOOR_FLOOR_HEIGHTT = 400;
-constexpr const unsigned int INDOOR_FLOOR_HEIGHT = (INDOOR_FLOOR_HEIGHTT + INDOOR_FLOOR_THICKNESS);
-/* ----------------------------------------------------------------------------
-** Classes / function prototypes section
-** --------------------------------------------------------------------------*/
+/**
+ * Gets a combined height of the floor and the area before it.
+ * This value is commonly used for operations like moving between floors.
+ */
+constexpr const unsigned int INDOOR_FLOOR_HEIGHT = (INDOOR_FLOOR_HEIGHTT + INDOOR_FLOOR_THICKNESS);
/**
- * The village class, used to group structures into villages.
+ * The village class.
+ * This class defines an area in a world that is considered to be a village,
+ * and provides a welcome message when the player enters the area.
*/
class Village {
public:
+ /**
+ * The name of the village.
+ */
std::string name;
+
+ /**
+ * The start and end coordinates of the village.
+ */
vec2 start, end;
+
+ /**
+ * A "player in village" flag.
+ * This flag is used to trigger displaying the welcome message.
+ */
bool in;
+ /**
+ * Constructs a village with the given name, inside the given world.
+ */
Village(std::string meme, World *w);
+
+ /**
+ * Destructs the village.
+ */
~Village(void){}
};
/**
- * The world class. This class does everything a world should do.
+ * The world class.
+ * This class handles entity creation, management, and deletion. Most
+ * world-related operations have to be done through this class, such as
+ * drawing.
*/
class World {
protected:
- // an array of all the world's ground data
+ /**
+ * An array of all the world's ground data, populated through
+ * World::generate().
+ *
+ * @see generate()
+ */
std::vector<WorldData> worldData;
- // the world's current weather
+ /**
+ * Contains the current state of weather in the world.
+ */
WorldWeather weather;
- // the size of `worldData`
+ /**
+ * Contains the size of the 'worldData' array.
+ */
unsigned int lineCount;
- // the left-most (negative) coordinate of the worldStart
+ /**
+ * The starting x-coordinate of the world.
+ */
float worldStart;
- // holds / handles textures for background elements
+ /**
+ * Handles textures for the background elements.
+ */
TextureIterator bgTex;
- // defines what type of background is being used
+ /**
+ * Defines the set of background images being used for the world.
+ *
+ * @see setBackground()
+ */
WorldBGType bgType;
- // an SDL_mixer object for the world's BGM
+ /**
+ * SDL_Mixer's object for the loaded BGM.
+ */
Mix_Music *bgmObj;
- // the pathname of the loaded BGM
+ /**
+ * The filename of the world's BGM file.
+ *
+ * @see setBGM()
+ */
std::string bgm;
- // XML file names of worlds to the left and right, empty if nonexistant
+ /**
+ * The path to the XML file of the world to the left.
+ *
+ * @see setToLeft()
+ */
std::string toLeft;
+
+ /**
+ * The path to the XML file of the world to the right.
+ *
+ * @see setToRight()
+ */
std::string toRight;
- // structure texture file paths
+ /**
+ * A vector of paths for the structure textures.
+ * The appearance of structures depends on the world's theme.
+ *
+ * @see setStyle()
+ */
std::vector<std::string> sTexLoc;
- // TODO
+ /**
+ * The paths of files to be used for the background textures.
+ *
+ * @see setStyle()
+ */
std::vector<std::string> bgFiles;
+
+ /**
+ * The paths of files to be used for the indoor background textures.
+ *
+ * @see setStyle()
+ */
std::vector<std::string> bgFilesIndoors;
- // an array of star coordinates
+ /**
+ * Contains randomly generated coordinates for stars.
+ */
std::vector<vec2> star;
- // entity vectors
+ /**
+ * A vector of all light elements in the world.
+ *
+ * @see addLight()
+ * @see getLastLight()
+ */
std::vector<Light> light;
+
+ /**
+ * A vector of all mobs in the world.
+ *
+ * @see addMob()
+ * @see getLastMob()
+ * @see getNearMob()
+ */
std::vector<Mob *> mob;
+
+ /**
+ * A vector of all objects in the world.
+ *
+ * @see addObject()
+ */
std::vector<Object> object;
+
+ /**
+ * A vector of all particles in the world.
+ *
+ * @see addParticle()
+ */
std::vector<Particles> particles;
+
+ /**
+ * A vector of all structures in the world.
+ *
+ * @see addStructure()
+ * @see getStructurePos()
+ */
std::vector<Structures *> build;
+
+ /**
+ * A vector of all villages in the world.
+ *
+ * @see addVillage()
+ */
std::vector<Village> village;
- // handles death, gravity, etc. for a single entity
+ /**
+ * Handles death, gravity, etc. for a single entity
+ */
virtual void singleDetect(Entity *e);
- // frees entities and clears vectors that contain them
+ /**
+ * Destroys entities and clears vectors that contain them.
+ * This function is only called in the world destructor.
+ */
void deleteEntities(void);
-
-protected:
+ /**
+ * Draws background textures.
+ */
void drawBackgrounds();
public:
- // entity vectors that need to be public because we're based
+ /**
+ * A vector of pointers to all entities from the other vectors.
+ * This is used to mass-manage entities, or operate on entities
+ * outside of what the world does.
+ *
+ * @see getNearInteractable()
+ */
std::vector<Entity *> entity;
+ /**
+ * A vector of all NPCs in the world.
+ *
+ * @see addNPC()
+ */
std::vector<NPC *> npc;
+
+ /**
+ * A vector of all merchants in the world.
+ *
+ * @see addMerchant()
+ */
std::vector<Merchant *> merchant;
- // the world constructor, prepares variables
+ /**
+ * Constructs the world, resets variables.
+ */
World(void);
- // destructor, frees used memory
+ /**
+ * Destructs the world, frees memory.
+ */
virtual ~World(void);
- // generates a world of the specified width
+ /**
+ * Generates a world of the specified width.
+ * This will populate the 'worldData' array and create star coordinates.
+ * It's necessary to call this function to actually use the world.
+ */
void generate(int width);
- // draws everything to the screen
+ /**
+ * Draws everything the world handles to the screen (and the player).
+ * Drawing is based off of the player so that off-screen elements are not
+ * drawn.
+ */
virtual void draw(Player *p);
- // handles collisions/death of player and all entities
+ /**
+ * Handles physics for all entities and the player.
+ *
+ * @see singleDetect()
+ */
void detect(Player *p);
- // updates entities, moving them and such
+ /**
+ * Updates entity positions, time of day, and music.
+ */
void update(Player *p, unsigned int delta, unsigned int ticks);
- // gets the world's width in TODO
+ /**
+ * Gets the width of the world, presumably in pixels.
+ * TODO
+ */
int getTheWidth(void) const;
- // gets the starting x coordinate of the world
+ /**
+ * Gets the starting x-coordinate of the world.
+ *
+ * @see worldStart
+ */
float getWorldStart(void) const;
- // gets a pointer to the most recently added light
+ /**
+ * Gets a pointer to the most recently created light.
+ * This is used to update properties of the light outside of the
+ * world class.
+ */
Light *getLastLight(void);
- // gets a pointer to the most recently added mob
+ /**
+ * Gets a pointer ot the most recently created mob.
+ * This is used to update properties of the mob outside of the
+ * world class.
+ */
Mob *getLastMob(void);
- // gets the nearest interactable entity to the given one
+ /**
+ * Finds the entity nearest to the provided one.
+ */
Entity *getNearInteractable(Entity &e);
+ /**
+ * Finds the mob nearest to the given entity.
+ */
Mob *getNearMob(Entity &e);
- // gets the coordinates of the `index`th structure
+ /**
+ * Gets the coordinates of the `index`th structure.
+ */
vec2 getStructurePos(int index);
- // gets the texture path of the `index`th structure
+ /**
+ * Gets the texture path of the `index`th structure
+ */
std::string getSTextureLocation(unsigned int index) const;
// saves the world's data to an XML file
@@ -239,12 +429,29 @@ public:
WorldSwitchInfo goWorldLeft(Player *p);
WorldSwitchInfo goWorldRight(Player *p);
- // attempts to move an NPC to the left adjacent world, returning true on success
+ /**
+ * Attempts to move an NPC to the left adjacent world, returning true on success.
+ */
bool goWorldLeft(NPC *e);
+ /**
+ * Attempts to move an NPC to the world to the right, returning true on success.
+ */
+ bool goWorldRight(NPC *e);
+
// attempts to enter a structure that the player would be standing in front of
WorldSwitchInfo goInsideStructure(Player *p);
+ /**
+ * Adopts an NPC from another world, taking its ownership.
+ */
+ void adoptNPC(NPC *e);
+
+ /**
+ * Adopts a mob from another world, taking its ownership.
+ */
+ void adoptMob(Mob *e);
+
// adds a hole at the specified start and end x-coordinates
void addHole(unsigned int start,unsigned int end);
diff --git a/main.cpp b/main.cpp
index 4c3ba81..a9138c7 100644
--- a/main.cpp
+++ b/main.cpp
@@ -506,6 +506,8 @@ void logic(){
e->near = false;
continue;
} else if (e->canMove) {
+ if (!currentWorld->goWorldLeft(dynamic_cast<NPC *>(e)))
+ currentWorld->goWorldRight(dynamic_cast<NPC *>(e));
e->wander((rand() % 120 + 30));
if (NPCSelected) {
e->near = false;
@@ -520,8 +522,13 @@ void logic(){
else
NPCSelected = true;
- if ((SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT)) && !ui::dialogBoxExists)
+ if ((SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT)) && !ui::dialogBoxExists) {
+ if (ui::mouse.x < player->loc.x && player->right)
+ player->left = true, player->right = false;
+ else if(ui::mouse.x > player->loc.x && player->left)
+ player->right = true, player->left = false;
e->interact();
+ }
} else {
e->near = false;
}
diff --git a/src/entities.cpp b/src/entities.cpp
index 14e1503..6b5e1d3 100644
--- a/src/entities.cpp
+++ b/src/entities.cpp
@@ -79,6 +79,7 @@ Entity::Entity(void)
height = 0;
health = 0;
maxHealth = 0;
+ outnabout = 0;
z = 1.0f;
targetx = 0.9112001f;
@@ -383,18 +384,19 @@ void Entity::draw(void)
case PLAYERT:
static int texState = 0;
if (speed && !(game::time::getTickCount() % ((2.0f/speed) < 1 ? 1 : (int)((float)2.0f/(float)speed)))) {
- if (++texState==9)texState=1;
+ if (++texState == 9)
+ texState = 1;
glActiveTexture(GL_TEXTURE0);
tex(texState);
}
if (!ground) {
- glActiveTexture(GL_TEXTURE0 + 0);
+ glActiveTexture(GL_TEXTURE0);
tex(0);
- }else if (vel.x) {
- glActiveTexture(GL_TEXTURE0 + 0);
+ } else if (vel.x) {
+ glActiveTexture(GL_TEXTURE0);
tex(texState);
- }else{
- glActiveTexture(GL_TEXTURE0 + 0);
+ } else {
+ glActiveTexture(GL_TEXTURE0);
tex(0);
}
break;
@@ -436,13 +438,13 @@ if (health != maxHealth) {
glUniform1i(worldShader_uniform_texture, 0);
GLfloat coord_back[] = {
- loc.x, loc.y + height, z,
- loc.x + width, loc.y + height, z,
- loc.x + width, loc.y + height + game::HLINE * 2,z,
+ loc.x, loc.y + height, z,
+ loc.x + width, loc.y + height, z,
+ loc.x + width, loc.y + height + game::HLINE * 2, z,
- loc.x + width, loc.y + height + game::HLINE * 2,z,
- loc.x, loc.y + height + game::HLINE * 2,z,
- loc.x, loc.y + height, z,
+ loc.x + width, loc.y + height + game::HLINE * 2, z,
+ loc.x, loc.y + height + game::HLINE * 2, z,
+ loc.x, loc.y + height, z,
};
GLfloat coord_front[] = {
@@ -559,7 +561,12 @@ void NPC::interact() { //have the npc's interact back to the player
if (dialogCount && dialogIndex != 9999) {
// load the XML file and find the dialog tags
- xml.LoadFile(currentXML.c_str());
+ if (outnabout == 0)
+ xml.LoadFile(currentXML.c_str());
+ else if (outnabout < 0)
+ xml.LoadFile((xmlFolder + currentWorld->getToLeft()).c_str());
+ else
+ xml.LoadFile((xmlFolder + currentWorld->getToRight()).c_str());
COMMONAIFUNC:
idx = 0;
stop = false;
@@ -617,6 +624,10 @@ COMMONAIFUNC:
if ((oxml = exml->FirstChildElement("gotox")))
moveTo(std::stoi(oxml->GetText()));
+ // asdlfkj
+ auto ptr = exml->GetText() - 1;
+ while (isspace(*++ptr));
+
// handle dialog options
if ((oxml = exml->FirstChildElement("option"))) {
std::string optstr;
@@ -629,9 +640,9 @@ COMMONAIFUNC:
// save the associated XMLElement
dopt.push_back(oxml);
} while ((oxml = oxml->NextSiblingElement()));
-
+
// run the dialog stuff
- ui::dialogBox(name, optstr, false, exml->GetText() + 2);
+ ui::dialogBox(name, optstr, false, ptr);
ui::waitForDialog();
if (ui::dialogOptChosen)
@@ -642,7 +653,7 @@ COMMONAIFUNC:
// optionless dialog
else {
- ui::dialogBox(name, "", false, exml->GetText());
+ ui::dialogBox(name, "", false, ptr);
ui::waitForDialog();
}
diff --git a/src/ui.cpp b/src/ui.cpp
index 64e18fe..51edb86 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -442,7 +442,7 @@ namespace ui {
std::string ret;
std::string typeOut(std::string str) {
- static unsigned int tadv = TICKS_PER_SEC / 12;
+ static unsigned int tadv = 1;
static unsigned int tickk,
linc=0, // Contains the number of letters that should be drawn.
size=0; // Contains the full size of the current string.
@@ -467,9 +467,21 @@ namespace ui {
tickk = tickCount + tadv;
ret += str[linc];
- if (linc < size)
- linc++;
- else
+ if (linc < size) {
+ switch (str[++linc]) {
+ case '!':
+ case '?':
+ case '.':
+ tadv = 10;
+ break;
+ case ',':
+ tadv = 5;
+ break;
+ default:
+ tadv = 1;
+ break;
+ }
+ } else
typeOutDone = true;
}
diff --git a/src/world.cpp b/src/world.cpp
index 88ef57a..327a787 100644
--- a/src/world.cpp
+++ b/src/world.cpp
@@ -1089,8 +1089,7 @@ void World::load(void){
* Toggle play/stop of the background music.
* If new music is to be played a crossfade will occur, otherwise... uhm.
*/
-void World::
-bgmPlay(World *prev) const
+void World::bgmPlay(World *prev) const
{
if (prev == nullptr || bgm != prev->bgm) {
Mix_FadeOutMusic(800);
@@ -1103,8 +1102,7 @@ bgmPlay(World *prev) const
* 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.
*/
-void World::
-setBGM(std::string path)
+void World::setBGM(std::string path)
{
if (!path.empty())
bgmObj = Mix_LoadMUS((bgm = path).c_str());
@@ -1115,8 +1113,7 @@ setBGM(std::string path)
* The images chosen for the background layers are selected depending on the
* world's background type.
*/
-void World::
-setBackground(WorldBGType bgt)
+void World::setBackground(WorldBGType bgt)
{
// load textures with a limit check
switch ((bgType = bgt)) {
@@ -1137,8 +1134,7 @@ setBackground(WorldBGType bgt)
* The world's style will determine what sprites are used for things like\
* generic structures.
*/
-void World::
-setStyle(std::string pre)
+void World::setStyle(std::string pre)
{
// get folder prefix
std::string prefix = pre.empty() ? "assets/style/classic/" : pre;
@@ -1157,8 +1153,7 @@ setStyle(std::string pre)
/**
* Pretty self-explanatory.
*/
-std::string World::
-getWeatherStr(void) const
+std::string World::getWeatherStr(void) const
{
switch (weather) {
case WorldWeather::Sunny:
@@ -1177,8 +1172,7 @@ getWeatherStr(void) const
return "???";
}
-const WorldWeather& World::
-getWeatherId(void) const
+const WorldWeather& World::getWeatherId(void) const
{
return weather;
}
@@ -1186,8 +1180,7 @@ getWeatherId(void) const
/**
* Pretty self-explanatory.
*/
-std::string World::
-setToLeft(std::string file)
+std::string World::setToLeft(std::string file)
{
return (toLeft = file);
}
@@ -1195,8 +1188,7 @@ setToLeft(std::string file)
/**
* Pretty self-explanatory.
*/
-std::string World::
-setToRight(std::string file)
+std::string World::setToRight(std::string file)
{
return (toRight = file);
}
@@ -1204,8 +1196,7 @@ setToRight(std::string file)
/**
* Pretty self-explanatory.
*/
-std::string World::
-getToLeft(void) const
+std::string World::getToLeft(void) const
{
return toLeft;
}
@@ -1213,8 +1204,7 @@ getToLeft(void) const
/**
* Pretty self-explanatory.
*/
-std::string World::
-getToRight(void) const
+std::string World::getToRight(void) const
{
return toRight;
}
@@ -1222,8 +1212,7 @@ getToRight(void) const
/**
* Attempts to go to the left world, returning either that world or itself.
*/
-WorldSwitchInfo World::
-goWorldLeft(Player *p)
+WorldSwitchInfo World::goWorldLeft(Player *p)
{
World *tmp;
@@ -1243,8 +1232,7 @@ goWorldLeft(Player *p)
/**
* Attempts to go to the right world, returning either that world or itself.
*/
-WorldSwitchInfo World::
-goWorldRight(Player *p)
+WorldSwitchInfo World::goWorldRight(Player *p)
{
World *tmp;
@@ -1256,19 +1244,51 @@ goWorldRight(Player *p)
return std::make_pair(this, vec2 {0, 0});
}
+void World::adoptNPC(NPC *e)
+{
+ entity.push_back(e);
+ npc.push_back(e);
+}
+
+void World::adoptMob(Mob *e)
+{
+ entity.push_back(e);
+ mob.push_back(e);
+}
+
/**
* Acts like goWorldLeft(), but takes an NPC; returning true on success.
*/
-bool World::
-goWorldLeft(NPC *e)
+bool World::goWorldLeft(NPC *e)
{
// check if entity is at world edge
- if(!toLeft.empty() && e->loc.x < worldStart + HLINES(15)) {
- currentWorldToLeft->addNPC(e->loc.x,e->loc.y);
- e->die();
+ if (!toLeft.empty() && e->loc.x < worldStart + HLINES(15)) {
+ currentWorldToLeft->adoptNPC(e);
+
+ npc.erase(std::find(std::begin(npc), std::end(npc), e));
+ entity.erase(std::find(std::begin(entity), std::end(entity), e));
+
+ e->loc.x = currentWorldToLeft->worldStart + currentWorldToLeft->getTheWidth() - HLINES(15);
+ e->loc.y = GROUND_HEIGHT_MAXIMUM;
+ ++e->outnabout;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool World::goWorldRight(NPC *e)
+{
+ if (!toRight.empty() && e->loc.x + e->width > -worldStart - HLINES(15)) {
+ currentWorldToRight->adoptNPC(e);
- currentWorldToLeft->npc.back()->loc.x = currentWorldToLeft->worldStart + currentWorldToLeft->getTheWidth() - HLINES(15);
- currentWorldToLeft->npc.back()->loc.y = GROUND_HEIGHT_MAXIMUM;
+ npc.erase(std::find(std::begin(npc), std::end(npc), e));
+ entity.erase(std::find(std::begin(entity), std::end(entity), e));
+
+ e->loc.x = currentWorldToRight->worldStart + HLINES(15);
+ e->loc.y = GROUND_HEIGHT_MINIMUM;
+ --e->outnabout;
return true;
}
@@ -1279,8 +1299,7 @@ goWorldLeft(NPC *e)
/**
* Attempts to enter a building that the player is standing in front of.
*/
-WorldSwitchInfo World::
-goInsideStructure(Player *p)
+WorldSwitchInfo World::goInsideStructure(Player *p)
{
World *tmp;