From faccf2ee1a414cf7500e995edc37d68aabcb4b46 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Mon, 18 Mar 2024 08:55:38 +0100 Subject: [PATCH] added correcting random numbers for predictable slime in BD engine --- src/files.c | 9 +++++++++ src/game_bd/bd_cave.h | 1 + src/game_bd/bd_caveobject.c | 15 +++++++++++++++ src/main.h | 2 ++ 4 files changed, 27 insertions(+) diff --git a/src/files.c b/src/files.c index e519b9b7..a150f891 100644 --- a/src/files.c +++ b/src/files.c @@ -310,6 +310,11 @@ static struct LevelFileConfigInfo chunk_config_INFO[] = TYPE_BOOLEAN, CONF_VALUE_8_BIT(23), &li.bd_gravity_affects_all, TRUE }, + { + -1, -1, + TYPE_INTEGER, CONF_VALUE_8_BIT(24), + &li.bd_cave_random_seed_c64, 0 + }, { -1, -1, @@ -3984,9 +3989,11 @@ static void CopyNativeLevel_RND_to_BD(struct LevelInfo *level) cave->amoeba_2_looks_like = map_element_RND_to_BD(level->bd_amoeba_2_content_looks_like); cave->slime_predictable = level->bd_slime_is_predictable; + cave->slime_correct_random = level->bd_slime_correct_random; cave->level_slime_permeability[0] = level->bd_slime_permeability_rate * 10000; cave->level_slime_permeability_c64[0] = level->bd_slime_permeability_bits_c64; cave->level_slime_seed_c64[0] = level->bd_slime_random_seed_c64; + cave->level_rand[0] = level->bd_cave_random_seed_c64; // level name strncpy(cave->name, level->name, sizeof(GdString)); @@ -4072,9 +4079,11 @@ static void CopyNativeLevel_BD_to_RND(struct LevelInfo *level) level->bd_amoeba_2_content_looks_like = map_element_BD_to_RND(cave->amoeba_2_looks_like); level->bd_slime_is_predictable = cave->slime_predictable; + level->bd_slime_correct_random = cave->slime_correct_random; level->bd_slime_permeability_rate = cave->level_slime_permeability[bd_level_nr] / 10000; level->bd_slime_permeability_bits_c64 = cave->level_slime_permeability_c64[bd_level_nr]; level->bd_slime_random_seed_c64 = cave->level_slime_seed_c64[bd_level_nr]; + level->bd_cave_random_seed_c64 = cave->level_rand[bd_level_nr]; // level name char *cave_name = getStringPrint("%s / %d", cave->name, bd_level_nr + 1); diff --git a/src/game_bd/bd_cave.h b/src/game_bd/bd_cave.h index b3133512..e76c9c5c 100644 --- a/src/game_bd/bd_cave.h +++ b/src/game_bd/bd_cave.h @@ -432,6 +432,7 @@ typedef struct _gd_cave int level_slime_permeability_c64[5]; // Appearing in bd 2 int level_slime_seed_c64[5]; // predictable slime random seed boolean slime_predictable; // predictable random start for slime. yes for plck. + boolean slime_correct_random; // correct random number generator for rendered caves GdElement slime_eats_1, slime_converts_1; // slime eats element x and converts to element x; // for example diamond -> falling diamond GdElement slime_eats_2, slime_converts_2; // this is usually stone -> stone_f diff --git a/src/game_bd/bd_caveobject.c b/src/game_bd/bd_caveobject.c index 6d5ca422..cea246fa 100644 --- a/src/game_bd/bd_caveobject.c +++ b/src/game_bd/bd_caveobject.c @@ -1488,6 +1488,9 @@ GdCave *gd_cave_new_rendered(const GdCave *data, const int level, const unsigned gd_cave_store_rc(cave, x, 0, cave->initial_border, NULL); gd_cave_store_rc(cave, x, cave->h - 1, cave->initial_border, NULL); } + + // store if random number generator needs correction for static random seed + cave->slime_correct_random = (data->level_rand[level] >= 0); } else { @@ -1496,6 +1499,18 @@ GdCave *gd_cave_new_rendered(const GdCave *data, const int level, const unsigned // initialize c64 predictable random for slime. // the values were taken from afl bd, see docs/internals.txt gd_cave_c64_random_set_seed(cave, 0, 0x1e); + + // correct random number generator if cave was rendered with static random seed + if (cave->slime_correct_random) + { + int i; + + // set static random seed used when rendering the cave + gd_cave_c64_random_set_seed(cave, 0, data->level_rand[level]); + + for (i = 0; i < cave->w * (cave->h - 2); i++) + gd_cave_c64_random(cave); + } } if (data->level_slime_seed_c64[level] != -1) diff --git a/src/main.h b/src/main.h index 96c72b29..36fbdb5c 100644 --- a/src/main.h +++ b/src/main.h @@ -3523,9 +3523,11 @@ struct LevelInfo boolean bd_voodoo_vanish_by_explosion;// BD voodoo doll can be destroyed by explosions int bd_voodoo_penalty_time; // BD engine penalty time when voodoo doll destroyed boolean bd_slime_is_predictable; // BD slime uses predictable random number generator + boolean bd_slime_correct_random; // BD slime needs corrected random number generator int bd_slime_permeability_rate; // BD slime permeability rate for unpredictable slime int bd_slime_permeability_bits_c64; // BD slime permeability bits for predictable slime int bd_slime_random_seed_c64; // BD slime random number seed for predictable slime + int bd_cave_random_seed_c64; // BD cave random number seed for predictable slime boolean em_slippery_gems; // EM style "gems slip from wall" behaviour boolean em_explodes_by_fire; // EM style chain explosion behaviour boolean use_spring_bug; // for compatibility with old levels -- 2.34.1