-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLevel.h
280 lines (228 loc) · 7.46 KB
/
Level.h
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
/*
Greyout - a colourful platformer about love
Greyout is Copyright (c)2011-2014 Janek Schäfer
This file is part of Greyout.
Greyout is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Greyout is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Please direct any feedback, questions or comments to
Janek Schäfer (foxblock), foxblock_at_gmail_dot_com
*/
#ifndef LEVEL_H
#define LEVEL_H
#if defined(_DEBUG) && !defined(PENJIN_CALC_FPS)
#define PENJIN_CALC_FPS
#endif
#include <list>
#include <map>
#include "PenjinTypes.h"
#include "Image.h"
#include "Text.h"
#include "Rectangle.h"
#include "BaseState.h"
#include "FileLister.h"
#include "SimpleDirection.h"
#include "AnimatedSprite.h"
#include "SimpleFlags.h"
#include "Camera.h"
#include "fileTypeDefines.h"
/**
Base level class interacting with the Penjin framwork through userInput,update and render
Does input processing, collision testing and bounds checking
**/
class BaseUnit;
class ControlUnit;
class PixelParticle;
class Link;
class Level : public BaseState
{
public:
Level();
virtual ~Level();
// Loads the classes parameters from the passed map of key=value pairs
// passes each pair to processParameter
// returns true on success and false otherwise
virtual bool load(const list<PARAMETER_TYPE >& params);
void tilingSetup();
// processes a single key=value pair for loading
// this function can be overwritten in child classes to allow for custom data fiels
// return true if the data has been successfully processed, false otherwise
virtual bool processParameter(const PARAMETER_TYPE& value);
// reset level to initial state
virtual void reset();
// framework related
virtual void init();
virtual void userInput();
virtual void update();
// draws everything
virtual void render();
// draws level data onto passed surface and passed surface onto collisionLayer
virtual void render(SDL_Surface* screen);
virtual void onPause();
virtual void onResume();
virtual void pauseInput();
virtual void pauseUpdate();
virtual void pauseScreen();
// size of the level in pixels
int getWidth() const;
int getHeight() const;
// this transforms a passed coordinate to conform to the level flags
// so for example if the level repeats, this will get applied here
// you should always pass a coordinate to this before it can be worked with
Vector2df transformCoordinate(const Vector2df& coord) const;
// checks whether the unit is leaving the bounds (aka standing on the edge of
// the screen) and returns an adjusted position
Vector2df boundsCheck(const BaseUnit* const unit) const; // only 2 directions
// checks whether the unit is leaving the bounds (aka standing on the edge of
// the screen)
// Returns a vector of possible/wrapped positions
// the vector will at least contain the original position on index 0 and no
// further elements if no wrapping is required
// Order of the following elements is (if required): x, y, x+y (direction)
// NOTE: This is more correct than the version above, but it's not actually
// used since it greatly increases complexity and is only visible in few
// certain corner situations (literally)
void boundsCheck( const BaseUnit* const unit, vector<Vector2df> &posVec ) const;
// returns the first player unit with takesControl == true
// returns NULL if none is found
ControlUnit* getFirstActivePlayer() const;
void swapControl(const bool &cycleForward = true);
void lose(CRbool playerReset = false);
void win();
// Input is a vector of unit IDs, function will go through unit and player
// vectors and put all matching units into referenced unitVector
// used by trigger or switch to get target units for example
void getUnitsByID(const vector<string>& IDs, vector<BaseUnit*>& unitVector) const;
// adds a formatted particle to the list
void addParticle(const BaseUnit* const caller, const Colour& col, const Vector2df& pos, const Vector2df& vel, CRint lifeTime);
// add/remove Links
void addLink(BaseUnit *source, BaseUnit *target);
void removeLink(BaseUnit *source);
vector<ControlUnit*> players;
vector<BaseUnit*> units;
vector<PixelParticle*> effects;
vector<Link*> links;
SDL_Surface* levelImage;
SimpleFlags flags;
string levelFileName; // chapterPath + filename
string chapterPath;
string name;
#ifdef _DEBUG
virtual string debugInfo();
string debugString;
string controlsString;
vector<BaseUnit*> debugUnits;
#endif
// errors (on loading) will be placed here
string errorString;
enum LevelFlag
{
lfScrollX = 1,
lfScrollY = 2,
lfRepeatX = 4,
lfRepeatY = 8,
lfDisableSwap = 16,
lfKeepCentred = 32,
lfScaleX = 64,
lfScaleY = 128,
lfSplitX = 256,
lfSplitY = 512,
lfDrawPattern = 1024,
lfCyclePlayers = 2048,
lfEOL = 4096
};
static map<string,int> stringToFlag;
Vector2df drawOffset;
Camera cam;
// counts how many players have left through exits
int winCounter;
// level time
int timeCounter;
int idCounter;
list<PARAMETER_TYPE > parameters;
protected:
// deletes the passed unit from the collision surface (to avoid checking
// the unit agains itself)
void clearUnitFromCollision(SDL_Surface* const surface, BaseUnit* const unit);
inline void clearRectangle(SDL_Surface* const surface, CRfloat posX, CRfloat posY, CRint width, CRint height);
// this renders a unit taking into account the flags, so if a unit moves out
// of bounds and the level is set to repeat it will also get drawn on the
// opposite side of the screen
// specify offset to pass to updateScreenPosition
void renderUnit(SDL_Surface* const surface, BaseUnit* const unit, const Vector2df& offset);
void renderTiling( SDL_Surface *src, SDL_Rect *srcRect, SDL_Surface *target, SDL_Rect *targetRect, SimpleDirection dir );
// checks whether the unit has left the bounds and adjust position accordingly
bool adjustPosition(BaseUnit* const unit, const bool adjustCamera = false);
bool playersVisible() const;
enum LevelProp
{
lpUnknown,
lpImage,
lpFlags,
lpFilename,
lpOffset,
lpBackground,
lpBoundaries,
lpName,
lpMusic,
lpDialogue,
lpGravity,
lpTerminalVelocity,
lpEOL
};
static map<string,int> stringToProp;
vector<ControlUnit*> removedPlayers;
vector<BaseUnit*> removedUnits;
// set to false on level restart
bool firstLoad;
bool trialEnd;
#ifdef _DEBUG
Text debugText;
bool frameLimiter;
#endif
SDL_Surface* collisionLayer;
int eventTimer; // used for fading in and out
enum LevelFinishState
{
fsNone=0,
fsWin,
fsLose,
fsRestart,
fsMenu
};
LevelFinishState eventState;
Text nameText;
Rectangle nameRect;
int nameTimer;
Text headline;
SDL_Rect headlineRect;
// pause menu is also used for displaying time trial results
SDL_Surface* pauseSurf;
vector<string> pauseItems;
int pauseSelection;
bool mouseInBounds;
Vector2di lastPos;
Rectangle overlay;
Text timeTrialText;
int timeDisplay;
bool newRecord;
bool hideHor;
bool hideVert;
AnimatedSprite arrows;
#ifdef _MUSIC
void saveMusicToFile(CRstring musicFile);
FileLister musicLister;
bool showMusicList;
#endif
int timeOnLevel;
int deathCount;
int resetCount;
};
#endif