aboutsummaryrefslogtreecommitdiffstats
path: root/include/world.hpp
blob: ac17580c4903885a3c587ae65d3991839d403fc0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
/* ----------------------------------------------------------------------------
** 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
** --------------------------------------------------------------------------*/

// 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
 * in World::setBackground() to select the appropriate images.
 */
enum class WorldBGType : unsigned char {
	Forest,		/**< A forest theme. */
	WoodHouse	/**< An indoor wooden house theme. */
};

/**
 * The weather type enum.
 * This enum contains every type of weather currently implemented in the game.
 * Weather is set by the world somewhere.
 */
enum class WorldWeather : unsigned char {
	Sunny = 0,	/**< Sunny/daytime */
	Dark,		/**< Nighttime */
	Rain,		/**< Rain */
	Snowy		/**< Snow */
};

/**
 * The line structure.
 * This structure is used to store the world's ground, stored in vertical
 * lines. Dirt color and grass properties are also kept track of here.
 */
typedef struct {
    bool          grassUnpressed;
    float         grassHeight[2];
    float         groundHeight;
    unsigned char groundColor;
} WorldData;

typedef std::pair<World *, vec2> WorldSwitchInfo;

/* ----------------------------------------------------------------------------
** Variables section
** --------------------------------------------------------------------------*/

// affects brightness of world elements when drawn
extern int worldShade;

// the path to the currently loaded XML file.
extern std::string currentXML;

// defines how many game ticks it takes for a day to elapse
constexpr const unsigned int DAY_CYCLE = 12000;

// velocity of player when moved by user
constexpr const float PLAYER_SPEED_CONSTANT = 0.15f;

// maximum pull of gravity in one game tick
constexpr const float GRAVITY_CONSTANT = 0.001f;

// height of the floor in an indoor world
constexpr const unsigned int INDOOR_FLOOR_THICKNESS = 50;
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
** --------------------------------------------------------------------------*/

/**
 * The village class, used to group structures into villages.
 */
class Village {
public:
	std::string name;
	vec2 start, end;
	bool in;

	Village(std::string meme, World *w);
	~Village(void){}
};

/**
 * The world class. This class does everything a world should do.
 */
class World {
protected:

	// an array of all the world's ground data
	std::vector<WorldData> worldData;

	// the world's current weather
	WorldWeather weather;

	// the size of `worldData`
	unsigned int lineCount;

	// the left-most (negative) coordinate of the worldStart
	float worldStart;

	// holds / handles textures for background elements
	TextureIterator bgTex;

	// defines what type of background is being used
	WorldBGType bgType;

	// an SDL_mixer object for the world's BGM
	Mix_Music *bgmObj;

	// the pathname of the loaded BGM
	std::string bgm;

	// XML file names of worlds to the left and right, empty if nonexistant
	std::string toLeft;
	std::string toRight;

	// structure texture file paths
	std::vector<std::string> sTexLoc;

	// TODO
	std::vector<std::string> bgFiles;
	std::vector<std::string> bgFilesIndoors;

	// an array of star coordinates
	std::vector<vec2> star;

	// entity vectors
	std::vector<Light>        light;
	std::vector<Mob *>        mob;
	std::vector<Object>	      object;
	std::vector<Particles>    particles;
	std::vector<Structures *> build;
	std::vector<Village>      village;

	// handles death, gravity, etc. for a single entity
	virtual void singleDetect(Entity *e);

	// frees entities and clears vectors that contain them
	void deleteEntities(void);

public:

	// entity vectors that need to be public because we're based
	std::vector<Entity *> entity;

	std::vector<NPC	*>      npc;
	std::vector<Merchant *> merchant;

	// the world constructor, prepares variables
	World(void);

	// destructor, frees used memory
	virtual ~World(void);

	// generates a world of the specified width
	void generate(int width);

	// draws everything to the screen
	virtual void draw(Player *p);

	// handles collisions/death of player and all entities
	void detect(Player *p);

	// updates entities, moving them and such
	void update(Player *p, unsigned int delta, unsigned int ticks);

	// gets the world's width in TODO
	int getTheWidth(void) const;

	// gets the starting x coordinate of the world
	float getWorldStart(void) const;

