Adds functioning player death and introduces better XP threshholds.

I'm pretty sure I've done the XP thing before. Perhaps I never comitted
that code?
This commit is contained in:
Linus_Probert 2018-02-14 11:00:34 +01:00
parent a045ffc07c
commit cfa522009e
4 changed files with 61 additions and 11 deletions

View File

@ -52,6 +52,7 @@ struct MENU_ITEM {
static void resetGame(void); static void resetGame(void);
static void initMainMenu(void); static void initMainMenu(void);
static bool is_player_dead(void);
static static
bool initSDL(void) bool initSDL(void)
@ -160,6 +161,9 @@ startGame(void *unused)
UNUSED(unused); UNUSED(unused);
cLevel = 1; cLevel = 1;
gGameState = PLAYING; gGameState = PLAYING;
if (gPlayer)
player_destroy(gPlayer);
gPlayer = player_create(WARRIOR, gRenderer);
resetGame(); resetGame();
} }
@ -174,8 +178,10 @@ static void
toggleInGameMenu(void *unused) toggleInGameMenu(void *unused)
{ {
UNUSED(unused); UNUSED(unused);
if (gGameState == PLAYING) if (gGameState == PLAYING || gGameState == GAME_OVER)
gGameState = IN_GAME_MENU; gGameState = IN_GAME_MENU;
else if (is_player_dead())
gGameState = GAME_OVER;
else else
gGameState = PLAYING; gGameState = PLAYING;
} }
@ -188,6 +194,9 @@ goToMainMenu(void *unused)
menu_destroy(inGameMenu); menu_destroy(inGameMenu);
inGameMenu = NULL; inGameMenu = NULL;
initMainMenu(); initMainMenu();
Position p = { 0, 0 };
map_set_current_room(gMap, &p);
camera_follow_position(&gCamera, &p);
} }
static void static void
@ -264,8 +273,11 @@ resetGame(void)
if (gMap) if (gMap)
map_destroy(gMap); map_destroy(gMap);
particle_engine_clear();
info("Building new map"); info("Building new map");
gMap = map_lua_generator_run(cLevel, gRenderer); gMap = map_lua_generator_run(cLevel, gRenderer);
gPlayer->sprite->pos = (Position) { gPlayer->sprite->pos = (Position) {
TILE_DIMENSION, TILE_DIMENSION }; TILE_DIMENSION, TILE_DIMENSION };
@ -297,7 +309,10 @@ loadMedia(void)
static bool static bool
handle_main_events(SDL_Event *event) handle_main_events(SDL_Event *event)
{ {
if (gGameState == PLAYING || gGameState == IN_GAME_MENU) { if (gGameState == PLAYING
|| gGameState == IN_GAME_MENU
|| gGameState == GAME_OVER)
{
if (keyboard_press(SDLK_ESCAPE, event)) { if (keyboard_press(SDLK_ESCAPE, event)) {
toggleInGameMenu(NULL); toggleInGameMenu(NULL);
return true; return true;
@ -340,10 +355,9 @@ handle_events(void)
} }
static bool static bool
check_if_dead(void) is_player_dead(void)
{ {
if (gPlayer->stats.hp <= 0) { if (gPlayer->stats.hp <= 0) {
gui_log("The dungeon consumed you");
return true; return true;
} }
return false; return false;
@ -392,10 +406,13 @@ run_game(void)
SDL_RenderSetViewport(gRenderer, &gameViewport); SDL_RenderSetViewport(gRenderer, &gameViewport);
map_render(gMap, &gCamera); map_render(gMap, &gCamera);
particle_engine_render(&gCamera); particle_engine_render(&gCamera);
player_render(gPlayer, &gCamera);
if (!is_player_dead())
player_render(gPlayer, &gCamera);
if (gPlayer->class == MAGE || gPlayer->class == PALADIN) if (gPlayer->class == MAGE || gPlayer->class == PALADIN)
roommatrix_render_mouse_square(gRoomMatrix, &gCamera); roommatrix_render_mouse_square(gRoomMatrix, &gCamera);
roommatrix_render_lightmap(gRoomMatrix, &gCamera); roommatrix_render_lightmap(gRoomMatrix, &gCamera);
SDL_RenderSetViewport(gRenderer, &rightGuiViewport); SDL_RenderSetViewport(gRenderer, &rightGuiViewport);
@ -413,12 +430,17 @@ run_game(void)
SDL_RenderFillRect(gRenderer, &dimmer); SDL_RenderFillRect(gRenderer, &dimmer);
menu_render(inGameMenu, &gCamera); menu_render(inGameMenu, &gCamera);
} }
if (gGameState == GAME_OVER) {
// TODO(Linus): Render game over?
}
pointer_render(gPointer, &gCamera); pointer_render(gPointer, &gCamera);
SDL_RenderPresent(gRenderer); SDL_RenderPresent(gRenderer);
if (check_if_dead()) if (gGameState == PLAYING && is_player_dead()) {
gui_log("The dungeon consumed you");
gGameState = GAME_OVER; gGameState = GAME_OVER;
}
check_next_level(); check_next_level();
} }
@ -470,14 +492,12 @@ void run(void)
switch (gGameState) { switch (gGameState) {
case PLAYING: case PLAYING:
case IN_GAME_MENU: case IN_GAME_MENU:
case GAME_OVER:
run_game(); run_game();
break; break;
case MENU: case MENU:
run_menu(); run_menu();
break; break;
case GAME_OVER:
fatal("GAME_OVER not implemented");
break;
case QUIT: case QUIT:
quit = true; quit = true;
break; break;

View File

@ -40,7 +40,6 @@ particle_engine_init(void)
void void
particle_engine_bloodspray(Position pos, Dimension dim, unsigned int count) particle_engine_bloodspray(Position pos, Dimension dim, unsigned int count)
{ {
check_engine(); check_engine();
if (count > 100) if (count > 100)
@ -145,6 +144,14 @@ particle_engine_render(Camera *cam)
} }
} }
void
particle_engine_clear(void)
{
check_engine();
while (engine->particles)
free(linkedlist_pop(&engine->particles));
}
void void
particle_engine_close(void) particle_engine_close(void)
{ {

View File

@ -18,6 +18,9 @@ particle_engine_update(float deltatime);
void void
particle_engine_render(Camera*); particle_engine_render(Camera*);
void
particle_engine_clear(void);
void void
particle_engine_close(void); particle_engine_close(void);

View File

@ -35,7 +35,15 @@ player_levelup(Player *player)
static unsigned int static unsigned int
next_level_threshold(unsigned int current_level) next_level_threshold(unsigned int current_level)
{ {
return (current_level * 50) + ((current_level > 0 ? current_level - 1 : 0) * 150); unsigned int last_level = 0;
unsigned int padding = 0;
if (current_level > 0) {
last_level = next_level_threshold(current_level - 1);
padding = (current_level - 1) * 150;
}
return last_level + (current_level * 50) + padding;
} }
static void static void
@ -190,6 +198,15 @@ handle_movement_input(Player *player, RoomMatrix *matrix, SDL_Event *event)
move_down(player, matrix); move_down(player, matrix);
moved = true; moved = true;
} }
#ifdef DEBUG
if (keyboard_mod_press(SDLK_SPACE, KMOD_CTRL, event)) {
Position pos = player->sprite->pos;
pos.x += 8;
pos.y += 8;
particle_engine_bloodspray(pos, (Dimension) { 8, 8 }, 200);
player->stats.hp = 0;
}
#endif // DEBUG
if (moved) { if (moved) {
player->sprite->clip.x = 16*step; player->sprite->clip.x = 16*step;
@ -292,6 +309,9 @@ ExperienceData player_get_xp_data(Player *p)
void void
player_hit(Player *p, unsigned int dmg) player_hit(Player *p, unsigned int dmg)
{ {
if (p->stats.hp <= 0) {
dmg = 200;
}
if (dmg > 0) { if (dmg > 0) {
p->hitText->active = true; p->hitText->active = true;
p->missText->active = false; p->missText->active = false;