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:
@@ -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) {
|
||||
|
||||
+162
-125
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user