1 | |
---|
2 | /* |
---|
3 | orxonox - the future of 3D-vertical-scrollers |
---|
4 | |
---|
5 | Copyright (C) 2004 orx |
---|
6 | |
---|
7 | This program is free software; you can redistribute it and/or modify |
---|
8 | it under the terms of the GNU General Public License as published by |
---|
9 | the Free Software Foundation; either version 2, or (at your option) |
---|
10 | any later version. |
---|
11 | |
---|
12 | ### File Specific: |
---|
13 | main-programmer: Patrick Boenzli |
---|
14 | co-programmer: |
---|
15 | */ |
---|
16 | |
---|
17 | #include <iostream> |
---|
18 | #include <stdlib.h> |
---|
19 | #include <cmath> |
---|
20 | #include <GL/glut.h> |
---|
21 | |
---|
22 | #include "npc.h" |
---|
23 | #include "player.h" |
---|
24 | #include "environment.h" |
---|
25 | #include "shoot_laser.h" |
---|
26 | #include "shoot_rocket.h" |
---|
27 | #include "stdincl.h" |
---|
28 | #include "data_tank.h" |
---|
29 | |
---|
30 | #include "list.h" |
---|
31 | #include "world_entity.h" |
---|
32 | |
---|
33 | #include "world.h" |
---|
34 | |
---|
35 | |
---|
36 | using namespace std; |
---|
37 | |
---|
38 | |
---|
39 | /** |
---|
40 | \brief Create a new World |
---|
41 | |
---|
42 | This creates a new, empty world! |
---|
43 | */ |
---|
44 | World::World () { |
---|
45 | //lastPlayer = null; |
---|
46 | //lastNPC = null; |
---|
47 | //lastEnv = null; |
---|
48 | primitiveMove = 0; |
---|
49 | step = 0; |
---|
50 | |
---|
51 | //List<int> *list = new List<int>(); |
---|
52 | npcList = new List<WorldEntity*>(); |
---|
53 | playerList = new List<WorldEntity*>(); |
---|
54 | envList = new List<WorldEntity*>(); |
---|
55 | } |
---|
56 | |
---|
57 | |
---|
58 | World::~World () {} |
---|
59 | |
---|
60 | |
---|
61 | |
---|
62 | /** |
---|
63 | \brief Load a new World |
---|
64 | |
---|
65 | Load a new world. The old world (if any) will be unloaded and becomes unrecoverable. |
---|
66 | */ |
---|
67 | void World::loadWorld() {} |
---|
68 | |
---|
69 | |
---|
70 | /** |
---|
71 | \brief Unloads a new World |
---|
72 | |
---|
73 | Unloads a world and frees the memory. You cant game until you have a new world loaded. |
---|
74 | */ |
---|
75 | void World::unloadWorld() {} |
---|
76 | |
---|
77 | |
---|
78 | /** |
---|
79 | \brief Pause the game |
---|
80 | |
---|
81 | Pauses the game until the pause is released. During this time nothing moves at all and nothing is calculated. Use it if you have to go out of the game to read some mails... |
---|
82 | */ |
---|
83 | void World::pauseWorld() {} |
---|
84 | |
---|
85 | |
---|
86 | /** |
---|
87 | \brief Save the game to file |
---|
88 | \param filename: the filename where the savegame should be saved to |
---|
89 | |
---|
90 | Saves the state of the game to a file. The state is catched like in a multiplayer game over a synchronisable interface. |
---|
91 | */ |
---|
92 | void World::saveGameState(char* filename) {} |
---|
93 | |
---|
94 | |
---|
95 | |
---|
96 | /** |
---|
97 | \brief Add Player |
---|
98 | \param player A reference to the new player object |
---|
99 | |
---|
100 | Add a new Player to the game. Player has to be initialised previously |
---|
101 | */ |
---|
102 | bool World::addPlayer(Player* player) |
---|
103 | { |
---|
104 | WorldEntity *we; |
---|
105 | playerList->add(we); |
---|
106 | /* |
---|
107 | playerList* listMember = new playerList; |
---|
108 | listMember->player = player; |
---|
109 | if ( lastPlayer != null ) |
---|
110 | { |
---|
111 | listMember->number = lastPlayer->number + 1; |
---|
112 | listMember->next = lastPlayer; |
---|
113 | } |
---|
114 | else |
---|
115 | { |
---|
116 | listMember->number = 0; |
---|
117 | listMember->next = null; |
---|
118 | } |
---|
119 | lastPlayer = listMember; |
---|
120 | */ |
---|
121 | } |
---|
122 | |
---|
123 | /** |
---|
124 | \brief Remove Player |
---|
125 | \param player A reference to the new npc object |
---|
126 | |
---|
127 | Remove a new Player to the game. This kills the player objects. |
---|
128 | */ |
---|
129 | bool World::removePlayer(Player* player) { |
---|
130 | playerList->remove(player, LIST_FIND_BW); |
---|
131 | } |
---|
132 | |
---|
133 | /** |
---|
134 | \brief Returns the player-entity controlled by the local gamer |
---|
135 | \return pointer to player object |
---|
136 | |
---|
137 | Remove a new Player to the game. This kills the player objects. |
---|
138 | */ |
---|
139 | Player* World::getLocalPlayer() |
---|
140 | { |
---|
141 | return localPlayer; |
---|
142 | } |
---|
143 | |
---|
144 | |
---|
145 | /** |
---|
146 | \brief Add Non-Player-Character |
---|
147 | \param player A reference to the new npc object |
---|
148 | |
---|
149 | Add a new Non-Player-Character to the game. Player has to be initialised previously |
---|
150 | */ |
---|
151 | bool World::addNPC(NPC* npc) |
---|
152 | { |
---|
153 | npcList->add(npc, LIST_ADD_NEXT); |
---|
154 | /* |
---|
155 | npcList* listMember = new npcList; |
---|
156 | listMember->npc = npc; |
---|
157 | if ( lastNPC != null ) |
---|
158 | { |
---|
159 | listMember->number = lastNPC->number + 1; |
---|
160 | listMember->next = lastNPC; |
---|
161 | } |
---|
162 | else |
---|
163 | { |
---|
164 | listMember->number = 0; |
---|
165 | listMember->next = null; |
---|
166 | } |
---|
167 | lastNPC = listMember; |
---|
168 | */ |
---|
169 | } |
---|
170 | |
---|
171 | |
---|
172 | /** |
---|
173 | \brief Remove Non-Player Character |
---|
174 | \param player A reference to the npc object |
---|
175 | |
---|
176 | Remove a Non-Player-Character to the game. |
---|
177 | */ |
---|
178 | bool World::removeNPC(NPC* npc) |
---|
179 | { |
---|
180 | npcList->remove(npc, LIST_FIND_FW); |
---|
181 | /* |
---|
182 | npcList* npcRef = lastNPC; |
---|
183 | npcList* lastRef = lastNPC; |
---|
184 | while ( npcRef != null ) |
---|
185 | { |
---|
186 | if ( npcRef->npc == npc ) { |
---|
187 | cout < |
---|
188 | < "found" << endl; |
---|
189 | if ( npcRef == lastRef ) { |
---|
190 | lastNPC = lastNPC->next; |
---|
191 | delete npcRef; |
---|
192 | npcRef = lastNPC; |
---|
193 | lastRef = lastNPC; |
---|
194 | } |
---|
195 | else { |
---|
196 | lastRef->next = npcRef->next; |
---|
197 | delete npcRef; |
---|
198 | npcRef = lastRef->next; |
---|
199 | } |
---|
200 | cout << "killed ..." << endl; |
---|
201 | } |
---|
202 | else { |
---|
203 | lastRef = npcRef; |
---|
204 | npcRef = npcRef->next; |
---|
205 | } |
---|
206 | } |
---|
207 | cout << "npc left" << endl; |
---|
208 | */ |
---|
209 | } |
---|
210 | |
---|
211 | |
---|
212 | |
---|
213 | /** |
---|
214 | \brief Add environmental object |
---|
215 | \param player A reference to the new env object |
---|
216 | |
---|
217 | Add a new Environment to the world. Env has to be initialised before. |
---|
218 | */ |
---|
219 | bool World::addEnv(Environment* env) |
---|
220 | { |
---|
221 | /* |
---|
222 | envList* listMember = new envList; |
---|
223 | listMember->env = env; |
---|
224 | if ( lastEnv != null ) |
---|
225 | { |
---|
226 | listMember->number = lastEnv->number + 1; |
---|
227 | listMember->next = lastEnv; |
---|
228 | } |
---|
229 | else |
---|
230 | { |
---|
231 | listMember->number = 0; |
---|
232 | listMember->next = null; |
---|
233 | } |
---|
234 | lastEnv = listMember; |
---|
235 | */ |
---|
236 | } |
---|
237 | |
---|
238 | /** |
---|
239 | \brief Remove an environmental object |
---|
240 | \param player A reference to the env object |
---|
241 | |
---|
242 | Remove a environment from the game. |
---|
243 | */ |
---|
244 | bool World::removeEnv(Environment* env) |
---|
245 | { |
---|
246 | |
---|
247 | } |
---|
248 | |
---|
249 | |
---|
250 | |
---|
251 | |
---|
252 | /** |
---|
253 | \brief Draws the World and all Objects contained |
---|
254 | |
---|
255 | Calls the draw function of all: Objects, Players, Environement. This is the core of all graphics here. |
---|
256 | */ |
---|
257 | void World::drawWorld(void) |
---|
258 | { |
---|
259 | |
---|
260 | glLoadIdentity(); |
---|
261 | gluLookAt(0.0, -14.0 + DataTank::yOffset, 15.0, 0.0, 0.0 + DataTank::yOffset, 0.0, 0.0, 1.0, 0.0); |
---|
262 | /* first draw all players */ |
---|
263 | |
---|
264 | |
---|
265 | /* |
---|
266 | playerList* tmpPlayer = lastPlayer; |
---|
267 | Player* player = tmpPlayer->player; |
---|
268 | while( tmpPlayer != null ) |
---|
269 | { |
---|
270 | tmpPlayer->player->paint(); |
---|
271 | tmpPlayer = tmpPlayer->next; |
---|
272 | } |
---|
273 | */ |
---|
274 | /* second draw all npcs */ |
---|
275 | /* |
---|
276 | npcList* tmpNPC = lastNPC; |
---|
277 | while( tmpNPC != null ) |
---|
278 | { |
---|
279 | (*tmpNPC->npc).paint(); |
---|
280 | tmpNPC = tmpNPC->next; |
---|
281 | } |
---|
282 | */ |
---|
283 | |
---|
284 | /* now draw the rest of the world: environement */ |
---|
285 | /* |
---|
286 | envList* tmpEnv = lastEnv; |
---|
287 | while( tmpEnv != null ) |
---|
288 | { |
---|
289 | (*tmpEnv->env).drawEnvironment(); |
---|
290 | tmpEnv = tmpEnv->next; |
---|
291 | } |
---|
292 | */ |
---|
293 | |
---|
294 | /* draw the ground grid */ |
---|
295 | glColor3f(0.0, 1.0, 0.0); |
---|
296 | glBegin(GL_LINES); |
---|
297 | /* for the moment, we've got only pseudo moving ground */ |
---|
298 | for (int y = 0; y < 60; y += 2) |
---|
299 | { |
---|
300 | for (int x = 0; x < 60; x += 2) |
---|
301 | { |
---|
302 | glVertex3f((float)(x - 30), (float)(y - 30), surface[x][y]); |
---|
303 | glVertex3f((float)(x - 28), (float)(y - 30), surface[x+2][y]); |
---|
304 | } |
---|
305 | } |
---|
306 | glEnd(); |
---|
307 | |
---|
308 | glBegin(GL_LINES); |
---|
309 | for (int x = 0; x < 60; x += 2) |
---|
310 | { |
---|
311 | for (int y = 0; y < 60; y += 2) |
---|
312 | { |
---|
313 | glVertex3f((float)(x - 30), (float)(y - 30), surface[x][y]); |
---|
314 | glVertex3f((float)(x - 30), (float)(y - 28), surface[x][y+2]); |
---|
315 | } |
---|
316 | } |
---|
317 | glEnd(); |
---|
318 | |
---|
319 | //primitiveMove+=0.07; |
---|
320 | DataTank::yOffset += step; |
---|
321 | |
---|
322 | /* |
---|
323 | tmpPlayer = lastPlayer; |
---|
324 | while( tmpPlayer != null ) |
---|
325 | { |
---|
326 | tmpPlayer->player->yCor += step; |
---|
327 | tmpPlayer = tmpPlayer->next; |
---|
328 | } |
---|
329 | */ |
---|
330 | |
---|
331 | } |
---|
332 | |
---|
333 | |
---|
334 | void World::initEnvironement() |
---|
335 | { |
---|
336 | |
---|
337 | for (int x = 0; x < 60; x += 2) |
---|
338 | { |
---|
339 | for (int y = 0; y < 60; y += 2) |
---|
340 | { |
---|
341 | surface[x][y] = 0; |
---|
342 | } |
---|
343 | } |
---|
344 | } |
---|
345 | |
---|
346 | |
---|
347 | void World::setWorldStep(float step) |
---|
348 | { |
---|
349 | //cout << "World::setWorldStep(" << step << ");" << endl; |
---|
350 | this->step = step; |
---|
351 | //cout << "setting speed to " << step << endl; |
---|
352 | } |
---|
353 | |
---|
354 | |
---|
355 | |
---|
356 | /** |
---|
357 | \brief Updates the world and all its objects |
---|
358 | |
---|
359 | Calculates the new state of the world. User-input and AI of |
---|
360 | the enemies are accounted for. |
---|
361 | */ |
---|
362 | void World::updateWorld(void) |
---|
363 | { |
---|
364 | |
---|
365 | |
---|
366 | } |
---|
367 | |
---|
368 | |
---|
369 | /* collision detection */ |
---|
370 | /* fix: bad efficency: stupid brute force */ |
---|
371 | |
---|
372 | void World::detectCollision() |
---|
373 | { |
---|
374 | /* |
---|
375 | //cout << "World::detectCollision" << endl; |
---|
376 | float xOff, yOff, zOff, radius; |
---|
377 | npcList* tmpNPC, *tmpRef; |
---|
378 | */ |
---|
379 | //cout << "World::detectCollsions" << endl; |
---|
380 | /* first: check if any player's shoots trigger a collision */ |
---|
381 | /* |
---|
382 | playerList* tmpPlayer = lastPlayer; |
---|
383 | Player* player = tmpPlayer->player; |
---|
384 | int state; |
---|
385 | while( tmpPlayer != null ) |
---|
386 | { |
---|
387 | tmpNPC = lastNPC; |
---|
388 | while( tmpNPC != null ) |
---|
389 | { |
---|
390 | //cout << "npc != null" << endl; |
---|
391 | radius = tmpNPC->npc->collisionRadius; |
---|
392 | //cout << "worki" << endl; |
---|
393 | ShootLaser::shoot* shoota = tmpPlayer->player->shootLaser->lastShoot; |
---|
394 | while( shoota != null ) |
---|
395 | { |
---|
396 | xOff = shoota->xCor - tmpNPC->npc->xCor; |
---|
397 | yOff = shoota->yCor - tmpNPC->npc->yCor; |
---|
398 | zOff = shoota->zCor - tmpNPC->npc->zCor; |
---|
399 | if ( sqrt(xOff*xOff + yOff*yOff + zOff*zOff) < radius ) |
---|
400 | { |
---|
401 | //cout << "COLLISION " << endl; |
---|
402 | int state = tmpNPC->npc->hit(); |
---|
403 | */ |
---|
404 | /* state is a value that marks if the ship dies or not */ |
---|
405 | /* if state == 0 the ship dies and we have to remove it */ |
---|
406 | /* |
---|
407 | if ( state == 0 ) { |
---|
408 | tmpRef = tmpNPC; |
---|
409 | tmpNPC = tmpNPC->next; |
---|
410 | removeNPC(tmpRef->npc); |
---|
411 | break; |
---|
412 | } |
---|
413 | |
---|
414 | } |
---|
415 | shoota = shoota->next; |
---|
416 | } |
---|
417 | //cout << "changing npc..." << endl; |
---|
418 | tmpNPC = tmpNPC->next; |
---|
419 | //cout << "..changing npc done" << endl; |
---|
420 | } |
---|
421 | //cout << "changing play..." << endl; |
---|
422 | tmpPlayer = tmpPlayer->next; |
---|
423 | //cout << "changing play done" << endl; |
---|
424 | |
---|
425 | } |
---|
426 | */ |
---|
427 | //cout << "World::detectCollisions middle" << endl; |
---|
428 | |
---|
429 | /* second: check if any player hits an enemy */ |
---|
430 | /* |
---|
431 | tmpPlayer = lastPlayer; |
---|
432 | while( tmpPlayer != null ) |
---|
433 | { |
---|
434 | tmpNPC = lastNPC; |
---|
435 | while( tmpNPC != null ) |
---|
436 | { |
---|
437 | radius = tmpNPC->npc->collisionRadius + tmpPlayer->player->collisionRadius; |
---|
438 | xOff = tmpPlayer->player->xCor - tmpNPC->npc->xCor; |
---|
439 | yOff = tmpPlayer->player->yCor - tmpNPC->npc->yCor; |
---|
440 | zOff = tmpPlayer->player->zCor - tmpNPC->npc->zCor; |
---|
441 | if ( sqrt(xOff*xOff + yOff*yOff + zOff*zOff) < radius ) { |
---|
442 | //cout << "COLLISION " << endl; |
---|
443 | tmpNPC->npc->hit(); |
---|
444 | } |
---|
445 | |
---|
446 | tmpNPC = tmpNPC->next; |
---|
447 | } |
---|
448 | |
---|
449 | tmpPlayer = tmpPlayer->next; |
---|
450 | } |
---|
451 | |
---|
452 | |
---|
453 | */ |
---|
454 | /* third: check if any enemy shoots a player */ |
---|
455 | |
---|
456 | //cout << "World::detectCollisions end" << endl; |
---|
457 | } |
---|
458 | |
---|
459 | |
---|
460 | |
---|
461 | /** |
---|
462 | \brief Routine for testing purposes. |
---|
463 | |
---|
464 | testing, testing, testing... |
---|
465 | */ |
---|
466 | void World::testThaTest(void) |
---|
467 | { |
---|
468 | /* |
---|
469 | cout << "World::testThaTest() called" << endl; |
---|
470 | |
---|
471 | cout << "addPlayer test..." << endl; |
---|
472 | playerList* pl = lastPlayer; |
---|
473 | while ( pl != null ) |
---|
474 | { |
---|
475 | cout << "player " << pl->number << " was found" << endl; |
---|
476 | pl = pl->next; |
---|
477 | } |
---|
478 | |
---|
479 | |
---|
480 | cout << "addNPC test..." << endl; |
---|
481 | npcList* nl = lastNPC; |
---|
482 | while ( nl != null ) |
---|
483 | { |
---|
484 | cout << "npc " << nl->number << " was found" << endl; |
---|
485 | nl = nl->next; |
---|
486 | } |
---|
487 | |
---|
488 | |
---|
489 | |
---|
490 | cout << "addEnv test..." << endl; |
---|
491 | envList* en = lastEnv; |
---|
492 | while ( en != null ) |
---|
493 | { |
---|
494 | cout << "env " << en->number << " was found" << endl; |
---|
495 | en = en->next; |
---|
496 | } |
---|
497 | */ |
---|
498 | } |
---|