From f67aab0b37d877b9fb2a60b6b7f032e0b1d39d8d Mon Sep 17 00:00:00 2001 From: Linus Probert Date: Wed, 22 Aug 2018 20:54:39 +0200 Subject: [PATCH] Completes #43 Add win state Game now ends if you reach depth level 20 Also fixed: - Funky bug with stats with 0 dmg - Wonky speed = 2 on monsters behaviour - Some other minor stuff --- CMakeLists.txt | 2 +- data/monstergen.lua | 8 +-- src/gamestate.h | 1 + src/main.c | 137 +++++++++++++++++++++++++++++++++----------- src/map.c | 8 ++- src/monster.c | 12 +++- src/monster.h | 3 + src/roommatrix.c | 2 + src/stats.c | 4 +- 9 files changed, 132 insertions(+), 45 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fbf024a..4c18097 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -244,7 +244,7 @@ ENDIF () # LINT: if (CPPCHECK_FOUND) add_custom_target(lint - COMMAND ${CPPCHECK_EXECUTABLE} --force --language=c --template=gcc --error-exitcode=1 --quiet --enable=warning,style,performance,portability,information,missingInclude --suppress=*:src/sqlite3.? -isrc/sqlite3.c src/ + COMMAND ${CPPCHECK_EXECUTABLE} --force --language=c --template=gcc --error-exitcode=1 --quiet --enable=warning,style,performance,portability,information,missingInclude src/ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMENT "Run cppcheck" ) diff --git a/data/monstergen.lua b/data/monstergen.lua index 30951f3..542883f 100644 --- a/data/monstergen.lua +++ b/data/monstergen.lua @@ -100,11 +100,11 @@ local stats = { speed = 1 }, platino = { - hp = 30, - dmg = 0, + hp = 90, + dmg = 1, atk = 0, def = 0, - speed = 2 + speed = 1 } } @@ -282,8 +282,6 @@ if(CURRENT_LEVEL > 0) then enemies = {} enemies = concat(enemies, undead) enemies = concat(enemies, orcs) - enemies = concat(enemies, reptile) - enemies = concat(enemies, avian) elseif (CURRENT_LEVEL > 10) then enemies = {} enemies = concat(enemies, undead) diff --git a/src/gamestate.h b/src/gamestate.h index 5e8a52f..ae564aa 100644 --- a/src/gamestate.h +++ b/src/gamestate.h @@ -26,6 +26,7 @@ typedef enum GameState_t { PLAYING, IN_GAME_MENU, GAME_OVER, + COMPLETED, QUIT } GameState; diff --git a/src/main.c b/src/main.c index 412eef4..e9d8c35 100644 --- a/src/main.c +++ b/src/main.c @@ -332,10 +332,14 @@ static void toggleInGameMenu(void *unused) { UNUSED(unused); - if (gGameState == PLAYING || gGameState == GAME_OVER) + if (gGameState == PLAYING || + gGameState == GAME_OVER || + gGameState == COMPLETED) gGameState = IN_GAME_MENU; else if (is_player_dead()) gGameState = GAME_OVER; + else if (cLevel >= 20) + gGameState = COMPLETED; else gGameState = PLAYING; } @@ -413,7 +417,6 @@ createInGameGameOverMenu(void) { struct MENU_ITEM menu_items[] = { { "NEW GAME", startGame }, - { "HOW TO PLAY", showHowToTooltip }, { "MAIN MENU", goToMainMenu }, { "QUIT", exitGame }, }; @@ -422,7 +425,7 @@ createInGameGameOverMenu(void) menu_destroy(inGameMenu); inGameMenu = NULL; } - createMenu(&inGameMenu, menu_items, 4); + createMenu(&inGameMenu, menu_items, 3); } static void @@ -486,8 +489,10 @@ resetGame(void) screen_destroy(scoreScreen); scoreScreen = NULL; - if (!inGameMenu) - initInGameMenu(); + if (inGameMenu) + menu_destroy(inGameMenu); + inGameMenu = NULL; + initInGameMenu(); if (gMap) map_destroy(gMap); @@ -536,7 +541,8 @@ handle_main_input(void) { if (gGameState == PLAYING || gGameState == IN_GAME_MENU - || gGameState == GAME_OVER) + || gGameState == GAME_OVER + || gGameState == COMPLETED) { if (!gGui->activeTooltip && input_key_is_pressed(&input, KEY_ESC)) toggleInGameMenu(NULL); @@ -615,9 +621,24 @@ is_player_dead(void) return false; } +static void +end_game_details(void) +{ + gui_log("You earned %.2f gold", gPlayer->gold); + gui_event_message("You earned %.2f gold", gPlayer->gold); + if (hiscore_get_top_gold() < gPlayer->gold) { + gui_event_message("NEW HIGHSCORE"); + gui_log("NEW HIGHSCORE"); + } +} + static void check_next_level(void) { + if (cLevel >= 20) { + return; + } + Room *room = gMap->rooms[gMap->currentRoom.x][gMap->currentRoom.y]; Position pos = position_to_matrix_coords(&gPlayer->sprite->pos); @@ -629,14 +650,18 @@ check_next_level(void) if (tile->levelExit) { mixer_play_effect(NEXT_LEVEL); ++cLevel; - if (cLevel % 5 == 0) { + if (cLevel > 19) { + mixer_play_music(BOSS_MUSIC0); + } else if (cLevel % 5 == 0) { gui_log("You sense something powerful in the vicinity"); - gui_event_message("Something powerful lurks in the dark"); mixer_play_music(BOSS_MUSIC0); } else { mixer_play_music(GAME_MUSIC0 + get_random(2)); } - resetGame(); + + if (cLevel < 20) { + resetGame(); + } } } @@ -679,7 +704,6 @@ run_game_update(void) gGui->activeTooltip = new_artifact_tooltip; } - map_clear_expired_entities(gMap, gPlayer); if (gGameState == PLAYING && currentTurn == PLAYER) player_update(&updateData); @@ -698,25 +722,62 @@ run_game_update(void) currentTurn = MONSTER; player_reset_steps(gPlayer); map_on_new_turn(gMap); + map_clear_expired_entities(gMap, gPlayer); repopulate_roommatrix(); } } else if (currentTurn == MONSTER) { if (map_move_monsters(gMap, gRoomMatrix)) { currentTurn = PLAYER; + map_clear_expired_entities(gMap, gPlayer); repopulate_roommatrix(); } } } static void -run_game_render(void) +render_gui(void) { - SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 0); - SDL_RenderClear(gRenderer); + SDL_RenderSetViewport(gRenderer, &statsGuiViewport); + gui_render_panel(gGui, gCamera); + SDL_RenderSetViewport(gRenderer, &minimapViewport); + gui_render_minimap(gGui, gMap, gCamera); + SDL_RenderSetViewport(gRenderer, &skillBarViewport); + skillbar_render(gSkillBar, gPlayer, gCamera); + SDL_RenderSetViewport(gRenderer, &bottomGuiViewport); + gui_render_log(gGui, gCamera); + SDL_RenderSetViewport(gRenderer, NULL); +} +static void +render_game_completed(void) +{ + SDL_RenderSetViewport(gRenderer, &gameViewport); + if (!is_player_dead()) { + player_render(gPlayer, gCamera); + player_render_toplayer(gPlayer, gCamera); + } + actiontextbuilder_render(gCamera); + gui_render_event_message(gGui, gCamera); + + if (gGameState == IN_GAME_MENU) { + SDL_Rect dimmer = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT }; + SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 150); + SDL_RenderFillRect(gRenderer, &dimmer); + menu_render(inGameMenu, gCamera); + } +#ifdef DEBUG + sprite_render(fpsSprite, gCamera); + pointer_render(gPointer, gCamera); +#endif // DEBUG +} + +static void +render_game(void) +{ SDL_RenderSetViewport(gRenderer, &gameViewport); map_render(gMap, gCamera); particle_engine_render_game(gCamera); + map_render_mid_layer(gMap, gCamera); if (!is_player_dead()) { @@ -732,20 +793,17 @@ run_game_render(void) roommatrix_render_lightmap(gRoomMatrix, gCamera); actiontextbuilder_render(gCamera); gui_render_event_message(gGui, gCamera); +} - SDL_RenderSetViewport(gRenderer, &statsGuiViewport); - gui_render_panel(gGui, gCamera); +static void +run_game_render(void) +{ + SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 0); + SDL_RenderClear(gRenderer); - SDL_RenderSetViewport(gRenderer, &minimapViewport); - gui_render_minimap(gGui, gMap, gCamera); + render_game(); + render_gui(); - SDL_RenderSetViewport(gRenderer, &skillBarViewport); - skillbar_render(gSkillBar, gPlayer, gCamera); - - SDL_RenderSetViewport(gRenderer, &bottomGuiViewport); - gui_render_log(gGui, gCamera); - - SDL_RenderSetViewport(gRenderer, NULL); particle_engine_render_global(gCamera); gui_render_tooltip(gGui, gCamera); @@ -768,18 +826,21 @@ run_game(void) { run_game_update(); - run_game_render(); + if (cLevel >= 20) { + SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 255); + SDL_RenderClear(gRenderer); + render_game_completed(); + render_gui(); + SDL_RenderPresent(gRenderer); + } else { + run_game_render(); + } if (gGameState == PLAYING && is_player_dead()) { camera_shake(VECTOR2D_RIGHT, 800); gui_log("The dungeon consumed you"); - gui_log("You earned %.2f gold", gPlayer->gold); gui_event_message("You died!"); - gui_event_message("You earned %.2f gold", gPlayer->gold); - if (hiscore_get_top_gold() < gPlayer->gold) { - gui_event_message("NEW HIGHSCORE"); - gui_log("NEW HIGHSCORE"); - } + end_game_details(); mixer_play_effect(SPLAT); gGameState = GAME_OVER; createInGameGameOverMenu(); @@ -788,6 +849,15 @@ run_game(void) } else { check_next_level(); } + + if (gGameState == PLAYING && cLevel >= 20) { + gGameState = COMPLETED; + createInGameGameOverMenu(); + gui_event_message("Your break is over!"); + gui_log("Your break is over!"); + gui_event_message("Well done!"); + end_game_details(); + } } static void @@ -833,8 +903,8 @@ run_menu(void) SDL_RenderPresent(gRenderer); } -static -void run(void) +static void +run(void) { static int oldTime = 0; static int currentTime = 0; @@ -865,6 +935,7 @@ void run(void) case PLAYING: case IN_GAME_MENU: case GAME_OVER: + case COMPLETED: run_game(); break; case MENU: diff --git a/src/map.c b/src/map.c index a9d166f..b67d6ec 100644 --- a/src/map.c +++ b/src/map.c @@ -206,14 +206,18 @@ map_move_monsters(Map *map, RoomMatrix *rm) if (monster->state.current == PASSIVE && position_proximity(1, &rm->playerRoomPos, &pos)) continue; + if (monster->steps >= monster->stats.speed) + continue; allDone = allDone && monster_move(monster, rm, map); } - if (allDone) + if (allDone) { timer_stop(map->monsterMoveTimer); - else + linkedlist_each(&map->monsters, (void (*)(void*)) monster_reset_steps); + } else { timer_start(map->monsterMoveTimer); + } return allDone; } diff --git a/src/monster.c b/src/monster.c index b14f27d..82460d8 100644 --- a/src/monster.c +++ b/src/monster.c @@ -472,7 +472,10 @@ monster_move(Monster *m, RoomMatrix *rm, Map *map) RoomSpace *space = &rm->spaces[newPos.x][newPos.y]; if (space->light < 100 && withinHearingDist) { - actiontextbuilder_create_text("!", C_WHITE, &m->sprite->pos); + Position alertPos = m->sprite->pos; + alertPos.x += TILE_DIMENSION >> 1; + alertPos.y += TILE_DIMENSION >> 1; + actiontextbuilder_create_text("!", C_WHITE, &alertPos); } } @@ -498,13 +501,18 @@ monster_move(Monster *m, RoomMatrix *rm, Map *map) if (m->stateIndicator.displayCount > 0) m->stateIndicator.displayCount -= 1; m->state.stepsSinceChange += 1; - m->steps = 0; return true; } return false; } +void +monster_reset_steps(Monster *m) +{ + m->steps = 0; +} + void monster_update(Monster *m, UpdateData *data) { diff --git a/src/monster.h b/src/monster.h index e99a0fb..e35d09c 100644 --- a/src/monster.h +++ b/src/monster.h @@ -109,6 +109,9 @@ monster_set_state(Monster *m, StateType state, Uint8 forceCount); void monster_push(Monster *, RoomMatrix*, Vector2d dir); +void +monster_reset_steps(Monster *m); + void monster_destroy(Monster*); diff --git a/src/roommatrix.c b/src/roommatrix.c index 7c5f9d0..519b37e 100644 --- a/src/roommatrix.c +++ b/src/roommatrix.c @@ -295,6 +295,8 @@ void roommatrix_destroy(RoomMatrix *m) linkedlist_pop(&space->items); while (space->artifacts) linkedlist_pop(&space->artifacts); + while (space->objects) + linkedlist_pop(&space->objects); } } diff --git a/src/stats.c b/src/stats.c index 8a5e393..1da5b88 100644 --- a/src/stats.c +++ b/src/stats.c @@ -75,9 +75,9 @@ stats_fight(Stats *attacker, Stats *defender) int dmgRoll = 0; if (atkRoll >= defRoll) { if (attacker->dmg > 0) - dmgRoll = get_random(attacker->dmg) + 1; - else dmgRoll = get_random(attacker->dmg - 1) + 1; + else + dmgRoll = 1; if (critical) { dmgRoll = dmgRoll * 2;