	// gets a pointer to the most recently added light
	Light *getLastLight(void);

	// gets a pointer to the most recently added mob
	Mob *getLastMob(void);

	// gets the nearest interactable entity to the given one
	Entity *getNearInteractable(Entity &e);

	Mob *getNearMob(Entity &e);

	// gets the coordinates of the `index`th structure
	vec2 getStructurePos(int index);

	// 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
	void save(void);

	// attempts to load world data from an XML file
	void load(void);

	// plays/pauses the world's music, according to if a new world is being entered
	void bgmPlay(World *prev) const;

	// sets and loads the specified BGM
	void setBGM(std::string path);

	// sets the world's background theme
	void setBackground(WorldBGType bgt);

	// sets the folder to collect entity textures from
	void setStyle(std::string pre);

	// gets the string that represents the current weather
	std::string getWeatherStr(void) const;
	const WorldWeather& getWeatherId(void) const;

	// sets / gets pathnames of XML files for worlds to the left and right
	std::string setToLeft(std::string file);
	std::string setToRight(std::string file);
	std::string getToLeft(void) const;
	std::string getToRight(void) const;

	// attempts to enter the left/right adjacent world, returning either that world or this
	WorldSwitchInfo goWorldLeft(Player *p);
	WorldSwitchInfo goWorldRight(Player *p);

	// attempts to move an NPC to the left adjacent world, returning true on success
	bool goWorldLeft(NPC *e);

	// attempts to enter a structure that the player would be standing in front of
	WorldSwitchInfo goInsideStructure(Player *p);

	// adds a hole at the specified start and end x-coordinates
	void addHole(unsigned int start,unsigned int end);

	// adds a hill that peaks at the given coordinate and is `width` HLINEs wide
	void addHill(ivec2 peak, unsigned int width);

	// functions to add entities to the world
	void addLight(vec2 xy, Color color);

	void addMerchant(float x, float y, bool housed);

	void addMob(Mob *m, vec2 coord);

	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 dur);
	void addParticle(float x, float y, float w, float h, float vx, float vy, Color color, int dur, 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);
};

/**
 * IndoorWorld - Indoor settings stored in a World class
 */
class IndoorWorld : public World {
private:

	// like lines, but split into floors
	std::vector<std::vector<float>> floor;

	// the x coordinate to start each floor at
	std::vector<float> fstart;

	// handles physics for a single entity
	void singleDetect(Entity *e);

public:

	// creates an IndoorWorld object
	IndoorWorld(void);

	// frees memory used by this object
	~IndoorWorld(void);

	// adds a floor of the desired width
	void addFloor(unsigned int width);

	// adds a floor at the desired x coordinate with the given width
	void addFloor(unsigned int width, unsigned int start);

	// attempts to move the entity provided to the given floor
	bool moveToFloor(Entity *e, unsigned int _floor);

	// checks for a floor above the given entity
	bool isFloorAbove(Entity *e);

	// checks for a floor below the given entity
	bool isFloorBelow(Entity *e);

	// draws the world about the player
	void draw(Player *p);
};

/**
 * The arena class - creates an arena.
 *
 * This world, when created, expects a pointer to a Mob. This mob will be
 * transported to a temporary world with the player, and the Mob will be
 * killed upon exiting the arena.
 */

class Arena : public World {
private:

	// the mob that the player is fighting
	Mob *mmob;

public:

	// creates the arena with the world being left for it
	Arena(void);

	// frees memory
	~Arena(void);

	// starts a new fight??
	void fight(World *leave, const Player *p, Mob *m);

	// attempts to exit the arena, returning what world the player should be in
	WorldSwitchInfo exitArena(Player *p);
};

/**
 * Loads the player into the world created by the given XML file. If a world is
 * already loaded it will be saved before the transition is made.
 */
World *loadWorldFromXML(std::string path);

/**
 * Loads the player into the XML-scripted world, but does not save data from the
 * previous world if one was loaded.
 */
World *loadWorldFromXMLNoSave(std::string path);

World *loadWorldFromPtr(World *ptr);

constexpr IndoorWorld *Indoorp(World *w)
{
    return (IndoorWorld *)w;
}

#endif // WORLD_H