2 Copyright (C) 2004-2010 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.
27 map.persistantList.clear();
28 engine.practice = false;
30 game.skill = engine.skill;
33 void showInGameOptions()
35 if (!engine.loadWidgets(_("data/inGameWidgets")))
37 graphics.showErrorAndExit(ERR_FILE, _("data/inGameWidgets"));
40 graphics.drawRect(120, 100, 400, 300, graphics.black, graphics.white, graphics.screen);
42 int cont, options, escape, quit, escapeyes, escapeno, warnno, warnyes, quitno, quityes, train, trainno, trainyes, restart, restartno, restartyes;
43 cont = options = escape = quit = escapeyes = escapeno = warnno = warnyes = quitno = quityes = train = trainno = trainyes = restart = restartno = restartyes = 0;
45 engine.setWidgetVariable("continue", &cont);
46 engine.setWidgetVariable("options", &options);
47 engine.setWidgetVariable("escape", &escape);
48 engine.setWidgetVariable("restart", &restart);
49 engine.setWidgetVariable("quit", &quit);
50 engine.setWidgetVariable("train", &train);
52 engine.setWidgetVariable("warnno", &warnno);
53 engine.setWidgetVariable("warnyes", &warnyes);
55 engine.setWidgetVariable("restartno", &restartno);
56 engine.setWidgetVariable("restartyes", &restartyes);
58 engine.setWidgetVariable("quitno", &quitno);
59 engine.setWidgetVariable("quityes", &quityes);
61 engine.setWidgetVariable("trainno", &quitno);
62 engine.setWidgetVariable("trainyes", &quityes);
64 engine.setWidgetVariable("escapeno", &escapeno);
65 engine.setWidgetVariable("escapeyes", &escapeyes);
67 engine.showWidgetGroup("warning", false);
68 engine.showWidgetGroup("restartconf", false);
69 engine.showWidgetGroup("escapeconf", false);
70 engine.showWidgetGroup("quitconf", false);
71 engine.showWidgetGroup("trainconf", false);
73 if ((map.isBossMission) || (engine.practice) || (strcmp(map.name, "Space Station") == 0))
75 engine.enableWidget("escape", false);
76 engine.enableWidget("restart", false);
81 engine.showWidget("train", false);
85 engine.showWidget("quit", false);
92 audio.playMenuSound(2);
98 graphics.updateScreen();
102 if ((config.isControl(CONTROL::PAUSE)) || (engine.keyState[SDLK_ESCAPE]))
104 engine.keyState[SDLK_ESCAPE] = 0;
105 config.resetControl(CONTROL::PAUSE);
109 menuSound = engine.processWidgets();
113 graphics.drawRect(120, 100, 400, 300, graphics.black, graphics.white, graphics.screen);
115 audio.playMenuSound(menuSound);
125 engine.showWidgetGroup("options", false);
127 if (!gameData.stagePreviouslyCleared(game.stageName))
129 engine.showWidgetGroup("warning", true);
130 engine.highlightWidget("warnno");
134 engine.showWidgetGroup("escapeconf", true);
135 engine.highlightWidget("escapeno");
138 graphics.drawRect(120, 100, 400, 300, graphics.black, graphics.white, graphics.screen);
143 if ((escapeyes) || (warnyes))
146 audio.stopAmbiance();
147 addTeleportParticles(player.x, player.y, 50, SND_TELEPORT3);
149 game.setMissionOver(MIS_PLAYERESCAPE);
159 if ((warnno) || (quitno) || (escapeno) || (trainno) || (restartno))
161 engine.highlightWidget("continue");
162 engine.showWidgetGroup("options", true);
163 engine.showWidgetGroup("warning", false);
164 engine.showWidgetGroup("trainconf", false);
165 engine.showWidgetGroup("escapeconf", false);
166 engine.showWidgetGroup("quitconf", false);
167 engine.showWidgetGroup("restartconf", false);
169 if (!engine.practice)
171 engine.showWidget("train", false);
175 engine.showWidget("quit", false);
178 graphics.drawRect(120, 100, 400, 300, graphics.black, graphics.white, graphics.screen);
180 quitno = trainno = warnno = escapeno = restartno = 0;
185 engine.showWidgetGroup("options", false);
186 engine.showWidgetGroup("quitconf", true);
187 engine.highlightWidget("quitno");
189 graphics.drawRect(120, 100, 400, 300, graphics.black, graphics.white, graphics.screen);
196 engine.showWidgetGroup("options", false);
197 engine.showWidgetGroup("trainconf", true);
198 engine.highlightWidget("trainno");
200 graphics.drawRect(120, 100, 400, 300, graphics.black, graphics.white, graphics.screen);
207 engine.showWidgetGroup("options", false);
208 engine.showWidgetGroup("restartconf", true);
209 engine.highlightWidget("restartno");
211 graphics.drawRect(120, 100, 400, 300, graphics.black, graphics.white, graphics.screen);
216 if ((quityes) || (trainyes))
218 game.setMissionOver(MIS_PLAYERQUIT);
224 game.setMissionOver(MIS_PLAYERRESTART);
225 SDL_FillRect(graphics.screen, NULL, graphics.black);
227 audio.stopAmbiance();
240 replayData.read(config.command);
242 if (game.missionOverReason == MIS_INPROGRESS)
247 engine.doFrameLoop();
249 graphics.updateScreen();
250 graphics.animateSprites();
251 graphics.drawBackground();
263 if (map.isBossMission)
272 if (map.isBlizzardLevel)
279 if ((SDL_GetAppState() & SDL_APPINPUTFOCUS) == 0)
281 engine.paused = true;
284 replayData.set(config.command);
291 audio.stopAmbiance();
293 if (!engine.loadWidgets(_("data/gameOverWidgets")))
295 graphics.showErrorAndExit(ERR_FILE, _("data/gameOverWidgets"));
298 SDL_Surface *gameover = graphics.quickSprite("Game Over", graphics.loadImage("gfx/main/gameover.png"));
299 graphics.setTransparent(gameover);
301 audio.loadGameOverMusic();
307 unsigned int frameLimit = SDL_GetTicks() + 16;
309 bool showGameOverOptions = false;
310 int cont, quit, menuSound;
311 cont = quit = menuSound = 0;
313 engine.setWidgetVariable("gameOverNo", &cont);
314 engine.setWidgetVariable("gameOverYes", &quit);
316 if (game.canContinue > 1)
318 Widget *widget = engine.getWidgetByName("gameOverNo");
320 snprintf(postfix, sizeof postfix, " (%d)", game.canContinue);
321 strlcat(widget->label, postfix, sizeof widget->label);
327 audio.playMenuSound(menuSound);
332 graphics.blit(gameover, 320, 240, graphics.screen, true);
334 if (engine.userAccepts())
336 if (!showGameOverOptions)
338 showGameOverOptions = true;
339 engine.showWidgetGroup("gameover", true);
340 engine.highlightWidget("gameOverNo");
345 // Can't continue on a boss mission or if no checkpoints reached!
346 if ((map.isBossMission) || (!game.canContinue))
348 engine.showWidgetGroup("gameover", false);
353 if (showGameOverOptions)
356 menuSound = engine.processWidgets();
359 if ((cont) || (quit))
362 engine.delay(frameLimit);
363 frameLimit = SDL_GetTicks() + 16;
369 graphics.fadeToBlack();
372 return SECTION_TITLE;
375 game.continueFromCheckPoint = true;
377 audio.reloadLevelMusic();
382 void showMissionInformation()
384 SDL_FillRect(graphics.screen, NULL, graphics.black);
385 graphics.updateScreen();
387 SDL_Surface *panel = graphics.createSurface(400, 300);
388 SDL_Surface *panelBack = graphics.alphaRect(400, 300, 0x00, 0x00, 0x00);
389 SDL_SetColorKey(panel, (SDL_SRCCOLORKEY|SDL_RLEACCEL), SDL_MapRGB(panel->format, 0, 0, 0));
391 graphics.drawRect(1, 1, 398, 298, graphics.black, graphics.white, panelBack);
398 Objective *objective;
400 graphics.setFontSize(0);
402 graphics.setFontSize(3);
403 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
404 graphics.drawString(_(game.stageName), 200, 20, TXT_CENTERED, panel);
406 graphics.setFontSize(0);
410 if (map.totalMIAs > 0)
412 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
413 snprintf(message, sizeof message, _("Rescue %d MIAs"), map.requiredMIAs);
414 graphics.drawString(message, col1, y, TXT_LEFT, panel);
416 if (map.foundMIAs < map.requiredMIAs)
418 graphics.setFontColor(0xff, 0x00, 0x00, 0x00, 0x00, 0x00);
419 snprintf(message, sizeof message, "%d / %d", map.foundMIAs, map.requiredMIAs);
420 graphics.drawString(message, col2, y, TXT_RIGHT, panel);
424 graphics.setFontColor(0x00, 0xff, 0x00, 0x00, 0x00, 0x00);
425 graphics.drawString(_("Completed"), col2, y, TXT_RIGHT, panel);
429 objective = (Objective*)map.objectiveList.getHead();
431 while (objective->next != NULL)
433 objective = (Objective*)objective->next;
437 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
439 if ((game.skill < 3) && (strstr(objective->description, "L.R.T.S.")) && (!gameData.completedWorld))
441 graphics.drawString(_("???? ???????? ????"), col1, y, TXT_LEFT, panel);
445 graphics.drawString(_(objective->description), col1, y, TXT_LEFT, panel);
448 // this is a fake objective (for the 4th Ancient Tomb)
449 if (objective->targetValue == -1)
451 graphics.setFontColor(0xff, 0x00, 0x00, 0x00, 0x00, 0x00);
452 graphics.drawString(_("Incomplete"), col2, y, TXT_RIGHT, panel);
454 else if (objective->currentValue < objective->targetValue)
456 graphics.setFontColor(0xff, 0x00, 0x00, 0x00, 0x00, 0x00);
457 if (objective->targetValue == 1)
459 graphics.drawString(_("Incomplete"), col2, y, TXT_RIGHT, panel);
463 snprintf(message, sizeof message, "%d / %d", objective->currentValue, objective->targetValue);
464 graphics.drawString(message, col2, y, TXT_RIGHT, panel);
469 graphics.setFontColor(0x00, 0xff, 0x00, 0x00, 0x00, 0x00);
470 graphics.drawString(_("Completed"), col2, y, TXT_RIGHT, panel);
476 graphics.setFontColor(0xff, 0xff, 0x00, 0x00, 0x00, 0x00);
477 snprintf(message, sizeof message, _("Time Limit - %d:%.2d Minutes"), map.remainingMinutes, map.remainingSeconds);
478 graphics.drawString(message, 200, 260, TXT_CENTERED, panel);
481 graphics.setFontColor(0xff, 0xff, 0xff, 0x00, 0x00, 0x00);
482 graphics.drawString(_("Press Fire to Continue"), 200, 280, TXT_CENTERED, panel);
489 map.getRandomEntityPosition(&px, &py);
490 map.getRandomEntityPosition(&player.tx, &player.ty);
495 unsigned int frameLimit = SDL_GetTicks() + 16;
499 if ((int)player.x < player.tx) player.x += 2;
500 if ((int)player.x > player.tx) player.x -= 2;
501 if ((int)player.y < player.ty) player.y += 2;
502 if ((int)player.y > player.ty) player.y -= 2;
504 if (Collision::collision(player.x, player.y, 5, 5, player.tx, player.ty, 5, 5))
505 map.getRandomEntityPosition(&player.tx, &player.ty);
507 engine.setPlayerPosition((int)player.x, (int)player.y, map.limitLeft, map.limitRight, map.limitUp, map.limitDown);
511 graphics.blit(panelBack, 320, 220, graphics.screen, true);
512 graphics.blit(panel, 320, 220, graphics.screen, true);
514 engine.delay(frameLimit);
515 frameLimit = SDL_GetTicks() + 16;
517 if (engine.userAccepts())
521 SDL_FreeSurface(panel);
522 SDL_FreeSurface(panelBack);
524 SDL_FillRect(graphics.screen, NULL, graphics.black);
525 graphics.delay(1000);
530 game.getCheckPoint(&player.x, &player.y);
532 int beamInTime = 180;
534 unsigned int frameLimit = SDL_GetTicks() + 16;
536 audio.playSound(SND_TELEPORT1, CH_ANY);
538 engine.setPlayerPosition((int)player.x, (int)player.y, map.limitLeft, map.limitRight, map.limitUp, map.limitDown);
540 while (beamInTime > 0)
542 engine.delay(frameLimit);
543 frameLimit = SDL_GetTicks() + 16;
548 if ((beamInTime % 10) == 0)
549 addTeleportParticles(player.x + 10, player.y + 10, 50, -1);
554 game.getCheckPoint(&player.x, &player.y);
559 player.environment = ENV_AIR;
562 Math::removeBit(&player.flags, ENT_FLIES);
567 graphics.setFontSize(0);
569 SDL_FillRect(graphics.screen, NULL, graphics.black);
570 graphics.delay(1000);
572 Uint32 then, frames, frameLimit, millis, frameCounter;
578 strlcpy(fps, "fps", sizeof fps);
581 engine.messageTime = -1;
582 engine.messagePriority = -1;
585 audio.playAmbiance();
587 if (!game.continueFromCheckPoint)
591 if ((!map.isBossMission) && (replayData.replayMode == REPLAY_MODE::NONE))
593 showMissionInformation();
596 game.levelsStarted++;
600 game.useObjectiveCheckPoint();
603 player.setVelocity(0, 1);
604 player.baseThink = 60;
605 player.health = MAX_HEALTH;
607 if (game.continueFromCheckPoint)
609 player.health = (MAX_HEALTH / 2);
610 player.setSprites(graphics.getSprite("BobRight", true), graphics.getSprite("BobLeft", true), graphics.getSprite("BobSpin", true));
614 player.currentWeapon = &weapon[WP_PISTOL];
617 game.resetMissionOver();
619 frameLimit = SDL_GetTicks() + 16;
621 start = then = SDL_GetTicks();
622 frameCounter = SDL_GetTicks();
624 if ((strcmp(map.name, "Space Station") == 0) && (!game.continueFromCheckPoint))
636 debug(("Map Clipping is %d %d %d %d\n", map.limitLeft, map.limitRight, map.limitUp, map.limitDown));
638 game.continueFromCheckPoint = false;
640 engine.paused = false;
646 cur = SDL_GetTicks();
648 if (game.missionOverReason != MIS_PLAYEROUT)
650 engine.setPlayerPosition((int)player.x, (int)player.y, map.limitLeft, map.limitRight, map.limitUp, map.limitDown);
659 if ((player.environment == ENV_SLIME) || (player.environment == ENV_LAVA) || (player.health < 1))
661 if (player.health < 1)
663 game.setMissionOver(MIS_PLAYERDEAD);
665 audio.stopAmbiance();
669 game.setMissionOver(MIS_PLAYEROUT);
674 if (config.isControl(CONTROL::MAP))
676 if (!map.isBossMission)
678 showMap((int)(player.x / 32), (int)(player.y / 32));
682 engine.setInfoMessage("Automap is not available!", 1, INFO_HINT);
688 doMusicInfo(cur - start);
690 if ((engine.keyState[SDLK_ESCAPE]) && (game.missionOver == 0))
692 if (replayData.replayMode == REPLAY_MODE::NONE)
702 if (allObjectivesCompleted())
704 if (game.missionOver == 0)
706 if (map.isBossMission)
708 map.killAllEnemies();
712 audio.stopAmbiance();
714 game.setMissionOver(MIS_COMPLETE);
715 engine.setInfoMessage("All Required Objectives Met - Mission Complete", 10, INFO_OBJECTIVE);
719 if (game.missionOver > 0)
723 if (game.missionOver == 0)
725 if (game.missionOverReason == MIS_PLAYEROUT)
727 SDL_FillRect(graphics.screen, NULL, graphics.black);
728 graphics.updateScreen();
729 graphics.delay(1000);
733 game.resetMissionOver();
737 if (game.missionOverReason == MIS_COMPLETE)
739 game.missionOver = MAX_FPS * 2;
741 if (strcmp(map.name, "Space Station") != 0)
743 addTeleportParticles(player.x, player.y, 50, SND_TELEPORT3);
745 game.missionOverReason = MIS_PLAYERESCAPE;
752 else if (game.missionOverReason == MIS_GAMECOMPLETE)
754 addTeleportParticles(player.x, player.y, 50, SND_TELEPORT3);
755 game.missionOverReason = MIS_PLAYERESCAPE;
756 game.missionOver = MAX_FPS * 4;
760 if (replayData.replayMode != REPLAY_MODE::NONE)
771 Math::limitInt(&(--game.lastComboTime), 0, 60);
777 if ((game.missionOverReason == MIS_INPROGRESS) || (game.missionOverReason == MIS_PLAYEROUT))
779 game.incrementMissionTime();
794 while (engine.paused)
799 graphics.updateScreen();
800 then = SDL_GetTicks();
811 if ((engine.keyState[SDLK_F3]) && (engine.cheatSkipLevel))
813 autoCompleteAllObjectives(true);
814 engine.keyState[SDLK_F3] = 0;
815 engine.setInfoMessage("Skipping Mission...", 2, INFO_OBJECTIVE);
819 if (engine.keyState[SDLK_F1])
821 autoCompleteAllObjectives(false);
825 if (replayData.replayMode != REPLAY_MODE::PLAYBACK)
827 engine.delay(frameLimit);
829 else if (!replayData.fast)
831 engine.delay(frameLimit);
834 if (engine.keyState[SDLK_F5])
836 replayData.fast = !replayData.fast;
837 engine.keyState[SDLK_F5] = 0;
840 frameLimit = SDL_GetTicks() + 16;
842 if (game.missionOverReason == MIS_GAMECOMPLETE)
843 frameLimit = SDL_GetTicks() + 64;
846 static Graphics::SurfaceCache fpsCache;
847 graphics.drawString(fps, 600, 30, true, graphics.screen, fpsCache);
849 if (SDL_GetTicks() > frameCounter + 500)
851 now = SDL_GetTicks();
852 snprintf(fps, sizeof fps, "%2.2f fps", ((double)frames*1000)/(now - then));
853 then = frameCounter = SDL_GetTicks();
859 if (allObjectivesCompleted())
861 if (strcmp(map.name, "Final Battle") == 0)
863 game.missionOverReason = MIS_GAMECOMPLETE;
867 game.missionOverReason = MIS_COMPLETE;
871 switch (game.missionOverReason)
874 if (strcmp(map.name, "Space Station"))
876 graphics.delay(1000);
877 audio.loadMusic("music/grasslands");
879 graphics.fadeToBlack();
881 bool previouslyCompleted = gameData.stagePreviouslyCleared(game.stageName);
887 return SECTION_TITLE;
890 if (!previouslyCompleted)
898 graphics.fadeToBlack();
899 processPostMissionData();
901 game.setMapName("data/finalBattle");
902 game.setStageName("Final Battle");
907 case MIS_GAMECOMPLETE:
908 SDL_FillRect(graphics.screen, NULL, graphics.white);
909 graphics.updateScreen();
910 graphics.fadeToBlack();
912 // we've finished the game. Extreme mode is now available! :)
913 engine.extremeAvailable = true;
918 return SECTION_CREDITS;
922 game.canContinue = 0;
924 if (player.health > -60)
929 return SECTION_GAMEOVER;
932 case MIS_PLAYERESCAPE:
934 if (gameData.stagePreviouslyCleared(game.stageName))
936 processPostMissionData();
942 case MIS_PLAYERRESTART:
943 clearAllMissionData();
948 return SECTION_TITLE;
952 return SECTION_TITLE;