mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-21 05:43:42 -07:00
Merge remote-tracking branch 'origin/develop' into actor-accessibility-experiments
This commit is contained in:
commit
14aa193d8c
36 changed files with 367 additions and 225 deletions
|
@ -266,9 +266,6 @@ typedef struct Actor {
|
||||||
/* 0x134 */ ActorFunc draw; // Draw Routine. Called by `Actor_Draw`
|
/* 0x134 */ ActorFunc draw; // Draw Routine. Called by `Actor_Draw`
|
||||||
/* 0x138 */ ActorResetFunc reset;
|
/* 0x138 */ ActorResetFunc reset;
|
||||||
/* 0x13C */ char dbgPad[0x10]; // Padding that only exists in the debug rom
|
/* 0x13C */ char dbgPad[0x10]; // Padding that only exists in the debug rom
|
||||||
// #region SOH [General]
|
|
||||||
/* */ u8 maximumHealth; // Max health value for use with health bars, set on actor init
|
|
||||||
// #endregion
|
|
||||||
} Actor; // size = 0x14C
|
} Actor; // size = 0x14C
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
19
soh/soh/Enhancements/CuccosToReturn.cpp
Normal file
19
soh/soh/Enhancements/CuccosToReturn.cpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
#include "soh/ShipInit.hpp"
|
||||||
|
#include "soh/Enhancements/randomizer/context.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
extern PlayState* gPlayState;
|
||||||
|
#include "src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterCuccosToReturn() {
|
||||||
|
COND_VB_SHOULD(VB_SET_CUCCO_COUNT, CVarGetInteger(CVAR_ENHANCEMENT("CuccosToReturn"), 7) != 7, {
|
||||||
|
EnNiwLady* enNiwLady = va_arg(args, EnNiwLady*);
|
||||||
|
// Override starting Cucco count using setting value
|
||||||
|
enNiwLady->cuccosInPen = 7 - CVarGetInteger(CVAR_ENHANCEMENT("CuccosToReturn"), 7);
|
||||||
|
*should = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static RegisterShipInitFunc initFunc(RegisterCuccosToReturn, { CVAR_ENHANCEMENT("CuccosToReturn") });
|
|
@ -110,6 +110,7 @@ void applyPreset(std::string presetName, std::vector<PresetSection> includeSecti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ShipInit::InitAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawPresetSelector(std::vector<PresetSection> includeSections, std::string presetLoc, bool disabled) {
|
void DrawPresetSelector(std::vector<PresetSection> includeSections, std::string presetLoc, bool disabled) {
|
||||||
|
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
31
soh/soh/Enhancements/TreesDropSticks.cpp
Normal file
31
soh/soh/Enhancements/TreesDropSticks.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
#include "soh/ShipInit.hpp"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include "src/overlays/actors/ovl_En_Wood02/z_en_wood02.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
extern PlayState* gPlayState;
|
||||||
|
|
||||||
|
void RegisterTreesDropSticks() {
|
||||||
|
COND_VB_SHOULD(VB_TREE_DROP_COLLECTIBLE, CVarGetInteger(CVAR_ENHANCEMENT("TreesDropSticks"), 0), {
|
||||||
|
if (INV_CONTENT(ITEM_STICK) != ITEM_NONE) {
|
||||||
|
EnWood02* tree = va_arg(args, EnWood02*);
|
||||||
|
Vec3f dropsSpawnPt = tree->actor.world.pos;
|
||||||
|
dropsSpawnPt.y += 200.0f;
|
||||||
|
|
||||||
|
*should = false;
|
||||||
|
for (s32 numDrops = Rand_Next() % 4; numDrops > 0; numDrops--) {
|
||||||
|
Item_DropCollectible(gPlayState, &dropsSpawnPt, ITEM00_STICK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
COND_VB_SHOULD(VB_PREVENT_ADULT_STICK, CVarGetInteger(CVAR_ENHANCEMENT("TreesDropSticks"), 0), {
|
||||||
|
if (INV_CONTENT(ITEM_STICK) != ITEM_NONE) {
|
||||||
|
*should = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static RegisterShipInitFunc initFunc(RegisterTreesDropSticks, { CVAR_ENHANCEMENT("TreesDropSticks") });
|
|
@ -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,6 +114,7 @@ const char* enemyNameList[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static EnemyEntry randomizedEnemySpawnTable[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] = {
|
static EnemyEntry randomizedEnemySpawnTable[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] = {
|
||||||
|
{ ACTOR_EN_ANUBICE_TAG, 1 }, // Anubis
|
||||||
{ ACTOR_EN_AM, -1 }, // Armos
|
{ ACTOR_EN_AM, -1 }, // Armos
|
||||||
{ ACTOR_EN_CLEAR_TAG, 1 }, // Arwing
|
{ ACTOR_EN_CLEAR_TAG, 1 }, // Arwing
|
||||||
{ ACTOR_EN_DODOJR, 0 }, // Baby Dodongo
|
{ ACTOR_EN_DODOJR, 0 }, // Baby Dodongo
|
||||||
|
@ -105,11 +126,13 @@ static EnemyEntry randomizedEnemySpawnTable[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] =
|
||||||
{ ACTOR_EN_IK, 2 }, // Iron Knuckle (black, standing)
|
{ ACTOR_EN_IK, 2 }, // Iron Knuckle (black, standing)
|
||||||
{ ACTOR_EN_TITE, -2 }, // Tektite (blue)
|
{ ACTOR_EN_TITE, -2 }, // Tektite (blue)
|
||||||
{ ACTOR_EN_BB, -1 }, // Bubble (flying skull enemy) (blue)
|
{ ACTOR_EN_BB, -1 }, // Bubble (flying skull enemy) (blue)
|
||||||
{ ACTOR_EN_MB, 0 }, // Moblins (Club)
|
{ ACTOR_EN_MB, 0 }, // Club Moblin
|
||||||
{ ACTOR_EN_TORCH2, 0 }, // Dark Link
|
{ ACTOR_EN_TORCH2, 0 }, // Dark Link
|
||||||
{ ACTOR_EN_ZF, -2 }, // Dinolfos
|
{ ACTOR_EN_ZF, -2 }, // Dinolfos
|
||||||
{ ACTOR_EN_DODONGO, -1 }, // Dodongo
|
{ ACTOR_EN_DODONGO, -1 }, // Dodongo
|
||||||
{ ACTOR_EN_FIREFLY, 1 }, // Fire Keese
|
{ ACTOR_EN_FIREFLY, 1 }, // Fire Keese
|
||||||
|
// { ACTOR_EN_FD, 0 }, // Flare Dancer (possible cause of crashes because of spawning flame actors on
|
||||||
|
// sloped ground)
|
||||||
{ ACTOR_EN_YUKABYUN, 0 }, // Flying Floor Tile
|
{ ACTOR_EN_YUKABYUN, 0 }, // Flying Floor Tile
|
||||||
{ ACTOR_EN_FLOORMAS, 0 }, // Floormaster
|
{ ACTOR_EN_FLOORMAS, 0 }, // Floormaster
|
||||||
{ ACTOR_EN_PEEHAT, -1 }, // Flying Peahat (big grounded, doesn't spawn larva)
|
{ ACTOR_EN_PEEHAT, -1 }, // Flying Peahat (big grounded, doesn't spawn larva)
|
||||||
|
@ -122,18 +145,30 @@ static EnemyEntry randomizedEnemySpawnTable[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] =
|
||||||
{ ACTOR_EN_ST, 2 }, // Skulltula (invisible)
|
{ ACTOR_EN_ST, 2 }, // Skulltula (invisible)
|
||||||
{ ACTOR_EN_FIREFLY, 2 }, // Regular Keese
|
{ ACTOR_EN_FIREFLY, 2 }, // Regular Keese
|
||||||
{ ACTOR_EN_DEKUBABA, 1 }, // Deku Baba (large)
|
{ 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)
|
||||||
|
// Doesn't work (actor directly uses water box collision to handle hiding/popping up)
|
||||||
|
// { ACTOR_EN_OKUTA, 0 }, // Octorok
|
||||||
{ ACTOR_EN_PEEHAT, 1 }, // Flying Peahat Larva
|
{ ACTOR_EN_PEEHAT, 1 }, // Flying Peahat Larva
|
||||||
|
// Doesn't work (Seems to rely on other objects?)
|
||||||
|
// { ACTOR_EN_POH, 0 }, // Poe
|
||||||
|
// Doesn't work (Seems to rely on other objects?)
|
||||||
|
// { ACTOR_EN_POH, 2 }, // Poe (composer Sharp)
|
||||||
|
// Doesn't work (Seems to rely on other objects?)
|
||||||
|
// { ACTOR_EN_POH, 3 }, // Poe (composer Flat)
|
||||||
{ ACTOR_EN_RD, 1 }, // Redead (standing)
|
{ ACTOR_EN_RD, 1 }, // Redead (standing)
|
||||||
{ ACTOR_EN_TITE, -1 }, // Tektite (red)
|
{ ACTOR_EN_TITE, -1 }, // Tektite (red)
|
||||||
{ ACTOR_EN_BUBBLE, 0 }, // Shabom (bubble)
|
{ ACTOR_EN_BUBBLE, 0 }, // Shabom (bubble)
|
||||||
{ ACTOR_EN_SB, 0 }, // Shell Blade
|
{ ACTOR_EN_SB, 0 }, // Shell Blade
|
||||||
{ ACTOR_EN_ST, 0 }, // Skulltula (normal)
|
{ ACTOR_EN_ST, 0 }, // Skulltula (normal)
|
||||||
|
{ ACTOR_EN_SKJ, 4159 }, // Skull Kid
|
||||||
{ ACTOR_EN_DEKUBABA, 0 }, // Deku Baba (small)
|
{ ACTOR_EN_DEKUBABA, 0 }, // Deku Baba (small)
|
||||||
{ ACTOR_EN_SKB, 1 }, // Stalchild (small)
|
{ ACTOR_EN_SKB, 1 }, // Stalchild (small)
|
||||||
|
{ ACTOR_EN_MB, -1 }, // Spear Moblin
|
||||||
{ ACTOR_EN_NY, 0 }, // Spike (rolling enemy)
|
{ ACTOR_EN_NY, 0 }, // Spike (rolling enemy)
|
||||||
{ ACTOR_EN_TEST, 2 }, // Stalfos
|
{ ACTOR_EN_TEST, 2 }, // Stalfos
|
||||||
{ ACTOR_EN_EIYER, 10 }, // Stinger (land) (One in formation, sink under floor and do not activate)
|
{ ACTOR_EN_EIYER, 10 }, // Stinger (land) (One in formation, sink under floor and do not activate)
|
||||||
|
@ -143,17 +178,10 @@ static EnemyEntry randomizedEnemySpawnTable[RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE] =
|
||||||
{ ACTOR_EN_IK, 3 }, // Iron Knuckle (white, standing)
|
{ ACTOR_EN_IK, 3 }, // Iron Knuckle (white, standing)
|
||||||
{ ACTOR_EN_WF, 1 }, // Wolfos (white)
|
{ ACTOR_EN_WF, 1 }, // Wolfos (white)
|
||||||
{ ACTOR_EN_KAREBABA, 0 }, // Withered Deku Baba
|
{ ACTOR_EN_KAREBABA, 0 }, // Withered Deku Baba
|
||||||
|
|
||||||
// Doesn't work {ACTOR_EN_POH, 0}, // Poe (Seems to rely on other objects?)
|
|
||||||
// Doesn't work {ACTOR_EN_POH, 2}, // Poe (composer Sharp) (Seems to rely on other objects?)
|
|
||||||
// Doesn't work {ACTOR_EN_POH, 3}, // Poe (composer Flat) (Seems to rely on other objects?)
|
|
||||||
// Doesn't work {ACTOR_EN_OKUTA, 0}, // Octorok (actor directly uses water box collision to handle hiding/popping
|
|
||||||
// up) Doesn't work {ACTOR_EN_REEBA, 0}, // Leever (reliant on surface and also normally used in tandem with a
|
|
||||||
// leever spawner, kills itself too quickly otherwise) Kinda doesn't work { ACTOR_EN_FD, 0 }, // Flare Dancer (jumps
|
|
||||||
// out of bounds a lot, and possible cause of crashes because of spawning a ton of flame actors)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int enemiesToRandomize[] = {
|
static int enemiesToRandomize[] = {
|
||||||
|
ACTOR_EN_ANUBICE_TAG, // Anubis
|
||||||
ACTOR_EN_FIREFLY, // Keese (including fire/ice)
|
ACTOR_EN_FIREFLY, // Keese (including fire/ice)
|
||||||
ACTOR_EN_TEST, // Stalfos
|
ACTOR_EN_TEST, // Stalfos
|
||||||
ACTOR_EN_TITE, // Tektite
|
ACTOR_EN_TITE, // Tektite
|
||||||
|
@ -161,7 +189,7 @@ static int enemiesToRandomize[] = {
|
||||||
ACTOR_EN_OKUTA, // Octorok
|
ACTOR_EN_OKUTA, // Octorok
|
||||||
ACTOR_EN_WALLMAS, // Wallmaster
|
ACTOR_EN_WALLMAS, // Wallmaster
|
||||||
ACTOR_EN_DODONGO, // Dodongo
|
ACTOR_EN_DODONGO, // Dodongo
|
||||||
// ACTOR_EN_REEBA, // Leever (reliant on spawner (z_e_encount1.c)
|
// ACTOR_EN_REEBA, // Leever (reliant on spawner (z_en_encount1.c))
|
||||||
ACTOR_EN_PEEHAT, // Flying Peahat, big one spawning larva, larva
|
ACTOR_EN_PEEHAT, // Flying Peahat, big one spawning larva, larva
|
||||||
ACTOR_EN_ZF, // Lizalfos, Dinolfos
|
ACTOR_EN_ZF, // Lizalfos, Dinolfos
|
||||||
ACTOR_EN_GOMA, // Gohma Larva (normal, eggs, gohma eggs)
|
ACTOR_EN_GOMA, // Gohma Larva (normal, eggs, gohma eggs)
|
||||||
|
@ -184,8 +212,7 @@ static int enemiesToRandomize[] = {
|
||||||
ACTOR_EN_FLOORMAS, // Floormaster
|
ACTOR_EN_FLOORMAS, // Floormaster
|
||||||
ACTOR_EN_RD, // Redead, Gibdo
|
ACTOR_EN_RD, // Redead, Gibdo
|
||||||
ACTOR_EN_SW, // Skullwalltula
|
ACTOR_EN_SW, // Skullwalltula
|
||||||
// ACTOR_EN_FD, // Flare Dancer (can be randomized, but not randomized to, so keeping it in vanilla locations
|
ACTOR_EN_FD, // Flare Dancer
|
||||||
// means it at least shows up in the game)
|
|
||||||
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
|
||||||
|
@ -1689,6 +1697,15 @@ typedef enum {
|
||||||
// - `*ObjTsubo`
|
// - `*ObjTsubo`
|
||||||
VB_POT_SETUP_DRAW,
|
VB_POT_SETUP_DRAW,
|
||||||
|
|
||||||
|
// #### `result`
|
||||||
|
// ```c
|
||||||
|
// dropId == ITEM00_STICK
|
||||||
|
// ```
|
||||||
|
// #### `args`
|
||||||
|
// - None
|
||||||
|
VB_PREVENT_ADULT_STICK,
|
||||||
|
|
||||||
|
// #### `result`
|
||||||
// #### `result`
|
// #### `result`
|
||||||
// ```c
|
// ```c
|
||||||
// true
|
// true
|
||||||
|
@ -2065,6 +2082,13 @@ typedef enum {
|
||||||
VB_TRANSITION_TO_SAVE_SCREEN_ON_DEATH,
|
VB_TRANSITION_TO_SAVE_SCREEN_ON_DEATH,
|
||||||
|
|
||||||
// #### `result`
|
// #### `result`
|
||||||
|
// ```c
|
||||||
|
// true
|
||||||
|
// ```
|
||||||
|
// #### `args`
|
||||||
|
// - `*EnWood02`
|
||||||
|
VB_TREE_DROP_COLLECTIBLE,
|
||||||
|
|
||||||
// ```c
|
// ```c
|
||||||
// true
|
// true
|
||||||
// ```
|
// ```
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#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) {
|
||||||
|
|
|
@ -71,8 +71,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;
|
||||||
|
@ -927,13 +925,6 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
||||||
*should = Flags_GetRandomizerInf(RAND_INF_LEARNED_EPONA_SONG);
|
*should = Flags_GetRandomizerInf(RAND_INF_LEARNED_EPONA_SONG);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VB_SET_CUCCO_COUNT: {
|
|
||||||
EnNiwLady* enNiwLady = va_arg(args, EnNiwLady*);
|
|
||||||
// Override starting Cucco count using setting value
|
|
||||||
enNiwLady->cuccosInPen = 7 - RAND_GET_OPTION(RSK_CUCCO_COUNT);
|
|
||||||
*should = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case VB_KING_ZORA_THANK_CHILD: {
|
case VB_KING_ZORA_THANK_CHILD: {
|
||||||
// Allow turning in Ruto's letter even if you have already rescued her
|
// Allow turning in Ruto's letter even if you have already rescued her
|
||||||
if (!Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) {
|
if (!Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)) {
|
||||||
|
@ -2144,7 +2135,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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -595,7 +595,6 @@ void Settings::CreateOptionDescriptions() {
|
||||||
"\n"
|
"\n"
|
||||||
"Greg as Wildcard - Greg does not change logic, Greg helps obtain GBK, max number of "
|
"Greg as Wildcard - Greg does not change logic, Greg helps obtain GBK, max number of "
|
||||||
"rewards on slider does not change.";
|
"rewards on slider does not change.";
|
||||||
mOptionDescriptions[RSK_CUCCO_COUNT] = "The amount of cuccos needed to claim the reward from Anju the Cucco Lady.";
|
|
||||||
mOptionDescriptions[RSK_BIG_POE_COUNT] = "The Poe collector will give a reward for turning in this many Big Poes.";
|
mOptionDescriptions[RSK_BIG_POE_COUNT] = "The Poe collector will give a reward for turning in this many Big Poes.";
|
||||||
mOptionDescriptions[RSK_SKIP_CHILD_STEALTH] =
|
mOptionDescriptions[RSK_SKIP_CHILD_STEALTH] =
|
||||||
"The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards.";
|
"The crawlspace into Hyrule Castle goes straight to Zelda, skipping the guards.";
|
||||||
|
|
|
@ -4393,7 +4393,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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5805,7 +5805,6 @@ typedef enum {
|
||||||
RSK_STARTING_NUTS,
|
RSK_STARTING_NUTS,
|
||||||
RSK_FULL_WALLETS,
|
RSK_FULL_WALLETS,
|
||||||
RSK_SHUFFLE_CHEST_MINIGAME,
|
RSK_SHUFFLE_CHEST_MINIGAME,
|
||||||
RSK_CUCCO_COUNT,
|
|
||||||
RSK_BIG_POE_COUNT,
|
RSK_BIG_POE_COUNT,
|
||||||
RSK_SKIP_EPONA_RACE,
|
RSK_SKIP_EPONA_RACE,
|
||||||
RSK_COMPLETE_MASK_QUEST,
|
RSK_COMPLETE_MASK_QUEST,
|
||||||
|
|
|
@ -269,7 +269,6 @@ void Settings::CreateOptions() {
|
||||||
OPT_BOOL(RSK_SKIP_EPONA_RACE, "Skip Epona Race", {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipEponaRace"), mOptionDescriptions[RSK_SKIP_EPONA_RACE], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP);
|
OPT_BOOL(RSK_SKIP_EPONA_RACE, "Skip Epona Race", {"Don't Skip", "Skip"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("SkipEponaRace"), mOptionDescriptions[RSK_SKIP_EPONA_RACE], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP);
|
||||||
OPT_BOOL(RSK_SKIP_SCARECROWS_SONG, "Skip Scarecrow's Song", CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), mOptionDescriptions[RSK_SKIP_SCARECROWS_SONG]);
|
OPT_BOOL(RSK_SKIP_SCARECROWS_SONG, "Skip Scarecrow's Song", CVAR_RANDOMIZER_SETTING("SkipScarecrowsSong"), mOptionDescriptions[RSK_SKIP_SCARECROWS_SONG]);
|
||||||
OPT_U8(RSK_BIG_POE_COUNT, "Big Poe Target Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), mOptionDescriptions[RSK_BIG_POE_COUNT], WidgetType::Slider, 10);
|
OPT_U8(RSK_BIG_POE_COUNT, "Big Poe Target Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BigPoeTargetCount"), mOptionDescriptions[RSK_BIG_POE_COUNT], WidgetType::Slider, 10);
|
||||||
OPT_U8(RSK_CUCCO_COUNT, "Cuccos to return", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("CuccosToReturn"), mOptionDescriptions[RSK_CUCCO_COUNT], WidgetType::Slider, 7);
|
|
||||||
OPT_BOOL(RSK_COMPLETE_MASK_QUEST, "Complete Mask Quest", CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), mOptionDescriptions[RSK_COMPLETE_MASK_QUEST]);
|
OPT_BOOL(RSK_COMPLETE_MASK_QUEST, "Complete Mask Quest", CVAR_RANDOMIZER_SETTING("CompleteMaskQuest"), mOptionDescriptions[RSK_COMPLETE_MASK_QUEST]);
|
||||||
OPT_U8(RSK_GOSSIP_STONE_HINTS, "Gossip Stone Hints", {"No Hints", "Need Nothing", "Mask of Truth", "Stone of Agony"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GossipStoneHints"), mOptionDescriptions[RSK_GOSSIP_STONE_HINTS], WidgetType::Combobox, RO_GOSSIP_STONES_NEED_NOTHING, false, IMFLAG_NONE);
|
OPT_U8(RSK_GOSSIP_STONE_HINTS, "Gossip Stone Hints", {"No Hints", "Need Nothing", "Mask of Truth", "Stone of Agony"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GossipStoneHints"), mOptionDescriptions[RSK_GOSSIP_STONE_HINTS], WidgetType::Combobox, RO_GOSSIP_STONES_NEED_NOTHING, false, IMFLAG_NONE);
|
||||||
OPT_U8(RSK_HINT_CLARITY, "Hint Clarity", {"Obscure", "Ambiguous", "Clear"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("HintClarity"), mOptionDescriptions[RSK_HINT_CLARITY], WidgetType::Combobox, RO_HINT_CLARITY_CLEAR, true, IMFLAG_INDENT);
|
OPT_U8(RSK_HINT_CLARITY, "Hint Clarity", {"Obscure", "Ambiguous", "Clear"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("HintClarity"), mOptionDescriptions[RSK_HINT_CLARITY], WidgetType::Combobox, RO_HINT_CLARITY_CLEAR, true, IMFLAG_INDENT);
|
||||||
|
@ -1316,8 +1315,8 @@ void Settings::CreateOptions() {
|
||||||
WidgetContainerType::TABLE);
|
WidgetContainerType::TABLE);
|
||||||
mOptionGroups[RSG_TIMESAVERS_IMGUI] = OptionGroup::SubGroup(
|
mOptionGroups[RSG_TIMESAVERS_IMGUI] = OptionGroup::SubGroup(
|
||||||
"Timesavers",
|
"Timesavers",
|
||||||
{ &mOptions[RSK_CUCCO_COUNT], &mOptions[RSK_BIG_POE_COUNT], &mOptions[RSK_SKIP_CHILD_ZELDA],
|
{ &mOptions[RSK_BIG_POE_COUNT], &mOptions[RSK_SKIP_CHILD_ZELDA], &mOptions[RSK_SKIP_EPONA_RACE],
|
||||||
&mOptions[RSK_SKIP_EPONA_RACE], &mOptions[RSK_COMPLETE_MASK_QUEST], &mOptions[RSK_SKIP_SCARECROWS_SONG] },
|
&mOptions[RSK_COMPLETE_MASK_QUEST], &mOptions[RSK_SKIP_SCARECROWS_SONG] },
|
||||||
WidgetContainerType::COLUMN);
|
WidgetContainerType::COLUMN);
|
||||||
mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI] = OptionGroup::SubGroup("",
|
mOptionGroups[RSG_ITEM_POOL_HINTS_IMGUI] = OptionGroup::SubGroup("",
|
||||||
{
|
{
|
||||||
|
@ -1582,7 +1581,6 @@ void Settings::CreateOptions() {
|
||||||
&mOptions[RSK_SKIP_EPONA_RACE],
|
&mOptions[RSK_SKIP_EPONA_RACE],
|
||||||
&mOptions[RSK_SKIP_SCARECROWS_SONG],
|
&mOptions[RSK_SKIP_SCARECROWS_SONG],
|
||||||
&mOptions[RSK_BIG_POE_COUNT],
|
&mOptions[RSK_BIG_POE_COUNT],
|
||||||
&mOptions[RSK_CUCCO_COUNT],
|
|
||||||
&mOptions[RSK_COMPLETE_MASK_QUEST],
|
&mOptions[RSK_COMPLETE_MASK_QUEST],
|
||||||
});
|
});
|
||||||
mOptionGroups[RSG_MISC] = OptionGroup("Miscellaneous Settings",
|
mOptionGroups[RSG_MISC] = OptionGroup("Miscellaneous Settings",
|
||||||
|
@ -2878,11 +2876,8 @@ void Context::FinalizeSettings(const std::set<RandomizerCheck>& excludedLocation
|
||||||
if (mOptions[RSK_FISHSANITY].IsNot(RO_FISHSANITY_HYRULE_LOACH)) {
|
if (mOptions[RSK_FISHSANITY].IsNot(RO_FISHSANITY_HYRULE_LOACH)) {
|
||||||
mOptions[RSK_LOACH_HINT].Set(RO_GENERIC_OFF);
|
mOptions[RSK_LOACH_HINT].Set(RO_GENERIC_OFF);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mOptions[RSK_CUCCO_COUNT].Is(0)) {
|
|
||||||
mOptions[RSK_CHICKENS_HINT].Set(RO_GENERIC_OFF);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void Settings::ParseJson(nlohmann::json spoilerFileJson) {
|
void Settings::ParseJson(nlohmann::json spoilerFileJson) {
|
||||||
mContext->SetSeedString(spoilerFileJson["seed"].get<std::string>());
|
mContext->SetSeedString(spoilerFileJson["seed"].get<std::string>());
|
||||||
mContext->SetSeed(spoilerFileJson["finalSeed"].get<uint32_t>());
|
mContext->SetSeed(spoilerFileJson["finalSeed"].get<uint32_t>());
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -147,28 +147,25 @@ void RegisterOnInterfaceUpdateHook() {
|
||||||
timer = gSaveContext.subTimerSeconds;
|
timer = gSaveContext.subTimerSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timer > 0) {
|
if (timer > 0 && timer % (timer < 60 ? 10 : 30) == 0 && timer != prevTimer) {
|
||||||
if (timer > prevTimer || (timer % 30 == 0 && prevTimer != timer)) {
|
|
||||||
uint32_t minutes = timer / 60;
|
uint32_t minutes = timer / 60;
|
||||||
uint32_t seconds = timer % 60;
|
uint32_t seconds = timer % 60;
|
||||||
char* announceBuf = ttsAnnounceBuf;
|
char* announceBuf = ttsAnnounceBuf;
|
||||||
char arg[8]; // at least big enough where no s8 string will overflow
|
char arg[8]; // at least big enough where no s8 string will overflow
|
||||||
if (minutes > 0) {
|
if (minutes > 0) {
|
||||||
snprintf(arg, sizeof(arg), "%d", minutes);
|
snprintf(arg, sizeof(arg), "%d", minutes);
|
||||||
auto translation = GetParameritizedText((minutes > 1) ? "minutes_plural" : "minutes_singular",
|
auto translation =
|
||||||
TEXT_BANK_MISC, arg);
|
GetParameritizedText((minutes > 1) ? "minutes_plural" : "minutes_singular", TEXT_BANK_MISC, arg);
|
||||||
announceBuf += snprintf(announceBuf, sizeof(ttsAnnounceBuf), "%s ", translation.c_str());
|
announceBuf += snprintf(announceBuf, sizeof(ttsAnnounceBuf), "%s ", translation.c_str());
|
||||||
}
|
}
|
||||||
if (seconds > 0) {
|
if (seconds > 0) {
|
||||||
snprintf(arg, sizeof(arg), "%d", seconds);
|
snprintf(arg, sizeof(arg), "%d", seconds);
|
||||||
auto translation = GetParameritizedText((seconds > 1) ? "seconds_plural" : "seconds_singular",
|
auto translation =
|
||||||
TEXT_BANK_MISC, arg);
|
GetParameritizedText((seconds > 1) ? "seconds_plural" : "seconds_singular", TEXT_BANK_MISC, arg);
|
||||||
announceBuf += snprintf(announceBuf, sizeof(ttsAnnounceBuf), "%s", translation.c_str());
|
announceBuf += snprintf(announceBuf, sizeof(ttsAnnounceBuf), "%s", translation.c_str());
|
||||||
}
|
}
|
||||||
assert(announceBuf < ttsAnnounceBuf + sizeof(ttsAnnounceBuf));
|
assert(announceBuf < ttsAnnounceBuf + sizeof(ttsAnnounceBuf));
|
||||||
SpeechSynthesizer::Instance->Speak(ttsAnnounceBuf, GetLanguageCode());
|
SpeechSynthesizer::Instance->Speak(ttsAnnounceBuf, GetLanguageCode());
|
||||||
prevTimer = timer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prevTimer = timer;
|
prevTimer = timer;
|
||||||
|
|
29
soh/soh/ObjectExtension/ActorMaximumHealth.cpp
Normal file
29
soh/soh/ObjectExtension/ActorMaximumHealth.cpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#include "ActorMaximumHealth.h"
|
||||||
|
#include "soh/ObjectExtension/ObjectExtension.h"
|
||||||
|
#include "soh/ShipInit.hpp"
|
||||||
|
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||||
|
|
||||||
|
struct ActorMaximumHealth {
|
||||||
|
u8 maximumHealth = 0;
|
||||||
|
};
|
||||||
|
static ObjectExtension::Register<ActorMaximumHealth> ActorMaximumHealthRegister;
|
||||||
|
|
||||||
|
u8 GetActorMaximumHealth(const Actor* actor) {
|
||||||
|
const ActorMaximumHealth* maxHealth = ObjectExtension::GetInstance().Get<ActorMaximumHealth>(actor);
|
||||||
|
return maxHealth != nullptr ? maxHealth->maximumHealth : ActorMaximumHealth{}.maximumHealth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetActorMaximumHealth(const Actor* actor, u8 maximumHealth) {
|
||||||
|
ObjectExtension::GetInstance().Set<ActorMaximumHealth>(actor, ActorMaximumHealth{ maximumHealth });
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ActorMaximumHealth_Register() {
|
||||||
|
COND_HOOK(OnActorInit, true, [](void* ptr) {
|
||||||
|
Actor* actor = static_cast<Actor*>(ptr);
|
||||||
|
if (actor->category == ACTORCAT_ENEMY) {
|
||||||
|
SetActorMaximumHealth(actor, actor->colChkInfo.health);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterShipInitFunc actorMaximumHealthInit(ActorMaximumHealth_Register);
|
17
soh/soh/ObjectExtension/ActorMaximumHealth.h
Normal file
17
soh/soh/ObjectExtension/ActorMaximumHealth.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef ACTOR_MAXIMUM_HEALTH_H
|
||||||
|
#define ACTOR_MAXIMUM_HEALTH_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#include "z64actor.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Max health value for use with health bars, set on actor init
|
||||||
|
u8 GetActorMaximumHealth(const Actor* actor);
|
||||||
|
void SetActorMaximumHealth(const Actor* actor, u8 maximumHealth);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // ACTOR_MAXIMUM_HEALTH_H
|
|
@ -1138,6 +1138,10 @@ void SohMenu::AddMenuEnhancements() {
|
||||||
.CVar(CVAR_ENHANCEMENT("CuccoStayDurationMult"))
|
.CVar(CVAR_ENHANCEMENT("CuccoStayDurationMult"))
|
||||||
.Options(IntSliderOptions().Min(1).Max(5).DefaultValue(1).Format("%dx").Tooltip(
|
.Options(IntSliderOptions().Min(1).Max(5).DefaultValue(1).Format("%dx").Tooltip(
|
||||||
"Cuccos will stay in place longer after putting them down, by a multiple of the value of the slider."));
|
"Cuccos will stay in place longer after putting them down, by a multiple of the value of the slider."));
|
||||||
|
AddWidget(path, "Cuccos Needed By Anju: %d", WIDGET_CVAR_SLIDER_INT)
|
||||||
|
.CVar(CVAR_ENHANCEMENT("CuccosToReturn"))
|
||||||
|
.Options(IntSliderOptions().Min(0).Max(7).DefaultValue(7).Format("%d").Tooltip(
|
||||||
|
"The amount of cuccos needed to receive bottle from Anju the Cucco Lady."));
|
||||||
|
|
||||||
path.column = SECTION_COLUMN_3;
|
path.column = SECTION_COLUMN_3;
|
||||||
AddWidget(path, "Enemies", WIDGET_SEPARATOR_TEXT);
|
AddWidget(path, "Enemies", WIDGET_SEPARATOR_TEXT);
|
||||||
|
@ -1312,6 +1316,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)
|
||||||
|
@ -1581,9 +1590,6 @@ void SohMenu::AddMenuEnhancements() {
|
||||||
.Options(CheckboxOptions().Tooltip(
|
.Options(CheckboxOptions().Tooltip(
|
||||||
"Keese and Guay no longer target you and simply ignore you as if you were wearing the "
|
"Keese and Guay no longer target you and simply ignore you as if you were wearing the "
|
||||||
"Skull Mask."));
|
"Skull Mask."));
|
||||||
AddWidget(path, "No Dampe Fire", WIDGET_CVAR_CHECKBOX)
|
|
||||||
.CVar(CVAR_CHEAT("NoDampeFire"))
|
|
||||||
.Options(CheckboxOptions().Tooltip("Dampe won't drop fireballs during race."));
|
|
||||||
|
|
||||||
AddWidget(path, "Glitch Aids", WIDGET_SEPARATOR_TEXT);
|
AddWidget(path, "Glitch Aids", WIDGET_SEPARATOR_TEXT);
|
||||||
AddWidget(path, "Easy Frame Advancing with Pause", WIDGET_CVAR_CHECKBOX)
|
AddWidget(path, "Easy Frame Advancing with Pause", WIDGET_CVAR_CHECKBOX)
|
||||||
|
|
|
@ -1261,11 +1261,6 @@ void Actor_Init(Actor* actor, PlayState* play) {
|
||||||
actor->init = NULL;
|
actor->init = NULL;
|
||||||
|
|
||||||
GameInteractor_ExecuteOnActorInit(actor);
|
GameInteractor_ExecuteOnActorInit(actor);
|
||||||
|
|
||||||
// For enemy health bar we need to know the max health during init
|
|
||||||
if (actor->category == ACTORCAT_ENEMY) {
|
|
||||||
actor->maximumHealth = actor->colChkInfo.health;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2633,11 +2628,6 @@ void Actor_UpdateAll(PlayState* play, ActorContext* actorCtx) {
|
||||||
actor->init = NULL;
|
actor->init = NULL;
|
||||||
|
|
||||||
GameInteractor_ExecuteOnActorInit(actor);
|
GameInteractor_ExecuteOnActorInit(actor);
|
||||||
|
|
||||||
// For enemy health bar we need to know the max health during init
|
|
||||||
if (actor->category == ACTORCAT_ENEMY) {
|
|
||||||
actor->maximumHealth = actor->colChkInfo.health;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
actor = actor->next;
|
actor = actor->next;
|
||||||
} else if (!Object_IsLoaded(&play->objectCtx, actor->objBankIndex)) {
|
} else if (!Object_IsLoaded(&play->objectCtx, actor->objBankIndex)) {
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
#include "overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.h"
|
#include "overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.h"
|
||||||
#include "textures/icon_item_static/icon_item_static.h"
|
#include "textures/icon_item_static/icon_item_static.h"
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||||
#include "soh/OTRGlobals.h"
|
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
#include "soh/OTRGlobals.h"
|
||||||
|
|
||||||
#define FLAGS 0
|
#define FLAGS 0
|
||||||
|
|
||||||
|
@ -1536,7 +1536,7 @@ s16 func_8001F404(s16 dropId) {
|
||||||
if (LINK_IS_ADULT) {
|
if (LINK_IS_ADULT) {
|
||||||
if (dropId == ITEM00_SEEDS) {
|
if (dropId == ITEM00_SEEDS) {
|
||||||
dropId = ITEM00_ARROWS_SMALL;
|
dropId = ITEM00_ARROWS_SMALL;
|
||||||
} else if ((dropId == ITEM00_STICK) && !(CVarGetInteger(CVAR_ENHANCEMENT("TreesDropSticks"), 0))) {
|
} else if (GameInteractor_Should(VB_PREVENT_ADULT_STICK, dropId == ITEM00_STICK)) {
|
||||||
dropId = ITEM00_RUPEE_GREEN;
|
dropId = ITEM00_RUPEE_GREEN;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "soh/OTRGlobals.h"
|
#include "soh/OTRGlobals.h"
|
||||||
#include "soh/ResourceManagerHelpers.h"
|
#include "soh/ResourceManagerHelpers.h"
|
||||||
#include "soh/Enhancements/gameplaystats.h"
|
#include "soh/Enhancements/gameplaystats.h"
|
||||||
|
#include "soh/ObjectExtension/ActorMaximumHealth.h"
|
||||||
|
|
||||||
#include "message_data_static.h"
|
#include "message_data_static.h"
|
||||||
extern MessageTableEntry* sNesMessageEntryTablePtr;
|
extern MessageTableEntry* sNesMessageEntryTablePtr;
|
||||||
|
@ -3643,7 +3644,7 @@ void Interface_DrawEnemyHealthBar(TargetContext* targetCtx, PlayState* play) {
|
||||||
f32 scaleY = -0.75f;
|
f32 scaleY = -0.75f;
|
||||||
f32 scaledHeight = -texHeight * scaleY;
|
f32 scaledHeight = -texHeight * scaleY;
|
||||||
f32 halfBarWidth = endTexWidth + ((f32)healthbar_fillWidth / 2);
|
f32 halfBarWidth = endTexWidth + ((f32)healthbar_fillWidth / 2);
|
||||||
s16 healthBarFill = ((f32)actor->colChkInfo.health / actor->maximumHealth) * healthbar_fillWidth;
|
s16 healthBarFill = ((f32)actor->colChkInfo.health / GetActorMaximumHealth(actor)) * healthbar_fillWidth;
|
||||||
|
|
||||||
if (anchorType == ENEMYHEALTH_ANCHOR_ACTOR) {
|
if (anchorType == ENEMYHEALTH_ANCHOR_ACTOR) {
|
||||||
// Get actor projected position
|
// Get actor projected position
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "objects/object_fz/object_fz.h"
|
#include "objects/object_fz/object_fz.h"
|
||||||
#include "soh/frame_interpolation.h"
|
#include "soh/frame_interpolation.h"
|
||||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
#include "soh/ObjectExtension/ActorMaximumHealth.h"
|
||||||
|
|
||||||
#define FLAGS \
|
#define FLAGS \
|
||||||
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
|
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
|
||||||
|
@ -725,7 +726,7 @@ void EnFz_Draw(Actor* thisx, PlayState* play) {
|
||||||
// displayLists, so we need to recompute the index based on the scaled health (using the maximum health value) and
|
// displayLists, so we need to recompute the index based on the scaled health (using the maximum health value) and
|
||||||
// clamp the final result for safety.
|
// clamp the final result for safety.
|
||||||
if (CVarGetInteger(CVAR_ENHANCEMENT("EnemySizeScalesHealth"), 0)) {
|
if (CVarGetInteger(CVAR_ENHANCEMENT("EnemySizeScalesHealth"), 0)) {
|
||||||
u8 scaledHealth = (u8)(((f32)this->actor.colChkInfo.health / this->actor.maximumHealth) * 6);
|
u8 scaledHealth = (u8)(((f32)this->actor.colChkInfo.health / GetActorMaximumHealth(this)) * 6);
|
||||||
index = (6 - scaledHealth) >> 1;
|
index = (6 - scaledHealth) >> 1;
|
||||||
index = CLAMP(index, 0, 2);
|
index = CLAMP(index, 0, 2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include "z_en_wood02.h"
|
#include "z_en_wood02.h"
|
||||||
#include "objects/object_wood02/object_wood02.h"
|
#include "objects/object_wood02/object_wood02.h"
|
||||||
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
|
||||||
#define FLAGS 0
|
#define FLAGS 0
|
||||||
|
|
||||||
|
@ -327,7 +328,6 @@ void EnWood02_Update(Actor* thisx, PlayState* play2) {
|
||||||
Vec3f dropsSpawnPt;
|
Vec3f dropsSpawnPt;
|
||||||
s32 i;
|
s32 i;
|
||||||
s32 leavesParams;
|
s32 leavesParams;
|
||||||
s32 numDrops;
|
|
||||||
|
|
||||||
// Despawn extra trees in a group if out of range
|
// Despawn extra trees in a group if out of range
|
||||||
if ((this->spawnType == WOOD_SPAWN_SPAWNED) && (this->actor.parent != NULL)) {
|
if ((this->spawnType == WOOD_SPAWN_SPAWNED) && (this->actor.parent != NULL)) {
|
||||||
|
@ -358,12 +358,7 @@ void EnWood02_Update(Actor* thisx, PlayState* play2) {
|
||||||
dropsSpawnPt.y += 200.0f;
|
dropsSpawnPt.y += 200.0f;
|
||||||
|
|
||||||
if ((this->unk_14C >= 0) && (this->unk_14C < 0x64)) {
|
if ((this->unk_14C >= 0) && (this->unk_14C < 0x64)) {
|
||||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TreesDropSticks"), 0) && INV_CONTENT(ITEM_STICK) != ITEM_NONE) {
|
if (GameInteractor_Should(VB_TREE_DROP_COLLECTIBLE, true, this)) {
|
||||||
numDrops = Rand_ZeroOne() * 4;
|
|
||||||
for (i = 0; i < numDrops; ++i) {
|
|
||||||
Item_DropCollectible(play, &dropsSpawnPt, ITEM00_STICK);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Item_DropCollectibleRandom(play, &this->actor, &dropsSpawnPt, this->unk_14C << 4);
|
Item_DropCollectibleRandom(play, &this->actor, &dropsSpawnPt, this->unk_14C << 4);
|
||||||
}
|
}
|
||||||
} else if (this->actor.home.rot.z != 0) {
|
} else if (this->actor.home.rot.z != 0) {
|
||||||
|
|
|
@ -1374,6 +1374,7 @@ void FileChoose_UpdateQuestMenu(GameState* thisx) {
|
||||||
} else {
|
} else {
|
||||||
defaultName = &emptyNameNES;
|
defaultName = &emptyNameNES;
|
||||||
}
|
}
|
||||||
|
this->charPage = FS_CHAR_PAGE_HIRA; // Default to Hiragana Keyboard
|
||||||
} else { // GAME_REGION_NTSC
|
} else { // GAME_REGION_NTSC
|
||||||
defaultName = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? &linkNameNES : &emptyNameNES;
|
defaultName = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? &linkNameNES : &emptyNameNES;
|
||||||
}
|
}
|
||||||
|
@ -1575,6 +1576,7 @@ void FileChoose_UpdateRandomizerMenu(GameState* thisx) {
|
||||||
} else {
|
} else {
|
||||||
defaultName = &emptyNameNES;
|
defaultName = &emptyNameNES;
|
||||||
}
|
}
|
||||||
|
this->charPage = FS_CHAR_PAGE_HIRA; // Default to Hiragana Keyboard
|
||||||
} else { // GAME_REGION_NTSC
|
} else { // GAME_REGION_NTSC
|
||||||
defaultName = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? &linkNameNES : &emptyNameNES;
|
defaultName = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? &linkNameNES : &emptyNameNES;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue