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
|
//
class event_handler
{
static const int MAX_EVENTS = 128;
static const int MAX_DATASIZE = 128*4;
int types[MAX_EVENTS]; // TODO: remove some of these arrays
int offsets[MAX_EVENTS];
int sizes[MAX_EVENTS];
int targets[MAX_EVENTS];
char data[MAX_DATASIZE];
int current_offset;
int num_events;
public:
event_handler();
void *create(int type, int size, int target = -1);
void clear();
void snap(int snapping_client);
};
extern event_handler events;
// a basic entity
class entity
{
private:
friend class game_world;
friend class player;
entity *prev_entity;
entity *next_entity;
entity *prev_type_entity;
entity *next_type_entity;
int index;
static int current_id;
protected:
int id;
public:
float proximity_radius;
unsigned flags;
int objtype;
baselib::vec2 pos;
enum
{
FLAG_DESTROY=0x00000001,
FLAG_ALIVE=0x00000002,
};
entity(int objtype);
virtual ~entity();
virtual void reset() {}
virtual void post_reset() {}
void set_flag(unsigned flag) { flags |= flag; }
void clear_flag(unsigned flag) { flags &= ~flag; }
virtual void destroy() { delete this; }
virtual void tick() {}
virtual void tick_defered() {}
virtual void snap(int snapping_client) {}
virtual bool take_damage(baselib::vec2 force, int dmg, int from, int weapon) { return true; }
};
class game_world
{
void reset();
void remove_entities();
public:
enum
{
NUM_ENT_TYPES=10, // TODO: are more exact value perhaps? :)
};
// TODO: two lists seams kinda not good, shouldn't be needed
entity *first_entity;
entity *first_entity_types[NUM_ENT_TYPES];
bool paused;
bool reset_requested;
game_world();
int find_entities(baselib::vec2 pos, float radius, entity **ents, int max);
int find_entities(baselib::vec2 pos, float radius, entity **ents, int max, const int* types, int maxtypes);
void insert_entity(entity *ent);
void destroy_entity(entity *ent);
void remove_entity(entity *ent);
//
void snap(int snapping_client);
void tick();
};
extern game_world world;
// game object
class gameobject : public entity
{
void resetgame();
void startround();
void endround();
int round_start_tick;
int game_over_tick;
int sudden_death;
public:
int gametype;
gameobject();
virtual void post_reset();
virtual void tick();
virtual void tick_dm();
virtual void tick_tdm();
virtual void snap(int snapping_client);
virtual int getteam(int notthisid);
};
extern gameobject gameobj;
// TODO: move to seperate file
class powerup : public entity
{
public:
static const int phys_size = 14;
int type;
int subtype; // weapon type for instance?
int spawntick;
powerup(int _type, int _subtype = 0);
virtual void reset();
virtual void tick();
virtual void snap(int snapping_client);
};
// projectile entity
class projectile : public entity
{
public:
enum
{
PROJECTILE_FLAGS_EXPLODE = 1 << 0,
WEAPON_PROJECTILETYPE_GUN = 0,
WEAPON_PROJECTILETYPE_ROCKET = 1,
WEAPON_PROJECTILETYPE_SHOTGUN = 2,
};
baselib::vec2 vel;
entity *powner; // this is nasty, could be removed when client quits
int lifespan;
int owner;
int type;
int flags;
int damage;
int sound_impact;
int weapon;
int bounce;
float force;
projectile(int type, int owner, baselib::vec2 pos, baselib::vec2 vel, int span, entity* powner,
int damage, int flags, float force, int sound_impact, int weapon);
virtual void reset();
virtual void tick();
virtual void snap(int snapping_client);
};
class projectile_backpackrocket : public projectile
{
int stage;
int start_tick;
int deply_ticks;
baselib::vec2 target;
baselib::vec2 start;
baselib::vec2 midpoint;
baselib::vec2 direction;
public:
projectile_backpackrocket(baselib::vec2 pos, baselib::vec2 target, int owner, entity* powner);
virtual void tick();
};
// player entity
class player : public entity
{
public:
static const int phys_size = 28;
enum // what are these?
{
MODIFIER_RETURNFLAGS_OVERRIDEVELOCITY = 1 << 0,
MODIFIER_RETURNFLAGS_OVERRIDEPOSITION = 1 << 1,
MODIFIER_RETURNFLAGS_OVERRIDEGRAVITY = 1 << 2,
};
// weapon info
entity* hitobjects[10];
int numobjectshit;
struct weaponstat
{
int ammoregenstart;
int ammo;
int ammocost;
bool got;
} weapons[NUM_WEAPONS];
int active_weapon;
int reload_timer;
int attack_tick;
int damage_taken;
int emote_type;
int emote_stop;
int last_action;
// we need a defered position so we can handle the physics correctly
baselib::vec2 defered_pos;
baselib::vec2 vel;
baselib::vec2 direction;
//
int client_id;
char name[64];
// input
player_input previnput;
player_input input;
int jumped;
int damage_taken_tick;
int health;
int armor;
// ninja
baselib::vec2 activationdir;
int ninjaactivationtick;
int extrapowerflags;
int currentcooldown;
int currentactivation;
int currentmovetime;
int score;
int team;
int state;
bool spawning;
bool dead;
int die_tick;
int latency_accum;
int latency_accum_min;
int latency_accum_max;
int latency_avg;
int latency_min;
int latency_max;
// hooking stuff
enum
{
HOOK_RETRACTED=-1,
HOOK_IDLE=0,
HOOK_FLYING,
HOOK_GRABBED
};
int hook_state;
int hook_tick;
player *hooked_player;
baselib::vec2 hook_pos;
baselib::vec2 hook_dir;
//
player();
void init();
virtual void reset();
virtual void destroy();
void try_respawn();
void respawn();
bool is_grounded();
void release_hooked();
void release_hooks();
int handle_weapons();
int handle_ninja();
virtual void tick();
virtual void tick_defered();
void die(int killer, int weapon);
virtual bool take_damage(baselib::vec2 force, int dmg, int from, int weapon);
virtual void snap(int snaping_client);
};
extern player players[MAX_CLIENTS];
// TODO: move to seperate file
class flag : public entity
{
public:
static const int phys_size = 14;
player *carrying_player;
baselib::vec2 vel;
int team;
int spawntick;
flag(int _team);
bool is_grounded();
virtual void reset();
virtual void tick();
virtual void snap(int snapping_client);
};
|