From b2bd4db89ac281ffddf23ef4469fa427eaa8b710 Mon Sep 17 00:00:00 2001 From: Aldrik Ramaekers Date: Sun, 7 Jan 2024 18:04:08 +0100 Subject: player death --- include/asset_defs.h | 5 +++++ include/players.h | 3 ++- include/sprite.h | 1 + notes | 2 -- src/asset_defs.c | 5 +++++ src/audio.c | 8 ++++++-- src/players.c | 55 +++++++++++++++++++++++++++++++++++++++------------- src/sprite.c | 10 ++++++++-- src/zombies.c | 33 ++++++++++++++++++++++++++++++- 9 files changed, 100 insertions(+), 22 deletions(-) delete mode 100644 notes diff --git a/include/asset_defs.h b/include/asset_defs.h index bf98710..60ad94a 100644 --- a/include/asset_defs.h +++ b/include/asset_defs.h @@ -49,18 +49,23 @@ image* img_molotov_explode; // Players image* img_gunner_blue_run; image* img_gunner_blue_idle; +image* img_gunner_blue_die; image* img_gunner_black_run; image* img_gunner_black_idle; +image* img_gunner_black_die; image* img_gunner_green_run; image* img_gunner_green_idle; +image* img_gunner_green_die; image* img_gunner_yellow_run; image* img_gunner_yellow_idle; +image* img_gunner_yellow_die; image* img_gunner_red_run; image* img_gunner_red_idle; +image* img_gunner_red_die; image* img_bullet_stream; image* img_muzzle_flash; diff --git a/include/players.h b/include/players.h index efafd2b..d230d0c 100644 --- a/include/players.h +++ b/include/players.h @@ -19,6 +19,7 @@ typedef enum t_player_interact_state { INTERACT_IDLE, INTERACT_RELOADING, + INTERACT_DEAD } player_interact_state; typedef enum t_player_direction { @@ -68,7 +69,7 @@ typedef struct t_player { int kills; u64 ping; sprite sprite; - sprite gun_sprite; + sprite sprite_death; network_state connection_state; u32 points; struct { diff --git a/include/sprite.h b/include/sprite.h index 2775b62..6c314d0 100644 --- a/include/sprite.h +++ b/include/sprite.h @@ -14,6 +14,7 @@ typedef struct t_sprite { int img_height; int frame_start; float zoom; + bool loop; } sprite; typedef struct t_sprite_frame { diff --git a/notes b/notes deleted file mode 100644 index 3b8d95d..0000000 --- a/notes +++ /dev/null @@ -1,2 +0,0 @@ -- monster aanval -> screen flash (rode randen) -- voetsteppen voor grote monster \ No newline at end of file diff --git a/src/asset_defs.c b/src/asset_defs.c index 3c6f328..6c8fc08 100644 --- a/src/asset_defs.c +++ b/src/asset_defs.c @@ -52,18 +52,23 @@ void load_assets() { // Players img_gunner_black_run = assets_load_image_from_file("data/imgs/players/Black/Gunner_Black_Run.png"); img_gunner_black_idle = assets_load_image_from_file("data/imgs/players/Black/Gunner_Black_Idle.png"); + img_gunner_black_die = assets_load_image_from_file("data/imgs/players/Black/Gunner_Black_Death.png"); img_gunner_blue_run = assets_load_image_from_file("data/imgs/players/Blue/Gunner_Blue_Run.png"); img_gunner_blue_idle = assets_load_image_from_file("data/imgs/players/Blue/Gunner_Blue_Idle.png"); + img_gunner_blue_die = assets_load_image_from_file("data/imgs/players/Blue/Gunner_Blue_Death.png"); img_gunner_green_run = assets_load_image_from_file("data/imgs/players/Green/Gunner_Green_Run.png"); img_gunner_green_idle = assets_load_image_from_file("data/imgs/players/Green/Gunner_Green_Idle.png"); + img_gunner_green_die = assets_load_image_from_file("data/imgs/players/Green/Gunner_Green_Death.png"); img_gunner_red_run = assets_load_image_from_file("data/imgs/players/Red/Gunner_Red_Run.png"); img_gunner_red_idle = assets_load_image_from_file("data/imgs/players/Red/Gunner_Red_Idle.png"); + img_gunner_red_die = assets_load_image_from_file("data/imgs/players/Red/Gunner_Red_Death.png"); img_gunner_yellow_run = assets_load_image_from_file("data/imgs/players/Yellow/Gunner_Yellow_Run.png"); img_gunner_yellow_idle = assets_load_image_from_file("data/imgs/players/Yellow/Gunner_Yellow_Idle.png"); + img_gunner_yellow_die = assets_load_image_from_file("data/imgs/players/Yellow/Gunner_Yellow_Death.png"); img_muzzle_flash = assets_load_image_from_file("data/imgs/players/MuzzleFlash.png"); img_bullet_stream = assets_load_image_from_file("data/imgs/players/BulletStream.png"); diff --git a/src/audio.c b/src/audio.c index e831f6b..b933f35 100644 --- a/src/audio.c +++ b/src/audio.c @@ -175,6 +175,10 @@ void play_positioned_sound(int channel, Mix_Chunk* wav, vec3f pos, float max_aud */ int c = Mix_PlayChannel(-1, wav, 0); - if (c == -1) log_info("Audio not playable because no channels are free"); - Mix_SetPosition(c, 0, (int)(volume*255)); + if (c == -1) { + log_info("Audio not playable because no channels are free"); + } + else { + Mix_SetPosition(c, 0, (int)(volume*255)); + } } diff --git a/src/players.c b/src/players.c index 627918c..fa3ea22 100644 --- a/src/players.c +++ b/src/players.c @@ -61,11 +61,13 @@ void spawn_player(u32 id, network_client client) { players[i].height = 0.0f; players[i].client = client; players[i].sprite = create_sprite(img_gunner_blue_run, 6, 48, 48, 0.1f); + players[i].sprite_death = create_sprite(img_gunner_blue_run, 8, 48, 48, 0.1f); + players[i].sprite_death.loop = false; players[i].sprite.zoom = 1.1f; + players[i].sprite_death.zoom = 1.1f; players[i].health = 500; players[i].max_health = 500; - players[i].gun_sprite = create_sprite(img_gun_mp5, 4, 256, 256, 0.0f); players[i].direction = DIRECTION_DOWN; players[i].connection_state = CONNECTED; players[i].throwables.grenades = 3; @@ -129,6 +131,8 @@ void move_user(platform_window* window, u32 id, protocol_move_type move, float d return; } + if (p->interact_state == INTERACT_DEAD) return; + if (p->sec_since_last_step > 0.2f) { add_audio_event_to_queue(EVENT_FOOTSTEP, p->id, (vec3f){.x = p->playerx, .y = p->playery, .z = p->height}); p->sec_since_last_step = 0.0f; @@ -321,7 +325,7 @@ void take_player_input(platform_window* window) { } } -void update_players_client() { +void update_players_orientation() { for (int i = 0; i < MAX_PLAYERS; i++) { if (!players[i].active) continue; @@ -353,6 +357,7 @@ void update_players_client() { update_sprite(&players[i].sprite); + if (players[i].interact_state == INTERACT_DEAD) update_sprite(&players[i].sprite_death); } } @@ -365,6 +370,11 @@ void hurt_player(u32 id, u32 damage) { p->health -= damage; p->sec_since_last_damage_taken = 0.0f; add_audio_event_to_queue(EVENT_PLAYERHURT, p->id, (vec3f){.x = p->playerx, .y = p->playery, .z = p->height}); + + if (p->health <= 0) { + p->health = 0; + p->interact_state = INTERACT_DEAD; + } } void update_players_server() { @@ -375,6 +385,8 @@ void update_players_server() { players[i].sec_since_last_step += SERVER_TICK_RATE; players[i].sec_since_last_damage_taken += SERVER_TICK_RATE; + if (players[i].interact_state == INTERACT_DEAD) continue; + // Reloading gun g = get_gun_by_type(players[i].guntype); if (players[i].interact_state == INTERACT_RELOADING && players[i].sec_since_interact_state_change >= g.reload_time) { @@ -393,7 +405,7 @@ void update_players_server() { } } - update_players_client(); + update_players_orientation(); } static void draw_player_bullet_cone(platform_window* window, player* p) { @@ -509,22 +521,37 @@ void draw_player(platform_window* window, player* p, int index) { frame = sprite_swap_frame_horizontally(frame); } - renderer->render_image_quad_partial(get_player_run_sprite_from_index(index), - player_render_x, player_render_y, - player_render_x, player_render_y + size, - player_render_x + size, player_render_y + size, - player_render_x + size, player_render_y, - frame.tl, frame.tr, frame.bl, frame.br); + if (p->interact_state == INTERACT_DEAD) { + frame = sprite_get_frame(img_gunner_blue_die, &p->sprite_death); + renderer->render_image_quad_partial(img_gunner_blue_die, + player_render_x, player_render_y, + player_render_x, player_render_y + size, + player_render_x + size, player_render_y + size, + player_render_x + size, player_render_y, + frame.tl, frame.tr, frame.bl, frame.br); + } + else { + renderer->render_image_quad_partial(get_player_run_sprite_from_index(index), + player_render_x, player_render_y, + player_render_x, player_render_y + size, + player_render_x + size, player_render_y + size, + player_render_x + size, player_render_y, + frame.tl, frame.tr, frame.bl, frame.br); + } } - font* name_fnt = get_font(window, 0.2f); - int name_x = player_render_x + (size)/2 - (renderer->calculate_text_width(name_fnt, name))/2; - int name_y = player_render_y - name_fnt->px_h - 5; - renderer->render_text(name_fnt, name_x+1, name_y+1, name, rgba(0,0,0,120)); - renderer->render_text(name_fnt, name_x, name_y, name, rgb(255,255,255)); + // Nametag + { + font* name_fnt = get_font(window, 0.2f); + int name_x = player_render_x + (size)/2 - (renderer->calculate_text_width(name_fnt, name))/2; + int name_y = player_render_y - name_fnt->px_h - 5; + renderer->render_text(name_fnt, name_x+1, name_y+1, name, rgba(0,0,0,120)); + renderer->render_text(name_fnt, name_x, name_y, name, rgb(255,255,255)); + } p->gun_height = p->height+0.2; + // Disconnected icon if (p->connection_state == DISCONNECTED) { float icon_h = (size)/2; renderer->render_image(img_disconnected, player_render_x + (icon_h/3), player_render_y - icon_h, icon_h, icon_h); diff --git a/src/sprite.c b/src/sprite.c index 3aeb047..4e56e79 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -12,6 +12,7 @@ sprite create_sprite(image* img, int frame_count, int fwidth, int fheight, float s.time = 0.0f; s.frame_start = 0; s.zoom = 1.0f; + s.loop = true; return s; } @@ -21,8 +22,13 @@ void update_sprite(sprite* sprite) { int frame = sprite->time / sprite->sec_per_frame; sprite->current_frame = frame; if (frame >= sprite->frame_count) { - sprite->time = 0.0f; - sprite->current_frame = 0; + if (sprite->loop) { + sprite->time = 0.0f; + sprite->current_frame = 0; + } + else { + sprite->current_frame = sprite->frame_count-1; + } } } diff --git a/src/zombies.c b/src/zombies.c index aa108b3..637d4dd 100644 --- a/src/zombies.c +++ b/src/zombies.c @@ -6,6 +6,7 @@ static player get_closest_player_to_tile_x(float x, float y, float* buf_length) for (int i = 0; i < MAX_PLAYERS; i++) { if (!players[i].active) continue; + if (players[i].interact_state == INTERACT_DEAD) continue; float dirx = (players[i].playerx - x); float diry = (players[i].playery - y); double length = sqrt(dirx * dirx + diry * diry); @@ -30,6 +31,7 @@ static player get_closest_player_to_tile(float x, float y) { for (int i = 0; i < MAX_PLAYERS; i++) { if (!players[i].active) continue; + if (players[i].interact_state == INTERACT_DEAD) continue; float dirx = (players[i].playerx - x); float diry = (players[i].playery - y); double length = sqrt(dirx * dirx + diry * diry); @@ -99,6 +101,19 @@ u32 number_of_zombies_active() return res; } +static vec2f get_random_target_for_zombie(zombie o) { + vec2f target = {0,0}; + try_again:; + int dist = 10; + target.x = o.position.x + (rand() % dist) - (dist/2); + target.y = o.position.y + (rand() % dist) - (dist/2); + + object obj = get_object_at_tile(target.x, target.y); + if (obj.active) goto try_again; + + return target; +} + static void set_enraged_zombie_stats(zombie *zombie) { zombie->health = 1500.0f; zombie->max_health = 1500.0f; @@ -154,8 +169,13 @@ void spawn_zombie(int x, int y) { _current_round.zombies--; player closest_player = get_closest_player_to_tile(x, y); + vec2f target = (vec2f){closest_player.playerx, closest_player.playery}; + // All players died, move around randomly + if (closest_player.id == -1) { + target = get_random_target_for_zombie(zombies[i]); + } - make_pathfinding_request((vec2f){x,y}, (vec2f){closest_player.playerx, closest_player.playery}, &zombies[i].next_path, &zombies[i].request); + make_pathfinding_request((vec2f){x,y}, target, &zombies[i].next_path, &zombies[i].request); break; } } @@ -337,6 +357,10 @@ void update_zombies_server(platform_window* window) { if (zombies[i].time_since_last_path > SERVER_PATHFINDING_INTERVAL) { player closest_player = get_closest_player_to_tile(o.position.x, o.position.y); vec2f target_tile = (vec2f){closest_player.playerx, closest_player.playery+(get_player_size_in_tile()/2)}; + // All players died, move around randomly + if (closest_player.id == -1) { + target_tile = get_random_target_for_zombie(o); + } array_clear(zombies[i].request.to_fill); make_pathfinding_request((vec2f){o.position.x,o.position.y}, target_tile, &zombies[i].next_path, &zombies[i].request); @@ -352,6 +376,13 @@ void update_zombies_server(platform_window* window) { zombies[i].path = array_copy(zombies[i].request.to_fill); player closest_player = get_closest_player_to_tile(o.position.x, o.position.y); + + // All players died, move around randomly + if (closest_player.id == -1) { + vec2f target = get_random_target_for_zombie(o); + closest_player.playerx = target.x; + closest_player.playery = target.y; + } vec2f final_pos = get_random_point_around_player(closest_player, zombies[i]); array_push_at(&zombies[i].path, (u8*)&final_pos, 0); -- cgit v1.2.3-70-g09d2