A few minor bug fixes with area expansion.

This commit is contained in:
Storm Dragon
2026-01-17 23:44:10 -05:00
parent ff9aa00590
commit 764eab45e4
7 changed files with 109 additions and 166 deletions
-1
View File
@@ -6,4 +6,3 @@ lib_windows/
stub/ stub/
include/ include/
save.dat save.dat
save.dat_robust
Binary file not shown.
+5
View File
@@ -5,6 +5,11 @@ string get_footstep_sound(int current_x, int base_end, int grass_end)
return "sounds/terrain/shallow_water.ogg"; return "sounds/terrain/shallow_water.ogg";
} }
// Firepit uses hard stone sound
if (get_firepit_at(current_x) != null) {
return "sounds/terrain/hard_stone.ogg";
}
if (current_x <= base_end) if (current_x <= base_end)
{ {
// Base area // Base area
+20 -21
View File
@@ -251,34 +251,22 @@ void perform_search(int current_x)
} }
} }
// Gravel Area - Stones (20-34) // Trees (Sticks/Vines) - Check for nearby tree anywhere
if (current_x >= 20 && current_x <= 34)
{
if (inv_stones < MAX_ITEM_STACK)
{
inv_stones++;
p.play_stationary("sounds/items/stone.ogg", false);
screen_reader_speak("Found a stone.", true);
}
else
{
screen_reader_speak("You can't carry any more stones.", true);
}
return;
}
// Grass Area - Trees (Sticks/Vines) (5-19)
if (current_x >= 5 && current_x <= 19)
{
Tree@ nearest = null; Tree@ nearest = null;
int nearest_distance = 999;
for(uint i=0; i<trees.length(); i++) for(uint i=0; i<trees.length(); i++)
{ {
if(trees[i].position >= current_x - 1 && trees[i].position <= current_x + 1) int distance = trees[i].position - current_x;
if (distance < 0) distance = -distance;
if(distance <= 1 && distance < nearest_distance)
{ {
nearest_distance = distance;
@nearest = @trees[i]; @nearest = @trees[i];
if (nearest_distance == 0) {
break; break;
} }
} }
}
if(@nearest != null) if(@nearest != null)
{ {
@@ -329,10 +317,21 @@ void perform_search(int current_x)
{ {
screen_reader_speak("This area has nothing left.", true); screen_reader_speak("This area has nothing left.", true);
} }
return;
}
// Gravel Area - Stones (20-34)
if (current_x >= 20 && current_x <= 34)
{
if (inv_stones < MAX_ITEM_STACK)
{
inv_stones++;
p.play_stationary("sounds/items/stone.ogg", false);
screen_reader_speak("Found a stone.", true);
} }
else else
{ {
screen_reader_speak("Found nothing.", true); screen_reader_speak("You can't carry any more stones.", true);
} }
return; return;
} }
+2 -20
View File
@@ -1,7 +1,6 @@
// Save system // Save system
const string SAVE_FILE_PATH = "save.dat"; const string SAVE_FILE_PATH = "save.dat";
const string SAVE_BACKUP_SUFFIX = "_robust";
const string SAVE_ENCRYPTION_KEY = "draugnorak_save_v1"; const string SAVE_ENCRYPTION_KEY = "draugnorak_save_v1";
const int SAVE_VERSION = 1; const int SAVE_VERSION = 1;
@@ -17,38 +16,21 @@ string decrypt_save_data(const string&in encryptedData) {
return string_aes_decrypt(encryptedData, SAVE_ENCRYPTION_KEY); return string_aes_decrypt(encryptedData, SAVE_ENCRYPTION_KEY);
} }
bool save_robust_data(const string&in filename, const string&in data) { bool save_data(const string&in filename, const string&in data) {
if (data.length() == 0) { if (data.length() == 0) {
return false; return false;
} }
string backupPath = filename + SAVE_BACKUP_SUFFIX;
if (file_exists(filename)) {
if (!file_copy(filename, backupPath, true)) {
return false;
}
}
file tmp; file tmp;
if (!tmp.open(filename, "wb")) { if (!tmp.open(filename, "wb")) {
if (file_exists(backupPath)) {
file_copy(backupPath, filename, true);
file_delete(backupPath);
}
return false; return false;
} }
if (tmp.write(data) < data.length()) { if (tmp.write(data) < data.length()) {
tmp.close(); tmp.close();
if (file_exists(backupPath)) {
file_copy(backupPath, filename, true);
file_delete(backupPath);
}
return false; return false;
} }
tmp.close(); tmp.close();
file_delete(backupPath);
return true; return true;
} }
@@ -310,7 +292,7 @@ bool save_game_state() {
string rawData = saveData.serialize(); string rawData = saveData.serialize();
string encryptedData = encrypt_save_data(rawData); string encryptedData = encrypt_save_data(rawData);
return save_robust_data(SAVE_FILE_PATH, encryptedData); return save_data(SAVE_FILE_PATH, encryptedData);
} }
bool load_game_state() { bool load_game_state() {
+19 -59
View File
@@ -44,52 +44,28 @@ void expand_area() {
expanded_area_end = MAP_SIZE + EXPANSION_SIZE - 1; expanded_area_end = MAP_SIZE + EXPANSION_SIZE - 1;
MAP_SIZE += EXPANSION_SIZE; MAP_SIZE += EXPANSION_SIZE;
// Generate random terrain for the 30 new tiles // Generate a single terrain type for the entire new area
expanded_terrain_types.resize(EXPANSION_SIZE); string terrain_type;
for (int i = 0; i < EXPANSION_SIZE; i++) {
int terrain_roll = random(0, 2); int terrain_roll = random(0, 2);
if (terrain_roll == 0) { if (terrain_roll == 0) {
expanded_terrain_types[i] = "stone"; terrain_type = "stone";
} else if (terrain_roll == 1) { } else if (terrain_roll == 1) {
expanded_terrain_types[i] = "grass"; terrain_type = "grass";
} else { } else {
expanded_terrain_types[i] = "snow"; terrain_type = "snow";
}
} }
// Generate streams (30% chance for a stream) expanded_terrain_types.resize(EXPANSION_SIZE);
int stream_roll = random(1, 100); for (int i = 0; i < EXPANSION_SIZE; i++) {
if (stream_roll <= 30) { expanded_terrain_types[i] = terrain_type;
// Determine stream width (1-5 tiles) }
// Place exactly one feature: either a stream or a tree
bool place_stream = (terrain_type != "grass") || (random(0, 1) == 0);
if (place_stream) {
int stream_width = random(1, 5); int stream_width = random(1, 5);
int stream_start = random(0, EXPANSION_SIZE - stream_width);
// Find a valid starting position for the stream
// Stream can only be in grass, stone, or snow areas
int attempts = 0;
int stream_start = -1;
while (attempts < 50) {
int candidate_start = random(0, EXPANSION_SIZE - stream_width);
bool valid_position = true;
// Check if all tiles in this range are valid for a stream
for (int i = 0; i < stream_width; i++) {
string terrain = expanded_terrain_types[candidate_start + i];
// Streams can be in any terrain type
if (terrain != "grass" && terrain != "stone" && terrain != "snow") {
valid_position = false;
break;
}
}
if (valid_position) {
stream_start = candidate_start;
break;
}
attempts++;
}
// Create the stream if we found a valid position
if (stream_start != -1) {
int actual_start = expanded_area_start + stream_start; int actual_start = expanded_area_start + stream_start;
add_world_stream(actual_start, stream_width); add_world_stream(actual_start, stream_width);
@@ -100,27 +76,11 @@ void expand_area() {
else if (stream_width == 5) width_desc = "very wide"; else if (stream_width == 5) width_desc = "very wide";
notify("A " + width_desc + " stream flows through the new area at x " + actual_start + "."); notify("A " + width_desc + " stream flows through the new area at x " + actual_start + ".");
} } else {
} int tree_pos = random(expanded_area_start, expanded_area_end);
Tree@ t = Tree(tree_pos);
// Generate trees in grass areas (50% chance for each grass tile)
for (int i = 0; i < EXPANSION_SIZE; i++) {
if (expanded_terrain_types[i] == "grass") {
int tile_pos = expanded_area_start + i;
// Skip if this position has a stream
if (is_position_in_water(tile_pos)) {
continue;
}
// 50% chance to spawn a tree
int tree_roll = random(1, 100);
if (tree_roll <= 50) {
Tree@ t = Tree(tile_pos);
trees.insert_last(t); trees.insert_last(t);
} }
}
}
area_expanded_today = true; area_expanded_today = true;
notify("The area has expanded! New territory discovered to the east."); notify("The area has expanded! New territory discovered to the east.");
@@ -235,7 +195,7 @@ string get_time_string() {
period = "pm"; period = "pm";
} }
return display_hour + " oclock " + period; return display_hour + " oclock " + period + " day " + current_day;
} }
void check_ambience_transition() { void check_ambience_transition() {
-5
View File
@@ -609,9 +609,7 @@ bool damage_zombie_at(int pos, int damage) {
if (zombies[i].health <= 0) { if (zombies[i].health <= 0) {
play_1d_with_volume_step("sounds/enemies/enemy_falls.ogg", x, pos, false, ZOMBIE_SOUND_VOLUME_STEP); play_1d_with_volume_step("sounds/enemies/enemy_falls.ogg", x, pos, false, ZOMBIE_SOUND_VOLUME_STEP);
zombies.remove_at(i); zombies.remove_at(i);
screen_reader_speak("Zombie killed.", true);
} else { } else {
screen_reader_speak("Hit zombie.", true);
} }
return true; return true;
} }
@@ -814,9 +812,7 @@ bool damage_bandit_at(int pos, int damage) {
if (bandits[i].health <= 0) { if (bandits[i].health <= 0) {
play_1d_with_volume_step("sounds/enemies/enemy_falls.ogg", x, pos, false, BANDIT_SOUND_VOLUME_STEP); play_1d_with_volume_step("sounds/enemies/enemy_falls.ogg", x, pos, false, BANDIT_SOUND_VOLUME_STEP);
bandits.remove_at(i); bandits.remove_at(i);
screen_reader_speak("Bandit killed.", true);
} else { } else {
screen_reader_speak("Hit bandit.", true);
} }
return true; return true;
} }
@@ -842,4 +838,3 @@ WorldStream@ get_stream_at(int pos) {
bool is_position_in_water(int pos) { bool is_position_in_water(int pos) {
return get_stream_at(pos) != null; return get_stream_at(pos) != null;
} }