Merge branch 'aManchipelago' into AddArchipelagoClientLib
This commit is contained in:
8
soh/soh/Enhancements/SkipAmyPuzzle.cpp
Normal file
8
soh/soh/Enhancements/SkipAmyPuzzle.cpp
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||||
|
#include "soh/ShipInit.hpp"
|
||||||
|
|
||||||
|
void RegisterSkipAmyPuzzle() {
|
||||||
|
COND_VB_SHOULD(VB_AMY_SOLVE, CVarGetInteger(CVAR_ENHANCEMENT("SkipAmyPuzzle"), 0), { *should = true; });
|
||||||
|
}
|
||||||
|
|
||||||
|
static RegisterShipInitFunc initFunc(RegisterSkipAmyPuzzle, { CVAR_ENHANCEMENT("SkipAmyPuzzle") });
|
||||||
@@ -10,8 +10,6 @@ extern "C" {
|
|||||||
#include "variables.h"
|
#include "variables.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
|
|
||||||
|
|
||||||
static bool sEnteredBlueWarp = false;
|
static bool sEnteredBlueWarp = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -13,15 +13,29 @@ extern "C" {
|
|||||||
#include <z64.h>
|
#include <z64.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* enemyCVarList[] = {
|
#define CVAR_ENEMY_RANDOMIZER_NAME CVAR_ENHANCEMENT("RandomizedEnemies")
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.Armos"), CVAR_ENHANCEMENT("RandomizedEnemyList.Arwing"),
|
#define CVAR_ENEMY_RANDOMIZER_DEFAULT ENEMY_RANDOMIZER_OFF
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.BabyDodongo"), CVAR_ENHANCEMENT("RandomizedEnemyList.Bari"),
|
#define CVAR_ENEMY_RANDOMIZER_VALUE CVarGetInteger(CVAR_ENEMY_RANDOMIZER_NAME, CVAR_ENEMY_RANDOMIZER_DEFAULT)
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.Beamos"), CVAR_ENHANCEMENT("RandomizedEnemyList.BigSkulltula"),
|
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.BigStalchild"), CVAR_ENHANCEMENT("RandomizedEnemyList.Biri"),
|
typedef struct EnemyEntry {
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.BlackKnuckle"), CVAR_ENHANCEMENT("RandomizedEnemyList.BlueTektite"),
|
int16_t id;
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.Bubble"), CVAR_ENHANCEMENT("RandomizedEnemyList.ClubMoblin"),
|
int16_t params;
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.DarkLink"), CVAR_ENHANCEMENT("RandomizedEnemyList.Dinolfos"),
|
} EnemyEntry;
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.Dodongo"), CVAR_ENHANCEMENT("RandomizedEnemyList.FireKeese"),
|
|
||||||
|
bool IsEnemyFoundToRandomize(int16_t sceneNum, int8_t roomNum, int16_t actorId, int16_t params, float posX);
|
||||||
|
bool IsEnemyAllowedToSpawn(int16_t sceneNum, int8_t roomNum, EnemyEntry enemy);
|
||||||
|
EnemyEntry GetRandomizedEnemyEntry(uint32_t seed);
|
||||||
|
|
||||||
|
const char* enemyCVarList[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] = {
|
||||||
|
CVAR_ENHANCEMENT("RandomizedEnemyList.Anubis"), CVAR_ENHANCEMENT("RandomizedEnemyList.Armos"),
|
||||||
|
CVAR_ENHANCEMENT("RandomizedEnemyList.Arwing"), CVAR_ENHANCEMENT("RandomizedEnemyList.BabyDodongo"),
|
||||||
|
CVAR_ENHANCEMENT("RandomizedEnemyList.Bari"), CVAR_ENHANCEMENT("RandomizedEnemyList.Beamos"),
|
||||||
|
CVAR_ENHANCEMENT("RandomizedEnemyList.BigSkulltula"), CVAR_ENHANCEMENT("RandomizedEnemyList.BigStalchild"),
|
||||||
|
CVAR_ENHANCEMENT("RandomizedEnemyList.Biri"), CVAR_ENHANCEMENT("RandomizedEnemyList.BlackKnuckle"),
|
||||||
|
CVAR_ENHANCEMENT("RandomizedEnemyList.BlueTektite"), CVAR_ENHANCEMENT("RandomizedEnemyList.Bubble"),
|
||||||
|
CVAR_ENHANCEMENT("RandomizedEnemyList.ClubMoblin"), CVAR_ENHANCEMENT("RandomizedEnemyList.DarkLink"),
|
||||||
|
CVAR_ENHANCEMENT("RandomizedEnemyList.Dinolfos"), CVAR_ENHANCEMENT("RandomizedEnemyList.Dodongo"),
|
||||||
|
CVAR_ENHANCEMENT("RandomizedEnemyList.FireKeese"), /*CVAR_ENHANCEMENT("RandomizedEnemyList.FlareDancer"),*/
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.FloorTile"), CVAR_ENHANCEMENT("RandomizedEnemyList.Floormaster"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.FloorTile"), CVAR_ENHANCEMENT("RandomizedEnemyList.Floormaster"),
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.FlyingPeahat"), CVAR_ENHANCEMENT("RandomizedEnemyList.FlyingPot"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.FlyingPeahat"), CVAR_ENHANCEMENT("RandomizedEnemyList.FlyingPot"),
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.Freezard"), CVAR_ENHANCEMENT("RandomizedEnemyList.Gibdo"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.Freezard"), CVAR_ENHANCEMENT("RandomizedEnemyList.Gibdo"),
|
||||||
@@ -30,18 +44,20 @@ const char* enemyCVarList[] = {
|
|||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.Keese"), CVAR_ENHANCEMENT("RandomizedEnemyList.LargeBaba"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.Keese"), CVAR_ENHANCEMENT("RandomizedEnemyList.LargeBaba"),
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.LikeLike"), CVAR_ENHANCEMENT("RandomizedEnemyList.Lizalfos"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.LikeLike"), CVAR_ENHANCEMENT("RandomizedEnemyList.Lizalfos"),
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.MadScrub"), CVAR_ENHANCEMENT("RandomizedEnemyList.NormalWolfos"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.MadScrub"), CVAR_ENHANCEMENT("RandomizedEnemyList.NormalWolfos"),
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.PeahatLarva"), CVAR_ENHANCEMENT("RandomizedEnemyList.Redead"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.PeahatLarva"), /*CVAR_ENHANCEMENT("RandomizedEnemyList.Poe"),*/
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.RedTektite"), CVAR_ENHANCEMENT("RandomizedEnemyList.Shabom"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.Redead"), CVAR_ENHANCEMENT("RandomizedEnemyList.RedTektite"),
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.ShellBlade"), CVAR_ENHANCEMENT("RandomizedEnemyList.Skulltula"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.Shabom"), CVAR_ENHANCEMENT("RandomizedEnemyList.ShellBlade"),
|
||||||
|
CVAR_ENHANCEMENT("RandomizedEnemyList.Skulltula"), CVAR_ENHANCEMENT("RandomizedEnemyList.SkullKid"),
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.SmallBaba"), CVAR_ENHANCEMENT("RandomizedEnemyList.SmallStalchild"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.SmallBaba"), CVAR_ENHANCEMENT("RandomizedEnemyList.SmallStalchild"),
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.Spike"), CVAR_ENHANCEMENT("RandomizedEnemyList.Stalfos"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.SpearMoblin"), CVAR_ENHANCEMENT("RandomizedEnemyList.Spike"),
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.Stinger"), CVAR_ENHANCEMENT("RandomizedEnemyList.Tailparasan"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.Stalfos"), CVAR_ENHANCEMENT("RandomizedEnemyList.Stinger"),
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.TorchSlug"), CVAR_ENHANCEMENT("RandomizedEnemyList.Wallmaster"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.Tailparasan"), CVAR_ENHANCEMENT("RandomizedEnemyList.TorchSlug"),
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.WhiteKnuckle"), CVAR_ENHANCEMENT("RandomizedEnemyList.WhiteWolfos"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.Wallmaster"), CVAR_ENHANCEMENT("RandomizedEnemyList.WhiteKnuckle"),
|
||||||
CVAR_ENHANCEMENT("RandomizedEnemyList.WitheredBaba"),
|
CVAR_ENHANCEMENT("RandomizedEnemyList.WhiteWolfos"), CVAR_ENHANCEMENT("RandomizedEnemyList.WitheredBaba"),
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* enemyNameList[] = {
|
const char* enemyNameList[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] = {
|
||||||
|
"Anubis",
|
||||||
"Armos",
|
"Armos",
|
||||||
"Arwing",
|
"Arwing",
|
||||||
"Baby Dodongo",
|
"Baby Dodongo",
|
||||||
@@ -58,6 +74,7 @@ const char* enemyNameList[] = {
|
|||||||
"Dinolfos",
|
"Dinolfos",
|
||||||
"Dodongo",
|
"Dodongo",
|
||||||
"Fire Keese",
|
"Fire Keese",
|
||||||
|
//"Flare Dancer",
|
||||||
"Floor Tile",
|
"Floor Tile",
|
||||||
"Floormaster",
|
"Floormaster",
|
||||||
"Flying Peahat",
|
"Flying Peahat",
|
||||||
@@ -75,13 +92,16 @@ const char* enemyNameList[] = {
|
|||||||
"Mad Scrub",
|
"Mad Scrub",
|
||||||
"Wolfos (Normal)",
|
"Wolfos (Normal)",
|
||||||
"Peahat Larva",
|
"Peahat Larva",
|
||||||
|
//"Poe",
|
||||||
"Redead",
|
"Redead",
|
||||||
"Red Tektite",
|
"Red Tektite",
|
||||||
"Shabom",
|
"Shabom",
|
||||||
"Shell Blade",
|
"Shell Blade",
|
||||||
"Skulltula",
|
"Skulltula",
|
||||||
|
"Skull Kid",
|
||||||
"Small Deku Baba",
|
"Small Deku Baba",
|
||||||
"Stalchild (Small)",
|
"Stalchild (Small)",
|
||||||
|
"Spear Moblin",
|
||||||
"Spike",
|
"Spike",
|
||||||
"Stalfos",
|
"Stalfos",
|
||||||
"Stinger",
|
"Stinger",
|
||||||
@@ -94,98 +114,105 @@ const char* enemyNameList[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static EnemyEntry randomizedEnemySpawnTable[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] = {
|
static EnemyEntry randomizedEnemySpawnTable[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] = {
|
||||||
{ ACTOR_EN_AM, -1 }, // Armos
|
{ ACTOR_EN_ANUBICE_TAG, 1 }, // Anubis
|
||||||
{ ACTOR_EN_CLEAR_TAG, 1 }, // Arwing
|
{ ACTOR_EN_AM, -1 }, // Armos
|
||||||
{ ACTOR_EN_DODOJR, 0 }, // Baby Dodongo
|
{ ACTOR_EN_CLEAR_TAG, 1 }, // Arwing
|
||||||
{ ACTOR_EN_VALI, -1 }, // Bari (big jellyfish)
|
{ ACTOR_EN_DODOJR, 0 }, // Baby Dodongo
|
||||||
{ ACTOR_EN_VM, 1280 }, // Beamos
|
{ ACTOR_EN_VALI, -1 }, // Bari (big jellyfish)
|
||||||
{ ACTOR_EN_ST, 1 }, // Skulltula (big)
|
{ ACTOR_EN_VM, 1280 }, // Beamos
|
||||||
{ ACTOR_EN_SKB, 20 }, // Stalchild (big)
|
{ ACTOR_EN_ST, 1 }, // Skulltula (big)
|
||||||
{ ACTOR_EN_BILI, 0 }, // Biri (jellyfish)
|
{ ACTOR_EN_SKB, 20 }, // Stalchild (big)
|
||||||
{ ACTOR_EN_IK, 2 }, // Iron Knuckle (black, standing)
|
{ ACTOR_EN_BILI, 0 }, // Biri (jellyfish)
|
||||||
{ ACTOR_EN_TITE, -2 }, // Tektite (blue)
|
{ ACTOR_EN_IK, 2 }, // Iron Knuckle (black, standing)
|
||||||
{ ACTOR_EN_BB, -1 }, // Bubble (flying skull enemy) (blue)
|
{ ACTOR_EN_TITE, -2 }, // Tektite (blue)
|
||||||
{ ACTOR_EN_MB, 0 }, // Moblins (Club)
|
{ ACTOR_EN_BB, -1 }, // Bubble (flying skull enemy) (blue)
|
||||||
{ ACTOR_EN_TORCH2, 0 }, // Dark Link
|
{ ACTOR_EN_MB, 0 }, // Club Moblin
|
||||||
{ ACTOR_EN_ZF, -2 }, // Dinolfos
|
{ ACTOR_EN_TORCH2, 0 }, // Dark Link
|
||||||
{ ACTOR_EN_DODONGO, -1 }, // Dodongo
|
{ ACTOR_EN_ZF, -2 }, // Dinolfos
|
||||||
{ ACTOR_EN_FIREFLY, 1 }, // Fire Keese
|
{ ACTOR_EN_DODONGO, -1 }, // Dodongo
|
||||||
{ ACTOR_EN_YUKABYUN, 0 }, // Flying Floor Tile
|
{ ACTOR_EN_FIREFLY, 1 }, // Fire Keese
|
||||||
{ ACTOR_EN_FLOORMAS, 0 }, // Floormaster
|
// { ACTOR_EN_FD, 0 }, // Flare Dancer (possible cause of crashes because of spawning flame actors on
|
||||||
{ ACTOR_EN_PEEHAT, -1 }, // Flying Peahat (big grounded, doesn't spawn larva)
|
// sloped ground)
|
||||||
{ ACTOR_EN_TUBO_TRAP, 0 }, // Flying pot
|
{ ACTOR_EN_YUKABYUN, 0 }, // Flying Floor Tile
|
||||||
{ ACTOR_EN_FZ, 0 }, // Freezard
|
{ ACTOR_EN_FLOORMAS, 0 }, // Floormaster
|
||||||
{ ACTOR_EN_RD, 32766 }, // Gibdo (standing)
|
{ ACTOR_EN_PEEHAT, -1 }, // Flying Peahat (big grounded, doesn't spawn larva)
|
||||||
{ ACTOR_EN_GOMA, 7 }, // Gohma Larva (Non-Gohma rooms)
|
{ ACTOR_EN_TUBO_TRAP, 0 }, // Flying pot
|
||||||
{ ACTOR_EN_CROW, 0 }, // Guay
|
{ ACTOR_EN_FZ, 0 }, // Freezard
|
||||||
{ ACTOR_EN_FIREFLY, 4 }, // Ice Keese
|
{ ACTOR_EN_RD, 32766 }, // Gibdo (standing)
|
||||||
{ ACTOR_EN_ST, 2 }, // Skulltula (invisible)
|
{ ACTOR_EN_GOMA, 7 }, // Gohma Larva (Non-Gohma rooms)
|
||||||
{ ACTOR_EN_FIREFLY, 2 }, // Regular Keese
|
{ ACTOR_EN_CROW, 0 }, // Guay
|
||||||
{ ACTOR_EN_DEKUBABA, 1 }, // Deku Baba (large)
|
{ ACTOR_EN_FIREFLY, 4 }, // Ice Keese
|
||||||
|
{ ACTOR_EN_ST, 2 }, // Skulltula (invisible)
|
||||||
|
{ ACTOR_EN_FIREFLY, 2 }, // Regular Keese
|
||||||
|
{ ACTOR_EN_DEKUBABA, 1 }, // Deku Baba (large)
|
||||||
|
// Doesn't work (reliant on surface and also normally used in tandem with a leever spawner, kills itself too quickly
|
||||||
|
// otherwise) { ACTOR_EN_REEBA, 0 }, // Leever
|
||||||
{ ACTOR_EN_RR, 0 }, // Like-Like
|
{ ACTOR_EN_RR, 0 }, // Like-Like
|
||||||
{ ACTOR_EN_ZF, -1 }, // Lizalfos
|
{ ACTOR_EN_ZF, -1 }, // Lizalfos
|
||||||
{ ACTOR_EN_DEKUNUTS, 768 }, // Mad Scrub (triple attack) (projectiles don't work)
|
{ ACTOR_EN_DEKUNUTS, 768 }, // Mad Scrub (triple attack) (projectiles don't work)
|
||||||
{ ACTOR_EN_WF, 0 }, // Wolfos (normal)
|
{ ACTOR_EN_WF, 0 }, // Wolfos (normal)
|
||||||
{ ACTOR_EN_PEEHAT, 1 }, // Flying Peahat Larva
|
// Doesn't work (actor directly uses water box collision to handle hiding/popping up)
|
||||||
{ ACTOR_EN_RD, 1 }, // Redead (standing)
|
// { ACTOR_EN_OKUTA, 0 }, // Octorok
|
||||||
{ ACTOR_EN_TITE, -1 }, // Tektite (red)
|
{ ACTOR_EN_PEEHAT, 1 }, // Flying Peahat Larva
|
||||||
{ ACTOR_EN_BUBBLE, 0 }, // Shabom (bubble)
|
// Doesn't work (Seems to rely on other objects?)
|
||||||
{ ACTOR_EN_SB, 0 }, // Shell Blade
|
// { ACTOR_EN_POH, 0 }, // Poe
|
||||||
{ ACTOR_EN_ST, 0 }, // Skulltula (normal)
|
// Doesn't work (Seems to rely on other objects?)
|
||||||
{ ACTOR_EN_DEKUBABA, 0 }, // Deku Baba (small)
|
// { ACTOR_EN_POH, 2 }, // Poe (composer Sharp)
|
||||||
{ ACTOR_EN_SKB, 1 }, // Stalchild (small)
|
// Doesn't work (Seems to rely on other objects?)
|
||||||
{ ACTOR_EN_NY, 0 }, // Spike (rolling enemy)
|
// { ACTOR_EN_POH, 3 }, // Poe (composer Flat)
|
||||||
{ ACTOR_EN_TEST, 2 }, // Stalfos
|
{ ACTOR_EN_RD, 1 }, // Redead (standing)
|
||||||
{ ACTOR_EN_EIYER, 10 }, // Stinger (land) (One in formation, sink under floor and do not activate)
|
{ ACTOR_EN_TITE, -1 }, // Tektite (red)
|
||||||
{ ACTOR_EN_TP, -1 }, // Electric Tailpasaran
|
{ ACTOR_EN_BUBBLE, 0 }, // Shabom (bubble)
|
||||||
{ ACTOR_EN_BW, 0 }, // Torch Slug
|
{ ACTOR_EN_SB, 0 }, // Shell Blade
|
||||||
{ ACTOR_EN_WALLMAS, 1 }, // Wallmaster
|
{ ACTOR_EN_ST, 0 }, // Skulltula (normal)
|
||||||
{ ACTOR_EN_IK, 3 }, // Iron Knuckle (white, standing)
|
{ ACTOR_EN_SKJ, 4159 }, // Skull Kid
|
||||||
{ ACTOR_EN_WF, 1 }, // Wolfos (white)
|
{ ACTOR_EN_DEKUBABA, 0 }, // Deku Baba (small)
|
||||||
{ ACTOR_EN_KAREBABA, 0 }, // Withered Deku Baba
|
{ ACTOR_EN_SKB, 1 }, // Stalchild (small)
|
||||||
|
{ ACTOR_EN_MB, -1 }, // Spear Moblin
|
||||||
// Doesn't work {ACTOR_EN_POH, 0}, // Poe (Seems to rely on other objects?)
|
{ ACTOR_EN_NY, 0 }, // Spike (rolling enemy)
|
||||||
// Doesn't work {ACTOR_EN_POH, 2}, // Poe (composer Sharp) (Seems to rely on other objects?)
|
{ ACTOR_EN_TEST, 2 }, // Stalfos
|
||||||
// Doesn't work {ACTOR_EN_POH, 3}, // Poe (composer Flat) (Seems to rely on other objects?)
|
{ ACTOR_EN_EIYER, 10 }, // Stinger (land) (One in formation, sink under floor and do not activate)
|
||||||
// Doesn't work {ACTOR_EN_OKUTA, 0}, // Octorok (actor directly uses water box collision to handle hiding/popping
|
{ ACTOR_EN_TP, -1 }, // Electric Tailpasaran
|
||||||
// up) Doesn't work {ACTOR_EN_REEBA, 0}, // Leever (reliant on surface and also normally used in tandem with a
|
{ ACTOR_EN_BW, 0 }, // Torch Slug
|
||||||
// leever spawner, kills itself too quickly otherwise) Kinda doesn't work { ACTOR_EN_FD, 0 }, // Flare Dancer (jumps
|
{ ACTOR_EN_WALLMAS, 1 }, // Wallmaster
|
||||||
// out of bounds a lot, and possible cause of crashes because of spawning a ton of flame actors)
|
{ ACTOR_EN_IK, 3 }, // Iron Knuckle (white, standing)
|
||||||
|
{ ACTOR_EN_WF, 1 }, // Wolfos (white)
|
||||||
|
{ ACTOR_EN_KAREBABA, 0 }, // Withered Deku Baba
|
||||||
};
|
};
|
||||||
|
|
||||||
static int enemiesToRandomize[] = {
|
static int enemiesToRandomize[] = {
|
||||||
ACTOR_EN_FIREFLY, // Keese (including fire/ice)
|
ACTOR_EN_ANUBICE_TAG, // Anubis
|
||||||
ACTOR_EN_TEST, // Stalfos
|
ACTOR_EN_FIREFLY, // Keese (including fire/ice)
|
||||||
ACTOR_EN_TITE, // Tektite
|
ACTOR_EN_TEST, // Stalfos
|
||||||
ACTOR_EN_POH, // Poe (normal, blue rupee, composers)
|
ACTOR_EN_TITE, // Tektite
|
||||||
ACTOR_EN_OKUTA, // Octorok
|
ACTOR_EN_POH, // Poe (normal, blue rupee, composers)
|
||||||
ACTOR_EN_WALLMAS, // Wallmaster
|
ACTOR_EN_OKUTA, // Octorok
|
||||||
ACTOR_EN_DODONGO, // Dodongo
|
ACTOR_EN_WALLMAS, // Wallmaster
|
||||||
// ACTOR_EN_REEBA, // Leever (reliant on spawner (z_e_encount1.c)
|
ACTOR_EN_DODONGO, // Dodongo
|
||||||
ACTOR_EN_PEEHAT, // Flying Peahat, big one spawning larva, larva
|
// ACTOR_EN_REEBA, // Leever (reliant on spawner (z_en_encount1.c))
|
||||||
ACTOR_EN_ZF, // Lizalfos, Dinolfos
|
ACTOR_EN_PEEHAT, // Flying Peahat, big one spawning larva, larva
|
||||||
ACTOR_EN_GOMA, // Gohma Larva (normal, eggs, gohma eggs)
|
ACTOR_EN_ZF, // Lizalfos, Dinolfos
|
||||||
ACTOR_EN_BUBBLE, // Shabom (bubble)
|
ACTOR_EN_GOMA, // Gohma Larva (normal, eggs, gohma eggs)
|
||||||
ACTOR_EN_DODOJR, // Baby Dodongo
|
ACTOR_EN_BUBBLE, // Shabom (bubble)
|
||||||
ACTOR_EN_TORCH2, // Dark Link
|
ACTOR_EN_DODOJR, // Baby Dodongo
|
||||||
ACTOR_EN_BILI, // Biri (small jellyfish)
|
ACTOR_EN_TORCH2, // Dark Link
|
||||||
ACTOR_EN_TP, // Electric Tailpasaran
|
ACTOR_EN_BILI, // Biri (small jellyfish)
|
||||||
ACTOR_EN_ST, // Skulltula (normal, big, invisible)
|
ACTOR_EN_TP, // Electric Tailpasaran
|
||||||
ACTOR_EN_BW, // Torch Slug
|
ACTOR_EN_ST, // Skulltula (normal, big, invisible)
|
||||||
ACTOR_EN_EIYER, // Stinger (land)
|
ACTOR_EN_BW, // Torch Slug
|
||||||
ACTOR_EN_MB, // Moblins (Club, spear)
|
ACTOR_EN_EIYER, // Stinger (land)
|
||||||
ACTOR_EN_DEKUBABA, // Deku Baba (small, large)
|
ACTOR_EN_MB, // Moblins (Club, spear)
|
||||||
ACTOR_EN_AM, // Armos (enemy variant)
|
ACTOR_EN_DEKUBABA, // Deku Baba (small, large)
|
||||||
ACTOR_EN_DEKUNUTS, // Mad Scrub (single attack, triple attack)
|
ACTOR_EN_AM, // Armos (enemy variant)
|
||||||
ACTOR_EN_VALI, // Bari (big jellyfish) (spawns very high up)
|
ACTOR_EN_DEKUNUTS, // Mad Scrub (single attack, triple attack)
|
||||||
ACTOR_EN_BB, // Bubble (flying skull enemy) (all colors)
|
ACTOR_EN_VALI, // Bari (big jellyfish) (spawns very high up)
|
||||||
ACTOR_EN_YUKABYUN, // Flying Floor Tile
|
ACTOR_EN_BB, // Bubble (flying skull enemy) (all colors)
|
||||||
ACTOR_EN_VM, // Beamos
|
ACTOR_EN_YUKABYUN, // Flying Floor Tile
|
||||||
ACTOR_EN_FLOORMAS, // Floormaster
|
ACTOR_EN_VM, // Beamos
|
||||||
ACTOR_EN_RD, // Redead, Gibdo
|
ACTOR_EN_FLOORMAS, // Floormaster
|
||||||
ACTOR_EN_SW, // Skullwalltula
|
ACTOR_EN_RD, // Redead, Gibdo
|
||||||
// ACTOR_EN_FD, // Flare Dancer (can be randomized, but not randomized to, so keeping it in vanilla locations
|
ACTOR_EN_SW, // Skullwalltula
|
||||||
// means it at least shows up in the game)
|
ACTOR_EN_FD, // Flare Dancer
|
||||||
ACTOR_EN_SB, // Shell Blade
|
ACTOR_EN_SB, // Shell Blade
|
||||||
ACTOR_EN_KAREBABA, // Withered Deku Baba
|
ACTOR_EN_KAREBABA, // Withered Deku Baba
|
||||||
ACTOR_EN_RR, // Like-Like
|
ACTOR_EN_RR, // Like-Like
|
||||||
@@ -198,6 +225,7 @@ static int enemiesToRandomize[] = {
|
|||||||
ACTOR_EN_WF, // Wolfos
|
ACTOR_EN_WF, // Wolfos
|
||||||
ACTOR_EN_SKB, // Stalchild
|
ACTOR_EN_SKB, // Stalchild
|
||||||
ACTOR_EN_CROW, // Guay
|
ACTOR_EN_CROW, // Guay
|
||||||
|
ACTOR_EN_SKJ, // Skull Kid
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" uint8_t GetRandomizedEnemy(PlayState* play, int16_t* actorId, f32* posX, f32* posY, f32* posZ, int16_t* rotX,
|
extern "C" uint8_t GetRandomizedEnemy(PlayState* play, int16_t* actorId, f32* posX, f32* posY, f32* posZ, int16_t* rotX,
|
||||||
@@ -322,7 +350,7 @@ static std::vector<EnemyEntry> selectedEnemyList;
|
|||||||
|
|
||||||
void GetSelectedEnemies() {
|
void GetSelectedEnemies() {
|
||||||
selectedEnemyList.clear();
|
selectedEnemyList.clear();
|
||||||
for (int i = 0; i < 49; i++) {
|
for (int i = 0; i < RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE; i++) {
|
||||||
if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemyList.All"), 0)) {
|
if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemyList.All"), 0)) {
|
||||||
selectedEnemyList.push_back(randomizedEnemySpawnTable[i]);
|
selectedEnemyList.push_back(randomizedEnemySpawnTable[i]);
|
||||||
} else if (CVarGetInteger(enemyCVarList[i], 1)) {
|
} else if (CVarGetInteger(enemyCVarList[i], 1)) {
|
||||||
@@ -408,6 +436,8 @@ bool IsEnemyFoundToRandomize(int16_t sceneNum, int8_t roomNum, int16_t actorId,
|
|||||||
case ACTOR_EN_SB:
|
case ACTOR_EN_SB:
|
||||||
case ACTOR_EN_NY:
|
case ACTOR_EN_NY:
|
||||||
return (!(!isMQ && sceneNum == SCENE_WATER_TEMPLE && roomNum == 2));
|
return (!(!isMQ && sceneNum == SCENE_WATER_TEMPLE && roomNum == 2));
|
||||||
|
case ACTOR_EN_SKJ:
|
||||||
|
return !(sceneNum == SCENE_LOST_WOODS && LINK_IS_CHILD);
|
||||||
default:
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -419,19 +449,19 @@ bool IsEnemyFoundToRandomize(int16_t sceneNum, int8_t roomNum, int16_t actorId,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IsEnemyAllowedToSpawn(int16_t sceneNum, int8_t roomNum, EnemyEntry enemy) {
|
bool IsEnemyAllowedToSpawn(int16_t sceneNum, int8_t roomNum, EnemyEntry enemy) {
|
||||||
|
|
||||||
uint32_t isMQ = ResourceMgr_IsSceneMasterQuest(sceneNum);
|
uint32_t isMQ = ResourceMgr_IsSceneMasterQuest(sceneNum);
|
||||||
|
|
||||||
// Freezard - Child Link can only kill this with jump slash Deku Sticks or other equipment like bombs.
|
// Freezard - Child Link can only kill this with jump slash Deku Sticks or other equipment like bombs.
|
||||||
// Beamos - Needs bombs.
|
// Beamos - Needs bombs.
|
||||||
|
// Anubis - Needs fire.
|
||||||
// Shell Blade & Spike - Child Link can't kill these with sword or Deku Stick.
|
// Shell Blade & Spike - Child Link can't kill these with sword or Deku Stick.
|
||||||
// Arwing & Dark Link - Both go out of bounds way too easily, softlocking the player.
|
// Flare dancer, Arwing & Dark Link - Both go out of bounds way too easily, softlocking the player.
|
||||||
// Wallmaster - Not easily visible, often makes players think they're softlocked and that there's no enemies left.
|
// Wallmaster - Not easily visible, often makes players think they're softlocked and that there's no enemies left.
|
||||||
// Club Moblin - Many issues with them falling or placing out of bounds. Maybe fixable in the future?
|
// Club Moblin - Many issues with them falling or placing out of bounds. Maybe fixable in the future?
|
||||||
bool enemiesToExcludeClearRooms = enemy.id == ACTOR_EN_FZ || enemy.id == ACTOR_EN_VM || enemy.id == ACTOR_EN_SB ||
|
bool enemiesToExcludeClearRooms =
|
||||||
enemy.id == ACTOR_EN_NY || enemy.id == ACTOR_EN_CLEAR_TAG ||
|
enemy.id == ACTOR_EN_FZ || enemy.id == ACTOR_EN_VM || enemy.id == ACTOR_EN_SB || enemy.id == ACTOR_EN_NY ||
|
||||||
enemy.id == ACTOR_EN_WALLMAS || enemy.id == ACTOR_EN_TORCH2 ||
|
enemy.id == ACTOR_EN_CLEAR_TAG || enemy.id == ACTOR_EN_WALLMAS || enemy.id == ACTOR_EN_TORCH2 ||
|
||||||
enemy.id == ACTOR_EN_MB;
|
(enemy.id == ACTOR_EN_MB && enemy.params == 0) || enemy.id == ACTOR_EN_FD || enemy.id == ACTOR_EN_ANUBICE_TAG;
|
||||||
|
|
||||||
// Bari - Spawns 3 more enemies, potentially extremely difficult in timed rooms.
|
// Bari - Spawns 3 more enemies, potentially extremely difficult in timed rooms.
|
||||||
bool enemiesToExcludeTimedRooms = enemiesToExcludeClearRooms || enemy.id == ACTOR_EN_VALI;
|
bool enemiesToExcludeTimedRooms = enemiesToExcludeClearRooms || enemy.id == ACTOR_EN_VALI;
|
||||||
@@ -532,3 +562,16 @@ bool IsEnemyAllowedToSpawn(int16_t sceneNum, int8_t roomNum, EnemyEntry enemy) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FixClubMoblinScale(void* ptr) {
|
||||||
|
Actor* actor = (Actor*)ptr;
|
||||||
|
if (actor->params == -1) {
|
||||||
|
Actor_SetScale(actor, 0.014f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterEnemyRandomizer() {
|
||||||
|
COND_ID_HOOK(OnActorInit, ACTOR_EN_MB, CVAR_ENEMY_RANDOMIZER_VALUE, FixClubMoblinScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
static RegisterShipInitFunc initFunc(RegisterEnemyRandomizer, { CVAR_ENEMY_RANDOMIZER_NAME });
|
||||||
@@ -1,23 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <libultraship/bridge.h>
|
#include <libultraship/libultra/types.h>
|
||||||
|
|
||||||
typedef struct EnemyEntry {
|
#define RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE 52
|
||||||
int16_t id;
|
|
||||||
int16_t params;
|
|
||||||
} EnemyEntry;
|
|
||||||
|
|
||||||
#define RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE 49
|
|
||||||
|
|
||||||
bool IsEnemyFoundToRandomize(int16_t sceneNum, int8_t roomNum, int16_t actorId, int16_t params, float posX);
|
|
||||||
bool IsEnemyAllowedToSpawn(int16_t sceneNum, int8_t roomNum, EnemyEntry enemy);
|
|
||||||
EnemyEntry GetRandomizedEnemyEntry(uint32_t seed);
|
|
||||||
|
|
||||||
extern const char* enemyCVarList[];
|
extern const char* enemyCVarList[];
|
||||||
extern const char* enemyNameList[];
|
extern const char* enemyNameList[];
|
||||||
extern void GetSelectedEnemies();
|
extern void GetSelectedEnemies();
|
||||||
|
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
uint8_t GetRandomizedEnemy(PlayState* play, int16_t* actorId, f32* posX, f32* posY, f32* posZ, int16_t* rotX,
|
struct PlayState;
|
||||||
|
|
||||||
|
uint8_t GetRandomizedEnemy(struct PlayState* play, int16_t* actorId, f32* posX, f32* posY, f32* posZ, int16_t* rotX,
|
||||||
int16_t* rotY, int16_t* rotZ, int16_t* params);
|
int16_t* rotY, int16_t* rotZ, int16_t* params);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,6 +20,14 @@ typedef enum {
|
|||||||
// - `int32_t` (entrance index) (promoted from `uint16_t` by va_arg)
|
// - `int32_t` (entrance index) (promoted from `uint16_t` by va_arg)
|
||||||
VB_ALLOW_ENTRANCE_CS_FOR_EITHER_AGE,
|
VB_ALLOW_ENTRANCE_CS_FOR_EITHER_AGE,
|
||||||
|
|
||||||
|
// #### `result`
|
||||||
|
// ```c
|
||||||
|
// sBgPoEventPuzzleState == 0xF
|
||||||
|
// ```
|
||||||
|
// #### `args`
|
||||||
|
// - None
|
||||||
|
VB_AMY_SOLVE,
|
||||||
|
|
||||||
// #### `result`
|
// #### `result`
|
||||||
// ```c
|
// ```c
|
||||||
// this->actor.textId == 0x401A
|
// this->actor.textId == 0x401A
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ extern PlayState* gPlayState;
|
|||||||
#include "src/overlays/actors/ovl_En_Door/z_en_door.h"
|
#include "src/overlays/actors/ovl_En_Door/z_en_door.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
|
|
||||||
|
|
||||||
using SceneDoorParamsPair = std::pair<int, int>;
|
using SceneDoorParamsPair = std::pair<int, int>;
|
||||||
std::map<SceneDoorParamsPair, RandomizerInf> lookupTable = {
|
std::map<SceneDoorParamsPair, RandomizerInf> lookupTable = {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play);
|
|||||||
void ObjComb_RandomizerChooseItemDrop(ObjComb* objComb, PlayState* play) {
|
void ObjComb_RandomizerChooseItemDrop(ObjComb* objComb, PlayState* play) {
|
||||||
s16 params = objComb->actor.params & 0x1F;
|
s16 params = objComb->actor.params & 0x1F;
|
||||||
|
|
||||||
if (Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_BEEHIVES).Get() &&
|
if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && !Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf)) {
|
||||||
!Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf)) {
|
|
||||||
EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &objComb->actor.world.pos, ITEM00_SOH_DUMMY);
|
EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &objComb->actor.world.pos, ITEM00_SOH_DUMMY);
|
||||||
item00->randoInf = objComb->beehiveIdentity.randomizerInf;
|
item00->randoInf = objComb->beehiveIdentity.randomizerInf;
|
||||||
item00->itemEntry =
|
item00->itemEntry =
|
||||||
@@ -41,8 +40,7 @@ void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) {
|
|||||||
s32 dmgFlags;
|
s32 dmgFlags;
|
||||||
|
|
||||||
objComb->unk_1B0 -= 50;
|
objComb->unk_1B0 -= 50;
|
||||||
if (Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_BEEHIVES).Get() &&
|
if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && !Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf)) {
|
||||||
!Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf)) {
|
|
||||||
if (objComb->unk_1B0 <= -5000) {
|
if (objComb->unk_1B0 <= -5000) {
|
||||||
objComb->unk_1B0 = 1500;
|
objComb->unk_1B0 = 1500;
|
||||||
}
|
}
|
||||||
@@ -85,7 +83,7 @@ void ObjComb_RandomizerUpdate(void* actor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RegisterShuffleBeehives() {
|
void RegisterShuffleBeehives() {
|
||||||
bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_BEEHIVES).Get();
|
bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES);
|
||||||
|
|
||||||
COND_ID_HOOK(OnActorInit, ACTOR_OBJ_COMB, shouldRegister, ObjComb_RandomizerInit);
|
COND_ID_HOOK(OnActorInit, ACTOR_OBJ_COMB, shouldRegister, ObjComb_RandomizerInit);
|
||||||
COND_ID_HOOK(OnActorUpdate, ACTOR_OBJ_COMB, shouldRegister, ObjComb_RandomizerUpdate);
|
COND_ID_HOOK(OnActorUpdate, ACTOR_OBJ_COMB, shouldRegister, ObjComb_RandomizerUpdate);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ void EnCow_MoveForRandomizer(EnCow* enCow, PlayState* play) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RegisterShuffleCows() {
|
void RegisterShuffleCows() {
|
||||||
bool shouldRegister = IS_RANDO && Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_COWS).Get();
|
bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_COWS);
|
||||||
|
|
||||||
COND_VB_SHOULD(VB_GIVE_ITEM_FROM_COW, shouldRegister, {
|
COND_VB_SHOULD(VB_GIVE_ITEM_FROM_COW, shouldRegister, {
|
||||||
EnCow* enCow = va_arg(args, EnCow*);
|
EnCow* enCow = va_arg(args, EnCow*);
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ extern "C" {
|
|||||||
extern PlayState* gPlayState;
|
extern PlayState* gPlayState;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
|
|
||||||
|
|
||||||
extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play);
|
extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play);
|
||||||
|
|
||||||
extern "C" void ObjKibako2_RandomizerDraw(Actor* thisx, PlayState* play) {
|
extern "C" void ObjKibako2_RandomizerDraw(Actor* thisx, PlayState* play) {
|
||||||
@@ -158,7 +156,7 @@ extern "C" void ObjKibako_RandomizerDraw(Actor* thisx, PlayState* play) {
|
|||||||
uint8_t ObjKibako2_RandomizerHoldsItem(ObjKibako2* crateActor, PlayState* play) {
|
uint8_t ObjKibako2_RandomizerHoldsItem(ObjKibako2* crateActor, PlayState* play) {
|
||||||
RandomizerCheck rc = crateActor->crateIdentity.randomizerCheck;
|
RandomizerCheck rc = crateActor->crateIdentity.randomizerCheck;
|
||||||
uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon();
|
uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon();
|
||||||
uint8_t crateSetting = Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_CRATES).Get();
|
uint8_t crateSetting = RAND_GET_OPTION(RSK_SHUFFLE_CRATES);
|
||||||
|
|
||||||
// Don't pull randomized item if crate isn't randomized or is already checked
|
// Don't pull randomized item if crate isn't randomized or is already checked
|
||||||
if (!IS_RANDO || (crateSetting == RO_SHUFFLE_CRATES_OVERWORLD && isDungeon) ||
|
if (!IS_RANDO || (crateSetting == RO_SHUFFLE_CRATES_OVERWORLD && isDungeon) ||
|
||||||
@@ -174,7 +172,7 @@ uint8_t ObjKibako2_RandomizerHoldsItem(ObjKibako2* crateActor, PlayState* play)
|
|||||||
uint8_t ObjKibako_RandomizerHoldsItem(ObjKibako* smallCrateActor, PlayState* play) {
|
uint8_t ObjKibako_RandomizerHoldsItem(ObjKibako* smallCrateActor, PlayState* play) {
|
||||||
RandomizerCheck rc = smallCrateActor->smallCrateIdentity.randomizerCheck;
|
RandomizerCheck rc = smallCrateActor->smallCrateIdentity.randomizerCheck;
|
||||||
uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon();
|
uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon();
|
||||||
uint8_t crateSetting = Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_CRATES).Get();
|
uint8_t crateSetting = RAND_GET_OPTION(RSK_SHUFFLE_CRATES);
|
||||||
|
|
||||||
// Don't pull randomized item if crate isn't randomized or is already checked
|
// Don't pull randomized item if crate isn't randomized or is already checked
|
||||||
if (!IS_RANDO || (crateSetting == RO_SHUFFLE_CRATES_OVERWORLD && isDungeon) ||
|
if (!IS_RANDO || (crateSetting == RO_SHUFFLE_CRATES_OVERWORLD && isDungeon) ||
|
||||||
@@ -211,7 +209,7 @@ void ObjKibako_RandomizerSpawnCollectible(ObjKibako* smallCrateActor, PlayState*
|
|||||||
|
|
||||||
void ObjKibako2_RandomizerInit(void* actorRef) {
|
void ObjKibako2_RandomizerInit(void* actorRef) {
|
||||||
Actor* actor = static_cast<Actor*>(actorRef);
|
Actor* actor = static_cast<Actor*>(actorRef);
|
||||||
uint8_t logicSetting = Rando::Context::GetInstance()->GetOption(RSK_LOGIC_RULES).Get();
|
uint8_t logicSetting = RAND_GET_OPTION(RSK_LOGIC_RULES);
|
||||||
|
|
||||||
// don't shuffle two OOB crates in GF and don't shuffle child GV/GF crates when not in no logic
|
// don't shuffle two OOB crates in GF and don't shuffle child GV/GF crates when not in no logic
|
||||||
if (actor->id != ACTOR_OBJ_KIBAKO2 ||
|
if (actor->id != ACTOR_OBJ_KIBAKO2 ||
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ void ShuffleFreestanding_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* sh
|
|||||||
Rando::Location* loc =
|
Rando::Location* loc =
|
||||||
OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(item00->actor.id, gPlayState->sceneNum, params);
|
OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(item00->actor.id, gPlayState->sceneNum, params);
|
||||||
uint8_t isDungeon = loc->IsDungeon();
|
uint8_t isDungeon = loc->IsDungeon();
|
||||||
uint8_t freestandingSetting = Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_FREESTANDING).Get();
|
uint8_t freestandingSetting = RAND_GET_OPTION(RSK_SHUFFLE_FREESTANDING);
|
||||||
RandomizerCheck randomizerCheck = loc->GetRandomizerCheck();
|
RandomizerCheck randomizerCheck = loc->GetRandomizerCheck();
|
||||||
bool checkObtained = Rando::Context::GetInstance()->GetItemLocation(randomizerCheck)->HasObtained();
|
bool checkObtained = Rando::Context::GetInstance()->GetItemLocation(randomizerCheck)->HasObtained();
|
||||||
|
|
||||||
|
|||||||
@@ -11,8 +11,6 @@ extern "C" {
|
|||||||
extern PlayState* gPlayState;
|
extern PlayState* gPlayState;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
|
|
||||||
|
|
||||||
extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play);
|
extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play);
|
||||||
|
|
||||||
void DrawTypeOfGrass(EnKusa* grassActor, Gfx* bushDList, Gfx* grassDList, PlayState* play) {
|
void DrawTypeOfGrass(EnKusa* grassActor, Gfx* bushDList, Gfx* grassDList, PlayState* play) {
|
||||||
@@ -96,7 +94,7 @@ uint8_t EnKusa_RandomizerHoldsItem(EnKusa* grassActor, PlayState* play) {
|
|||||||
RandomizerCheck rc = grassActor->grassIdentity.randomizerCheck;
|
RandomizerCheck rc = grassActor->grassIdentity.randomizerCheck;
|
||||||
|
|
||||||
uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon();
|
uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon();
|
||||||
uint8_t grassSetting = Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_GRASS).Get();
|
uint8_t grassSetting = RAND_GET_OPTION(RSK_SHUFFLE_GRASS);
|
||||||
|
|
||||||
// Don't pull randomized item if grass isn't randomized or is already checked
|
// Don't pull randomized item if grass isn't randomized or is already checked
|
||||||
if (!IS_RANDO || (grassSetting == RO_SHUFFLE_GRASS_OVERWORLD && isDungeon) ||
|
if (!IS_RANDO || (grassSetting == RO_SHUFFLE_GRASS_OVERWORLD && isDungeon) ||
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ extern "C" void ObjTsubo_RandomizerDraw(Actor* thisx, PlayState* play) {
|
|||||||
uint8_t ObjTsubo_RandomizerHoldsItem(ObjTsubo* potActor, PlayState* play) {
|
uint8_t ObjTsubo_RandomizerHoldsItem(ObjTsubo* potActor, PlayState* play) {
|
||||||
RandomizerCheck rc = potActor->potIdentity.randomizerCheck;
|
RandomizerCheck rc = potActor->potIdentity.randomizerCheck;
|
||||||
uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon();
|
uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon();
|
||||||
uint8_t potSetting = Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_POTS).Get();
|
uint8_t potSetting = RAND_GET_OPTION(RSK_SHUFFLE_POTS);
|
||||||
|
|
||||||
// Don't pull randomized item if pot isn't randomized or is already checked
|
// Don't pull randomized item if pot isn't randomized or is already checked
|
||||||
if (!IS_RANDO || (potSetting == RO_SHUFFLE_POTS_OVERWORLD && isDungeon) ||
|
if (!IS_RANDO || (potSetting == RO_SHUFFLE_POTS_OVERWORLD && isDungeon) ||
|
||||||
@@ -85,7 +85,7 @@ void ShufflePots_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va
|
|||||||
// Unlock early Ganon's Boss Key doors to allow access to the pots there when pots are shuffled in dungeon
|
// Unlock early Ganon's Boss Key doors to allow access to the pots there when pots are shuffled in dungeon
|
||||||
if (id == VB_LOCK_BOSS_DOOR) {
|
if (id == VB_LOCK_BOSS_DOOR) {
|
||||||
DoorShutter* doorActor = va_arg(args, DoorShutter*);
|
DoorShutter* doorActor = va_arg(args, DoorShutter*);
|
||||||
uint8_t shufflePotSetting = Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_POTS).Get();
|
uint8_t shufflePotSetting = RAND_GET_OPTION(RSK_SHUFFLE_POTS);
|
||||||
if (gPlayState->sceneNum == SCENE_GANONS_TOWER && doorActor->dyna.actor.world.pos.y == 800 &&
|
if (gPlayState->sceneNum == SCENE_GANONS_TOWER && doorActor->dyna.actor.world.pos.y == 800 &&
|
||||||
(shufflePotSetting == RO_SHUFFLE_POTS_DUNGEONS || shufflePotSetting == RO_SHUFFLE_POTS_ALL)) {
|
(shufflePotSetting == RO_SHUFFLE_POTS_DUNGEONS || shufflePotSetting == RO_SHUFFLE_POTS_ALL)) {
|
||||||
*should = false;
|
*should = false;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Singleton for storing and accessing dynamic Randomizer-related data
|
* @brief Singleton for storing and accessing dynamic Randomizer-related data
|
||||||
|
|||||||
@@ -15,10 +15,6 @@ extern SaveContext gSaveContext;
|
|||||||
extern PlayState* gPlayState;
|
extern PlayState* gPlayState;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FSi OTRGlobals::Instance->gRandoContext->GetFishsanity()
|
|
||||||
|
|
||||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Parallel list of pond fish checks for both ages
|
* @brief Parallel list of pond fish checks for both ages
|
||||||
*/
|
*/
|
||||||
@@ -488,15 +484,15 @@ void Fishsanity::OnItemReceiveHandler(GetItemEntry itemEntry) {
|
|||||||
// C interface
|
// C interface
|
||||||
extern "C" {
|
extern "C" {
|
||||||
bool Randomizer_GetPondFishShuffled() {
|
bool Randomizer_GetPondFishShuffled() {
|
||||||
return FSi->GetPondFishShuffled();
|
return Rando::Context::GetInstance()->GetFishsanity()->GetPondFishShuffled();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Randomizer_GetOverworldFishShuffled() {
|
bool Randomizer_GetOverworldFishShuffled() {
|
||||||
return FSi->GetOverworldFishShuffled();
|
return Rando::Context::GetInstance()->GetFishsanity()->GetOverworldFishShuffled();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Randomizer_IsAdultPond() {
|
bool Randomizer_IsAdultPond() {
|
||||||
return FSi->IsAdultPond();
|
return Rando::Context::GetInstance()->GetFishsanity()->IsAdultPond();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fishsanity_DrawEffShadow(Actor* actor, Lights* lights, PlayState* play) {
|
void Fishsanity_DrawEffShadow(Actor* actor, Lights* lights, PlayState* play) {
|
||||||
|
|||||||
@@ -72,8 +72,6 @@ extern void EnGe1_Wait_Archery(EnGe1* enGe1, PlayState* play);
|
|||||||
extern void EnGe1_SetAnimationIdle(EnGe1* enGe1);
|
extern void EnGe1_SetAnimationIdle(EnGe1* enGe1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
|
|
||||||
|
|
||||||
bool LocMatchesQuest(Rando::Location loc) {
|
bool LocMatchesQuest(Rando::Location loc) {
|
||||||
if (loc.GetQuest() == RCQUEST_BOTH) {
|
if (loc.GetQuest() == RCQUEST_BOTH) {
|
||||||
return true;
|
return true;
|
||||||
@@ -2225,7 +2223,7 @@ void RandomizerOnActorUpdateHandler(void* refActor) {
|
|||||||
shutterDoor->unk_16E = 0;
|
shutterDoor->unk_16E = 0;
|
||||||
}
|
}
|
||||||
} else if (actor->id == ACTOR_DOOR_GERUDO) {
|
} else if (actor->id == ACTOR_DOOR_GERUDO) {
|
||||||
DoorGerudo* gerudoDoor = (DoorGerudo*)actor;
|
DoorGerudo* gerudoDoor = reinterpret_cast<DoorGerudo*>(actor);
|
||||||
gerudoDoor->actionFunc = func_8099485C;
|
gerudoDoor->actionFunc = func_8099485C;
|
||||||
gerudoDoor->dyna.actor.world.pos.y = gerudoDoor->dyna.actor.home.pos.y + 200.0f;
|
gerudoDoor->dyna.actor.world.pos.y = gerudoDoor->dyna.actor.home.pos.y + 200.0f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4398,7 +4398,7 @@ CustomMessage Randomizer::GetFishingPondOwnerMessage(u16 originalTextId) {
|
|||||||
"fischen!",
|
"fischen!",
|
||||||
"Désolé, mais l'étang est fermé.&J'ai perdu ma bonne %rCanne à Pêche%w...&Impossible de pêcher sans elle!");
|
"Désolé, mais l'étang est fermé.&J'ai perdu ma bonne %rCanne à Pêche%w...&Impossible de pêcher sans elle!");
|
||||||
|
|
||||||
if (Rando::Context::GetInstance()->GetOption(RSK_FISHING_POLE_HINT)) {
|
if (GetRandoSettingValue(RSK_FISHING_POLE_HINT)) {
|
||||||
messageEntry = messageEntry + CustomMessage(ctx->GetHint(RH_FISHING_POLE)->GetHintMessage());
|
messageEntry = messageEntry + CustomMessage(ctx->GetHint(RH_FISHING_POLE)->GetHintMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ extern "C" {
|
|||||||
#include "src/overlays/actors/ovl_En_Daiku/z_en_daiku.h"
|
#include "src/overlays/actors/ovl_En_Daiku/z_en_daiku.h"
|
||||||
#include "src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h"
|
#include "src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h"
|
||||||
#include "src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.h"
|
#include "src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.h"
|
||||||
|
#include "src/overlays/actors/ovl_Bg_Spot06_Objects/z_bg_spot06_objects.h"
|
||||||
#include "src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h"
|
#include "src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h"
|
||||||
#include "src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h"
|
#include "src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h"
|
||||||
#include "src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h"
|
#include "src/overlays/actors/ovl_En_Dnt_Demo/z_en_dnt_demo.h"
|
||||||
@@ -49,8 +50,6 @@ extern void EnRu2_SetEncounterSwitchFlag(EnRu2* enRu2, PlayState* play);
|
|||||||
extern void EnDaiku_EscapeSuccess(EnDaiku* enDaiku, PlayState* play);
|
extern void EnDaiku_EscapeSuccess(EnDaiku* enDaiku, PlayState* play);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
|
|
||||||
|
|
||||||
void EnMa1_EndTeachSong(EnMa1* enMa1, PlayState* play) {
|
void EnMa1_EndTeachSong(EnMa1* enMa1, PlayState* play) {
|
||||||
if (Message_GetState(&gPlayState->msgCtx) == TEXT_STATE_CLOSING) {
|
if (Message_GetState(&gPlayState->msgCtx) == TEXT_STATE_CLOSING) {
|
||||||
Flags_SetRandomizerInf(RAND_INF_LEARNED_EPONA_SONG);
|
Flags_SetRandomizerInf(RAND_INF_LEARNED_EPONA_SONG);
|
||||||
@@ -1386,3 +1385,15 @@ void TimeSaverRegisterHooks() {
|
|||||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>(TimeSaverOnItemReceiveHandler);
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>(TimeSaverOnItemReceiveHandler);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegisterSkipWaterTempleGateDelay() {
|
||||||
|
COND_ID_HOOK(OnActorUpdate, ACTOR_BG_SPOT06_OBJECTS,
|
||||||
|
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO), [](void* actor) {
|
||||||
|
BgSpot06Objects* spot06 = static_cast<BgSpot06Objects*>(actor);
|
||||||
|
if (spot06->dyna.actor.params == 0) {
|
||||||
|
spot06->timer = 0;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static RegisterShipInitFunc skipWaterTempleGateDelay(RegisterSkipWaterTempleGateDelay);
|
||||||
|
|||||||
@@ -1312,6 +1312,11 @@ void SohMenu::AddMenuEnhancements() {
|
|||||||
.Format("%d notes")
|
.Format("%d notes")
|
||||||
.Tooltip("Adjust the number of notes you need to play to end the third round."));
|
.Tooltip("Adjust the number of notes you need to play to end the third round."));
|
||||||
|
|
||||||
|
AddWidget(path, "Forest Temple", WIDGET_SEPARATOR_TEXT);
|
||||||
|
AddWidget(path, "Solve Amy's Puzzle", WIDGET_CVAR_CHECKBOX)
|
||||||
|
.CVar(CVAR_ENHANCEMENT("SkipAmyPuzzle"))
|
||||||
|
.Options(CheckboxOptions().Tooltip("Amy's block pushing puzzle instantly solved."));
|
||||||
|
|
||||||
path.column = SECTION_COLUMN_3;
|
path.column = SECTION_COLUMN_3;
|
||||||
AddWidget(path, "Fishing", WIDGET_SEPARATOR_TEXT);
|
AddWidget(path, "Fishing", WIDGET_SEPARATOR_TEXT);
|
||||||
AddWidget(path, "Customize Behavior##Fishing", WIDGET_CVAR_CHECKBOX)
|
AddWidget(path, "Customize Behavior##Fishing", WIDGET_CVAR_CHECKBOX)
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
#include "z_bg_po_event.h"
|
#include "z_bg_po_event.h"
|
||||||
#include "objects/object_po_sisters/object_po_sisters.h"
|
#include "objects/object_po_sisters/object_po_sisters.h"
|
||||||
|
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||||
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
|
||||||
#define FLAGS 0
|
#define FLAGS 0
|
||||||
|
|
||||||
@@ -333,7 +335,7 @@ void BgPoEvent_BlockIdle(BgPoEvent* this, PlayState* play) {
|
|||||||
Player* player = GET_PLAYER(play);
|
Player* player = GET_PLAYER(play);
|
||||||
Actor* amy;
|
Actor* amy;
|
||||||
|
|
||||||
if (sBgPoEventPuzzleState == 0xF) {
|
if (GameInteractor_Should(VB_AMY_SOLVE, sBgPoEventPuzzleState == 0xF)) {
|
||||||
this->actionFunc = BgPoEvent_BlockSolved;
|
this->actionFunc = BgPoEvent_BlockSolved;
|
||||||
if ((this->type == 0) && (this->index == 0)) {
|
if ((this->type == 0) && (this->index == 0)) {
|
||||||
amy = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_PO_SISTERS, this->dyna.actor.world.pos.x + 30.0f,
|
amy = Actor_Spawn(&play->actorCtx, play, ACTOR_EN_PO_SISTERS, this->dyna.actor.world.pos.x + 30.0f,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "z_en_skj.h"
|
#include "z_en_skj.h"
|
||||||
#include "overlays/actors/ovl_En_Skjneedle/z_en_skjneedle.h"
|
#include "overlays/actors/ovl_En_Skjneedle/z_en_skjneedle.h"
|
||||||
#include "objects/object_skj/object_skj.h"
|
#include "objects/object_skj/object_skj.h"
|
||||||
|
#include "soh/Enhancements/enhancementTypes.h"
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
#include "soh/OTRGlobals.h"
|
#include "soh/OTRGlobals.h"
|
||||||
#include "soh/ResourceManagerHelpers.h"
|
#include "soh/ResourceManagerHelpers.h"
|
||||||
@@ -404,7 +405,9 @@ void EnSkj_Init(Actor* thisx, PlayState* play2) {
|
|||||||
default:
|
default:
|
||||||
this->actor.params = type;
|
this->actor.params = type;
|
||||||
if (((this->actor.params != 0) && (this->actor.params != 1)) && (this->actor.params != 2)) {
|
if (((this->actor.params != 0) && (this->actor.params != 1)) && (this->actor.params != 2)) {
|
||||||
if (INV_CONTENT(ITEM_TRADE_ADULT) < ITEM_SAW) {
|
if (INV_CONTENT(ITEM_TRADE_ADULT) < ITEM_SAW &&
|
||||||
|
CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemies"), ENEMY_RANDOMIZER_OFF) ==
|
||||||
|
ENEMY_RANDOMIZER_OFF) {
|
||||||
Actor_Kill(&this->actor);
|
Actor_Kill(&this->actor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1381,7 +1381,8 @@ void FileChoose_UpdateQuestMenu(GameState* thisx) {
|
|||||||
} else {
|
} else {
|
||||||
defaultName = &emptyNameNES;
|
defaultName = &emptyNameNES;
|
||||||
}
|
}
|
||||||
} else { // GAME_REGION_NTSC
|
this->charPage = FS_CHAR_PAGE_HIRA; // Default to Hiragana Keyboard
|
||||||
|
} else { // GAME_REGION_NTSC
|
||||||
defaultName = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? &linkNameNES : &emptyNameNES;
|
defaultName = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? &linkNameNES : &emptyNameNES;
|
||||||
}
|
}
|
||||||
memcpy(Save_GetSaveMetaInfo(this->buttonIndex)->playerName, defaultName, 8);
|
memcpy(Save_GetSaveMetaInfo(this->buttonIndex)->playerName, defaultName, 8);
|
||||||
@@ -1582,7 +1583,8 @@ void FileChoose_UpdateRandomizerMenu(GameState* thisx) {
|
|||||||
} else {
|
} else {
|
||||||
defaultName = &emptyNameNES;
|
defaultName = &emptyNameNES;
|
||||||
}
|
}
|
||||||
} else { // GAME_REGION_NTSC
|
this->charPage = FS_CHAR_PAGE_HIRA; // Default to Hiragana Keyboard
|
||||||
|
} else { // GAME_REGION_NTSC
|
||||||
defaultName = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? &linkNameNES : &emptyNameNES;
|
defaultName = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? &linkNameNES : &emptyNameNES;
|
||||||
}
|
}
|
||||||
memcpy(Save_GetSaveMetaInfo(this->buttonIndex)->playerName, defaultName, 8);
|
memcpy(Save_GetSaveMetaInfo(this->buttonIndex)->playerName, defaultName, 8);
|
||||||
|
|||||||
Reference in New Issue
Block a user