2 Copyright (C) 2004-2011 Parallel Realities
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 int medalWorker(void *data)
25 char *tname = (char*)data;
27 SDL_mutexP(medalServer.lock);
29 int type = medalServer.postMedal(tname);
31 while (!graphics.canShowMedalMessage())
38 if (type >= 1 && type <= 3)
40 audio.playSound(SND_ITEM, CH_ANY);
41 graphics.showMedalMessage(type, medalServer.getMessage());
43 if (medalServer.hasRuby())
45 while (!graphics.canShowMedalMessage())
52 audio.playSound(SND_ITEM, CH_ANY);
53 graphics.showMedalMessage(4, medalServer.getRubyMessage());
57 SDL_mutexV(medalServer.lock);
64 void presentPlayerMedal(const char *tname)
66 // Copy the input, so that threading
67 // doesn't trip us up!
68 char *data = new char[128];
69 strlcpy(data, tname, 128);
71 SDL_Thread *thread = SDL_CreateThread(medalWorker, (void*)data);
75 printf("Unable to create thread: %s\n", SDL_GetError());
76 printf("Calling medal server directly\n");
77 medalWorker((void*)data);
82 void addPlayerScore(int score)
84 if (game.score < 100000 && game.score + score >= 100000)
86 presentPlayerMedal("Score_100000");
88 else if (game.score < 250000 && game.score + score >= 250000)
90 presentPlayerMedal("Score_250000");
92 else if (game.score < 500000 && game.score + score >= 500000)
94 presentPlayerMedal("Score_500000");
102 game.getCheckPoint(&player.x, &player.y);
107 player.environment = ENV_AIR;
110 addTeleportParticles(player.x + 10, player.y + 10, 50, SND_TELEPORT2);
112 Math::removeBit(&player.flags, ENT_FLIES);
113 Math::removeBit(&player.flags, ENT_TELEPORTING);
114 player.setSprites(graphics.getSprite("BobRight", true), graphics.getSprite("BobLeft", true), graphics.getSprite("BobSpin", true));
117 map.windChangeTime = 90;
123 int amount = (game.gore) ? 25 : 150;
125 for (int i = 0 ; i < amount ; i++)
127 x = player.x + Math::rrand(-3, 3);
128 y = player.y + Math::rrand(-3, 3);
132 dx = Math::rrand(-5, 5);
133 dy = Math::rrand(-15, -5);
134 addEffect(x, y, dx, dy, EFF_BLEEDS);
138 dx = Math::rrand(-5, 5);
139 dy = Math::rrand(-5, 5);
140 addColoredEffect(x, y, dx, dy, graphics.yellow, EFF_COLORED + EFF_WEIGHTLESS);
144 (game.gore) ? audio.playSound(SND_SPLAT, CH_ANY) : audio.playSound(SND_POP, CH_ANY);
147 void checkPlayerBulletCollisions(Entity *bullet)
149 if ((bullet->health < 1) || (player.health <= -60))
154 if ((player.flags & ENT_TELEPORTING) || (game.missionOver > 0))
159 if (bullet->owner != &player)
161 if (Collision::collision(&player, bullet))
163 if ((!player.immune) && (!(bullet->flags & ENT_EXPLODES)))
165 addBlood(&player, bullet->dx / 4, Math::rrand(-6, -3), 1);
166 audio.playSound(SND_HIT, CH_ANY);
167 if (game.missionOverReason == MIS_INPROGRESS)
169 player.health -= bullet->damage;
174 Math::removeBit(&bullet->flags, ENT_SPARKS);
175 Math::removeBit(&bullet->flags, ENT_PUFFS);
177 if (player.health <= 0)
179 player.dx = bullet->dx;
181 audio.playSound(SND_DEATH1 + Math::prand() % 3, CH_DEATH);
185 if (bullet->id == WP_LASER)
187 debug(("Laser Hit Player"));
188 throwAndDamageEntity(&player, 0, -3, 3, -8);
200 if (engine.cheatHealth)
202 player.health = MAX_HEALTH;
205 if (game.missionOverReason == MIS_PLAYERESCAPE)
210 if (player.y > (map.limitDown + 500))
212 if (game.missionOver == 0)
217 if (player.health > 0)
219 game.setMissionOver(MIS_PLAYEROUT);
223 game.setMissionOver(MIS_PLAYERDEAD);
227 if (player.flags & ENT_TELEPORTING)
233 if (game.missionOverReason == MIS_PLAYEROUT)
235 graphics.blit(player.getFaceImage(), (int)(player.x - engine.playerPosX), (int)(player.y - engine.playerPosY), graphics.screen, false);
240 if ((player.health < 1) || (player.immune > 120))
242 if (player.health <= -60)
249 if (game.hasAquaLung)
256 graphics.blit(player.getFaceImage(), (int)(player.x - engine.playerPosX), (int)(player.y - engine.playerPosY), graphics.screen, false);
258 if (player.health < 1)
263 if (player.health <= -60)
271 if ((!(player.flags & ENT_FLIES)) && (!map.isIceLevel))
276 // toggles the Jetpack if available
277 if (config.isControl(CONTROL::JETPACK))
279 if ((game.hasJetPack) || (engine.cheatExtras))
281 if (player.flags & ENT_FLIES)
283 Math::removeBit(&player.flags, ENT_FLIES);
284 player.setSprites(graphics.getSprite("BobRight", true), graphics.getSprite("BobLeft", true), graphics.getSprite("BobSpin", true));
288 if ((player.fuel > 3) && (player.environment == ENV_AIR))
290 Math::addBit(&player.flags, ENT_FLIES);
291 player.setSprites(graphics.getSprite("JPBobRight", true), graphics.getSprite("JPBobLeft", true), graphics.getSprite("BobSpin", true));
293 else if (player.environment == ENV_WATER)
295 engine.setInfoMessage("Jetpack cannot be used underwater", 0, INFO_NORMAL);
299 engine.setInfoMessage("Jetpack is recharging...", 0, INFO_NORMAL);
305 engine.setInfoMessage("Don't have jetpack!", 0, INFO_NORMAL);
308 config.resetControl(CONTROL::JETPACK);
311 if (map.isBlizzardLevel)
313 if ((!config.isControl(CONTROL::LEFT)) && (!config.isControl(CONTROL::RIGHT)))
315 if ((player.dx > -2) && (player.dx < 2))
317 player.dx += map.windPower * 0.1;
322 if (config.isControl(CONTROL::LEFT))
326 if (player.flags & ENT_FLIES)
329 Math::limitFloat(&player.dx, -PLAYER_FLY_SPEED, PLAYER_FLY_SPEED);
331 else if (map.isIceLevel)
334 Math::limitFloat(&player.dx, -PLAYER_WALK_SPEED * 1.25, PLAYER_WALK_SPEED * 1.25);
339 player.dx = -PLAYER_WALK_SPEED;
343 if (engine.cheatSpeed)
348 else if (config.isControl(CONTROL::RIGHT))
352 if (player.flags & ENT_FLIES)
355 Math::limitFloat(&player.dx, -PLAYER_FLY_SPEED, PLAYER_FLY_SPEED);
357 else if (map.isIceLevel)
361 Math::limitFloat(&player.dx, -PLAYER_WALK_SPEED * 1.25, PLAYER_WALK_SPEED * 1.25);
365 player.dx = PLAYER_WALK_SPEED;
369 if (engine.cheatSpeed)
374 else if (!(player.flags & ENT_FLIES))
377 player.currentFrame = 0;
380 Math::limitFloat(&player.x, 10, map.limitRight + 608);
381 Math::limitFloat(&player.y, map.limitUp + 5, (MAPHEIGHT * BRICKSIZE) + 64);
383 // Keyboard break fix - Feb 09
384 if ((config.isControl(CONTROL::UP)) || (config.isControl(CONTROL::JUMP)))
386 if (player.flags & ENT_FLIES)
389 Math::limitFloat(&player.dy, -PLAYER_FLY_SPEED, PLAYER_FLY_SPEED);
390 if (engine.cheatSpeed)
395 else if ((player.environment == ENV_AIR) && (player.falling == false))
397 player.falling = true;
398 player.dy = PLAYER_JUMP_SPEED;
399 config.resetControl(CONTROL::UP);
400 config.resetControl(CONTROL::JUMP);
402 else if (player.environment != ENV_AIR)
404 player.dy = -PLAYER_WALK_SPEED;
406 if (engine.cheatSpeed)
413 if (config.isControl(CONTROL::DOWN))
415 if (player.flags & ENT_FLIES)
418 Math::limitFloat(&player.dy, -PLAYER_FLY_SPEED, PLAYER_FLY_SPEED);
420 else if (player.environment != ENV_AIR)
426 if (engine.cheatSpeed)
433 if (engine.keyState[SDLK_1])
434 player.currentWeapon = &weapon[WP_PISTOL];
435 else if (engine.keyState[SDLK_2])
436 player.currentWeapon = &weapon[WP_MACHINEGUN];
437 else if (engine.keyState[SDLK_3])
438 player.currentWeapon = &weapon[WP_GRENADES];
439 else if (engine.keyState[SDLK_4])
440 player.currentWeapon = &weapon[WP_LASER];
441 else if (engine.keyState[SDLK_5])
442 player.currentWeapon = &weapon[WP_SPREAD];
447 // Math::limitFloat(&player.x, 10, map.limitRight + 608);
448 // moveEntity() limits x < 10
449 if (player.x > map.limitRight + 608)
451 player.x = map.limitRight + 608;
457 // Math::limitFloat(&player.y, map.limitUp + 5, (MAPHEIGHT * BRICKSIZE) + 64);
458 if (player.y < map.limitUp + 5)
460 player.y = map.limitUp + 5;
466 else if (player.y > (MAPHEIGHT * BRICKSIZE) + 64)
468 player.y = (MAPHEIGHT * BRICKSIZE) + 64;
471 if (config.isControl(CONTROL::FIRE))
473 if (player.reload == 0)
475 addBullet(&player, player.currentWeapon->getSpeed(player.face), 0);
476 if (player.currentWeapon == &weapon[WP_SPREAD])
478 addBullet(&player, player.currentWeapon->getSpeed(player.face), 2);
479 addBullet(&player, player.currentWeapon->getSpeed(player.face), -2);
484 if (player.environment == ENV_WATER)
486 Math::removeBit(&player.flags, ENT_FLIES);
488 addBubble(player.x, player.y);
490 if ((player.thinktime == 30) && (player.oxygen == 0))
492 audio.playSound(SND_DROWNING, CH_ANY);
498 if (player.fuel == 0)
500 player.setSprites(graphics.getSprite("BobRight", true), graphics.getSprite("BobLeft", true), graphics.getSprite("BobSpin", true));
503 if ((game.hasAquaLung) || (engine.cheatExtras))
508 if (engine.cheatFuel)
513 if (((player.immune % 5) == 0) && (!(player.flags & ENT_TELEPORTING)))
515 if ((game.missionOverReason == MIS_COMPLETE) || (game.missionOverReason == MIS_INPROGRESS) || (game.missionOverReason == MIS_GAMECOMPLETE))
517 if (player.flags & ENT_FLIES)
520 addFireTrailParticle(player.x + (player.face * 16) + Math::rrand(-1, 1), player.y + 10 + Math::rrand(-1, 1));
522 graphics.blit(player.getFaceImage(), (int)(player.x - engine.playerPosX), (int)(player.y - engine.playerPosY), graphics.screen, false);