A ton of changes including bug fixes, new craftable items, altar with favor system added. Info for player and base added.
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
// Bat Invasion quest game
|
||||
string[] bat_sounds = {"sounds/quests/bat1.ogg", "sounds/quests/bat2.ogg"};
|
||||
|
||||
int run_bat_invasion() {
|
||||
screen_reader_speak("Bat Invasion. Bats will fly past from left or right. Press space to throw your spear when the bat is centered. Press enter to continue.", true);
|
||||
|
||||
// Wait for enter
|
||||
while (!key_pressed(KEY_RETURN)) {
|
||||
wait(5);
|
||||
}
|
||||
|
||||
screen_reader_speak("Starting.", true);
|
||||
wait(500);
|
||||
|
||||
int turns = 10;
|
||||
int score = 0;
|
||||
|
||||
// Position configuration
|
||||
const int BAT_START_DISTANCE = 15; // How far left/right the bat starts
|
||||
const int CENTER_TOLERANCE = 2; // How close to center counts as a hit
|
||||
const int LISTENER_POS = 0; // Player is at center
|
||||
|
||||
for (int i = 0; i < turns; i++) {
|
||||
// Pick random bat sound
|
||||
string bat_sound = bat_sounds[random(0, bat_sounds.length() - 1)];
|
||||
|
||||
// Randomly start from left or right
|
||||
int direction = (random(0, 1) == 0) ? 1 : -1; // 1 = left to right, -1 = right to left
|
||||
int start_pos = -BAT_START_DISTANCE * direction;
|
||||
int end_pos = BAT_START_DISTANCE * direction;
|
||||
|
||||
// Random flight speed (slower range with variation)
|
||||
int flight_time = random(2200, 3400);
|
||||
int update_interval = 30; // Update position every 30ms
|
||||
|
||||
// Start bat sound at starting position
|
||||
int bat_handle = p.play_1d(bat_sound, LISTENER_POS, start_pos, true);
|
||||
|
||||
timer flight_timer;
|
||||
flight_timer.restart();
|
||||
bool threw = false;
|
||||
bool hit = false;
|
||||
|
||||
while (flight_timer.elapsed < flight_time) {
|
||||
wait(update_interval);
|
||||
|
||||
// Calculate current position based on elapsed time
|
||||
float progress = float(flight_timer.elapsed) / float(flight_time);
|
||||
int current_pos = int(start_pos + (progress * (end_pos - start_pos)));
|
||||
|
||||
// Update bat sound position
|
||||
if (bat_handle != -1) {
|
||||
p.update_sound_1d(bat_handle, current_pos);
|
||||
}
|
||||
|
||||
// Check for throw
|
||||
if (!threw && key_pressed(KEY_SPACE)) {
|
||||
threw = true;
|
||||
p.play_stationary("sounds/quests/spear_throw.ogg", false);
|
||||
|
||||
// Check if bat is centered (within tolerance)
|
||||
int distance_from_center = current_pos;
|
||||
if (distance_from_center < 0) distance_from_center = -distance_from_center;
|
||||
|
||||
if (distance_from_center <= CENTER_TOLERANCE) {
|
||||
hit = true;
|
||||
// Stop bat sound and play hit
|
||||
if (bat_handle != -1) {
|
||||
p.destroy_sound(bat_handle);
|
||||
bat_handle = -1;
|
||||
}
|
||||
wait(150);
|
||||
p.play_stationary("sounds/quests/spear_hit.ogg", false);
|
||||
score += 2;
|
||||
break;
|
||||
} else {
|
||||
wait(150);
|
||||
p.play_stationary("sounds/quests/spear_miss.ogg", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up bat sound if still playing
|
||||
if (bat_handle != -1) {
|
||||
p.destroy_sound(bat_handle);
|
||||
bat_handle = -1;
|
||||
}
|
||||
|
||||
// If didn't throw at all, count as miss
|
||||
if (!threw) {
|
||||
p.play_stationary("sounds/quests/spear_miss.ogg", false);
|
||||
}
|
||||
|
||||
wait(400);
|
||||
}
|
||||
|
||||
screen_reader_speak("Bat invasion complete. Score " + score + ".", true);
|
||||
return score;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// Enchanted Melody quest game
|
||||
string[] quest_notes = {
|
||||
"sounds/quests/bone1.ogg",
|
||||
"sounds/quests/bone2.ogg",
|
||||
"sounds/quests/bone3.ogg",
|
||||
"sounds/quests/bone4.ogg"
|
||||
};
|
||||
|
||||
void play_note(int note_index) {
|
||||
if (note_index < 0 || note_index >= int(quest_notes.length())) return;
|
||||
p.play_stationary(quest_notes[note_index], false);
|
||||
}
|
||||
|
||||
int get_note_from_key() {
|
||||
if (key_pressed(KEY_F) || key_pressed(KEY_K)) return 0;
|
||||
if (key_pressed(KEY_D) || key_pressed(KEY_J)) return 1;
|
||||
if (key_pressed(KEY_R) || key_pressed(KEY_I)) return 2;
|
||||
if (key_pressed(KEY_E) || key_pressed(KEY_U)) return 3;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void run_practice_mode() {
|
||||
screen_reader_speak("Enchanted Melody. Repeat the magical pattern using F D R E or K J I U, from lowest to highest pitch. Practice the notes now, then press enter to begin, or escape to cancel.", true);
|
||||
|
||||
while (true) {
|
||||
wait(5);
|
||||
|
||||
// Check for practice note input
|
||||
int note = get_note_from_key();
|
||||
if (note != -1) {
|
||||
play_note(note);
|
||||
}
|
||||
|
||||
// Enter to start the game
|
||||
if (key_pressed(KEY_RETURN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Escape to cancel
|
||||
if (key_pressed(KEY_ESCAPE)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int run_enchanted_melody() {
|
||||
// Practice mode first
|
||||
run_practice_mode();
|
||||
|
||||
// Check if player pressed escape during practice
|
||||
if (key_down(KEY_ESCAPE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
screen_reader_speak("Starting. Repeat the pattern.", true);
|
||||
wait(500);
|
||||
|
||||
int[] pattern;
|
||||
pattern.insert_last(random(0, 3));
|
||||
int rounds = 0;
|
||||
|
||||
while (true) {
|
||||
for (uint i = 0; i < pattern.length(); i++) {
|
||||
play_note(pattern[i]);
|
||||
wait(600);
|
||||
}
|
||||
|
||||
uint index = 0;
|
||||
while (index < pattern.length()) {
|
||||
wait(5);
|
||||
int note = get_note_from_key();
|
||||
if (note == -1) continue;
|
||||
play_note(note);
|
||||
if (note != pattern[index]) {
|
||||
int score = rounds * 2;
|
||||
screen_reader_speak("You matched " + rounds + " notes. Score " + score + ".", true);
|
||||
return score;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
rounds++;
|
||||
pattern.insert_last(random(0, 3));
|
||||
wait(500);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
// Escape from Hel quest game
|
||||
int run_escape_from_hel() {
|
||||
screen_reader_speak("Escape from Hel. You are running from the Draugr, good luck. Press space to jump over open graves as you hear them approach. Press enter to continue.", true);
|
||||
|
||||
// Wait for enter
|
||||
while (!key_pressed(KEY_RETURN)) {
|
||||
wait(5);
|
||||
}
|
||||
|
||||
screen_reader_speak("Starting.", true);
|
||||
wait(500);
|
||||
|
||||
int score = 0;
|
||||
int steps_until_pit = 10; // First pit after exactly 10 steps
|
||||
int steps_taken = 0;
|
||||
int total_steps = 0;
|
||||
int base_step_time = 900;
|
||||
string step_sound = "sounds/quests/footstep.ogg";
|
||||
|
||||
// Pit audio configuration
|
||||
int pit_fade_start = 6; // Start pit sound 6 steps before the pit
|
||||
float start_volume = -35.0; // Start very quiet
|
||||
float max_volume = 0.0; // Full volume at pit
|
||||
int pit_handle = -1;
|
||||
|
||||
// Jump state
|
||||
bool jumping = false;
|
||||
timer jump_timer;
|
||||
const int JUMP_DURATION = 400; // How long a jump lasts
|
||||
|
||||
while (true) {
|
||||
// Speed increases indefinitely until player can't keep up
|
||||
int step_time = base_step_time - (total_steps * 8);
|
||||
if (step_time < 50) step_time = 50; // Minimum to prevent audio/timing issues
|
||||
|
||||
// Check if jump finished
|
||||
if (jumping && jump_timer.elapsed >= JUMP_DURATION) {
|
||||
jumping = false;
|
||||
}
|
||||
|
||||
// Process step with input checking
|
||||
timer step_timer;
|
||||
step_timer.restart();
|
||||
|
||||
// Play footstep at start of step
|
||||
if (!jumping) {
|
||||
p.play_stationary(step_sound, false);
|
||||
}
|
||||
|
||||
// Wait for step duration, checking for jump input
|
||||
while (step_timer.elapsed < step_time) {
|
||||
wait(5);
|
||||
|
||||
// Allow jump anytime when not already jumping
|
||||
if (!jumping && key_pressed(KEY_SPACE)) {
|
||||
p.play_stationary("sounds/quests/jump.ogg", false);
|
||||
jumping = true;
|
||||
jump_timer.restart();
|
||||
}
|
||||
|
||||
// Update jump state during wait
|
||||
if (jumping && jump_timer.elapsed >= JUMP_DURATION) {
|
||||
jumping = false;
|
||||
}
|
||||
}
|
||||
|
||||
steps_taken++;
|
||||
total_steps++;
|
||||
|
||||
// Calculate steps remaining until pit
|
||||
int steps_remaining = steps_until_pit - steps_taken;
|
||||
|
||||
// Start pit sound when approaching
|
||||
if (steps_remaining <= pit_fade_start && steps_remaining >= 0 && pit_handle == -1) {
|
||||
pit_handle = p.play_stationary("sounds/quests/pit.ogg", true);
|
||||
if (pit_handle != -1) {
|
||||
p.update_sound_start_values(pit_handle, 0.0, start_volume, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
// Update pit volume as we get closer
|
||||
if (pit_handle != -1 && steps_remaining >= 0) {
|
||||
float progress = float(pit_fade_start - steps_remaining) / float(pit_fade_start);
|
||||
if (progress > 1.0) progress = 1.0;
|
||||
float current_volume = start_volume + (progress * (max_volume - start_volume));
|
||||
p.update_sound_start_values(pit_handle, 0.0, current_volume, 1.0);
|
||||
}
|
||||
|
||||
// Reached the pit
|
||||
if (steps_taken >= steps_until_pit) {
|
||||
// Must be jumping to clear the pit
|
||||
if (!jumping) {
|
||||
// Fell in
|
||||
if (pit_handle != -1) {
|
||||
p.destroy_sound(pit_handle);
|
||||
pit_handle = -1;
|
||||
}
|
||||
p.play_stationary("sounds/quests/fall.ogg", false);
|
||||
screen_reader_speak("You fell in. Score " + score + ".", true);
|
||||
return score;
|
||||
}
|
||||
|
||||
// Successfully jumped over
|
||||
if (pit_handle != -1) {
|
||||
p.destroy_sound(pit_handle);
|
||||
pit_handle = -1;
|
||||
}
|
||||
|
||||
score += 2;
|
||||
|
||||
// Reset for next pit - random spacing between 5-15 steps
|
||||
steps_taken = 0;
|
||||
steps_until_pit = random(5, 15);
|
||||
}
|
||||
}
|
||||
return score;
|
||||
}
|
||||
Reference in New Issue
Block a user