diff options
Diffstat (limited to 'src/screens/gameScreen.c')
-rw-r--r-- | src/screens/gameScreen.c | 545 |
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!!! |