Compare commits

..

No commits in common. "main" and "notashelf/push-nrzuupynktom" have entirely different histories.

18 changed files with 40 additions and 104 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,6 +1,5 @@
#include "audio.h" #include "audio.h"
#include "raylib.h" #include "raylib.h"
#include "common.h"
#include <math.h> #include <math.h>
#include <stddef.h> #include <stddef.h>
@ -71,79 +70,50 @@ void audio_play_move(void) {
play_tone(200.0f, 0.05f, 0.3f); play_tone(200.0f, 0.05f, 0.3f);
} }
void audio_play_attack(GameState *gs) { void audio_play_attack(void) {
// Mid-range hit sound // Mid-range hit sound
// play_tone(400.0f, 0.1f, 0.5f); play_tone(400.0f, 0.1f, 0.5f);
int choice = GetRandomValue(1, 3);
switch (choice) {
case 1:
PlaySound(gs->sounds.attack1);
break;
case 2:
PlaySound(gs->sounds.attack2);
break;
case 3:
PlaySound(gs->sounds.attack3);
break;
default:
PlaySound(gs->sounds.attack1);
break;
}
} }
void audio_play_item_pickup(GameState *gs) { void audio_play_item_pickup(void) {
// High-pitched pickup sound // High-pitched pickup sound
PlaySound(gs->sounds.pickup); play_tone(800.0f, 0.15f, 0.4f);
} }
void audio_play_enemy_death(GameState *gs) { void audio_play_enemy_death(void) {
// Descending death sound // Descending death sound
play_tone(300.0f, 0.1f, 0.5f); play_tone(300.0f, 0.1f, 0.5f);
play_tone(150.0f, 0.15f, 0.4f); play_tone(150.0f, 0.15f, 0.4f);
} }
void audio_play_player_damage(GameState *gs) { void audio_play_player_damage(void) {
// Harsh damage sound // Harsh damage sound
play_tone(150.0f, 0.1f, 0.6f); play_tone(150.0f, 0.1f, 0.6f);
play_tone(100.0f, 0.1f, 0.4f); play_tone(100.0f, 0.1f, 0.4f);
} }
void audio_play_stairs(GameState *gs) { void audio_play_stairs(void) {
// Ascending stairs sound // Ascending stairs sound
PlaySound(gs->sounds.staircase); play_tone(400.0f, 0.1f, 0.3f);
play_tone(600.0f, 0.1f, 0.3f);
play_tone(800.0f, 0.15f, 0.3f);
} }
void audio_play_dodge(GameState *gs) { void audio_play_dodge(void) {
// High-pitched whoosh // High-pitched whoosh
// play_tone(900.0f, 0.08f, 0.3f); play_tone(900.0f, 0.08f, 0.3f);
int choice = GetRandomValue(1, 3);
switch (choice) {
case 1:
PlaySound(gs->sounds.dodge1);
break;
case 2:
PlaySound(gs->sounds.dodge2);
break;
case 3:
PlaySound(gs->sounds.dodge3);
break;
default:
PlaySound(gs->sounds.dodge1);
break;
}
return;
} }
void audio_play_block(GameState *gs) { void audio_play_block(void) {
// Low-then-mid metallic clang // Low-then-mid metallic clang
play_tone(250.0f, 0.06f, 0.5f); play_tone(250.0f, 0.06f, 0.5f);
play_tone(350.0f, 0.04f, 0.3f); play_tone(350.0f, 0.04f, 0.3f);
} }
void audio_play_crit(GameState *gs) { void audio_play_crit(void) {
// Sharp crack with high-pitched follow // Sharp crack with high-pitched follow
audio_play_attack(gs); play_tone(600.0f, 0.05f, 0.7f);
PlaySound(gs->sounds.crit); play_tone(900.0f, 0.1f, 0.5f);
} }
void audio_play_proc(void) { void audio_play_proc(void) {

View file

@ -1,6 +1,5 @@
#ifndef AUDIO_H #ifndef AUDIO_H
#define AUDIO_H #define AUDIO_H
#include "common.h"
// Initialize audio system // Initialize audio system
void audio_init(void); void audio_init(void);
@ -12,28 +11,28 @@ void audio_close(void);
void audio_play_move(void); void audio_play_move(void);
// Play attack sound // Play attack sound
void audio_play_attack(GameState *gs); void audio_play_attack(void);
// Play item pickup sound // Play item pickup sound
void audio_play_item_pickup(GameState *gs); void audio_play_item_pickup(void);
// Play enemy death sound // Play enemy death sound
void audio_play_enemy_death(GameState *gs); void audio_play_enemy_death(void);
// Play player damage sound // Play player damage sound
void audio_play_player_damage(GameState *gs); void audio_play_player_damage(void);
// Play stairs/level change sound // Play stairs/level change sound
void audio_play_stairs(GameState *gs); void audio_play_stairs(void);
// Play dodge sound // Play dodge sound
void audio_play_dodge(GameState *gs); void audio_play_dodge(void);
// Play block sound // Play block sound
void audio_play_block(GameState *gs); void audio_play_block(void);
// Play critical hit sound // Play critical hit sound
void audio_play_crit(GameState *gs); void audio_play_crit(void);
// Play status effect proc sound // Play status effect proc sound
void audio_play_proc(void); void audio_play_proc(void);

View file

@ -2,7 +2,6 @@
#define COMMON_H #define COMMON_H
#include "settings.h" #include "settings.h"
#include <raylib.h>
// Tile types // Tile types
typedef enum { TILE_WALL, TILE_FLOOR, TILE_STAIRS } TileType; typedef enum { TILE_WALL, TILE_FLOOR, TILE_STAIRS } TileType;
@ -113,15 +112,6 @@ typedef struct {
StatusEffectType effect_type; // used to pick color for proc labels StatusEffectType effect_type; // used to pick color for proc labels
} FloatingText; } FloatingText;
// AudioAssets
typedef struct {
Sound attack1, attack2, attack3;
Sound pickup;
Sound staircase;
Sound dodge1, dodge2, dodge3;
Sound crit;
} AudioAssets;
// GameState - encapsulates all game state for testability and save/load // GameState - encapsulates all game state for testability and save/load
typedef struct { typedef struct {
Player player; Player player;
@ -149,8 +139,6 @@ typedef struct {
int screen_shake; // frames of screen shake remaining int screen_shake; // frames of screen shake remaining
int shake_x; int shake_x;
int shake_y; int shake_y;
AudioAssets sounds;
} GameState; } GameState;
#endif // COMMON_H #endif // COMMON_H

View file

@ -65,18 +65,12 @@ static void spawn_floating_label(GameState *gs, int x, int y, const char *label,
static const char *proc_label_for(StatusEffectType effect) { static const char *proc_label_for(StatusEffectType effect) {
switch (effect) { switch (effect) {
case EFFECT_POISON: case EFFECT_POISON: return "POISON!";
return "POISON!"; case EFFECT_BLEED: return "BLEED!";
case EFFECT_BLEED: case EFFECT_BURN: return "BURN!";
return "BLEED!"; case EFFECT_STUN: return "STUN!";
case EFFECT_BURN: case EFFECT_WEAKEN: return "WEAKEN!";
return "BURN!"; default: return "";
case EFFECT_STUN:
return "STUN!";
case EFFECT_WEAKEN:
return "WEAKEN!";
default:
return "";
} }
} }
@ -187,18 +181,17 @@ static void post_action(GameState *gs, Enemy *attacked_enemy) {
if (combat_was_dodged()) { if (combat_was_dodged()) {
spawn_floating_label(gs, ex, ey, "DODGE", EFFECT_NONE); spawn_floating_label(gs, ex, ey, "DODGE", EFFECT_NONE);
audio_play_dodge(gs); audio_play_dodge();
} else { } else {
if (combat_get_last_damage() > 0) if (combat_get_last_damage() > 0)
spawn_floating_text(gs, ex, ey, combat_get_last_damage(), combat_was_critical()); spawn_floating_text(gs, ex, ey, combat_get_last_damage(), combat_was_critical());
audio_play_attack(gs);
if (combat_was_blocked()) { if (combat_was_blocked()) {
spawn_floating_label(gs, ex, ey - 10, "BLOCK", EFFECT_NONE); spawn_floating_label(gs, ex, ey - 10, "BLOCK", EFFECT_NONE);
audio_play_block(gs); audio_play_block();
} }
if (combat_was_critical()) { if (combat_was_critical()) {
spawn_floating_label(gs, ex + 8, ey - 10, "CRIT!", EFFECT_NONE); spawn_floating_label(gs, ex + 8, ey - 10, "CRIT!", EFFECT_NONE);
audio_play_crit(gs); audio_play_crit();
} }
StatusEffectType applied = combat_get_applied_effect(); StatusEffectType applied = combat_get_applied_effect();
if (applied != EFFECT_NONE) { if (applied != EFFECT_NONE) {
@ -207,7 +200,7 @@ static void post_action(GameState *gs, Enemy *attacked_enemy) {
} }
if (!attacked_enemy->alive) { if (!attacked_enemy->alive) {
spawn_floating_label(gs, ex, ey - 20, "SLAIN", EFFECT_NONE); spawn_floating_label(gs, ex, ey - 20, "SLAIN", EFFECT_NONE);
audio_play_enemy_death(gs); audio_play_enemy_death();
} }
} }
} }
@ -217,7 +210,7 @@ static void post_action(GameState *gs, Enemy *attacked_enemy) {
// Check if player took damage // Check if player took damage
if (combat_was_player_damage() && combat_get_last_damage() > 0) { if (combat_was_player_damage() && combat_get_last_damage() > 0) {
audio_play_player_damage(gs); audio_play_player_damage();
gs->screen_shake = 8; gs->screen_shake = 8;
spawn_floating_text(gs, gs->player.x * TILE_SIZE + 8, gs->player.y * TILE_SIZE, combat_get_last_damage(), spawn_floating_text(gs, gs->player.x * TILE_SIZE + 8, gs->player.y * TILE_SIZE, combat_get_last_damage(),
combat_was_critical()); combat_was_critical());
@ -349,7 +342,7 @@ static int handle_inventory_input(GameState *gs) {
static int handle_descend_input(GameState *gs) { static int handle_descend_input(GameState *gs) {
if (IsKeyPressed(KEY_Y)) { if (IsKeyPressed(KEY_Y)) {
if (gs->player.floor < NUM_FLOORS) { if (gs->player.floor < NUM_FLOORS) {
audio_play_stairs(gs); audio_play_stairs();
init_floor(gs, gs->player.floor + 1); init_floor(gs, gs->player.floor + 1);
gs->last_message = "Descended to next floor!"; gs->last_message = "Descended to next floor!";
gs->message_timer = 60; gs->message_timer = 60;
@ -388,7 +381,7 @@ static int handle_movement_input(GameState *gs) {
add_log(gs, pickup_msg); add_log(gs, pickup_msg);
gs->last_message = "Picked up item!"; gs->last_message = "Picked up item!";
gs->message_timer = 60; gs->message_timer = 60;
audio_play_item_pickup(gs); audio_play_item_pickup();
} else { } else {
gs->last_message = "Inventory full!"; gs->last_message = "Inventory full!";
gs->message_timer = 60; gs->message_timer = 60;
@ -402,7 +395,7 @@ static int handle_movement_input(GameState *gs) {
if (gs->player.inventory_count > 0 && player_use_first_item(&gs->player)) { if (gs->player.inventory_count > 0 && player_use_first_item(&gs->player)) {
gs->last_message = "Used potion!"; gs->last_message = "Used potion!";
gs->message_timer = 60; gs->message_timer = 60;
audio_play_item_pickup(gs); audio_play_item_pickup();
return 1; return 1;
} }
} }
@ -468,24 +461,11 @@ static int handle_input(GameState *gs) {
return handle_movement_input(gs); return handle_movement_input(gs);
} }
void load_audio_assets(GameState *gs) {
gs->sounds.attack1 = LoadSound("./assets/sounds/sword1.wav");
gs->sounds.attack2 = LoadSound("./assets/sounds/sword2.wav");
gs->sounds.attack3 = LoadSound("./assets/sounds/sword3.wav");
gs->sounds.pickup = LoadSound("./assets/sounds/itempickup.wav");
gs->sounds.staircase = LoadSound("./assets/sounds/levelcomplete.wav");
gs->sounds.dodge1 = LoadSound("./assets/sounds/dodge1.wav");
gs->sounds.dodge2 = LoadSound("./assets/sounds/dodge2.wav");
gs->sounds.dodge3 = LoadSound("./assets/sounds/dodge3.wav");
gs->sounds.crit = LoadSound("./assets/sounds/crit.wav");
return;
}
// Main game loop // Main game loop
static void game_loop(void) { static void game_loop(void) {
GameState gs; GameState gs;
memset(&gs, 0, sizeof(GameState)); memset(&gs, 0, sizeof(GameState));
load_audio_assets(&gs);
// Initialize first floor // Initialize first floor
rng_seed(12345); rng_seed(12345);
init_floor(&gs, 1); init_floor(&gs, 1);
@ -573,8 +553,7 @@ static void game_loop(void) {
int main(void) { int main(void) {
// Initialize audio // Initialize audio
audio_init(); audio_init();
// Initialize random number generator
SetRandomSeed(88435);
// Initialize window // Initialize window
InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT + 60, "Roguelike"); InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT + 60, "Roguelike");
SetTargetFPS(60); SetTargetFPS(60);