A few bug fixes. God speed gets added even with runed speed enhancement. Sounds shouldn't abruptly update after menu close any more.

This commit is contained in:
Storm Dragon
2026-01-25 11:08:25 -05:00
parent ddcaca6f2f
commit f80e3263a3
4 changed files with 176 additions and 128 deletions

View File

@@ -84,6 +84,7 @@ void main()
show_window("Draugnorak");
init_flying_creature_configs();
init_item_registry();
init_search_pools();
bool game_started = false;
while (!game_started) {

View File

@@ -183,6 +183,51 @@ class Tree {
}
Tree@[] trees;
const int SEARCH_POOL_STREAM_BANK = 0;
const int SEARCH_POOL_FOREST = 1;
const int SEARCH_POOL_STONE_TERRAIN = 2;
const int SEARCH_POOL_COUNT = 3;
class SearchPool {
int[] item_types;
int[] weights;
string[] found_messages;
string[] terrain_tags;
}
SearchPool@[] search_pools;
int[] search_mass_noun_items;
void init_search_pools() {
// Add or adjust all terrain-based search content here.
// Keep item_types, weights, and found_messages aligned by index.
// Leave found_messages empty to use the auto "Found a/an X." or "Found X." logic.
// Use terrain_tags to map pool usage without touching perform_search().
search_pools.resize(SEARCH_POOL_COUNT);
@search_pools[SEARCH_POOL_STREAM_BANK] = SearchPool();
search_pools[SEARCH_POOL_STREAM_BANK].item_types = { ITEM_REEDS, ITEM_CLAY };
search_pools[SEARCH_POOL_STREAM_BANK].weights = { 30, 70 };
search_pools[SEARCH_POOL_STREAM_BANK].found_messages = { "Found a reed.", "Found clay." };
search_pools[SEARCH_POOL_STREAM_BANK].terrain_tags = { "stream_bank" };
@search_pools[SEARCH_POOL_FOREST] = SearchPool();
search_pools[SEARCH_POOL_FOREST].item_types = { ITEM_STICKS, ITEM_VINES };
search_pools[SEARCH_POOL_FOREST].weights = { 1, 1 };
search_pools[SEARCH_POOL_FOREST].found_messages = { "Found a stick.", "Found a vine." };
search_pools[SEARCH_POOL_FOREST].terrain_tags = { "forest", "deep_forest" };
@search_pools[SEARCH_POOL_STONE_TERRAIN] = SearchPool();
search_pools[SEARCH_POOL_STONE_TERRAIN].item_types = { ITEM_STONES };
search_pools[SEARCH_POOL_STONE_TERRAIN].weights = { 1 };
search_pools[SEARCH_POOL_STONE_TERRAIN].found_messages = { "Found a stone." };
search_pools[SEARCH_POOL_STONE_TERRAIN].terrain_tags = { "gravel", "stone", "hard_stone" };
// Mass nouns for auto "Found X." fallback (no article).
// Add new mass nouns here when adding search items that should not use "a/an".
search_mass_noun_items = { ITEM_CLAY };
}
string get_tree_area_terrain(int areaStart, int areaEnd) {
if (areaStart >= BASE_END + 1 && areaEnd <= GRASS_END) {
return "grass";
@@ -505,6 +550,121 @@ void damage_tree(int target_x, int damage) {
}
}
string build_item_list(int[] item_types) {
string list_text = "";
for (uint i = 0; i < item_types.length(); i++) {
string item_name = item_registry[item_types[i]].name;
if (i == 0) {
list_text = item_name;
} else if (i == item_types.length() - 1) {
if (item_types.length() == 2) {
list_text += " or " + item_name;
} else {
list_text += ", or " + item_name;
}
} else {
list_text += ", " + item_name;
}
}
return list_text;
}
bool is_mass_noun_item(int item_type) {
for (uint i = 0; i < search_mass_noun_items.length(); i++) {
if (search_mass_noun_items[i] == item_type) {
return true;
}
}
return false;
}
string get_auto_found_message(int item_type) {
string singular = item_registry[item_type].singular;
if (is_mass_noun_item(item_type)) {
return "Found " + singular + ".";
}
string first_letter = singular.substr(0, 1);
if (first_letter == "a" || first_letter == "e" || first_letter == "i" || first_letter == "o" || first_letter == "u") {
return "Found an " + singular + ".";
}
return "Found a " + singular + ".";
}
int get_search_weight(int[] weights, uint index) {
if (index >= weights.length()) {
return 1;
}
int weight = weights[index];
if (weight <= 0) {
return 1;
}
return weight;
}
bool try_find_weighted_resource(int[] item_types, int[] weights, string[] found_messages) {
if (item_types.length() == 0) {
return false;
}
int total_weight = 0;
int[] available_indices;
available_indices.resize(0);
for (uint i = 0; i < item_types.length(); i++) {
if (get_personal_count(item_types[i]) >= get_personal_stack_limit()) {
continue;
}
int weight = get_search_weight(weights, i);
total_weight += weight;
available_indices.insert_last(i);
}
if (available_indices.length() == 0) {
speak_with_history("You can't carry any more " + build_item_list(item_types) + ".", true);
return true;
}
int roll = random(1, total_weight);
int running_weight = 0;
uint chosen_index = available_indices[0];
for (uint i = 0; i < available_indices.length(); i++) {
uint candidate_index = available_indices[i];
int weight = get_search_weight(weights, candidate_index);
running_weight += weight;
if (roll <= running_weight) {
chosen_index = candidate_index;
break;
}
}
int item_type = item_types[chosen_index];
add_personal_count(item_type, 1);
play_item_collect_sound(item_registry[item_type].singular);
if (found_messages.length() > chosen_index && found_messages[chosen_index] != "") {
speak_with_history(found_messages[chosen_index], true);
} else {
speak_with_history(get_auto_found_message(item_type), true);
}
return true;
}
bool try_search_for_terrain(string terrain_type) {
for (uint i = 0; i < search_pools.length(); i++) {
if (search_pools[i] is null) {
continue;
}
for (uint j = 0; j < search_pools[i].terrain_tags.length(); j++) {
if (search_pools[i].terrain_tags[j] == terrain_type) {
return try_find_weighted_resource(search_pools[i].item_types,
search_pools[i].weights, search_pools[i].found_messages);
}
}
}
return false;
}
void perform_search(int current_x)
{
// First priority: Check for world drops on this tile or adjacent
@@ -579,36 +739,7 @@ void perform_search(int current_x)
}
if (near_stream_bank) {
bool found_reed = random(1, 100) <= 30;
if (found_reed) {
if (get_personal_count(ITEM_REEDS) < get_personal_stack_limit()) {
add_personal_count(ITEM_REEDS, 1);
play_item_collect_sound("reed");
speak_with_history("Found a reed.", true);
return;
}
} else {
if (get_personal_count(ITEM_CLAY) < get_personal_stack_limit()) {
add_personal_count(ITEM_CLAY, 1);
play_item_collect_sound("clay");
speak_with_history("Found clay.", true);
return;
}
}
if (!found_reed && get_personal_count(ITEM_REEDS) < get_personal_stack_limit()) {
add_personal_count(ITEM_REEDS, 1);
play_item_collect_sound("reed");
speak_with_history("Found a reed.", true);
} else if (found_reed && get_personal_count(ITEM_CLAY) < get_personal_stack_limit()) {
add_personal_count(ITEM_CLAY, 1);
play_item_collect_sound("clay");
speak_with_history("Found clay.", true);
} else if (found_reed) {
speak_with_history("You can't carry any more reeds.", true);
} else {
speak_with_history("You can't carry any more clay.", true);
}
try_search_for_terrain("stream_bank");
return;
}
@@ -706,101 +837,7 @@ void perform_search(int current_x)
return;
}
// Stone terrain - check for stones
bool is_stone_terrain = false;
// Check base gravel area (20-34)
if (current_x >= GRAVEL_START && current_x <= GRAVEL_END) {
is_stone_terrain = true;
}
// Check expanded areas
else if (expanded_area_start != -1 && current_x >= expanded_area_start && current_x <= expanded_area_end) {
// Check for mountain terrain first
MountainRange@ mountain = get_mountain_at(current_x);
if (mountain !is null) {
string terrain = mountain.get_terrain_at(current_x);
if (terrain == "stone" || terrain == "hard_stone" || terrain == "gravel") {
is_stone_terrain = true;
}
} else {
// Regular expanded area - check terrain type
int index = current_x - expanded_area_start;
if (index >= 0 && index < int(expanded_terrain_types.length())) {
string terrain = expanded_terrain_types[index];
// Handle "mountain:terrain" format from older saves
if (terrain.find("mountain:") == 0) {
terrain = terrain.substr(9);
}
if (terrain == "stone" || terrain == "hard_stone" || terrain == "gravel") {
is_stone_terrain = true;
}
}
}
}
if (is_stone_terrain)
{
if (get_personal_count(ITEM_STONES) < get_personal_stack_limit())
{
add_personal_count(ITEM_STONES, 1);
play_item_collect_sound("stone");
speak_with_history("Found a stone.", true);
}
else
{
speak_with_history("You can't carry any more stones.", true);
}
return;
}
// Forest terrain - check for sticks and vines
bool is_forest_terrain = false;
string current_terrain = "";
// Check expanded areas for forest/deep_forest
if (expanded_area_start != -1 && current_x >= expanded_area_start && current_x <= expanded_area_end) {
// Check for mountain terrain first
MountainRange@ mountain = get_mountain_at(current_x);
if (mountain !is null) {
current_terrain = mountain.get_terrain_at(current_x);
} else {
// Regular expanded area - check terrain type
int index = current_x - expanded_area_start;
if (index >= 0 && index < int(expanded_terrain_types.length())) {
current_terrain = expanded_terrain_types[index];
// Handle "mountain:terrain" format from older saves
if (current_terrain.find("mountain:") == 0) {
current_terrain = current_terrain.substr(9);
}
}
}
if (current_terrain == "forest" || current_terrain == "deep_forest") {
is_forest_terrain = true;
}
}
if (is_forest_terrain)
{
bool can_find_stick = get_personal_count(ITEM_STICKS) < get_personal_stack_limit();
bool can_find_vine = get_personal_count(ITEM_VINES) < get_personal_stack_limit();
if (!can_find_stick && !can_find_vine) {
speak_with_history("You can't carry any more sticks or vines.", true);
return;
}
// Random choice: if both available, 50/50. If only one, find that.
bool find_stick = can_find_stick && (!can_find_vine || random(0, 1) == 0);
if (find_stick) {
add_personal_count(ITEM_STICKS, 1);
play_item_collect_sound("stick");
speak_with_history("Found a stick.", true);
} else {
add_personal_count(ITEM_VINES, 1);
play_item_collect_sound("vine");
speak_with_history("Found a vine.", true);
}
if (try_search_for_terrain(search_terrain)) {
return;
}

View File

@@ -193,9 +193,11 @@ void update_max_health_from_equipment() {
int rune_bonus = get_total_rune_walk_speed_bonus();
walk_speed = base_speed - rune_bonus;
// Apply blessing (if active and faster than current)
if (blessing_speed_active && BLESSING_WALK_SPEED < walk_speed) {
walk_speed = BLESSING_WALK_SPEED;
// Apply blessing bonus on top of existing speed
if (blessing_speed_active) {
int blessing_bonus = BASE_WALK_SPEED - BLESSING_WALK_SPEED;
if (blessing_bonus < 0) blessing_bonus = 0;
walk_speed -= blessing_bonus;
}
// Ensure minimum walk speed

View File

@@ -2,11 +2,19 @@
// Helper functions used across multiple menu systems
void menu_background_tick() {
// Keep this list in sync with the main game loop to avoid pausing ambience/weather/time.
update_time();
update_crossfade();
update_weather();
update_environment();
update_snares();
update_streams();
update_fires();
update_zombies();
update_bandits();
update_boars();
update_flying_creatures();
update_world_drops();
update_blessings();
update_notifications();