Merge branch 'rando-mod' of https://github.com/TwilitRealm/dusk into rando-mod

This commit is contained in:
gymnast86
2026-08-20 19:59:19 -07:00
82 changed files with 5087 additions and 390 deletions
+42 -1
View File
@@ -1367,7 +1367,48 @@ HookAction hookPreGetLayerNo(ModContext*, void* args, void* retval, void*) {
}
}
return HOOK_CONTINUE;
if (layer == 14) {
// Warped meteor to Zora's Domain
if (dComIfGs_isEventBit(dSv_event_flag_c::saveBitLabels[65])) {
// Stage is Zora's River, Zora's Domain, Lake Hylia, Castle Town, Telma's Bar, R_SP115,
// Hyrule Field, Upper Zora's River, or Outside Castle Town
if (!strcmp(i_stageName, "F_SP112") || !strcmp(i_stageName, "F_SP113") ||
!strcmp(i_stageName, "F_SP115") || !strcmp(i_stageName, "F_SP116") ||
(!strcmp(i_stageName, "R_SP116") && i_roomNo == 5) ||
!strcmp(i_stageName, "R_SP115") || !strcmp(i_stageName, "F_SP121") ||
!strcmp(i_stageName, "F_SP126") || !strcmp(i_stageName, "F_SP122"))
{
// Stage is Hyrule Field
if (!strcmp(i_stageName, "F_SP121")) {
if (i_roomNo >= 9 && i_roomNo <= 14) {
layer = 13;
}
} else {
layer = 13;
}
}
}
// Stage is Hyrule Castle Sewers and room is Prison Cell
if (!strcmp(i_stageName, "R_SP107") && i_roomNo == 0) {
// Haven't been to Hyrule Castle Sewers
if (!dComIfGs_isEventBit(0x4D08)) {
layer = 11;
}
}
// Stage and room is Zant Throne Room
else if (!strcmp(i_stageName, "D_MN08A") && i_roomNo == 10)
{
// Defeated Zant
if (dComIfGs_isEventBit(0x5410)) {
layer = 1;
} else {
layer = 0;
}
}
}
return HOOK_SKIP_ORIGINAL;
}
HookAction hookPreOnStageSwitch(ModContext*, void* args, void* retval, void*) {
-5
View File
@@ -44,11 +44,6 @@ MOD_EXPORT ModResult mod_initialize(ModError* error) {
return mods::set_error(error, result, "failed to initialize session");
}
result = randomizer::ui::initialize();
if (result != MOD_OK) {
return mods::set_error(error, result, "failed to initialize ui");
}
svc_log->info(mod_ctx, "randomizer initialized");
return MOD_OK;
}
-105
View File
@@ -408,12 +408,8 @@ RandomizerState g_randomizerState;
int RandomizerState::_create() {
mInitialized = true;
mEventItemStatus = QUEUE_EMPTY;
mHasPendingToDChange = false;
// g_customMenuRing._initialize();
for (int i = 0; i < EVENT_ITEM_QUEUE_SIZE; i++) {
mEventItemQueue[i] = 0;
}
return 1;
}
@@ -629,8 +625,6 @@ int RandomizerState::execute() {
// Any custom functionality that relies on Link's actor being on a stage
if (daAlink_getAlinkActorClass()) {
currentReloadingState = daAlink_getAlinkActorClass()->checkRestartRoom();
// Handle giving item to the player at any time.
//initGiveItemToPlayer();
}
else {
currentReloadingState = true;
@@ -655,105 +649,6 @@ int RandomizerState::draw() {
return 1;
}
void RandomizerState::handlePoeItem(u8 bitSw)
{
u16 key = getStageID() << 8 | bitSw;
u8 item = randomizer_GetContext().mPoeOverrides[key];
addItemToEventQueue(item);
daAlink_getAlinkActorClass()->procWolfAtnActorMoveInit();
}
void RandomizerState::addItemToEventQueue(u8 item)
{
for (int i = 0; i < EVENT_ITEM_QUEUE_SIZE; i++)
{
if (mEventItemQueue[i] == 0)
{
mEventItemQueue[i] = item;
break;
}
}
}
void RandomizerState::initGiveItemToPlayer()
{
switch (daAlink_getAlinkActorClass()->mProcID)
{
case daAlink_c::PROC_WAIT:
case daAlink_c::PROC_TIRED_WAIT:
case daAlink_c::PROC_MOVE:
case daAlink_c::PROC_WOLF_WAIT:
case daAlink_c::PROC_WOLF_TIRED_WAIT:
case daAlink_c::PROC_WOLF_MOVE:
case daAlink_c::PROC_ATN_MOVE:
case daAlink_c::PROC_WOLF_ATN_AC_MOVE:
{
// Check if link is currently in a cutscene
if (daAlink_getAlinkActorClass()->checkEventRun())
{
break;
}
// Ensure that link is not currently in a message-based event.
int event_item_id = 0;
if (daAlink_getAlinkActorClass()->mMsgFlow.getEventId(&event_item_id) != 0)
{
break;
}
u8 itemToGive = 0xFF;
for (int i = 0; i < EVENT_ITEM_QUEUE_SIZE; i++)
{
const u8 storedItem = mEventItemQueue[i];
if (storedItem)
{
const u8 giveItemToPlayerStatus = getGiveItemToPlayerStatus();
// If we have the call to clear the queue, then we want to clear the item and break out.
if (giveItemToPlayerStatus == CLEAR_QUEUE)
{
mEventItemQueue[i] = 0;
setGiveItemToPlayerStatus(QUEUE_EMPTY);
break;
}
// If the queue is empty and we have an item to give, update the queue state.
else if (giveItemToPlayerStatus == QUEUE_EMPTY)
{
setGiveItemToPlayerStatus(ITEM_IN_QUEUE);
}
itemToGive = verifyProgressiveItem(storedItem);
break;
}
}
// if there is no item to give, break out of the case.
if (itemToGive == 0xFF)
{
break;
}
g_dComIfG_gameInfo.play.getEvent()->setGtItm(itemToGive);
// Set the process value for getting an item to start the "get item" cutscene when next available.
daAlink_getAlinkActorClass()->mProcID = daAlink_c::PROC_GET_ITEM;
// Get the event index for the "Get Item" event.
const s16 eventIdx = dComIfGp_getEventManager().getEventIdx((fopAc_ac_c*)daAlink_getAlinkActorClass(),"DEFAULT_GETITEM",0xFF);
// Finally we want to modify the event stack to prioritize our custom event so that it happens next.
fopAcM_orderChangeEventId(daAlink_getAlinkActorClass(), eventIdx, 1, 0xFFFF);
}
default:
{
break;
}
}
}
void RandomizerState::handleTimeOfDayChange()
{
if (dComIfGp_roomControl_getTimePass())
+1 -17
View File
@@ -156,45 +156,29 @@ public:
CHANGE_TO_DAY,
};
enum EventItemStatus {
QUEUE_EMPTY,
ITEM_IN_QUEUE,
CLEAR_QUEUE,
};
static constexpr u8 EVENT_ITEM_QUEUE_SIZE = 10;
RandomizerState() { mInitialized = false; }
int _create();
int _delete();
int execute();
int draw();
void addItemToEventQueue(u8 item);
void initGiveItemToPlayer();
// void handleBonkDamage();
void handleTimeOfDayChange();
void handleTimeSpeed();
void offLoad();
void handlePoeItem(u8 bitSw);
u8 getGiveItemToPlayerStatus() const { return mEventItemStatus; }
u8 getTimeChange() const { return mTimeChange; }
bool getRoomReloadingState() const { return mRoomReloadingState; }
bool getHasPendingToDChange() const { return mHasPendingToDChange; }
void setGiveItemToPlayerStatus(u8 status) { mEventItemStatus = status; }
void setHasPendingToDChange(bool hasPending) { mHasPendingToDChange = hasPending; }
void setTimeChange(u8 newTimeChange) { mTimeChange = newTimeChange; }
void setRoomReloadingState(bool newState) { mRoomReloadingState = newState; }
bool mInitialized{false};
int mFileNum{-1};
u8 mEventItemStatus{};
bool mHasPendingToDChange{false};
u8 mTimeChange{};
u8 mEventItemQueue[EVENT_ITEM_QUEUE_SIZE];
bool mRoomReloadingState{false};
// Used to store an item id for a flow message override so that we can give the item
+6
View File
@@ -405,6 +405,11 @@ ModResult onGameModeActivated(void*, ModError* error) {
return mods::set_error(error, result, "failed to register texture replacement");
}
result = ui::initialize();
if (result != MOD_OK) {
return mods::set_error(error, result, "failed to initialize ui");
}
mods::log::info("randomizer game mode activated");
return MOD_OK;
}
@@ -412,6 +417,7 @@ ModResult onGameModeActivated(void*, ModError* error) {
void shutdown() {
deactivateSeed();
hooks::uninstall();
ui::shutdown();
svc_mng.save->unobserve_saves(mod_ctx, s_save_observer);
svc_mng.texture->unregister(mod_ctx, logoTexHandle);
}
+7 -3
View File
@@ -441,8 +441,8 @@ ModResult buildSeedManagementTab(ModContext* ctx, UiWindowHandle, UiElementHandl
session::svc_mng.ui->push_toast(session::svc_mng.mod_ctx, &desc);
});
add_section(leftPane, "Presets");
// TODO: need some ui service updates to properly support this. disabling for now
/* add_section(leftPane, "Presets");
add_button(leftPane,
"Save Current Settings as Preset",
"Save the current settings to your list of presets.",
@@ -455,7 +455,7 @@ ModResult buildSeedManagementTab(ModContext* ctx, UiWindowHandle, UiElementHandl
"Choose an existing preset to load from.",
[](ModContext*, void*) {
// TODO
});
}); */
return MOD_OK;
}
@@ -1172,6 +1172,10 @@ ModResult buildMenuTab() {
return session::svc_mng.ui->register_menu_tab(session::svc_mng.mod_ctx, &desc, &g_menu_tab);
}
ModResult removeMenuTab() {
return session::svc_mng.ui->unregister_menu_tab(session::svc_mng.mod_ctx, g_menu_tab);
}
ModResult buildFileSelectGateMenu(dFile_select_c* fileSelect) {
UiTabDesc tabs[6]{};
+1
View File
@@ -31,5 +31,6 @@ void CopyPermalinkToClipboard();
void PastePermalinkFromClipboard();
ModResult buildMenuTab();
ModResult removeMenuTab();
ModResult buildFileSelectGateMenu(dFile_select_c*);
}
+9 -1
View File
@@ -8,6 +8,8 @@
#include "rando_config.hpp"
namespace randomizer::ui {
UiStyleHandle styleHandle{};
ModResult initialize() {
ModResult res;
@@ -15,7 +17,7 @@ ModResult initialize() {
session::svc_mng.mod_ctx,
UI_SCOPE_WINDOW,
"ui.rcss",
nullptr);
&styleHandle);
if (res != MOD_OK) {
mods::log::error("failed to register rcss!");
return res;
@@ -34,4 +36,10 @@ void update() {
UpdateSeedGenerationDialog();
}
ModResult shutdown() {
removeMenuTab();
session::svc_mng.ui->unregister_styles(mod_ctx, styleHandle);
return MOD_OK;
}
}
+1
View File
@@ -5,4 +5,5 @@
namespace randomizer::ui {
ModResult initialize();
void update();
ModResult shutdown();
}