Eradicate rand (#6553)

Random seed: always generate 10 digits

Reduce max seed size, this is getting hashed so it's not valuable to have so many characters
This commit is contained in:
Philip Dubé
2026-05-29 21:50:19 +00:00
committed by GitHub
parent 30dcd7946f
commit a3ab0e2bdf
10 changed files with 46 additions and 50 deletions
@@ -763,7 +763,7 @@ void RegisterEnemyRandomizer() {
// Offset small jellyfish with Enemy Randomizer, otherwise it gets
// stuck in a loop spawning more big jellyfish with seeded spawns.
if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemies"), 0)) {
rotY += rand() % 50;
rotY += ShipUtils::Random(0, 50);
}
if (!GetRandomizedEnemy(play, &actorId, &posX, &posY, &posZ, &rotX, &rotY, &rotZ, &params)) {
@@ -1,6 +1,7 @@
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ObjectExtension/ActorMaximumHealth.h"
#include "soh/ShipInit.hpp"
#include "soh/ShipUtils.h"
extern "C" {
#include "functions.h"
@@ -30,25 +31,17 @@ static void RandomizedEnemySizes(void* refActor) {
return;
}
float randomNumber;
float randomScale;
// Dodongo, Volvagia and Dead Hand are always smaller because they're impossible when bigger.
bool smallOnlyEnemy = actor->id == ACTOR_BOSS_DODONGO || actor->id == ACTOR_BOSS_FD ||
actor->id == ACTOR_BOSS_FD2 || actor->id == ACTOR_EN_DH;
bool bigActor = !smallOnlyEnemy && (rand() % 2);
bool bigActor = !smallOnlyEnemy && ShipUtils::Random(0, 2) == 0;
// Big actor
float randomScale;
if (bigActor) {
randomNumber = rand() % 200;
// Between 100% and 300% size.
randomScale = 1.0f + (randomNumber / 100);
randomScale = 1.0f + ShipUtils::RandomDouble() * 2.0f;
} else {
// Small actor
randomNumber = rand() % 90;
// Between 10% and 100% size.
randomScale = 0.1f + (randomNumber / 100);
randomScale = 0.1f + ShipUtils::RandomDouble() * 0.9f;
}
Actor_SetScale(actor, actor->scale.z * randomScale);
+2 -1
View File
@@ -14,6 +14,7 @@
#include "soh/SohGui/SohGui.hpp"
#include "AudioCollection.h"
#include "soh/Enhancements/enhancementTypes.h"
#include "soh/ShipUtils.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/randomizer/SeedContext.h"
@@ -406,7 +407,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type, const std::string& tabN
if (validSequences.size()) {
auto it = validSequences.begin();
const auto& seqData = *std::next(it, rand() % validSequences.size());
const auto& seqData = *std::next(it, ShipUtils::Random(0, validSequences.size()));
CVarSetInteger(cvarKey.c_str(), seqData->sequenceId);
if (locked) {
CVarClear(cvarLockKey.c_str());
@@ -4,6 +4,7 @@
#include <math.h>
#include "soh/Enhancements/debugger/colViewer.h"
#include "soh/Enhancements/nametag.h"
#include "soh/ShipUtils.h"
extern "C" {
#include "variables.h"
@@ -410,15 +411,11 @@ void GameInteractor::RawAction::EmulateButtonPress(int32_t button) {
}
void GameInteractor::RawAction::EmulateRandomButtonPress(uint32_t chancePercentage) {
uint32_t emulatedButton;
uint32_t randomNumber = rand();
uint32_t randomNumber = ShipUtils::Random(0, 1400);
uint32_t possibleButtons[14] = { BTN_CRIGHT, BTN_CLEFT, BTN_CDOWN, BTN_CUP, BTN_R, BTN_L, BTN_DRIGHT,
BTN_DLEFT, BTN_DDOWN, BTN_DUP, BTN_START, BTN_Z, BTN_B, BTN_A };
emulatedButton = possibleButtons[randomNumber % 14];
if (randomNumber % 100 < chancePercentage) {
GameInteractor::State::EmulatedButtons |= emulatedButton;
GameInteractor::State::EmulatedButtons |= possibleButtons[randomNumber / 100];
}
}
@@ -431,7 +428,7 @@ void GameInteractor::RawAction::SetRandomWind(bool active) {
if (active) {
GameInteractor::State::RandomWindActive = 1;
if (GameInteractor::State::RandomWindSecondsSinceLastDirectionChange == 0) {
player->pushedYaw = (rand() % 49152) - 32767;
player->pushedYaw = ShipUtils::Random(0, 0xc000) - 0x8000;
GameInteractor::State::RandomWindSecondsSinceLastDirectionChange = 5;
} else {
GameInteractor::State::RandomWindSecondsSinceLastDirectionChange--;
@@ -1,11 +1,7 @@
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <ctime>
#include "menu.hpp"
#include "playthrough.hpp"
#include "soh/Enhancements/debugger/performanceTimer.h"
#include "soh/ShipUtils.h"
#include <spdlog/spdlog.h>
#include "../../randomizer/randomizerTypes.h"
@@ -22,10 +18,14 @@ bool GenerateRandomizer(std::set<RandomizerCheck> excludedLocations, std::set<Ra
ResetPerformanceTimers();
StartPerformanceTimer(PT_WHOLE_SEED);
srand(static_cast<uint32_t>(time(NULL)));
// if a blank seed was entered, make a random one
if (seedInput.empty()) {
seedInput = std::to_string(rand());
char seedString[12];
for (size_t i = 0; i < 10; i++) {
seedString[i] = '0' + ShipUtils::Random(0, 10);
}
seedString[11] = '\0';
seedInput = std::string(seedString);
} else if (seedInput.rfind("seed_testing_count", 0) == 0 && seedInput.length() > 18) {
int count;
try {
@@ -94,7 +94,12 @@ int Playthrough_Repeat(std::set<RandomizerCheck> excludedLocations, std::set<Ran
auto ctx = Rando::Context::GetInstance();
uint32_t repeatedSeed = 0;
for (int i = 0; i < count; i++) {
ctx->SetSeedString(std::to_string(rand()));
char seedString[12];
for (size_t i = 0; i < 10; i++) {
seedString[i] = '0' + ShipUtils::Random(0, 10);
}
seedString[11] = '\0';
ctx->SetSeedString(std::string(seedString));
repeatedSeed = SohUtils::Hash(ctx->GetSeedString());
ctx->SetSeed(repeatedSeed);
SPDLOG_DEBUG("testing seed: %d", repeatedSeed);
@@ -1,12 +1,9 @@
#pragma once
#include <unordered_map>
#include <unordered_set>
#include <string>
#include <vector>
#include <libultraship/libultra.h>
#include "z64item.h"
#include <memory>
#include "SeedContext.h"
#include <soh/Enhancements/randomizer/randomizerTypes.h>
#include "soh/Enhancements/randomizer/randomizer_check_objects.h"
@@ -15,7 +12,6 @@
#include <soh/Enhancements/custom-message/CustomMessageManager.h>
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
#include "../custom-message/CustomMessageTypes.h"
#include "soh/Enhancements/randomizer/fishsanity.h"
#define MAX_SEED_STRING_SIZE 1024
+11 -10
View File
@@ -4,6 +4,7 @@
#include <nlohmann/json.hpp>
#include "soh/OTRGlobals.h"
#include "soh/util.h"
#include "soh/ShipUtils.h"
template <class DstType, class SrcType> bool IsType(const SrcType* src) {
return dynamic_cast<const DstType*>(src) != nullptr;
@@ -339,7 +340,7 @@ void Sail::RegisterHooks() {
return;
nlohmann::json payload;
payload["id"] = std::rand();
payload["id"] = ShipUtils::Random(0, UINT32_MAX);
payload["type"] = "hook";
payload["hook"]["type"] = "OnTransitionEnd";
payload["hook"]["sceneNum"] = sceneNum;
@@ -352,7 +353,7 @@ void Sail::RegisterHooks() {
return;
nlohmann::json payload;
payload["id"] = std::rand();
payload["id"] = ShipUtils::Random(0, UINT32_MAX);
payload["type"] = "hook";
payload["hook"]["type"] = "OnLoadGame";
payload["hook"]["fileNum"] = fileNum;
@@ -365,7 +366,7 @@ void Sail::RegisterHooks() {
return;
nlohmann::json payload;
payload["id"] = std::rand();
payload["id"] = ShipUtils::Random(0, UINT32_MAX);
payload["type"] = "hook";
payload["hook"]["type"] = "OnExitGame";
payload["hook"]["fileNum"] = fileNum;
@@ -377,7 +378,7 @@ void Sail::RegisterHooks() {
if (!isConnected || !GameInteractor::IsSaveLoaded())
return;
nlohmann::json payload;
payload["id"] = std::rand();
payload["id"] = ShipUtils::Random(0, UINT32_MAX);
payload["type"] = "hook";
payload["hook"]["type"] = "OnItemReceive";
payload["hook"]["tableId"] = itemEntry.tableId;
@@ -392,7 +393,7 @@ void Sail::RegisterHooks() {
Actor* actor = (Actor*)refActor;
nlohmann::json payload;
payload["id"] = std::rand();
payload["id"] = ShipUtils::Random(0, UINT32_MAX);
payload["type"] = "hook";
payload["hook"]["type"] = "OnEnemyDefeat";
payload["hook"]["actorId"] = actor->id;
@@ -407,7 +408,7 @@ void Sail::RegisterHooks() {
Actor* actor = (Actor*)refActor;
nlohmann::json payload;
payload["id"] = std::rand();
payload["id"] = ShipUtils::Random(0, UINT32_MAX);
payload["type"] = "hook";
payload["hook"]["type"] = "OnActorInit";
payload["hook"]["actorId"] = actor->id;
@@ -420,7 +421,7 @@ void Sail::RegisterHooks() {
if (!isConnected || !GameInteractor::IsSaveLoaded())
return;
nlohmann::json payload;
payload["id"] = std::rand();
payload["id"] = ShipUtils::Random(0, UINT32_MAX);
payload["type"] = "hook";
payload["hook"]["type"] = "OnFlagSet";
payload["hook"]["flagType"] = flagType;
@@ -433,7 +434,7 @@ void Sail::RegisterHooks() {
if (!isConnected || !GameInteractor::IsSaveLoaded())
return;
nlohmann::json payload;
payload["id"] = std::rand();
payload["id"] = ShipUtils::Random(0, UINT32_MAX);
payload["type"] = "hook";
payload["hook"]["type"] = "OnFlagUnset";
payload["hook"]["flagType"] = flagType;
@@ -446,7 +447,7 @@ void Sail::RegisterHooks() {
if (!isConnected || !GameInteractor::IsSaveLoaded())
return;
nlohmann::json payload;
payload["id"] = std::rand();
payload["id"] = ShipUtils::Random(0, UINT32_MAX);
payload["type"] = "hook";
payload["hook"]["type"] = "OnSceneFlagSet";
payload["hook"]["flagType"] = flagType;
@@ -460,7 +461,7 @@ void Sail::RegisterHooks() {
if (!isConnected || !GameInteractor::IsSaveLoaded())
return;
nlohmann::json payload;
payload["id"] = std::rand();
payload["id"] = ShipUtils::Random(0, UINT32_MAX);
payload["type"] = "hook";
payload["hook"]["type"] = "OnSceneFlagUnset";
payload["hook"]["flagType"] = flagType;
+7 -3
View File
@@ -4,6 +4,7 @@
#include "soh/Enhancements/randomizer/randomizerTypes.h"
#include "soh/Enhancements/randomizer/settings.h"
#include "soh/OTRGlobals.h"
#include "soh/ShipUtils.h"
#include "soh/SohGui/SohGui.hpp"
extern "C" {
@@ -559,16 +560,19 @@ void SohMenu::AddMenuRandomizer() {
.Color(THEME_COLOR)
.Padding(ImVec2(10.f, 6.f))
.Tooltip("Creates a new random seed value to be used when generating a randomizer"))) {
SohUtils::CopyStringToCharArray(seedString, std::to_string(rand() & 0xFFFFFFFF), MAX_SEED_STRING_SIZE);
for (size_t i = 0; i < 10; i++) {
seedString[i] = '0' + ShipUtils::Random(0, 10);
}
seedString[11] = '\0';
}
ImGui::SameLine();
if (UIWidgets::Button(ICON_FA_ERASER, UIWidgets::ButtonOptions()
.Size(UIWidgets::Sizes::Inline)
.Color(THEME_COLOR)
.Padding(ImVec2(10.f, 6.f)))) {
memset(seedString, 0, MAX_SEED_STRING_SIZE);
seedString[0] = 0;
}
if (strnlen(seedString, MAX_SEED_STRING_SIZE) == 0) {
if (seedString[0] == 0) {
ImGui::SameLine(17.0f);
ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 0.4f), "Leave blank for random seed");
}
@@ -8,7 +8,7 @@
#include "overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include <stdlib.h>
#include "soh/ShipUtils.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
@@ -104,14 +104,13 @@ void EnBom_Init(Actor* thisx, PlayState* play) {
} else {
// Set random fuse timer with a minimum of 10. Do the sound and scale immediately,
// otherwise the bomb is invisible until the timer hits the "normal" amount.
uint32_t randomTimer = (rand() % 150) + 10;
this->timer = randomTimer;
this->timer = 10 + (s16)(Rand_ZeroOne() * 150.0f);
Audio_PlayActorSound2(thisx, NA_SE_PL_TAKE_OUT_SHIELD);
Actor_SetScale(thisx, 0.01f);
}
if (CVarGetFloat(CVAR_CHEAT("BombTimerMultiplier"), 1.0f) != 1.0f) {
this->timer = (s32)(70 * CVarGetFloat(CVAR_CHEAT("BombTimerMultiplier"), 1.0f));
this->timer *= CVarGetFloat(CVAR_CHEAT("BombTimerMultiplier"), 1.0f);
// Do the sound and scale immediately if GameInteractor hasn't already.
if (!GameInteractor_GetRandomBombFuseTimerActive()) {
Audio_PlayActorSound2(thisx, NA_SE_PL_TAKE_OUT_SHIELD);