aboutsummaryrefslogtreecommitdiffstats
path: root/include/world.hpp
blob: d53a40b378fe99fe7091796d66e7fd52d7bc155f (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
/**
 * @file  world.hpp
 * @brief The world system
 */
#ifndef WORLD_HPP_
#define WORLD_HPP_

#include <string>
#include <vector>

#include <SDL2/SDL_mixer.h>
#include <entityx/entityx.h>

#include <tinyxml2.h>
using namespace tinyxml2;

#include <components.hpp>
#include <events.hpp>
#include <texture.hpp>
#include <thread.hpp>
#include <vector2.hpp>

/**
 * 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.
 */
struct WorldData {
    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 */
};

/**
 * Defines how many game ticks it takes to go from day to night or vice versa.
 * Technically a half day cycle...
 */
constexpr const unsigned int DAY_CYCLE = 10000;

/**
 * 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;

/**
 * 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;

/**
 * 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);

/**
 * World data.
 * Contains all necessary data for a world. An instance of this is kept in the
 * world system, and is populated through it's load() function.
 */
struct WorldData2 {

	// Data variables
	ObjectTexture ground;
	float startX;                /**< The furthest left coordinate of the world. */

	// Indoor variables
	bool indoor;                 /**< Set to true if this is an indoor world. */
	Texture indoorTex;           /**< The house's inside texture. */
	std::string outdoor;         /**< The file name of the outdoor world. */
	vec2 outdoorCoords;          /**< The coordinates the player should spawn to when exiting. */

	// World linkage
	std::string toLeft, toRight; /**< File names of the worlds adjacent to this one. */

	// Style variables
	std::string styleFolder;          /**< The folder to get stylized textures from. */

	// Music
	std::string bgm;             /**< The path to the BGM file. */
};

/**
 * The world system
 * Does everything needed to take care of the world.
 */
class WorldSystem : public entityx::System<WorldSystem>, public entityx::Receiver<WorldSystem> {
private:

	/**
	 * The world's data.
	 */
	static WorldData2 world;

	/**
	 * SDL's object for handling the background music.
	 */
	static Mix_Music *bgmObj;
	static std::string bgmCurrent;

	/**
	 * Allows for iteration between background textures, for rendering.
	 */
	static TextureIterator bgTex;

	/**
	 * An object to handle and parse world XML files.
	 */
	static XMLDocument xmlDoc;

	/**
	 * The file path to the currently loaded world.
	 */
	static std::string currentXMLFile;

	static std::string toLoad;

	static std::vector<vec2> stars;

public:
	static std::thread thAmbient;

	explicit WorldSystem(void);
	~WorldSystem(void);

	void configure(entityx::EventManager &ev) {
		ev.subscribe<BGMToggleEvent>(*this);
	}

	static inline XMLDocument* getXML(void)
	{ return &xmlDoc; }

	static inline float getWidth(void) //const
	{ return world.startX * -2.0f; }

	static inline const std::string& getXMLFile(void) //const
	{ return currentXMLFile; }

	static float isAboveGround(const vec2& p); //const;

	bool receive(const BGMToggleEvent &bte);
	void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override;
	static void render(void);


	void detect(entityx::TimeDelta dt);

	static void goWorldLeft(Position& p);
	static void goWorldRight(Position& p, Solid &d);
	static void goWorldPortal(Position& p);

	static void generate(const char *file);
	static float getGroundHeight(float x);

	static bool save(void);
	static void load(const std::string& file);

	void fight(entityx::Entity entity);

	static void die(void);
	static void loader(void);

	static inline bool shouldLoad(void)
	{ return !toLoad.empty(); }
};

#endif // WORLD_HPP_