#include "gameScreen.h" #include "game.h" #include "world.h" #include "bullets.h" #include "assets.h" #include "killLog.h" #include "entitiesInclude.h" 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; // 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); Vector3 position = player->position; Vector3 velocity = player->velocity.velocity; // 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", player->health, position.x, position.y, position.z, Vector3Length(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", game->levels.currentLevel + 1 ); DrawText( buf, (width / 2.0) - (50.0 * strnlen(buf, bufSize) / 4.0), height / 3.0, 50, GREEN ); } 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) { gameScreen->levelComplete = false; startLevel(game, &game->levels, gameScreen->lastLevel + 1); } return; } bool complete = updateLevel(game, &game->levels); // This fucker been completed. if (complete) { gameScreen->lastLevel = game->levels.currentLevel; endLevel(game, &game->levels); gameScreen->levelComplete = true; gameScreen->timeAtLevelComplete = GetTime(); } } 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, WHITE); } void resetGame(Game * game, GameScreen * gameScreen) { gameScreen->gameOver = false; gameScreen->lastLevel = 0; gameScreen->levelComplete = 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) { 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 updateGameScreen(Game * game) { GameScreen * gameScreen = &game->gameScreen; handleGameScreenInput(game, gameScreen); ClearBackground(BLACK); // Game over ): if (handleGameOver(game, gameScreen)) { drawGameOverGameScreen(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(); }