aboutsummaryrefslogtreecommitdiff
path: root/src/screens/gameScreen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/screens/gameScreen.c')
-rw-r--r--src/screens/gameScreen.c545
1 files changed, 545 insertions, 0 deletions
diff --git a/src/screens/gameScreen.c b/src/screens/gameScreen.c
new file mode 100644
index 0000000..de650c5
--- /dev/null
+++ b/src/screens/gameScreen.c
@@ -0,0 +1,545 @@
+#include "gameScreen.h"
+#include "game.h"
+#include "world.h"
+#include "entity.h"
+#include "bullets.h"
+#include "assets.h"
+#include "killLog.h"
+#include "entitiesInclude.h"
+
+#define NEXT_LEVEL_INSULTS_COUNT 4
+
+const char * nextLevelInsults[NEXT_LEVEL_INSULTS_COUNT] = {
+ "You suck at this game",
+ "Your the living enbodiment of a skill issue",
+ "Your grandma could do better then that",
+ "Go touch grass"
+};
+
+void initGameScreenGui(GameScreen * gameScreen) {
+ float width = GetScreenWidth();
+ float height = GetScreenHeight();
+
+ // It is kind of terrible but works.
+ gameScreen->infoTextPosition = (Vector2){0.0, height / 1.5};
+
+ gameScreen->targetInfoPosition = (Vector2){
+ width - (GAME_SCREEN_TEXT_SIZE * (GAME_SCREEN_TARGET_INFO_MAX / 2.0)),
+ height - RADAR_TEXTURE_SIZE - (GAME_SCREEN_TEXT_SIZE * 4.0)
+ };
+
+ gameScreen->zoomViewPosition = (Vector2){width - GAME_SCREEN_ZOOM_VIEW_UI_SIZE - 20.0, 10.0};
+
+ gameScreen->killLogPosition = (Vector2){0.0, 40.0};
+
+ resetRadarPosition(&gameScreen->radar);
+ resetGyroscopePosition(&gameScreen->gyroscope);
+}
+
+void initGameScreen(Game * game, GameScreen * gameScreen) {
+
+ // World render.
+ if (game->settings.useWorldRenderTexture) {
+ gameScreen->worldRender = LoadRenderTexture(game->settings.renderWidth, game->settings.renderHeight);
+ gameScreen->usingWorldRenderTexture = true;
+ } else {
+ gameScreen->usingWorldRenderTexture = false;
+ }
+
+ // Zoom view.
+ gameScreen->zoomViewTexture = LoadRenderTexture(GAME_SCREEN_ZOOM_VIEW_SIZE, GAME_SCREEN_ZOOM_VIEW_SIZE);
+
+ gameScreen->gameOver = false;
+ gameScreen->mainCamera = THIRD_PERSON_CAMERA;
+ gameScreen->levelComplete = false;
+ gameScreen->healthAtLevelEnd = ENTITY_MAX_HEALTH;
+ gameScreen->nextLevelInsultNum = 0;
+ gameScreen->gameComplete = false;
+
+ // Gyroscope indeed
+ initGyroscope(&gameScreen->gyroscope);
+
+ // Radar indeed.
+ initRadar(&gameScreen->radar);
+
+ initStars(&gameScreen->stars);
+
+ initGameScreenGui(gameScreen);
+}
+
+void freeGameScreen(GameScreen * gameScreen) {
+ closeGyroscope(&gameScreen->gyroscope);
+ closeRadar(&gameScreen->radar);
+
+ if (gameScreen->usingWorldRenderTexture)
+ UnloadRenderTexture(gameScreen->worldRender);
+
+ UnloadRenderTexture(gameScreen->zoomViewTexture);
+}
+
+void drawCrossHairPosition(Vector2 position, float size, float thick, Color color) {
+ // Left to right.
+ DrawLineEx(
+ (Vector2){position.x - size, position.y},
+ (Vector2){position.x + size, position.y},
+ thick,
+ color
+ );
+
+ // Top to bottom.
+ DrawLineEx(
+ (Vector2){position.x, position.y - size},
+ (Vector2){position.x, position.y + size},
+ thick,
+ color
+ );
+}
+
+void drawCrossHair(float size, float thick, Color color) {
+ Vector2 center = (Vector2){GetScreenWidth() / 2.0, GetScreenHeight() / 2.0};
+ drawCrossHairPosition(center, size, thick, color);
+}
+
+void drawGameScreenInfoText(Game * game, GameScreen * gameScreen) {
+ Entity * player = getEntityFromWorld(game->world, 0);
+ AntifaShip * data = (AntifaShip*)player->data;
+
+ // Hello reader. I fucking hate you!
+ size_t bufSize = 255;
+ char buf[bufSize];
+
+ // Format text.
+ snprintf(
+ buf,
+ bufSize,
+ "Health %.2f\n\nX %.2f\nY %.2f\nZ %.2f\n\nSpeed %.2f/%.2f",
+ player->health,
+ player->position.x,
+ player->position.y,
+ player->position.z,
+ data->forwardSpeed,
+ Vector3Length(player->velocity.velocity)
+ );
+
+ // Draw info text.
+ DrawText(
+ buf,
+ gameScreen->infoTextPosition.x,
+ gameScreen->infoTextPosition.y,
+ GAME_SCREEN_TEXT_SIZE,
+ GREEN
+ );
+}
+
+void drawGameScreenTargetInfo(Game * game, GameScreen * gameScreen) {
+ Entity * player = getEntityFromWorld(game->world, 0);
+ AntifaShip * data = (AntifaShip*)player->data;
+
+ size_t bufSize = 255;
+ char buf[bufSize];
+
+ // Format.
+ snprintf(
+ buf,
+ bufSize,
+ "Auto: %s",
+ data->doAutoTarget ? "On" : "Off"
+ );
+
+ // Is auto targeting.
+ if (data->doAutoTarget) {
+ Entity * targetedEntity = getEntityFromWorld(game->world, data->targetedEntityId);
+
+ if (targetedEntity != NULL) {
+ char bufCopy[bufSize];
+ strncpy(bufCopy, buf, bufSize);
+
+ // Add more formatted text.
+ snprintf(
+ buf,
+ bufSize,
+ "%s\nId: %d@%x\nDistance: %.2f\nOn Target: %s",
+ bufCopy,
+ data->targetedEntityId,
+ data->targetedEntityFingerprint,
+ Vector3Distance(player->position, targetedEntity->position),
+ data->isOnTarget ? "Yes" : "No"
+ );
+ }
+ }
+
+ // Draw.
+ DrawText(
+ buf,
+ gameScreen->targetInfoPosition.x,
+ gameScreen->targetInfoPosition.y,
+ GAME_SCREEN_TEXT_SIZE,
+ GREEN
+ );
+}
+
+void drawGameScreenGui(Game * game) {
+ GameScreen * gameScreen = &game->gameScreen;
+
+ // Draw cross hair.
+ if (gameScreen->mainCamera == FIRST_PERSON_CAMERA || gameScreen->mainCamera == ZOOM_CAMERA) {
+ // Get color depending if on target or not.
+ Entity * player = getEntityFromWorld(game->world, 0);
+ AntifaShip * data = (AntifaShip*)player->data;
+ Color color = data->isOnTarget ? RED : BLUE;
+
+ drawCrossHair(10.0, 2.0, color);
+ }
+
+ drawKillLog(&game->killLog, gameScreen->killLogPosition);
+ drawGameScreenInfoText(game, gameScreen);
+ drawGameScreenTargetInfo(game, gameScreen);
+ drawGyroscope(game, &gameScreen->gyroscope);
+ drawRadar(game, &gameScreen->radar);
+}
+
+void handleGameScreenInput(Game * game, GameScreen * gameScreen) {
+ switch(GetKeyPressed()) {
+ case KEY_ONE:
+ gameScreen->mainCamera = FIRST_PERSON_CAMERA;
+ break;
+ case KEY_TWO:
+ gameScreen->mainCamera = THIRD_PERSON_CAMERA;
+ break;
+ case KEY_THREE:
+ gameScreen->mainCamera = ZOOM_CAMERA;
+ break;
+ // case KEY_FOUR:
+ // gameScreen->mainCamera = DEBUG_CAMERA;
+ // break;
+ default:
+ break;
+ }
+}
+
+void drawNextLevelScreen(Game * game, GameScreen * gameScreen) {
+ float width = GetScreenWidth();
+ float height = GetScreenHeight();
+
+ size_t bufSize = 100;
+ char buf[bufSize];
+
+ // Complete message.
+ snprintf(
+ buf,
+ bufSize,
+ "Level %d complete",
+ gameScreen->lastLevel + 1
+ );
+
+ DrawText(
+ buf,
+ (width / 2.0) - (50.0 * strnlen(buf, bufSize) / 4.0),
+ height / 3.0,
+ 50,
+ GREEN
+ );
+
+ // Draw insult.
+ const char * insult = nextLevelInsults[gameScreen->nextLevelInsultNum];
+
+ DrawText(
+ insult,
+ (width / 2.0) - (GAME_SCREEN_TEXT_SIZE * strlen(insult) / 4.0),
+ height / 3.0 + 70.0,
+ GAME_SCREEN_TEXT_SIZE,
+ GREEN
+ );
+}
+
+void callThisFuckerAtGameComplete(Game * game, GameScreen * gameScreen) {
+ gameScreen->gameComplete = true;
+ gameScreen->gameCompleteAt = GetTime();
+}
+
+void gameScreenHandleLevels(Game * game, GameScreen * gameScreen) {
+ // Show complete screen if level complete.
+ if (gameScreen->levelComplete) {
+ drawNextLevelScreen(game, gameScreen);
+
+ // Next fucking level.
+ if (GetTime() - gameScreen->timeAtLevelComplete >= GAME_SCREEN_NEXT_LEVEL_DELAY || IsKeyPressed(KEY_SPACE)) {
+ gameScreen->levelComplete = false;
+ startLevel(game, &game->levels, gameScreen->lastLevel + 1);
+ getEntityFromWorld(game->world, 0)->health = Clamp(gameScreen->healthAtLevelEnd * 1.5, 0.0, 1.0);
+ }
+
+ return;
+ }
+
+ bool complete = updateLevel(game, &game->levels);
+
+ // This fucker been completed.
+ if (complete) {
+ gameScreen->lastLevel = game->levels.currentLevel;
+ gameScreen->healthAtLevelEnd = getEntityFromWorld(game->world, 0)->health;
+
+ // Game is complete lol.
+ if (game->levels.currentLevel == GAME_LEVELS_COMPLETE_AT)
+ callThisFuckerAtGameComplete(game, gameScreen);
+
+ endLevel(game, &game->levels);
+
+ gameScreen->levelComplete = true;
+ gameScreen->timeAtLevelComplete = GetTime();
+
+ SetRandomSeed(time(NULL));
+ gameScreen->nextLevelInsultNum = GetRandomValue(0, NEXT_LEVEL_INSULTS_COUNT - 1);
+ }
+}
+
+void drawGameScreenStars(Game * game, GameScreen * gameScreen) {
+ DrawModel(
+ game->assets.models[SKY_ASSET],
+ getEntityFromWorld(game->world, 0)->position,
+ GAME_SCREEN_SKY_BOX_SIZE,
+ WHITE
+ );
+
+ drawStars(game, &gameScreen->stars);
+}
+
+void renderWorldGameScreen(Game * game, GameScreen * gameScreen) {
+ BeginMode3D(game->cameras[gameScreen->mainCamera]);
+
+ drawGameScreenStars(game, gameScreen);
+
+ // Draw world.
+ drawWorld(&game->world, game);
+
+ EndMode3D();
+}
+
+void drawZoomViewGameScreen(Game * game, GameScreen * gameScreen) {
+ CameraId cameraId = ZOOM_CAMERA;
+
+ if (gameScreen->mainCamera == ZOOM_CAMERA)
+ cameraId = THIRD_PERSON_CAMERA;
+
+ // Update camera.
+ runCameraUpdate(game, game->cameras, cameraId);
+
+ // Render onto texture.
+ BeginTextureMode(gameScreen->zoomViewTexture);
+ ClearBackground(BLACK);
+
+ BeginMode3D(game->cameras[cameraId]);
+ drawWorld(&game->world, game);
+ EndMode3D();
+
+ EndTextureMode();
+
+ // Draw texture.
+ DrawTexturePro(
+ gameScreen->zoomViewTexture.texture,
+ (Rectangle){0.0, 0.0, GAME_SCREEN_ZOOM_VIEW_SIZE, -GAME_SCREEN_ZOOM_VIEW_SIZE},
+ (Rectangle){
+ gameScreen->zoomViewPosition.x,
+ gameScreen->zoomViewPosition.y,
+ GAME_SCREEN_ZOOM_VIEW_UI_SIZE,
+ GAME_SCREEN_ZOOM_VIEW_UI_SIZE,
+ },
+ (Vector2){0.0, 0.0},
+ 0.0,
+ WHITE
+ );
+
+ // Draw cross hair.
+ if (cameraId == ZOOM_CAMERA) {
+ float halfSize = GAME_SCREEN_ZOOM_VIEW_UI_SIZE / 2.0;
+ Vector2 crossHairPosition = Vector2Add(gameScreen->zoomViewPosition, (Vector2){halfSize, halfSize});
+
+ Entity * player = getEntityFromWorld(game->world, 0);
+ AntifaShip * data = (AntifaShip*)player->data;
+ Color color = data->isOnTarget ? RED : BLUE;
+
+ drawCrossHairPosition(crossHairPosition, 4.0, 2.0, color);
+ }
+
+ // Draw outline.
+ DrawRectangleLines(
+ gameScreen->zoomViewPosition.x,
+ gameScreen->zoomViewPosition.y,
+ GAME_SCREEN_ZOOM_VIEW_UI_SIZE,
+ GAME_SCREEN_ZOOM_VIEW_UI_SIZE,
+ GREEN
+ );
+}
+
+void drawGameOverGameScreen(Game * game, GameScreen * gameScreen) {
+ float width = GetScreenWidth();
+ float height = GetScreenHeight();
+
+ const char gameOverMsg[] = "Game Over";
+
+ Vector2 position = (Vector2){
+ width / 2.0 - ((sizeof(gameOverMsg) + 1) * (GAME_SCREEN_GAME_OVER_FONT_SIZE / 2.0) / 2.0),
+ height / 3.0
+ };
+
+ DrawText(gameOverMsg, position.x, position.y, GAME_SCREEN_GAME_OVER_FONT_SIZE, GREEN);
+}
+
+void resetGame(Game * game, GameScreen * gameScreen) {
+ gameScreen->gameOver = false;
+ gameScreen->lastLevel = 0;
+ gameScreen->levelComplete = false;
+ gameScreen->gameComplete = false;
+ resetKillLog(&game->killLog);
+
+ startLevel(game, &game->levels, 0);
+}
+
+bool handleGameOver(Game * game, GameScreen * gameScreen) {
+ Entity * player = getEntityFromWorld(game->world, 0);
+
+ // Already game over.
+ if (gameScreen->gameOver) {
+
+ // To main after after so much time.
+ if (GetTime() - gameScreen->gameOverAt >= GAME_SCREEN_SHOW_GAME_OVER_FOR || IsKeyPressed(KEY_SPACE)) {
+ closeGameScreen(game);
+ game->screenId = SCREEN_MAIN_MENU;
+ resetGame(game, gameScreen);
+ }
+
+ return true;
+ }
+
+ // Check if there is player.
+ if (!gameScreen->levelComplete) {
+ if (player == NULL)
+ gameScreen->gameOver = true;
+ else if (player->health <= 0.0)
+ gameScreen->gameOver = true;
+ }
+
+ // End game ):
+ if (gameScreen->gameOver) {
+ gameScreen->gameOverAt = GetTime();
+ endLevel(game, &game->levels);
+ }
+
+ return gameScreen->gameOver;
+}
+
+void handleGameComplete(Game * game, GameScreen * gameScreen) {
+ float width = GetScreenWidth();
+ float height = GetScreenHeight();
+
+ const char gameCompleteMsg[] = "Game Complete";
+
+ // Game over message.
+ Vector2 position = (Vector2){
+ width / 2.0 - ((sizeof(gameCompleteMsg) + 1) * (GAME_SCREEN_GAME_COMPLETE_FONT_SIZE / 2.0) / 2.0),
+ height / 3.0
+ };
+
+ DrawText(gameCompleteMsg, position.x, position.y, GAME_SCREEN_GAME_COMPLETE_FONT_SIZE, GREEN);
+
+ // Funny little shitty message.
+ const char funnyLittleMsg[] = "I guess you don't completely suck at this game lmao";
+
+ position = (Vector2){
+ width / 2.0 - ((sizeof(funnyLittleMsg) + 1) * (GAME_SCREEN_TEXT_SIZE / 2.0) / 2.0),
+ height / 3.0 + GAME_SCREEN_GAME_COMPLETE_FONT_SIZE + 10
+ };
+
+ DrawText(funnyLittleMsg, position.x, position.y, GAME_SCREEN_TEXT_SIZE, GREEN);
+
+ // End game.
+ if (GetTime() - gameScreen->gameCompleteAt >= GAME_SCREEN_GAME_COMPLETE_SHOW_FOR || IsKeyPressed(KEY_SPACE)) {
+ closeGameScreen(game);
+ game->screenId = SCREEN_MAIN_MENU;
+ resetGame(game, gameScreen);
+ }
+}
+
+void updateGameScreen(Game * game) {
+ GameScreen * gameScreen = &game->gameScreen;
+
+ handleGameScreenInput(game, gameScreen);
+
+ ClearBackground(BLACK);
+
+ // Game over ):
+ if (handleGameOver(game, gameScreen)) {
+ drawGameOverGameScreen(game, gameScreen);
+ return;
+ }
+
+ // Game complete stuff.
+ if (gameScreen->gameComplete) {
+ handleGameComplete(game, gameScreen);
+ return;
+ }
+
+ // Levels indeed.
+ gameScreenHandleLevels(game, gameScreen);
+
+ if (gameScreen->levelComplete)
+ return;
+
+ // Update world.
+ updateWorld(&game->world, game);
+
+ // Camera.
+ runCameraUpdate(game, game->cameras, gameScreen->mainCamera);
+
+ // Draw world.
+ if (gameScreen->usingWorldRenderTexture) {
+ BeginTextureMode(gameScreen->worldRender);
+ ClearBackground(BLACK);
+ renderWorldGameScreen(game, gameScreen);
+ EndTextureMode();
+
+ DrawTexturePro(
+ gameScreen->worldRender.texture,
+ (Rectangle){0.0, 0.0, game->settings.renderWidth, -game->settings.renderHeight},
+ (Rectangle){0.0, 0.0, GetScreenWidth(), GetScreenHeight()},
+ (Vector2){0.0, 0.0},
+ 0.0,
+ WHITE
+ );
+ } else {
+ renderWorldGameScreen(game, gameScreen);
+ }
+
+ drawZoomViewGameScreen(game, gameScreen);
+
+ // GUI.
+ drawGameScreenGui(game);
+}
+
+void resizeGameScreen(Game * game, GameScreen * gameScreen) {
+ initGameScreenGui(gameScreen);
+}
+
+void openGameScreen(Game * game) {
+ game->screenId = SCREEN_GAME;
+
+ if (game->settings.lockMouse)
+ DisableCursor();
+}
+
+void closeGameScreen(Game * game) {
+ if (game->settings.lockMouse)
+ EnableCursor();
+}
+
+// You may think are minds are empty and we lack soul. Have you ever thought that was just a way to cover up what you have to hide?
+// While to you I seemed a bit weird to me you were not even human. To me you were just a copy paste child with the same
+// fake nice act that I know the teacher told you to put on only around me. It doesn't matter if you put on the fake little nice act or
+// was a straight up bully because you were still a complete asshole. I could have watched the most terrible things happen to you and I would have just
+// stood there and not done anything about it even if I had the power to stop it. The teachers at school put a lot of shit
+// into teaching me and others like me how to put on a little mask so we could exist around people like you.
+// Why do I need to be trained to act in a acceptable way just to even exist around you while you were saying and doing
+// your stupid little shit. I was being put down by all the adults for doing something close to as shitty as the
+// things you did daily. Now you see yourself as a decent person and might even think you support people like me.
+// The truth is your hands are covered with blood and the layer of blood only gets thicker every day.
+// FUCK YOU!!!