From c5db797beb92cd0923e463293768fe24e40a9822 Mon Sep 17 00:00:00 2001 From: ZoeyZolotova Date: Thu, 16 Jan 2025 21:39:26 +1100 Subject: [PATCH 01/34] Powder Keg as Human with Golden Gauntlets. (#821) * Add setting to be able to buy and use Powder Kegs if you have Golden Gauntlets in MM, and be able to attempt the Keg Trial. * Remove unnecessary include. --- packages/core/include/combo.h | 1 + .../core/include/combo/mm/actors/En_S_Goro.h | 57 +++++++++++++ packages/core/include/combo/mm/asm_defs.h | 2 + packages/core/include/combo/mm/player.h | 1 + packages/core/include/combo/mm/save.h | 2 + packages/core/include/combo/mm/z_msgevent.h | 25 ++++++ packages/core/include/combo/text.h | 1 + packages/core/lib/combo/confvars.ts | 1 + packages/core/lib/combo/patch-build/group.ts | 1 + packages/core/lib/combo/patch-build/index.ts | 1 + .../core/lib/combo/patch-build/randomizer.ts | 1 + packages/core/lib/combo/settings/data.ts | 8 ++ packages/core/src/common/item/item_add.c | 8 ++ packages/core/src/link_mm.in | 5 ++ packages/core/src/mm/actors/En/En_Go.S | 8 ++ packages/core/src/mm/actors/En/En_Go.c | 48 ++++++++++- packages/core/src/mm/actors/En/En_S_Goro.S | 14 ++++ packages/core/src/mm/actors/En/En_S_Goro.c | 48 +++++++++++ packages/core/src/mm/play/play.c | 10 +++ packages/core/src/mm/z_msgevent.c | 81 +++++++++++++++++++ packages/core/src/mm/z_parameter.c | 4 +- packages/data/src/macros/macros_mm.yml | 1 + packages/data/src/world/mm/overworld.yml | 10 +-- 23 files changed, 329 insertions(+), 9 deletions(-) create mode 100644 packages/core/include/combo/mm/actors/En_S_Goro.h create mode 100644 packages/core/include/combo/mm/z_msgevent.h create mode 100644 packages/core/src/mm/actors/En/En_S_Goro.c create mode 100644 packages/core/src/mm/z_msgevent.c diff --git a/packages/core/include/combo.h b/packages/core/include/combo.h index 30bf40383f..abbf5e6c37 100644 --- a/packages/core/include/combo.h +++ b/packages/core/include/combo.h @@ -72,6 +72,7 @@ # include # include # include +# include # include # include # endif diff --git a/packages/core/include/combo/mm/actors/En_S_Goro.h b/packages/core/include/combo/mm/actors/En_S_Goro.h new file mode 100644 index 0000000000..a9c86b6c32 --- /dev/null +++ b/packages/core/include/combo/mm/actors/En_S_Goro.h @@ -0,0 +1,57 @@ +#ifndef Z_EN_S_GORO_H +#define Z_EN_S_GORO_H + +#include + +#define EN_S_GORO_GET_MAIN_TYPE(thisx) ((thisx)->params & 0xF) +#define EN_S_GORO_GET_SWITCH_FLAG(thisx) (((thisx)->params & 0x7F0) >> 4) + +struct EnSGoro; + +typedef void (*EnSGoroActionFunc)(struct EnSGoro*, PlayState*); + +typedef struct EnSGoro { + /* 0x000 */ Actor actor; + /* 0x144 */ Actor* otherGoron; + /* 0x148 */ SkelAnime skelAnime; + /* 0x18C */ EnSGoroActionFunc actionFunc; + /* 0x190 */ ColliderCylinder collider; + /* 0x1DC */ u16 actionFlags; + /* 0x1DE */ u16 bombbuyFlags; + /* 0x1E0 */ char unk_1E0[0xC]; + /* 0x1EC */ s16 eyeTexIndex; + /* 0x1EE */ s16 eyeTimer; + /* 0x1F0 */ s16 loseAttentionTimer; + /* 0x1F4 */ s32 objectSlot; + /* 0x1F8 */ Vec3s jointTable[18]; /* GORON_LIMB_MAX */ + /* 0x264 */ Vec3s morphTable[18]; /* GORON_LIMB_MAX */ + /* 0x2D0 */ f32 scaleFactor; + /* 0x2D4 */ s16 headRotZ; + /* 0x2D6 */ s16 headRotY; + /* 0x2D8 */ s16 bodyRotZ; + /* 0x2DA */ s16 bodyRotY; + /* 0x2DC */ Vec3f headTranslate; + /* 0x2E8 */ Vec3s headRotate; + /* 0x2F0 */ Vec3f bodyTranslate; + /* 0x2FC */ Vec3s bodyRotate; + /* 0x302 */ char unk_302[2]; + /* 0x304 */ u16 textId; + /* 0x306 */ s16 snorePhase; + /* 0x308 */ s32 animIndex; + /* 0x30C */ s16 powderKegPrice; +} EnSGoro; // size = 0x310 + +typedef enum EnSGoroType { + /* 0x0 */ EN_S_GORO_TYPE_SHRINE_WINTER_A, + /* 0x1 */ EN_S_GORO_TYPE_SHRINE_WINTER_B, + /* 0x2 */ EN_S_GORO_TYPE_SHRINE_WINTER_C, + /* 0x3 */ EN_S_GORO_TYPE_SHRINE_SPRING_A, + /* 0x4 */ EN_S_GORO_TYPE_SHRINE_SPRING_B, + /* 0x5 */ EN_S_GORO_TYPE_SHRINE_SPRING_C, + /* 0x6 */ EN_S_GORO_TYPE_SHRINE_SPRING_D, + /* 0x7 */ EN_S_GORO_TYPE_SHRINE_SPRING_E, + /* 0x8 */ EN_S_GORO_TYPE_SHRINE_SPRING_F, + /* 0x9 */ EN_S_GORO_TYPE_BOMBSHOP +} EnSGoroType; + +#endif // Z_EN_S_GORO_H diff --git a/packages/core/include/combo/mm/asm_defs.h b/packages/core/include/combo/mm/asm_defs.h index 47e26c1d0d..67415450f9 100644 --- a/packages/core/include/combo/mm/asm_defs.h +++ b/packages/core/include/combo/mm/asm_defs.h @@ -29,3 +29,5 @@ #define PLAYER_TUNIC_GORON 2 #define PLAYER_TUNIC_ZORA 3 #define PLAYER_TUNIC_MAX 3 + +#define MSCRIPT_CUSTOM_CMD_ID_CHECK_STRENGTH_3 0x33 diff --git a/packages/core/include/combo/mm/player.h b/packages/core/include/combo/mm/player.h index d532f5293b..5190aa91be 100644 --- a/packages/core/include/combo/mm/player.h +++ b/packages/core/include/combo/mm/player.h @@ -9,6 +9,7 @@ struct Player; int Player_GetMask(PlayState* play); +s32 Player_HasStrength(u8 requiredStrength); typedef struct { /* 0x00 */ u8 unk_00; diff --git a/packages/core/include/combo/mm/save.h b/packages/core/include/combo/mm/save.h index 822ace77af..8e11c78e03 100644 --- a/packages/core/include/combo/mm/save.h +++ b/packages/core/include/combo/mm/save.h @@ -444,6 +444,8 @@ ALIGNED(16) extern MmSaveContext gSaveContext; ALIGNED(16) extern MmSave gMmSave; #endif +extern s8 gPlayerFormItemRestrictions[5][0x72]; + /* Custom */ typedef struct { diff --git a/packages/core/include/combo/mm/z_msgevent.h b/packages/core/include/combo/mm/z_msgevent.h new file mode 100644 index 0000000000..e23e401f78 --- /dev/null +++ b/packages/core/include/combo/mm/z_msgevent.h @@ -0,0 +1,25 @@ +#ifndef COMBO_MM_Z_MSGEVENT_H +#define COMBO_MM_Z_MSGEVENT_H + +#include + +typedef s32 (*MsgScriptCallback)(struct Actor*, struct PlayState*); +typedef s32 (*MsgScriptCmdHandler)(struct Actor*, struct PlayState*, u8**, MsgScriptCallback, s32*); +typedef u8 MsgScript; + +extern u8 sMsgScriptCmdSizes[51]; +extern MsgScriptCmdHandler sMsgScriptCmdHandlers[51]; + +#define SCRIPT_PACK_16(h, l) (((h) << 8) | (l)) + +typedef struct { + /* 0x0 */ u8 cmd; +} MsgScriptCmdBase; + +typedef struct { + /* 0x0 */ MsgScriptCmdBase base; + /* 0x1 */ u8 offsetH; + /* 0x2 */ u8 offsetL; +} MsgScriptCmdCheckStrength3; + +#endif diff --git a/packages/core/include/combo/text.h b/packages/core/include/combo/text.h index a232846a07..1c331071d9 100644 --- a/packages/core/include/combo/text.h +++ b/packages/core/include/combo/text.h @@ -43,6 +43,7 @@ # define TEXT_SIGNAL "\xe0" # define TEXT_ICON "" # define TEXT_BB "\x10" +# define TEXT_SFX(sfxId) "\x1e" sfxId #endif #define TEXT_C0 TEXT_COLOR_TEAL diff --git a/packages/core/lib/combo/confvars.ts b/packages/core/lib/combo/confvars.ts index 9d851a5aad..37e7ab41f0 100644 --- a/packages/core/lib/combo/confvars.ts +++ b/packages/core/lib/combo/confvars.ts @@ -146,6 +146,7 @@ export const CONFVARS = [ 'MM_TUNIC_ZORA', 'MM_SCALES', 'MM_STRENGTH', + 'MM_KEG_STRENGTH_3', 'OOT_GANON_BOSS_KEY_HINT', 'BLAST_MASK_DELAY_INSTANT', 'BLAST_MASK_DELAY_VERYSHORT', diff --git a/packages/core/lib/combo/patch-build/group.ts b/packages/core/lib/combo/patch-build/group.ts index 1ce99379ec..6bcebdecd2 100644 --- a/packages/core/lib/combo/patch-build/group.ts +++ b/packages/core/lib/combo/patch-build/group.ts @@ -53,6 +53,7 @@ export const PATCH_GROUPS = [ 'MM_JP_LAYOUT_DEKU_PALACE', 'MM_JP_LAYOUT_STONE_TOWER', 'MM_JP_LAYOUT_STONE_TOWER_TEMPLE', + 'MM_KEG_STRENGTH_3', ] as const; export type PatchGroup = typeof PATCH_GROUPS[number]; diff --git a/packages/core/lib/combo/patch-build/index.ts b/packages/core/lib/combo/patch-build/index.ts index 5d3a84fbf9..9cc2653596 100644 --- a/packages/core/lib/combo/patch-build/index.ts +++ b/packages/core/lib/combo/patch-build/index.ts @@ -80,6 +80,7 @@ function asmPatchGroups(world: World, settings: Settings) { MM_JP_LAYOUT_DEKU_PALACE: world.resolvedFlags.jpLayouts.has('DekuPalace'), MM_JP_LAYOUT_STONE_TOWER: world.resolvedFlags.jpLayouts.has('StoneTower') && !world.resolvedFlags.openDungeonsMm.has('ST'), MM_JP_LAYOUT_STONE_TOWER_TEMPLE: world.resolvedFlags.jpLayouts.has('ST'), + MM_KEG_STRENGTH_3: settings.kegStrength3, }; const keys = Object.keys(groups) as PatchGroup[]; return keys.filter((k) => groups[k]); diff --git a/packages/core/lib/combo/patch-build/randomizer.ts b/packages/core/lib/combo/patch-build/randomizer.ts index c95e9311f5..30552bb83c 100644 --- a/packages/core/lib/combo/patch-build/randomizer.ts +++ b/packages/core/lib/combo/patch-build/randomizer.ts @@ -940,6 +940,7 @@ function worldConfig(world: World, settings: Settings): Set { MM_TUNIC_ZORA: settings.tunicZoraMm, MM_SCALES: settings.scalesMm, MM_STRENGTH: settings.strengthMm, + MM_KEG_STRENGTH_3: settings.kegStrength3, OOT_GANON_BOSS_KEY_HINT: settings.ganonBossKey === 'anywhere', BLAST_MASK_DELAY_INSTANT: settings.blastMaskCooldown === 'instant', BLAST_MASK_DELAY_VERYSHORT: settings.blastMaskCooldown === 'veryshort', diff --git a/packages/core/lib/combo/settings/data.ts b/packages/core/lib/combo/settings/data.ts index f4fe78c173..93b72f12db 100644 --- a/packages/core/lib/combo/settings/data.ts +++ b/packages/core/lib/combo/settings/data.ts @@ -1808,6 +1808,14 @@ export const SETTINGS = [{ description: "Adds the Goron's Bracelet, Silver Gauntlets and Golden Gauntlets in Majora's Mask.", default: false, cond: hasMM, +}, { + key: 'kegStrength3', + name: "Use Keg With Golden Gauntlets", + category: 'items.extensions', + type: 'boolean', + description: "If you have the Golden Gauntlets in Majora's Mask, this allows you to purchase and use Powder Kegs and attempt the Keg Trial.", + default: false, + cond: (x: any) => x.strengthMm && hasMM(x), }, { key: 'hammerMm', name: "Megaton Hammer (MM)", diff --git a/packages/core/src/common/item/item_add.c b/packages/core/src/common/item/item_add.c index ca3d04a722..2f72ce9837 100644 --- a/packages/core/src/common/item/item_add.c +++ b/packages/core/src/common/item/item_add.c @@ -1056,6 +1056,14 @@ static int addItemStrengthMm(PlayState* play, u8 itemId, s16 gi, u16 param) { if (param > gMmSave.info.inventory.upgrades.strength) gMmSave.info.inventory.upgrades.strength = param; + +#if defined(GAME_MM) + if (gPlayerFormItemRestrictions[MM_PLAYER_FORM_HUMAN][ITEM_MM_POWDER_KEG] == 0 && Config_Flag(CFG_MM_KEG_STRENGTH_3) && gSave.info.inventory.upgrades.strength >= 3) + { + gPlayerFormItemRestrictions[MM_PLAYER_FORM_HUMAN][ITEM_MM_POWDER_KEG] = 1; + } +#endif + return 0; } diff --git a/packages/core/src/link_mm.in b/packages/core/src/link_mm.in index 67b95b7e22..99f967f6f7 100644 --- a/packages/core/src/link_mm.in +++ b/packages/core/src/link_mm.in @@ -93,6 +93,9 @@ PictoUpdateFlags = 0x8013a240; gPictoboxState = 0x801bf884; gPictoboxPhotoTaken = 0x801bf888; +sMsgScriptCmdHandlers = 0x801bf5c0; +sMsgScriptCmdSizes = 0x801bf68c; + SpawnRoomActors = 0x800bb140; Flags_GetSwitch = 0x800b5bb0; @@ -684,3 +687,5 @@ Collider_InitTris = 0x800e16d0; Collider_SetTris = 0x800e1958; Audio_SetFileSelectSettings = 0x801a3d98; + +gPlayerFormItemRestrictions = 0x801c2410; diff --git a/packages/core/src/mm/actors/En/En_Go.S b/packages/core/src/mm/actors/En/En_Go.S index e1e528062f..a5de73c9ef 100644 --- a/packages/core/src/mm/actors/En/En_Go.S +++ b/packages/core/src/mm/actors/En/En_Go.S @@ -8,3 +8,11 @@ PATCH_END PATCH_START 0x80a162bf .short 0x0 PATCH_END + +PATCH_GROUP PG_MM_KEG_STRENGTH_3 + +PATCH_START 0x80a16280 + .byte MSCRIPT_CUSTOM_CMD_ID_CHECK_STRENGTH_3 +PATCH_END + +PATCH_GROUP_END diff --git a/packages/core/src/mm/actors/En/En_Go.c b/packages/core/src/mm/actors/En/En_Go.c index acd5816168..b2d08ed1d5 100644 --- a/packages/core/src/mm/actors/En/En_Go.c +++ b/packages/core/src/mm/actors/En/En_Go.c @@ -47,10 +47,56 @@ static void powderKegHint(PlayState* play) comboTextAutoLineBreaks(start); } +static void strengthText(PlayState* play) +{ + if (!Config_Flag(CFG_MM_KEG_STRENGTH_3)) return; + + char* b; + + b = play->msgCtx.font.textBuffer.schar; + comboTextAppendHeader(&b); + comboTextAppendStr(&b, "I'm the Goron who sells " TEXT_COLOR_RED "Powder" TEXT_NL "Kegs"); + comboTextAppendClearColor(&b); + comboTextAppendStr(&b, ", the most famous product of" TEXT_NL); + comboTextAppendStr(&b, "the Gorons." TEXT_NL TEXT_BOX_BREAK_2); + comboTextAppendStr(&b, "But the rules say I can't sell" TEXT_NL); + comboTextAppendStr(&b, TEXT_COLOR_RED "Powder Kegs"); + comboTextAppendClearColor(&b); + comboTextAppendStr(&b, " to anyone who isn't" TEXT_NL); + comboTextAppendStr(&b, TEXT_COLOR_RED "strong enough"); + comboTextAppendClearColor(&b); + comboTextAppendStr(&b, " to carry them. " TEXT_SFX("\x39\x1c") "Sorry." TEXT_END); +} + +static void strengthTextRepeat(PlayState* play) +{ + if (!Config_Flag(CFG_MM_KEG_STRENGTH_3)) return; + + char* b; + + b = play->msgCtx.font.textBuffer.schar; + comboTextAppendHeader(&b); + comboTextAppendStr(&b, "The rules say I can't sell " TEXT_COLOR_RED "Powder" TEXT_NL); + comboTextAppendStr(&b, "Kegs"); + comboTextAppendClearColor(&b); + comboTextAppendStr(&b, " to anyone who isn't " TEXT_COLOR_RED "strong" TEXT_NL); + comboTextAppendStr(&b, "enough"); + comboTextAppendClearColor(&b); + comboTextAppendStr(&b, " to carry them. " TEXT_SFX("\x39\x1c") "Sorry." TEXT_END); +} + void EnGo_AfterTextBox(Actor* this, PlayState* play, s16 messageId) { - if (messageId == 0x0c81) + switch (messageId) { + case 0x0c81: powderKegHint(play); + break; + case 0xc8e: + strengthText(play); + break; + case 0xc8f: + strengthTextRepeat(play); + break; } } diff --git a/packages/core/src/mm/actors/En/En_S_Goro.S b/packages/core/src/mm/actors/En/En_S_Goro.S index 833fa0e28e..9ff10fe2c7 100644 --- a/packages/core/src/mm/actors/En/En_S_Goro.S +++ b/packages/core/src/mm/actors/En/En_S_Goro.S @@ -8,3 +8,17 @@ PATCH_END PATCH_START 0x80bbef14 li a2,GI_MM_POWDER_KEG PATCH_END + +EnSGoro_OverrideBombshopGoronTextId_Hook: + j EnSGoro_OverrideBombshopGoronTextId + move a0, a2 /* This isn't necessarily always current actor, but it is for the use-cases. */ + +/* +Replaces: + jr ra + nop +*/ +PATCH_START 0x80bbd8e8 + j EnSGoro_OverrideBombshopGoronTextId_Hook + move a1, v0 +PATCH_END diff --git a/packages/core/src/mm/actors/En/En_S_Goro.c b/packages/core/src/mm/actors/En/En_S_Goro.c new file mode 100644 index 0000000000..8f83f5dfbc --- /dev/null +++ b/packages/core/src/mm/actors/En/En_S_Goro.c @@ -0,0 +1,48 @@ +#include +#include +#include + +#define EN_S_GORO_ACTIONFLAG_ROLLEDUP (1 << 0) +#define EN_S_GORO_ACTIONFLAG_FACEPLAYER (1 << 1) +#define EN_S_GORO_ACTIONFLAG_EYESOPEN (1 << 2) +#define EN_S_GORO_ACTIONFLAG_EARSCOVERED (1 << 3) +#define EN_S_GORO_ACTIONFLAG_ENGAGED (1 << 4) +#define EN_S_GORO_ACTIONFLAG_LASTMESSAGE (1 << 5) +#define EN_S_GORO_ACTIONFLAG_GKQUIET_ACKNOWLEDGED (1 << 6) +#define EN_S_GORO_ACTIONFLAG_SNOREPHASE (1 << 7) +#define EN_S_GORO_ACTIONFLAG_UNK0100 (1 << 8) +#define EN_S_GORO_ACTIONFLAG_HANDTAP (1 << 9) +#define EN_S_GORO_ACTIONFLAG_TIRED (1 << 10) +#define EN_S_GORO_ACTIONFLAG_SUPPRESS_SNORE (1 << 11) + +/* `this` isn't necessarily always current actor, but it is for these use-cases. */ +u16 EnSGoro_OverrideBombshopGoronTextId(EnSGoro* this, u16 textId) +{ + if (Config_Flag(CFG_MM_KEG_STRENGTH_3) && gSave.info.inventory.upgrades.strength >= 3) + { + s32 hasKeg = gSave.info.inventory.items[ITS_MM_KEG] == ITEM_MM_POWDER_KEG; + switch (textId) + { + /* My product is so heavy... */ + case 0x666: /* Human first time, after flavor text */ + return hasKeg + ? 0x66f /* Goron first time with keg, after flavor text */ + : 0x67c; /* Goron first time no keg, after flavor text */ + case 0x66c: /* Human second time */ + this->actionFlags &= ~EN_S_GORO_ACTIONFLAG_LASTMESSAGE; + return hasKeg + ? 0x679 /* Goron second time with keg */ + : 0x681; /* Goron second time no keg */ + case 0x66a: /* Human first time, night 3 after flavor text */ + return hasKeg + ? 0x678 /* Goron first time with keg, night 3 after flavor text */ + : 0x67f; /* Goron first time no keg, night 3 after flavor text */ + case 0x66d: /* Human second time, night 3 */ + this->actionFlags &= ~EN_S_GORO_ACTIONFLAG_LASTMESSAGE; + return hasKeg + ? 0x67a /* Goron second time with keg, night 3 */ + : 0x683; /* Goron second time no keg, night 3 */ + } + } + return textId; +} diff --git a/packages/core/src/mm/play/play.c b/packages/core/src/mm/play/play.c index 70c0f09886..215ebb0243 100644 --- a/packages/core/src/mm/play/play.c +++ b/packages/core/src/mm/play/play.c @@ -437,6 +437,14 @@ void Play_CheckRoomChangeHook(PlayState* play) } } +static void Play_CheckItemRestrictions() +{ + if (gPlayerFormItemRestrictions[MM_PLAYER_FORM_HUMAN][ITEM_MM_POWDER_KEG] == 0 && Config_Flag(CFG_MM_KEG_STRENGTH_3) && gSave.info.inventory.upgrades.strength >= 3) + { + gPlayerFormItemRestrictions[MM_PLAYER_FORM_HUMAN][ITEM_MM_POWDER_KEG] = 1; + } +} + static void Play_AfterInit(PlayState* play) { DrawGiSystem_Reset(play); @@ -453,6 +461,8 @@ static void Play_AfterInit(PlayState* play) ComboPlay_SpawnExtraSigns(play); Play_CheckRoomChangeHook(play); + Play_CheckItemRestrictions(); + if (Config_Flag(CFG_ER_ANY)) { if (play->sceneId == SCE_MM_STONE_TOWER_INVERTED) diff --git a/packages/core/src/mm/z_msgevent.c b/packages/core/src/mm/z_msgevent.c new file mode 100644 index 0000000000..842328f9ad --- /dev/null +++ b/packages/core/src/mm/z_msgevent.c @@ -0,0 +1,81 @@ +#include + +s32 MsgEvent_CheckStrength3(Actor* actor, PlayState* play, u8** script, MsgScriptCallback callback, s32* endScript) +{ + MsgScriptCmdCheckStrength3* cmd = (MsgScriptCmdCheckStrength3*)*script; + s16 skip = SCRIPT_PACK_16(cmd->offsetH, cmd->offsetL); + + if (Player_HasStrength(3)) + { + *script += skip; + } + + return false; +} + +MsgScriptCmdHandler sCustomMsgScriptCmdHandlers[] = +{ + MsgEvent_CheckStrength3, /* MSCRIPT_CUSTOM_CMD_ID_CHECK_STRENGTH_3 */ +}; + +u8 sCustomMsgScriptCmdSizes[] = +{ + sizeof(MsgScriptCmdCheckStrength3), /* MSCRIPT_CUSTOM_CMD_ID_CHECK_STRENGTH_3 */ +}; + +s32 MsgEvent_RunScript(Actor* actor, PlayState* play, MsgScript* script, MsgScriptCallback callback, s32* pos) +{ + u8* start; + u8* cur; + s32 scriptDone = false; + s32 cmdLen; + u8 cmdId; + u8 customCmdId; + s32 stop; + + start = script; + script += *pos; + + cmdLen = 0; + do + { + /* Skip data from previous command */ + script += cmdLen; + + /* Get command id */ + cmdId = *script; + + /* Get command length */ + if (cmdId < ARRAY_COUNTU(sMsgScriptCmdSizes)) + { + cmdLen = sMsgScriptCmdSizes[cmdId]; + stop = sMsgScriptCmdHandlers[cmdId](actor, play, &script, callback, &scriptDone); + } + else + { + customCmdId = cmdId - ARRAY_COUNTU(sMsgScriptCmdSizes); + if (customCmdId < ARRAY_COUNTU(sCustomMsgScriptCmdSizes)) + { + cmdLen = sCustomMsgScriptCmdSizes[customCmdId]; + stop = sCustomMsgScriptCmdHandlers[customCmdId](actor, play, &script, callback, &scriptDone); + } + else + { + cmdLen = -1; + } + } + } while (!stop); + + cur = script; + if (!scriptDone) + { + *pos = cur - start; + } + else + { + *pos = 0; + } + return scriptDone; +} + +PATCH_FUNC(0x8010BF58, MsgEvent_RunScript) diff --git a/packages/core/src/mm/z_parameter.c b/packages/core/src/mm/z_parameter.c index 9e99d61639..2eff8c0978 100644 --- a/packages/core/src/mm/z_parameter.c +++ b/packages/core/src/mm/z_parameter.c @@ -74,11 +74,9 @@ extern s8 gPlayerFormCustomItemRestrictions[5][8]; /* button and item are stored in SP10 and SP14 by HOOK_SAVE */ s8 Interface_GetItemRestriction(u8 playerForm, PlayState* play, s16* restoreHudVisibility, s32 nothing, u8 item, s16 button) { - s8 (*gPlayerFormItemRestrictions)[0x72] = (s8(*)[0x72])0x801c2410; if (item == ITEM_MM_MASK_GIANT && !comboHasSoulMm(GI_MM_SOUL_BOSS_TWINMOLD)) { - gPlayerFormItemRestrictions[playerForm][item] = 0; - gSaveContext.buttonStatus[button] = 0xff; + return 0; } if (item < ITEM_MM_CUSTOM_MIN) diff --git a/packages/data/src/macros/macros_mm.yml b/packages/data/src/macros/macros_mm.yml index b38595503f..35673c806f 100644 --- a/packages/data/src/macros/macros_mm.yml +++ b/packages/data/src/macros/macros_mm.yml @@ -84,6 +84,7 @@ "can_lift_bracelet": "!setting(strengthMm) || has_strength_raw(1)" "can_lift_silver": "setting(strengthMm) && has_strength_raw(2)" "can_lift_gold": "setting(strengthMm) && has_strength_raw(3)" +"can_carry_keg": "has_mask_goron || (setting(kegStrength3) && can_lift_gold)" # Megaton Hammer "can_hammer": "setting(hammerMm) && has_hammer_raw" diff --git a/packages/data/src/world/mm/overworld.yml b/packages/data/src/world/mm/overworld.yml index b4218b3af7..f32164034a 100644 --- a/packages/data/src/world/mm/overworld.yml +++ b/packages/data/src/world/mm/overworld.yml @@ -426,7 +426,7 @@ "Bomb Shop": region: ENTRANCE events: - BUY_KEG: "soul_goron && has_mask_goron && has(POWDER_KEG) && can_use_wallet(1)" + BUY_KEG: "soul_goron && can_carry_keg && has(POWDER_KEG) && can_use_wallet(1)" exits: "Clock Town West": "true" locations: @@ -2061,7 +2061,7 @@ STICKS: "can_kill_baba_sticks" MUSHROOM: "has(MASK_SCENTS)" locations: - "Twin Islands Frozen Grotto Chest": "has_explosives || trick_keg_explosives || (trick(MM_KEG_EXPLOSIVES) && event(POWDER_KEG_TRIAL))" + "Twin Islands Frozen Grotto Chest": "has_explosives || trick_keg_explosives || (trick(MM_KEG_EXPLOSIVES) && event(POWDER_KEG_TRIAL) && setting(erOverworld, none) && setting(erGrottos, none))" "Near Goron Race": region: TWIN_ISLANDS exits: @@ -2069,14 +2069,14 @@ "Goron Race": "event(TRIAL_BOULDER) || (short_hook_anywhere && trick(MM_HARD_HOOKSHOT))" "Near Ramp Grotto": "true" events: - TRIAL_BOULDER: "can_use_keg || (setting(erOverworld, none) && event(POWDER_KEG_TRIAL))" + TRIAL_BOULDER: "can_use_keg || (setting(erOverworld, none) && event(POWDER_KEG_TRIAL) && (has_mask_goron || has_mask_bunny))" "Near Ramp Grotto": region: TWIN_ISLANDS events: MAGIC: "true" exits: "Twin Islands": "true" - "Twin Islands Ramp Grotto": "stone_of_agony && (has_explosives || trick_keg_explosives || (trick(MM_KEG_EXPLOSIVES) && event(POWDER_KEG_TRIAL)) || can_hammer)" + "Twin Islands Ramp Grotto": "stone_of_agony && (has_explosives || trick_keg_explosives || (trick(MM_KEG_EXPLOSIVES) && event(POWDER_KEG_TRIAL) && setting(erOverworld, none)) || can_hammer)" locations: "Twin Islands Small Snowball Ramp 1": "is_winter" "Twin Islands Small Snowball Ramp 2": "is_winter" @@ -2088,7 +2088,7 @@ "Front of Lone Peak Shrine": "is_winter" "Goron Shrine": "(soul_goron && first_day) || has_mask_goron || can_hammer" events: - POWDER_KEG_TRIAL: "soul_medigoron && (is_spring || can_use_fire_short_range) && has_mask_goron" + POWDER_KEG_TRIAL: "soul_medigoron && (is_spring || can_use_fire_short_range) && can_carry_keg && (has_mask_goron || scarecrow_hookshot)" BUY_KEG: "soul_medigoron && event(POWDER_KEG_TRIAL) && event(TRIAL_BOULDER) && has(POWDER_KEG) && can_use_wallet(2)" MAGIC: "true" ARROWS: "true" From a330d24c9b914d62c6cfde67440fb08a3962a6e6 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Thu, 16 Jan 2025 16:41:54 +0100 Subject: [PATCH 02/34] Logic fix for MM/shared shields --- packages/data/src/macros/macros_oot.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/data/src/macros/macros_oot.yml b/packages/data/src/macros/macros_oot.yml index 231a39405a..9a3c9984b2 100644 --- a/packages/data/src/macros/macros_oot.yml +++ b/packages/data/src/macros/macros_oot.yml @@ -116,8 +116,8 @@ "can_use_sword_or_sticks": "can_use_sword || can_use_sticks" # Shields -"has_shield_deku": "age_shield_child && (renewable(SHIELD_DEKU) || event(SHIELD_DEKU) || has(SHIELD, 1) || has(SHARED_SHIELD, 1))" -"has_shield_hylian": "cond(setting(sharedShields), renewable(SHARED_SHIELD_HYLIAN), renewable(SHIELD_HYLIAN)) || has(SHIELD, 2) || has(SHARED_SHIELD, 2)" +"has_shield_deku": "age_shield_child && (renewable(SHIELD_DEKU) || renewable(SHARED_SHIELD_DEKU) || event(SHIELD_DEKU) || has(SHIELD, 1) || has(SHARED_SHIELD, 1))" +"has_shield_hylian": "renewable(SHIELD_HYLIAN) || renewable(SHIELD_HYLIAN) || has(SHIELD, 2) || has(SHARED_SHIELD, 2)" "has_shield": "has_shield_hylian || has_mirror_shield || has_shield_deku" "has_shield_for_scrubs": "(is_adult && has_shield_hylian) || has_shield_deku" "has_mirror_shield_raw_nonshared": "cond(setting(progressiveShieldsOot, progressive), has(SHIELD, 3), has(SHIELD_MIRROR))" @@ -208,7 +208,7 @@ "trick_mido": "trick(OOT_MIDO_SKIP) && (has_bow || has_hookshot(1) || has(SHARED_ARROW_FIRE) || has(ARROW_FIRE) || has(SHARED_ARROW_LIGHT) || has(ARROW_LIGHT))" # Mido / Deku Tree -"can_move_mido_reqs": "is_child && has_sword_kokiri && renewable(SHIELD_DEKU)" +"can_move_mido_reqs": "is_child && has_sword_kokiri && has_shield_deku" "can_move_mido": "can_move_mido_reqs && soul_npc(SOUL_NPC_MIDO)" "can_bypass_mido": "setting(dekuTree, open) || is_adult || climb_anywhere || hookshot_anywhere || can_move_mido_reqs" From e31ffb61f2547a4827dd643689fe452cab2a58f6 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Fri, 17 Jan 2025 19:22:17 +0100 Subject: [PATCH 03/34] Rename moon crash behavior reset -> last save --- packages/core/lib/combo/settings/data.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/lib/combo/settings/data.ts b/packages/core/lib/combo/settings/data.ts index 93b72f12db..dfee9efc30 100644 --- a/packages/core/lib/combo/settings/data.ts +++ b/packages/core/lib/combo/settings/data.ts @@ -900,7 +900,7 @@ export const SETTINGS = [{ type: 'enum', description: 'Change the behavior of moon crashing', values: [ - { value: 'reset', name: 'Reset', description: 'Moon Crash will restore the last save. No progress will be kept.' }, + { value: 'reset', name: 'Last Save', description: 'Moon Crash will restore the last save. No progress will be kept.' }, { value: 'cycle', name: 'New Cycle', description: 'Moon Crash will initiate a new cycle, keeping progress. Saving is enabled on the Clock Tower Roof.' }, ], cond: hasMM, From cef4bf0ad84f54fd77f433ca274cb71dcb19230c Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Fri, 17 Jan 2025 02:25:39 +0100 Subject: [PATCH 04/34] Add pool data --- packages/core/lib/combo/logic/fixer.ts | 6 +++++- packages/core/lib/combo/logic/locations.ts | 10 ++++++++-- packages/core/lib/combo/logic/price.ts | 4 ++++ packages/core/lib/combo/settings/data.ts | 9 +++++++++ packages/core/lib/combo/settings/random.ts | 1 + packages/data/src/defs/npc.yml | 4 ++-- packages/data/src/macros/macros_oot.yml | 1 + packages/data/src/pool/pool_oot.csv | 3 +++ packages/data/src/world/oot/overworld.yml | 9 ++++----- 9 files changed, 37 insertions(+), 10 deletions(-) diff --git a/packages/core/lib/combo/logic/fixer.ts b/packages/core/lib/combo/logic/fixer.ts index cde30737da..d75b966d00 100644 --- a/packages/core/lib/combo/logic/fixer.ts +++ b/packages/core/lib/combo/logic/fixer.ts @@ -2,7 +2,7 @@ import { ItemHelpers, Items } from '../items'; import { Monitor } from '../monitor'; import { Settings } from '../settings'; import { mustStartWithMasterSword } from '../settings/util'; -import { Location, MM_MERCHANTS, MM_SCRUBS, ONE_TIME_SHOP_CHECKS, OOT_ONE_TIME_SCRUBS, isLocationChestFairy, isLocationOtherFairy, makeLocation } from './locations'; +import { Location, MM_MERCHANTS, MM_SCRUBS, ONE_TIME_SHOP_CHECKS, OOT_MERCHANTS, OOT_ONE_TIME_SCRUBS, isLocationChestFairy, isLocationOtherFairy, makeLocation } from './locations'; import { World } from './world'; export class LogicPassFixer { @@ -36,6 +36,10 @@ export class LogicPassFixer { return true; } + if (!settings.shuffleMerchantsOot && OOT_MERCHANTS.includes(locId)) { + return true; + } + if (type === 'cow') { if (game === 'oot' && !this.state.settings.cowShuffleOot) { return true; diff --git a/packages/core/lib/combo/logic/locations.ts b/packages/core/lib/combo/logic/locations.ts index 1eeaebc21c..2998ce1493 100644 --- a/packages/core/lib/combo/logic/locations.ts +++ b/packages/core/lib/combo/logic/locations.ts @@ -45,6 +45,12 @@ export const MM_SCRUBS = [ 'MM Ikana Valley Scrub Shop', ]; +export const OOT_MERCHANTS = [ + 'OOT Haunted Wasteland Carpet Merchant', + 'OOT Kakariko Potion Shop Buy Blue Potion', + 'OOT Lon Lon Ranch Talon Buy Milk', +]; + export const MM_MERCHANTS = [ 'MM Gorman Track Milk Purchase', 'MM Milk Bar Purchase Milk', @@ -67,7 +73,7 @@ export function locationsZelda(settings: Settings) { export function isLocationRenewable(world: World, loc: Location) { const locationId = locationData(loc).id; - if (MM_SCRUBS.includes(locationId) || MM_MERCHANTS.includes(locationId)) + if (MM_SCRUBS.includes(locationId) || MM_MERCHANTS.includes(locationId) || OOT_MERCHANTS.includes(locationId)) return true; if (ONE_TIME_SHOP_CHECKS.includes(locationId)) return false; @@ -84,7 +90,7 @@ export function isLocationRenewable(world: World, loc: Location) { export function isLocationLicenseGranting(world: World, loc: Location) { const locationId = locationData(loc).id; - if (ONE_TIME_SHOP_CHECKS.includes(locationId) || MM_MERCHANTS.includes(locationId)) { + if (ONE_TIME_SHOP_CHECKS.includes(locationId) || MM_MERCHANTS.includes(locationId) || OOT_MERCHANTS.includes(locationId)) { return false; } const check = world.checks[locationId]; diff --git a/packages/core/lib/combo/logic/price.ts b/packages/core/lib/combo/logic/price.ts index 4620f09201..c3c4b05c60 100644 --- a/packages/core/lib/combo/logic/price.ts +++ b/packages/core/lib/combo/logic/price.ts @@ -38,6 +38,8 @@ const OOT_SCRUBS = [ ...OOT_SCRUBS_GC, ]; +const OOT_MERCHANTS = [200, 200, 100, 30]; + const MM_SHOP_BOMB = [30, 40, 50, 90]; const MM_SHOP_CURIOSITY = [500]; const MM_SHOP_TRADING = [30, 80, 80, 50, 10, 30, 30, 30]; @@ -65,6 +67,7 @@ const MM_TINGLE = [5, 40, 20, 40, 20, 40, 20, 40, 20, 40, 20, 40]; const PRICES = { OOT_SHOPS, OOT_SCRUBS, + OOT_MERCHANTS, MM_SHOPS, MM_SHOPS_EX, MM_TINGLE, @@ -195,6 +198,7 @@ export class LogicPassPrice { for (const world of this.state.worlds) { this.shufflePrices(world, 'OOT_SHOPS', this.state.settings.priceOotShops); this.shufflePrices(world, 'OOT_SCRUBS', this.state.settings.priceOotScrubs); + this.shufflePrices(world, 'OOT_MERCHANTS', this.state.settings.priceOotMerchants); this.shufflePrices(world, 'MM_SHOPS', this.state.settings.priceMmShops); this.shufflePrices(world, 'MM_SHOPS_EX', this.state.settings.priceMmShops); this.shufflePrices(world, 'MM_TINGLE', this.state.settings.priceMmTingle); diff --git a/packages/core/lib/combo/settings/data.ts b/packages/core/lib/combo/settings/data.ts index dfee9efc30..62c166f009 100644 --- a/packages/core/lib/combo/settings/data.ts +++ b/packages/core/lib/combo/settings/data.ts @@ -816,6 +816,14 @@ export const SETTINGS = [{ description: 'Controls whether or not trading the masks are checks', cond: hasOoT, default: false, +}, { + key: 'shuffleMerchantsOot', + name: 'Merchants Shuffle (OoT)', + category: 'main.shuffle', + type: 'boolean', + description: 'Controls whether or not the Old Hag Potion, Talon Milk and Carpet Man Bombchu are shuffled.', + cond: hasOoT, + default: false }, { key: 'shuffleMerchantsMm', name: 'Merchants Shuffle (MM)', @@ -875,6 +883,7 @@ export const SETTINGS = [{ }, { ...SETTING_PRICE, key: 'priceOotShops', name: 'OoT Shop Prices', description: 'Sets the price of items inside OoT shops', cond: hasOoT }, { ...SETTING_PRICE, key: 'priceOotScrubs', name: 'OoT Scrub Prices', description: 'Sets the price of items sold by OoT scrubs', cond: hasOoT }, +{ ...SETTING_PRICE, key: 'priceOotMerchants', name: 'OoT Merchants Prices', description: 'Sets the price of items sold by OoT merchants', cond: hasOoT }, { ...SETTING_PRICE, key: 'priceMmShops', name: 'MM Shop Prices', description: 'Sets the price of items sold inside MM shops', cond: hasMM }, { ...SETTING_PRICE, key: 'priceMmTingle', name: 'MM Tingle Prices', description: 'Sets the price of items sold by Tingle', cond: hasMM }, { diff --git a/packages/core/lib/combo/settings/random.ts b/packages/core/lib/combo/settings/random.ts index 308204d01c..47e64184d6 100644 --- a/packages/core/lib/combo/settings/random.ts +++ b/packages/core/lib/combo/settings/random.ts @@ -102,6 +102,7 @@ export async function applyRandomSettings(rnd: OptionRandomSettings, oldSettings } base.shuffleMerchantsMm = booleanWeighted(random, 0.50); + base.shuffleMerchantsOot = booleanWeighted(random, 0.50); base.eggShuffle = booleanWeighted(random, 0.50); base.songs = sampleWeighted(random, { songLocations: 6, anywhere: 4 }); base.divingGameRupeeShuffle = booleanWeighted(random, 0.50); diff --git a/packages/data/src/defs/npc.yml b/packages/data/src/defs/npc.yml index b9fbd116bc..5ec170a73a 100644 --- a/packages/data/src/defs/npc.yml +++ b/packages/data/src/defs/npc.yml @@ -14,8 +14,8 @@ OOT_LOST_WOODS_MEMORY: 0x0c OOT_THEATER_STICKS: 0x0d OOT_THEATER_NUTS: 0x0e OOT_BEAN_SELLER: 0x0f -#OOT_SCRUB_STICKS: 0x10 -#OOT_SCRUB_NUTS: 0x11 +OOT_WITCH_BLUE_POTION: 0x10 +OOT_TALON_MILK: 0x11 #OOT_SCRUB_HP: 0x12 OOT_GS_10: 0x13 OOT_GS_20: 0x14 diff --git a/packages/data/src/macros/macros_oot.yml b/packages/data/src/macros/macros_oot.yml index 9a3c9984b2..064b115d97 100644 --- a/packages/data/src/macros/macros_oot.yml +++ b/packages/data/src/macros/macros_oot.yml @@ -230,6 +230,7 @@ "wallet_price(range, id)": "price(range, id, 0) || has_rupees && ((price(range, id, 99) && has_wallet(1)) || (price(range, id, 200) && has_wallet(2)) || (price(range, id, 500) && has_wallet(3)) || (setting(colossalWallets) && price(range, id, 999) && has_wallet(4)) || (setting(bottomlessWallets) && price(range, id, 9999) && has_wallet(5)))" "shop_price(id)": "wallet_price(OOT_SHOPS, id)" "scrub_price(id)": "wallet_price(OOT_SCRUBS, id)" +"merchant_price(id)": "wallet_price(OOT_MERCHANTS, id)" # Keys "has_skeleton_key": "setting(skeletonKeyOot) && cond(setting(sharedSkeletonKey), has(SHARED_SKELETON_KEY), has(SKELETON_KEY))" diff --git a/packages/data/src/pool/pool_oot.csv b/packages/data/src/pool/pool_oot.csv index f12be7e824..c827259b7e 100644 --- a/packages/data/src/pool/pool_oot.csv +++ b/packages/data/src/pool/pool_oot.csv @@ -248,6 +248,7 @@ Kakariko Wonder Item, wonder, NONE Kakariko Butterfly 1, butterfly, NONE, KAKARIKO_VILLAGE, 0x0002e, FAIRY Kakariko Butterfly 2, butterfly, NONE, KAKARIKO_VILLAGE, 0x1002e, NOTHING Kakariko Potion Shop Odd Potion, npc, NONE, KAKARIKO_POTION_SHOP, TRADE_ODD_POTION, ODD_POTION +Kakariko Potion Shop Buy Blue Potion, npc, NONE, KAKARIKO_POTION_SHOP, WITCH_BLUE_POTION, POTION_BLUE Kakariko Bazaar Item 1, shop, NONE, BAZAAR, 0x30, ARROWS_5 Kakariko Bazaar Item 2, shop, NONE, BAZAAR, 0x31, ARROWS_10 Kakariko Bazaar Item 3, shop, NONE, BAZAAR, 0x32, ARROWS_30 @@ -693,6 +694,7 @@ Fishing Pond Adult Loach, fish, NONE Lon Lon Ranch Malon Song, npc, NONE, LON_LON_RANCH, MALON_SONG, SONG_EPONA Lon Lon Ranch Silo HP, collectible, NONE, RANCH_HOUSE_SILO, 0x01, HEART_PIECE Lon Lon Ranch Talon Bottle, npc, NONE, RANCH_HOUSE_SILO, TALON_BOTTLE, BOTTLE_MILK +Lon Lon Ranch Talon Buy Milk, npc, NONE, RANCH_HOUSE_SILO, TALON_MILK, MILK Lon Lon Ranch Talon House Pot 1, pot, NONE, RANCH_HOUSE_SILO, 0x0200, RUPEE_BLUE Lon Lon Ranch Talon House Pot 2, pot, NONE, RANCH_HOUSE_SILO, 0x0201, RUPEE_BLUE Lon Lon Ranch Talon House Pot 3, pot, NONE, RANCH_HOUSE_SILO, 0x0202, RUPEE_GREEN @@ -1052,6 +1054,7 @@ Gerudo Fortress Fairy Fountain Fairy 5, fairy, NONE Gerudo Fortress Fairy Fountain Fairy 6, fairy, NONE, FAIRY_FOUNTAIN, 0x52400, FAIRY Gerudo Fortress Fairy Fountain Fairy 7, fairy, NONE, FAIRY_FOUNTAIN, 0x62400, FAIRY Gerudo Fortress Fairy Fountain Fairy 8, fairy, NONE, FAIRY_FOUNTAIN, 0x72400, FAIRY +Haunted Wasteland Carpet Merchant, npc, NONE, HAUNTED_WASTELAND, CARPET_MERCHANT, BOMBCHU_20 Haunted Wasteland Chest, chest, HAUNTED_WASTELAND, HAUNTED_WASTELAND, 0x00, RUPEE_PURPLE Haunted Wasteland GS, gs, NONE, HAUNTED_WASTELAND, 0xb1, GS_TOKEN Haunted Wasteland Pot 1, pot, NONE, HAUNTED_WASTELAND, 0x0000, RECOVERY_HEART diff --git a/packages/data/src/world/oot/overworld.yml b/packages/data/src/world/oot/overworld.yml index deb8a7f2b2..0806ffc9a3 100644 --- a/packages/data/src/world/oot/overworld.yml +++ b/packages/data/src/world/oot/overworld.yml @@ -798,6 +798,7 @@ "Lon Lon Ranch": "true" locations: "Lon Lon Ranch Talon Bottle": "is_child && woke_talon_child && can_use_wallet(1) && is_day && soul_talon" + "Lon Lon Ranch Talon Buy Milk": "is_child && woke_talon_child && can_use_wallet(1) && is_day && soul_talon && merchant_price(0x03)" "Lon Lon Ranch Talon House Pot 1": "true" "Lon Lon Ranch Talon House Pot 2": "true" "Lon Lon Ranch Talon House Pot 3": "true" @@ -1329,10 +1330,9 @@ region: ENTRANCE exits: "Kakariko Back": "true" - events: - MAGIC: "adult_trade(ODD_MUSHROOM) && can_use_wallet(2) && has_bottle" locations: "Kakariko Potion Shop Odd Potion": "soul_old_hag && adult_trade(ODD_MUSHROOM)" + "Kakariko Potion Shop Buy Blue Potion": "soul_old_hag && adult_trade(ODD_MUSHROOM) && merchant_price(0x02)" "Shooting Gallery Adult": region: ENTRANCE exits: @@ -1669,7 +1669,7 @@ "Goron City Big Pot HP": "is_child && has_bombs && (event(DARUNIA_TORCH) || has_fire)" "Goron City Tunic": "is_adult && (has_explosives || can_use_bow || has_goron_bracelet) && soul_goron_child" "Goron City Bomb Bag": "is_child && has_explosives && soul_goron" - "Goron City Medigoron Giant Knife": "is_adult && (has_bombflowers || can_hammer || has_blue_fire_arrows_mudwall) && can_use_wallet(2) && soul_medigoron" + "Goron City Medigoron Giant Knife": "is_adult && (has_bombflowers || can_hammer || has_blue_fire_arrows_mudwall) && merchant_price(0x00) && soul_medigoron" "Goron City GS Platform": "gs && is_adult && can_damage_skull" "Goron City GS Maze": "gs && is_child && (has_explosives_or_hammer || (climb_anywhere && can_damage_skull) || hookshot_anywhere)" "Goron City Pot Stairs 1": "true" @@ -2521,9 +2521,8 @@ exits: "Haunted Wasteland Start": "can_longshot || has_hover_boots || trick(OOT_SAND_RIVER_NOTHING)" "Haunted Wasteland End": "has_lens_strict || trick(OOT_BLIND_WASTELAND)" - events: - BOMBCHU: "soul_carpet_man && can_use_wallet(2)" locations: + "Haunted Wasteland Carpet Merchant": "soul_carpet_man && merchant_price(0x01)" "Haunted Wasteland Chest": "has_fire" "Haunted Wasteland GS": "gs && (can_collect_distance || (climb_anywhere && (has_ranged_weapon || has_explosives || can_use_sword || can_use_sticks || can_use_din)))" "Haunted Wasteland Pot 1": "true" From b6afc9136d021e8402c0c050fe61187485143ae4 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Fri, 17 Jan 2025 03:08:49 +0100 Subject: [PATCH 05/34] Working Blue Potion check --- packages/core/src/oot/actors/En/En_Ds.c | 107 ++++++++++++++++++++++++ packages/core/src/oot/actors/Player.c | 4 + 2 files changed, 111 insertions(+) diff --git a/packages/core/src/oot/actors/En/En_Ds.c b/packages/core/src/oot/actors/En/En_Ds.c index d871c86a5d..18640368ad 100644 --- a/packages/core/src/oot/actors/En/En_Ds.c +++ b/packages/core/src/oot/actors/En/En_Ds.c @@ -2,6 +2,9 @@ #include #include #include +#include + +#define PRICE (gComboConfig.prices[PRICES_OOT_MERCHANTS + 0x02]) void EnDs_GiveItem(Actor* actor, PlayState* play, s16 gi, float a, float b) { @@ -13,3 +16,107 @@ void EnDs_GiveItem(Actor* actor, PlayState* play, s16 gi, float a, float b) PATCH_CALL(0x80aabcec, EnDs_GiveItem); PATCH_CALL(0x80aabc6c, EnDs_GiveItem); + +void EnDs_BluePotionItemQuery(ComboItemQuery* q) +{ + memset(q, 0, sizeof(ComboItemQuery)); + q->gi = GI_OOT_POTION_BLUE; + q->ovType = OV_NPC; + q->id = NPC_OOT_WITCH_BLUE_POTION; + q->giRenew = GI_OOT_RECOVERY_HEART; + if (BITMAP8_GET(gSharedCustomSave.oot.npc, NPC_OOT_WITCH_BLUE_POTION)) + q->ovFlags |= OVF_RENEW; +} + +static void EnDs_BluePotionItemOverride(ComboItemOverride* o) +{ + ComboItemQuery q; + + EnDs_BluePotionItemQuery(&q); + comboItemOverride(o, &q); +} + +static void EnDs_BluePotionTextOverride(PlayState* play) +{ + char* b; + ComboItemOverride o; + + EnDs_BluePotionItemOverride(&o); + b = play->msgCtx.textBuffer; + comboTextAppendHeader(&b); + comboTextAppendItemName(&b, o.giRaw, TF_CAPITALIZE | TF_PREPOS | TF_PROGRESSIVE); + comboTextAppendStr(&b, "!" TEXT_NL "How about " TEXT_COLOR_RED); + comboTextAppendNum(&b, PRICE); + comboTextAppendStr(&b, " Rupees"); + comboTextAppendClearColor(&b); + comboTextAppendStr(&b, "?" TEXT_NL TEXT_COLOR_GREEN TEXT_CHOICE2 "Yes" TEXT_NL "No" TEXT_END); +} + +void EnDs_TalkedTo(Actor* actor, PlayState* play, s16 textId) +{ + if (textId == 0x500c) + { + EnDs_BluePotionTextOverride(play); + } +} + +static void EnDs_MessageBoxCantBuy(PlayState* play, s16 textId) +{ + DisplayTextBox2(play, textId); + comboTextMessageCantBuy(play, 0); +} + +PATCH_CALL(0x80aac0b8, EnDs_MessageBoxCantBuy); + +static int EnDs_CanBuy(void) +{ + ComboItemQuery q; + int ret; + + EnDs_BluePotionItemQuery(&q); + ret = comboItemPrecondEx(&q, PRICE); + switch (ret) + { + case SC_ERR_NORUPEES: + return 0; + case SC_OK: + case SC_OK_NOCUTSCENE: + return 2; + default: + return 1; + } +} + +PATCH_FUNC(0x80aabf68, EnDs_CanBuy); + +static void EnDs_PayBluePotion(void) +{ + AddRupeesRaw(-PRICE); +} + +PATCH_CALL(0x80aac0d4, EnDs_PayBluePotion); + +static void EnDs_GiveBluePotion(Actor* this, PlayState* play, s16 gi, float a, float b) +{ + ComboItemQuery q; + Player* player; + + player = GET_PLAYER(play); + if (player->stateFlags1 & PLAYER_ACTOR_STATE_GET_ITEM) + return; + EnDs_BluePotionItemQuery(&q); + comboGiveItem(this, play, &q, a, b); +} + +PATCH_CALL(0x80aac10c, EnDs_GiveBluePotion); +PATCH_CALL(0x80aac004, EnDs_GiveBluePotion); + +static int EnDs_AfterBuy(Actor* this, PlayState* play) +{ + if (!Actor_HasParentZ(this)) + return 0; + BITMAP8_SET(gSharedCustomSave.oot.npc, NPC_OOT_WITCH_BLUE_POTION); + return 1; +} + +PATCH_CALL(0x80aabfc8, EnDs_AfterBuy); diff --git a/packages/core/src/oot/actors/Player.c b/packages/core/src/oot/actors/Player.c index 67c6a6901d..7c615f9fcc 100644 --- a/packages/core/src/oot/actors/Player.c +++ b/packages/core/src/oot/actors/Player.c @@ -304,6 +304,7 @@ void EnGs_TalkedTo(Actor*, PlayState*); void EnGm_TalkedTo(Actor*, PlayState*); void EnMs_TalkedTo(Actor*, PlayState*); void EnSsh_TalkedTo(Actor*, PlayState*); +void EnDs_TalkedTo(Actor*, PlayState*, s16); void DemoEffect_TextRutoSapphire(PlayState*); @@ -331,6 +332,9 @@ void Player_TalkDisplayTextBox(PlayState* play, s16 textId, Actor* actor) case ACTOR_EN_KANBAN: gEnKanban_TalkedTo(actor, play); break; + case ACTOR_EN_DS: + EnDs_TalkedTo(actor, play, textId); + break; } } From bc9b276a5fc588c1089197114d92ebe406473bc0 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Fri, 17 Jan 2025 19:21:34 +0100 Subject: [PATCH 06/34] Carpet Merchant stub --- packages/core/src/oot/actors/En/En_Js.c | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/core/src/oot/actors/En/En_Js.c diff --git a/packages/core/src/oot/actors/En/En_Js.c b/packages/core/src/oot/actors/En/En_Js.c new file mode 100644 index 0000000000..bc854174ab --- /dev/null +++ b/packages/core/src/oot/actors/En/En_Js.c @@ -0,0 +1,5 @@ +#include +#include +#include +#include + From 8f90ec294fe459ae52c6955c493a141739dc78a4 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Fri, 17 Jan 2025 19:58:04 +0100 Subject: [PATCH 07/34] Working Carpet Merchant --- packages/core/src/oot/actors/En/En_Js.S | 10 +++ packages/core/src/oot/actors/En/En_Js.c | 84 +++++++++++++++++++++++++ packages/core/src/oot/actors/Player.c | 4 ++ 3 files changed, 98 insertions(+) create mode 100644 packages/core/src/oot/actors/En/En_Js.S diff --git a/packages/core/src/oot/actors/En/En_Js.S b/packages/core/src/oot/actors/En/En_Js.S new file mode 100644 index 0000000000..2a20598b94 --- /dev/null +++ b/packages/core/src/oot/actors/En/En_Js.S @@ -0,0 +1,10 @@ +#include + +/* Use our own handler for the buy */ +PATCH_START 0x80adb790 + li at,0 +PATCH_END + +PATCH_START 0x80adb7b4 + nop +PATCH_END diff --git a/packages/core/src/oot/actors/En/En_Js.c b/packages/core/src/oot/actors/En/En_Js.c index bc854174ab..05453918c3 100644 --- a/packages/core/src/oot/actors/En/En_Js.c +++ b/packages/core/src/oot/actors/En/En_Js.c @@ -3,3 +3,87 @@ #include #include +#define SET_HANDLER(a, h) do { *(void**)(((char*)(a)) + 0x27c) = (h); } while (0) +#define PRICE (gComboConfig.prices[PRICES_OOT_MERCHANTS + 0x01]) + +void EnJs_ItemQuery(ComboItemQuery* q) +{ + memset(q, 0, sizeof(ComboItemQuery)); + q->gi = GI_OOT_BOMBCHU_20; + q->ovType = OV_NPC; + q->id = NPC_OOT_CARPET_MERCHANT; + q->giRenew = GI_OOT_RECOVERY_HEART; + if (BITMAP8_GET(gSharedCustomSave.oot.npc, NPC_OOT_CARPET_MERCHANT)) + q->ovFlags |= OVF_RENEW; +} + +static void EnJs_TextOverride(PlayState* play) +{ + char* b; + ComboItemQuery q; + + EnJs_ItemQuery(&q); + b = play->msgCtx.textBuffer; + comboTextAppendHeader(&b); + comboTextAppendItemNameQuery(&b, &q, TF_CAPITALIZE | TF_PREPOS | TF_PROGRESSIVE); + comboTextAppendStr(&b, "!" TEXT_NL "How about " TEXT_COLOR_RED); + comboTextAppendNum(&b, PRICE); + comboTextAppendStr(&b, " Rupees"); + comboTextAppendClearColor(&b); + comboTextAppendStr(&b, "?" TEXT_NL TEXT_COLOR_GREEN TEXT_CHOICE2 "Yes" TEXT_NL "No" TEXT_END); +} + +void EnJs_TalkedTo(Actor* actor, PlayState* play, s16 textId) +{ + if (textId == 0x6077) + { + EnJs_TextOverride(play); + } +} + +static void EnJs_HandleBuyGetItem(Actor* this, PlayState* play) +{ + Player* player; + ComboItemQuery q; + + if (Actor_HasParentZ(this)) + { + BITMAP8_SET(gSharedCustomSave.oot.npc, NPC_OOT_CARPET_MERCHANT); + *(int*)((char*)this + 0x118) = 0; + SET_HANDLER(this, actorAddr(ACTOR_EN_JS, 0x80adb868)); + return; + } + + player = GET_PLAYER(play); + if (player->stateFlags1 & PLAYER_ACTOR_STATE_GET_ITEM) + return; + + EnJs_ItemQuery(&q); + comboGiveItem(this, play, &q, 9999.f, 9999.f); +} + +static void EnJs_HandleBuy(Actor* this, PlayState* play) +{ + void (*EnJs_CancelBuy)(Actor*); + ComboItemQuery q; + int ret; + + EnJs_ItemQuery(&q); + ret = comboItemPrecondEx(&q, PRICE); + + if (ret == SC_OK || ret == SC_OK_NOCUTSCENE) + { + AddRupeesRaw(-PRICE); + SET_HANDLER(this, EnJs_HandleBuyGetItem); + } + else + { + DisplayTextBox2(play, 0x6074); + if (ret != SC_ERR_NORUPEES) + comboTextMessageCantBuy(play, 0); + EnJs_CancelBuy = actorAddr(ACTOR_EN_JS, 0x80adb554); + EnJs_CancelBuy(this); + } +} + +PATCH_FUNC(0x80adb6b8, EnJs_HandleBuy); diff --git a/packages/core/src/oot/actors/Player.c b/packages/core/src/oot/actors/Player.c index 7c615f9fcc..1dbfb5af07 100644 --- a/packages/core/src/oot/actors/Player.c +++ b/packages/core/src/oot/actors/Player.c @@ -305,6 +305,7 @@ void EnGm_TalkedTo(Actor*, PlayState*); void EnMs_TalkedTo(Actor*, PlayState*); void EnSsh_TalkedTo(Actor*, PlayState*); void EnDs_TalkedTo(Actor*, PlayState*, s16); +void EnJs_TalkedTo(Actor*, PlayState*, s16); void DemoEffect_TextRutoSapphire(PlayState*); @@ -335,6 +336,9 @@ void Player_TalkDisplayTextBox(PlayState* play, s16 textId, Actor* actor) case ACTOR_EN_DS: EnDs_TalkedTo(actor, play, textId); break; + case ACTOR_EN_JS: + EnJs_TalkedTo(actor, play, textId); + break; } } From e155036f1f620c483ead5ead94901330baa3b103 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Fri, 17 Jan 2025 20:27:18 +0100 Subject: [PATCH 08/34] Working Talon Milk --- packages/core/src/link_oot.in | 1 + packages/core/src/oot/actors/En/En_Ds.c | 14 +-- packages/core/src/oot/actors/En/En_Js.c | 2 +- packages/core/src/oot/actors/En/En_Ta.c | 108 ++++++++++++++++++++++++ packages/core/src/oot/actors/Player.c | 4 + 5 files changed, 117 insertions(+), 12 deletions(-) diff --git a/packages/core/src/link_oot.in b/packages/core/src/link_oot.in index fae8522567..86fcfdfa2c 100644 --- a/packages/core/src/link_oot.in +++ b/packages/core/src/link_oot.in @@ -65,6 +65,7 @@ Actor_OfferGetItem = 0x80022bd4; GiveItemDefaultRange = 0x80022cf4; DisplayTextBox = 0x800dc838; DisplayTextBox2 = 0x800dce80; +Message_ShouldAdvance = 0x800d6110; RequestDma = 0x80000d28; kObjectsTable = 0x800f8ff8; diff --git a/packages/core/src/oot/actors/En/En_Ds.c b/packages/core/src/oot/actors/En/En_Ds.c index 18640368ad..b8ee2845b1 100644 --- a/packages/core/src/oot/actors/En/En_Ds.c +++ b/packages/core/src/oot/actors/En/En_Ds.c @@ -28,23 +28,15 @@ void EnDs_BluePotionItemQuery(ComboItemQuery* q) q->ovFlags |= OVF_RENEW; } -static void EnDs_BluePotionItemOverride(ComboItemOverride* o) -{ - ComboItemQuery q; - - EnDs_BluePotionItemQuery(&q); - comboItemOverride(o, &q); -} - static void EnDs_BluePotionTextOverride(PlayState* play) { char* b; - ComboItemOverride o; + ComboItemQuery q; - EnDs_BluePotionItemOverride(&o); + EnDs_BluePotionItemQuery(&q); b = play->msgCtx.textBuffer; comboTextAppendHeader(&b); - comboTextAppendItemName(&b, o.giRaw, TF_CAPITALIZE | TF_PREPOS | TF_PROGRESSIVE); + comboTextAppendItemNameQuery(&b, &q, TF_CAPITALIZE | TF_PREPOS | TF_PROGRESSIVE); comboTextAppendStr(&b, "!" TEXT_NL "How about " TEXT_COLOR_RED); comboTextAppendNum(&b, PRICE); comboTextAppendStr(&b, " Rupees"); diff --git a/packages/core/src/oot/actors/En/En_Js.c b/packages/core/src/oot/actors/En/En_Js.c index 05453918c3..b9c4dd77e9 100644 --- a/packages/core/src/oot/actors/En/En_Js.c +++ b/packages/core/src/oot/actors/En/En_Js.c @@ -6,7 +6,7 @@ #define SET_HANDLER(a, h) do { *(void**)(((char*)(a)) + 0x27c) = (h); } while (0) #define PRICE (gComboConfig.prices[PRICES_OOT_MERCHANTS + 0x01]) -void EnJs_ItemQuery(ComboItemQuery* q) +static void EnJs_ItemQuery(ComboItemQuery* q) { memset(q, 0, sizeof(ComboItemQuery)); q->gi = GI_OOT_BOMBCHU_20; diff --git a/packages/core/src/oot/actors/En/En_Ta.c b/packages/core/src/oot/actors/En/En_Ta.c index 573c2e2952..a73935753f 100644 --- a/packages/core/src/oot/actors/En/En_Ta.c +++ b/packages/core/src/oot/actors/En/En_Ta.c @@ -1,6 +1,10 @@ #include #include #include +#include + +#define SET_HANDLER(a, h) do { *(void**)(((char*)(a)) + 0x24c) = (h); } while (0) +#define PRICE (gComboConfig.prices[PRICES_OOT_MERCHANTS + 0x03]) int EnTa_GetActiveItem_Chicken(Actor* this, PlayState* play) { @@ -21,3 +25,107 @@ void EnTa_GiveItem_MilkBottle(Actor* this, PlayState* play, s16 gi, float a, flo PATCH_CALL(0x80923cd8, EnTa_GiveItem_MilkBottle); PATCH_CALL(0x80923d7c, EnTa_GiveItem_MilkBottle); + +static void EnTa_BuyItemQuery(ComboItemQuery* q) +{ + memset(q, 0, sizeof(ComboItemQuery)); + q->gi = GI_OOT_MILK; + q->ovType = OV_NPC; + q->id = NPC_OOT_TALON_MILK; + q->giRenew = GI_OOT_RECOVERY_HEART; + if (BITMAP8_GET(gSharedCustomSave.oot.npc, NPC_OOT_TALON_MILK)) + q->ovFlags |= OVF_RENEW; +} + +static void EnTa_BuyTextOverride(PlayState* play) +{ + char* b; + ComboItemQuery q; + + EnTa_BuyItemQuery(&q); + b = play->msgCtx.textBuffer; + comboTextAppendHeader(&b); + comboTextAppendItemNameQuery(&b, &q, TF_CAPITALIZE | TF_PREPOS | TF_PROGRESSIVE); + comboTextAppendStr(&b, "!" TEXT_NL "How about " TEXT_COLOR_RED); + comboTextAppendNum(&b, PRICE); + comboTextAppendStr(&b, " Rupees"); + comboTextAppendClearColor(&b); + comboTextAppendStr(&b, "?" TEXT_NL TEXT_COLOR_GREEN TEXT_CHOICE2 "Yes" TEXT_NL "No" TEXT_END); +} + +void EnTa_TalkedTo(Actor* actor, PlayState* play, s16 textId) +{ + if (textId == 0x208b) + { + EnTa_BuyTextOverride(play); + } +} + +static void EnTa_Reset(Actor* this) +{ + void (*resetFunc)(Actor*, void*); + void* arg; + + resetFunc = actorAddr(ACTOR_EN_TA, 0x80922cb4); + arg = actorAddr(ACTOR_EN_TA, 0x809242bc); + + resetFunc(this, arg); +} + +static void EnTa_BuyMilkHandler(Actor* this, PlayState* play) +{ + Player* player; + ComboItemQuery q; + + if (Actor_HasParentZ(this)) + { + BITMAP8_SET(gSharedCustomSave.oot.npc, NPC_OOT_TALON_MILK); + EnTa_Reset(this); + return; + } + + player = GET_PLAYER(play); + if (player->stateFlags1 & PLAYER_ACTOR_STATE_GET_ITEM) + return; + + EnTa_BuyItemQuery(&q); + comboGiveItem(this, play, &q, 9999.f, 9999.f); +} + +static void EnTa_BuyMilk(Actor* this, PlayState* play) +{ + ComboItemQuery q; + int ret; + + EnTa_BuyItemQuery(&q); + ret = comboItemPrecondEx(&q, PRICE); + + if (ret == SC_OK || ret == SC_OK_NOCUTSCENE) + { + AddRupeesRaw(-PRICE); + SET_HANDLER(this, EnTa_BuyMilkHandler); + } + else + { + DisplayTextBox2(play, 0x85); + if (ret != SC_ERR_NORUPEES) + comboTextMessageCantBuy(play, 0); + EnTa_Reset(this); + } +} + +static void EnTa_BuyMilkPromptHandler(Actor* this, PlayState* play) +{ + if (Message_GetState(&play->msgCtx) != 4 || !Message_ShouldAdvance(play)) + return; + + if (play->msgCtx.choiceIndex == 1) + { + EnTa_Reset(this); + return; + } + + EnTa_BuyMilk(this, play); +} + +PATCH_FUNC(0x80923d94, EnTa_BuyMilkPromptHandler); diff --git a/packages/core/src/oot/actors/Player.c b/packages/core/src/oot/actors/Player.c index 1dbfb5af07..bbd0857f1d 100644 --- a/packages/core/src/oot/actors/Player.c +++ b/packages/core/src/oot/actors/Player.c @@ -306,6 +306,7 @@ void EnMs_TalkedTo(Actor*, PlayState*); void EnSsh_TalkedTo(Actor*, PlayState*); void EnDs_TalkedTo(Actor*, PlayState*, s16); void EnJs_TalkedTo(Actor*, PlayState*, s16); +void EnTa_TalkedTo(Actor*, PlayState*, s16); void DemoEffect_TextRutoSapphire(PlayState*); @@ -339,6 +340,9 @@ void Player_TalkDisplayTextBox(PlayState* play, s16 textId, Actor* actor) case ACTOR_EN_JS: EnJs_TalkedTo(actor, play, textId); break; + case ACTOR_EN_TA: + EnTa_TalkedTo(actor, play, textId); + break; } } From 036013275d123ef3b48a4ee9d79929996f0a3fd5 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Fri, 17 Jan 2025 20:41:05 +0100 Subject: [PATCH 09/34] Fix Medigoron --- packages/core/src/oot/actors/En/En_Gm.S | 9 +++++ packages/core/src/oot/actors/En/En_Gm.c | 48 ++++++++++++++++++------- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/packages/core/src/oot/actors/En/En_Gm.S b/packages/core/src/oot/actors/En/En_Gm.S index 95876b6d22..eb70071dba 100644 --- a/packages/core/src/oot/actors/En/En_Gm.S +++ b/packages/core/src/oot/actors/En/En_Gm.S @@ -8,3 +8,12 @@ PATCH_END PATCH_START 0x80a9fbe4 nop PATCH_END + +/* Custom rupee cost */ +PATCH_START 0x80a9ff9c + li at,0 +PATCH_END + +PATCH_START 0x80a9ffd8 + nop +PATCH_END diff --git a/packages/core/src/oot/actors/En/En_Gm.c b/packages/core/src/oot/actors/En/En_Gm.c index 541b55c1b5..bcf44e0257 100644 --- a/packages/core/src/oot/actors/En/En_Gm.c +++ b/packages/core/src/oot/actors/En/En_Gm.c @@ -1,6 +1,9 @@ #include #include +#define SET_HANDLER(a, h) do { *(void**)(((char*)(a)) + 0x25c) = (h); } while (0) +#define PRICE (gComboConfig.prices[PRICES_OOT_MERCHANTS + 0x00]) + static void EnGm_ItemQuery(ComboItemQuery* q) { bzero(q, sizeof(ComboItemQuery)); @@ -10,28 +13,45 @@ static void EnGm_ItemQuery(ComboItemQuery* q) q->id = NPC_OOT_MEDIGORON; } -int EnGm_HasGivenItem(Actor* this) +static void EnGm_Reset(Actor* this) +{ + SET_HANDLER(this, actorAddr(ACTOR_EN_GM, 0x80a9fd5c)); +} + +static void EnGm_GiveItemHandler2(Actor* this, PlayState* play) { + Player* player; + ComboItemQuery q; + if (Actor_HasParentZ(this)) { BITMAP16_SET(gSave.info.eventsMisc, EV_OOT_INF_MEDIGORON); - return 1; + EnGm_Reset(this); + return; } - return 0; -} -PATCH_CALL(0x80aa0030, EnGm_HasGivenItem); + player = GET_PLAYER(play); + if (player->stateFlags1 & PLAYER_ACTOR_STATE_GET_ITEM) + return; + EnGm_ItemQuery(&q); + comboGiveItem(this, play, &q, 9999.0f, 9999.0f); +} -void EnGm_GiveItem(Actor* actor, PlayState* play, s16 gi, float a, float b) +static void EnGm_GiveItemHandler(Actor* this, PlayState* play) { - ComboItemQuery q; + if (gSave.info.playerData.rupees < PRICE) + { + DisplayTextBox2(play, 200); + EnGm_Reset(this); + return; + } - EnGm_ItemQuery(&q); - comboGiveItem(actor, play, &q, a, b); + AddRupeesRaw(-PRICE); + SET_HANDLER(this, EnGm_GiveItemHandler2); + EnGm_GiveItemHandler2(this, play); } -PATCH_CALL(0x80a9ffd8, EnGm_GiveItem); -PATCH_CALL(0x80aa006c, EnGm_GiveItem); +PATCH_FUNC(0x80aa0020, EnGm_GiveItemHandler); int EnGm_GetState(void) { @@ -59,7 +79,11 @@ static void hintMedigoron(PlayState* play) comboTextAppendHeader(&b); comboTextAppendStr(&b, "How about buying "); comboTextAppendItemNameQuery(&b, &q, TF_PREPOS | TF_PROGRESSIVE); - comboTextAppendStr(&b, " for 200 Rupees?" TEXT_NL TEXT_COLOR_GREEN TEXT_CHOICE2 "Buy" TEXT_NL "Don't buy" TEXT_END); + comboTextAppendStr(&b, " for " TEXT_COLOR_RED); + comboTextAppendNum(&b, PRICE); + comboTextAppendStr(&b, " Rupees"); + comboTextAppendClearColor(&b); + comboTextAppendStr(&b, "?" TEXT_NL TEXT_COLOR_GREEN TEXT_CHOICE2 "Buy" TEXT_NL "Don't buy" TEXT_END); comboTextAutoLineBreaks(start); } From f3bbd73e3ddd481442f4b95a8e7412dc4c63ee89 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Fri, 17 Jan 2025 20:42:23 +0100 Subject: [PATCH 10/34] CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dfca0e40a..d7487c7120 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file. ### Added +- Add the ability to shuffle extra merchants in OoT. +- Add the ability to shuffle merchant prices in OoT. - Implement the Deku Shield in MM. - Completely rework bombchu, behavior is now a setting with 4 values : free like in OoT, tied to bomb bag like in MM, old-style bombchu bags, and a new bombchu bag setting where 3 bags are in the pool, allowing for 20/30/40 bombchu. From 91f60e5d6155c51beabdc044e361471ce32ac9bc Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Fri, 17 Jan 2025 22:01:49 +0100 Subject: [PATCH 11/34] Increase fish draw distance in OoT fish pond shuffle --- packages/core/src/oot/actors/Misc/Fishing.S | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/core/src/oot/actors/Misc/Fishing.S b/packages/core/src/oot/actors/Misc/Fishing.S index bac1c292d8..e73b4957c7 100644 --- a/packages/core/src/oot/actors/Misc/Fishing.S +++ b/packages/core/src/oot/actors/Misc/Fishing.S @@ -173,6 +173,11 @@ PATCH_END PATCH_GROUP PG_OOT_FISHING_POND_SHUFFLE +/* Increase draw distance */ +PATCH_START 0x80a3be08 + lui at,0x46ff +PATCH_END + /* Replaces: LUI V0, 0x80A4 // Relocation From 5134a5e1fcfc38a83c1515db895990ce6bb9cf17 Mon Sep 17 00:00:00 2001 From: XenoWars Date: Fri, 17 Jan 2025 18:26:30 -0500 Subject: [PATCH 12/34] Spirit Temple child climb minor logic add --- CHANGELOG.md | 1 + packages/data/src/world/oot/spirit_temple.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7487c7120..4303f2eb69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ All notable changes to this project will be documented in this file. - Change the Old Hag checks in MM, now the two checks are separate instead of progressing into each other. - Completely reworked the stray fairy item model to be much closer to the actual fairies. - Path hints now tell the exact world the path corresponds to in multiworld. +- Logic can now expect Sunlight Arrows to go through Spirit Temple child climb. ### Fixed diff --git a/packages/data/src/world/oot/spirit_temple.yml b/packages/data/src/world/oot/spirit_temple.yml index 04aa9bd6cf..6931a2bd43 100644 --- a/packages/data/src/world/oot/spirit_temple.yml +++ b/packages/data/src/world/oot/spirit_temple.yml @@ -84,7 +84,7 @@ "Spirit Temple Child Climb": dungeon: Spirit exits: - "Spirit Temple Statue": "has_explosives" + "Spirit Temple Statue": "has_explosives || has_sunlight_arrows" "Spirit Temple Child Crawlspace": "small_keys_spirit(5)" locations: "Spirit Temple Child Climb 1": "has_ranged_weapon_both || (climb_anywhere && (can_use_sword || can_use_sticks || can_hammer)) || (event(SPIRIT_CHILD_DOOR) && (has_ranged_weapon_child || can_hookshot)) || (event(SPIRIT_ADULT_DOOR) && (has_ranged_weapon_adult || can_boomerang))" From 83e98532f3e3674e8a86d593a2d7761b6145b039 Mon Sep 17 00:00:00 2001 From: CelestalKitsune <30158363+CelestialKitsune@users.noreply.github.com> Date: Wed, 22 Jan 2025 20:36:21 +0100 Subject: [PATCH 13/34] Fix mirror shield macro --- CHANGELOG.md | 1 + packages/data/src/macros/macros_mm.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4303f2eb69..161d31df7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ All notable changes to this project will be documented in this file. - Fix a bug where magical rupee would sometimes require a scene reload to work properly. - Fix an odd interaction between open MM dungeons and the moon crash. +- Fix Mirror Shield macro required 2 progressive shields if MM Deku Shield was on, instead of 3. ## [27.0] - 2025-01-04 diff --git a/packages/data/src/macros/macros_mm.yml b/packages/data/src/macros/macros_mm.yml index 35673c806f..ad34972dae 100644 --- a/packages/data/src/macros/macros_mm.yml +++ b/packages/data/src/macros/macros_mm.yml @@ -166,7 +166,7 @@ "can_use_ice_arrows": "has_magic && has_arrows && (has(ARROW_ICE) || has(SHARED_ARROW_ICE))" "can_use_light_arrows": "has_magic && has_arrows && (has(ARROW_LIGHT) || has(SHARED_ARROW_LIGHT))" "can_use_keg": "event(BUY_KEG)" -"has_mirror_shield": "has(SHIELD_MIRROR) || has(SHARED_SHIELD_MIRROR) || has(SHARED_SHIELD, 3) || (cond(setting(dekuShieldMm), has(SHIELD, 2), has(SHIELD, 3)))" +"has_mirror_shield": "has(SHIELD_MIRROR) || has(SHARED_SHIELD_MIRROR) || has(SHARED_SHIELD, 3) || (cond(setting(dekuShieldMm), has(SHIELD, 3), has(SHIELD, 2)))" "can_use_elegy": "can_play_emptiness" "can_use_elegy2": "can_play_emptiness && (has_mask_zora || has_mask_goron)" "can_use_elegy3": "can_play_emptiness && has_mask_zora && has_mask_goron" From b3e782dae132aee0c3c697df7f92be7e4ebce8e1 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Sat, 25 Jan 2025 07:43:35 +0100 Subject: [PATCH 14/34] Fix changelog (don't document fixes for bugs introduced in the same release) --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 161d31df7e..4303f2eb69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,6 @@ All notable changes to this project will be documented in this file. - Fix a bug where magical rupee would sometimes require a scene reload to work properly. - Fix an odd interaction between open MM dungeons and the moon crash. -- Fix Mirror Shield macro required 2 progressive shields if MM Deku Shield was on, instead of 3. ## [27.0] - 2025-01-04 From 89810a08269027196a9f52c972ba4e67c4fdbd32 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Sat, 25 Jan 2025 07:51:04 +0100 Subject: [PATCH 15/34] Fix a small region issue near swamp spider house --- CHANGELOG.md | 1 + packages/data/src/world/mm/overworld.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4303f2eb69..8c1e30d05c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ All notable changes to this project will be documented in this file. ### Fixed +- Fix a small region issue near swamp spider house. - Fix a bug where magical rupee would sometimes require a scene reload to work properly. - Fix an odd interaction between open MM dungeons and the moon crash. diff --git a/packages/data/src/world/mm/overworld.yml b/packages/data/src/world/mm/overworld.yml index f32164034a..cfe146bc5c 100644 --- a/packages/data/src/world/mm/overworld.yml +++ b/packages/data/src/world/mm/overworld.yml @@ -1388,7 +1388,7 @@ "Near Swamp Grotto": "has(MASK_DEKU) || is_tall || is_swamp_cleared || short_hook_anywhere || has_hover_boots" "Swamp Canopy Front": "short_hook_anywhere" "Near Swamp Grotto": - region: ENTRANCE + region: SOUTHERN_SWAMP events: MUSHROOM: "has(MASK_SCENTS)" exits: From 129424ad45a4c897de6ba9da9c826d6a1ee787c0 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Sat, 25 Jan 2025 08:33:34 +0100 Subject: [PATCH 16/34] Fix a deku shield MM rendering issue with adult link/gilded sword --- packages/core/include/combo/custom.h | 108 +++++++++--------- .../combo/custom/custom-objects-builder.ts | 4 +- 2 files changed, 57 insertions(+), 55 deletions(-) diff --git a/packages/core/include/combo/custom.h b/packages/core/include/combo/custom.h index c1e152b69e..73ac50093d 100644 --- a/packages/core/include/combo/custom.h +++ b/packages/core/include/combo/custom.h @@ -164,59 +164,59 @@ #define CUSTOM_KEEP_GORON_SYMBOL_TEXTURE 0x58e0 #define CUSTOM_KEEP_GAUNTLET1_TEXTURE 0x5ce0 #define CUSTOM_KEEP_GAUNTLET2_TEXTURE 0x60e0 -#define CUSTOM_KEEP_VROM 0x8051db0 -#define CUSTOM_CHEST_MAJOR_FRONT_ADDR 0x8058690 -#define CUSTOM_CHEST_MAJOR_SIDE_ADDR 0x8059690 -#define CUSTOM_CHEST_KEY_FRONT_ADDR 0x8059e90 -#define CUSTOM_CHEST_KEY_SIDE_ADDR 0x805ae90 -#define CUSTOM_CHEST_SPIDER_FRONT_ADDR 0x805b690 -#define CUSTOM_CHEST_SPIDER_SIDE_ADDR 0x805c690 -#define CUSTOM_CHEST_FAIRY_FRONT_ADDR 0x805ce90 -#define CUSTOM_CHEST_FAIRY_SIDE_ADDR 0x805de90 -#define CUSTOM_CHEST_HEART_FRONT_ADDR 0x805e690 -#define CUSTOM_CHEST_HEART_SIDE_ADDR 0x805f690 -#define CUSTOM_CHEST_SOUL_FRONT_ADDR 0x805fe90 -#define CUSTOM_CHEST_SOUL_SIDE_ADDR 0x8060e90 -#define CUSTOM_CHEST_MAP_FRONT_ADDR 0x8061690 -#define CUSTOM_CHEST_MAP_SIDE_ADDR 0x8062690 -#define CUSTOM_CRATE_BOSS_KEY_ADDR 0x8062e90 -#define CUSTOM_POT_MAJOR_SIDE_ADDR 0x8063e90 -#define CUSTOM_POT_MAJOR_TOP_ADDR 0x8064e90 -#define CUSTOM_POT_SPIDER_SIDE_ADDR 0x8065090 -#define CUSTOM_POT_SPIDER_TOP_ADDR 0x8066090 -#define CUSTOM_POT_KEY_SIDE_ADDR 0x8066290 -#define CUSTOM_POT_FAIRY_SIDE_ADDR 0x8067290 -#define CUSTOM_POT_FAIRY_TOP_ADDR 0x8068290 -#define CUSTOM_POT_HEART_SIDE_ADDR 0x8068490 -#define CUSTOM_POT_HEART_TOP_ADDR 0x8069490 -#define CUSTOM_POT_BOSSKEY_SIDE_ADDR 0x8069690 -#define CUSTOM_POT_BOSSKEY_TOP_ADDR 0x806a690 -#define CUSTOM_POT_SOUL_SIDE_ADDR 0x806a890 -#define CUSTOM_POT_SOUL_TOP_ADDR 0x806b890 -#define CUSTOM_POT_MAP_SIDE_ADDR 0x806ba90 -#define CUSTOM_GLITTER_ADDR 0x806ca90 -#define CUSTOM_GRASS_ADDR 0x806cb90 -#define CUSTOM_GRASS_ALT_ADDR 0x806d390 -#define CUSTOM_HIVE_ADDR 0x806db90 -#define CUSTOM_BUTTERFLY_ADDR 0x806e390 -#define CUSTOM_SEQ_TABLE_OOT_VROM 0x806f390 -#define CUSTOM_SEQ_TABLE_MM_VROM 0x806fb90 -#define CUSTOM_BANK_TABLE_OOT_VROM 0x8070390 -#define CUSTOM_BANK_TABLE_MM_VROM 0x8070690 -#define CUSTOM_BANK_TABLE_CUSTOM_VROM 0x8070990 -#define CUSTOM_AUDIO_TABLE_OOT_VROM 0x8071290 -#define CUSTOM_AUDIO_TABLE_MM_VROM 0x8071310 -#define CUSTOM_SEQ_BANKS_OOT_VROM 0x8071390 -#define CUSTOM_SEQ_BANKS_MM_VROM 0x8071490 -#define CUSTOM_MQ_ROOMS_ADDR 0x8071590 -#define CUSTOM_MQ_SCENES_ADDR 0x807fba0 -#define CUSTOM_MQ_MAPS_ADDR 0x80889a0 -#define CUSTOM_XFLAG_TABLE_OOT_SCENES_ADDR 0x808cb00 -#define CUSTOM_XFLAG_TABLE_OOT_SETUPS_ADDR 0x808cbd0 -#define CUSTOM_XFLAG_TABLE_OOT_ROOMS_ADDR 0x808ccf0 -#define CUSTOM_XFLAG_TABLE_MM_SCENES_ADDR 0x808fdd0 -#define CUSTOM_XFLAG_TABLE_MM_SETUPS_ADDR 0x808fec0 -#define CUSTOM_XFLAG_TABLE_MM_ROOMS_ADDR 0x808ffb0 +#define CUSTOM_KEEP_VROM 0x8051dc0 +#define CUSTOM_CHEST_MAJOR_FRONT_ADDR 0x80586a0 +#define CUSTOM_CHEST_MAJOR_SIDE_ADDR 0x80596a0 +#define CUSTOM_CHEST_KEY_FRONT_ADDR 0x8059ea0 +#define CUSTOM_CHEST_KEY_SIDE_ADDR 0x805aea0 +#define CUSTOM_CHEST_SPIDER_FRONT_ADDR 0x805b6a0 +#define CUSTOM_CHEST_SPIDER_SIDE_ADDR 0x805c6a0 +#define CUSTOM_CHEST_FAIRY_FRONT_ADDR 0x805cea0 +#define CUSTOM_CHEST_FAIRY_SIDE_ADDR 0x805dea0 +#define CUSTOM_CHEST_HEART_FRONT_ADDR 0x805e6a0 +#define CUSTOM_CHEST_HEART_SIDE_ADDR 0x805f6a0 +#define CUSTOM_CHEST_SOUL_FRONT_ADDR 0x805fea0 +#define CUSTOM_CHEST_SOUL_SIDE_ADDR 0x8060ea0 +#define CUSTOM_CHEST_MAP_FRONT_ADDR 0x80616a0 +#define CUSTOM_CHEST_MAP_SIDE_ADDR 0x80626a0 +#define CUSTOM_CRATE_BOSS_KEY_ADDR 0x8062ea0 +#define CUSTOM_POT_MAJOR_SIDE_ADDR 0x8063ea0 +#define CUSTOM_POT_MAJOR_TOP_ADDR 0x8064ea0 +#define CUSTOM_POT_SPIDER_SIDE_ADDR 0x80650a0 +#define CUSTOM_POT_SPIDER_TOP_ADDR 0x80660a0 +#define CUSTOM_POT_KEY_SIDE_ADDR 0x80662a0 +#define CUSTOM_POT_FAIRY_SIDE_ADDR 0x80672a0 +#define CUSTOM_POT_FAIRY_TOP_ADDR 0x80682a0 +#define CUSTOM_POT_HEART_SIDE_ADDR 0x80684a0 +#define CUSTOM_POT_HEART_TOP_ADDR 0x80694a0 +#define CUSTOM_POT_BOSSKEY_SIDE_ADDR 0x80696a0 +#define CUSTOM_POT_BOSSKEY_TOP_ADDR 0x806a6a0 +#define CUSTOM_POT_SOUL_SIDE_ADDR 0x806a8a0 +#define CUSTOM_POT_SOUL_TOP_ADDR 0x806b8a0 +#define CUSTOM_POT_MAP_SIDE_ADDR 0x806baa0 +#define CUSTOM_GLITTER_ADDR 0x806caa0 +#define CUSTOM_GRASS_ADDR 0x806cba0 +#define CUSTOM_GRASS_ALT_ADDR 0x806d3a0 +#define CUSTOM_HIVE_ADDR 0x806dba0 +#define CUSTOM_BUTTERFLY_ADDR 0x806e3a0 +#define CUSTOM_SEQ_TABLE_OOT_VROM 0x806f3a0 +#define CUSTOM_SEQ_TABLE_MM_VROM 0x806fba0 +#define CUSTOM_BANK_TABLE_OOT_VROM 0x80703a0 +#define CUSTOM_BANK_TABLE_MM_VROM 0x80706a0 +#define CUSTOM_BANK_TABLE_CUSTOM_VROM 0x80709a0 +#define CUSTOM_AUDIO_TABLE_OOT_VROM 0x80712a0 +#define CUSTOM_AUDIO_TABLE_MM_VROM 0x8071320 +#define CUSTOM_SEQ_BANKS_OOT_VROM 0x80713a0 +#define CUSTOM_SEQ_BANKS_MM_VROM 0x80714a0 +#define CUSTOM_MQ_ROOMS_ADDR 0x80715a0 +#define CUSTOM_MQ_SCENES_ADDR 0x807fbb0 +#define CUSTOM_MQ_MAPS_ADDR 0x80889b0 +#define CUSTOM_XFLAG_TABLE_OOT_SCENES_ADDR 0x808cb10 +#define CUSTOM_XFLAG_TABLE_OOT_SETUPS_ADDR 0x808cbe0 +#define CUSTOM_XFLAG_TABLE_OOT_ROOMS_ADDR 0x808cd00 +#define CUSTOM_XFLAG_TABLE_MM_SCENES_ADDR 0x808fde0 +#define CUSTOM_XFLAG_TABLE_MM_SETUPS_ADDR 0x808fed0 +#define CUSTOM_XFLAG_TABLE_MM_ROOMS_ADDR 0x808ffc0 #define CUSTOM_OBJECT_ID_TRIFORCE 0x2035 #define CUSTOM_OBJECT_TRIFORCE_0 0x6000a30 #define CUSTOM_OBJECT_ID_BTN_A 0x2036 @@ -267,7 +267,7 @@ #define CUSTOM_OBJECT_ID_MM_ADULT_LINK_SPIN_ATTACK_VTX_2 0x203e #define CUSTOM_OBJECT_ID_MM_ADULT_LINK_SPIN_ATTACK_VTX_3 0x203f #define CUSTOM_OBJECT_ID_MM_ADULT_LINK_MASK_MTX 0x2040 -#define CUSTOM_OBJECT_TABLE_VROM 0x80c5250 +#define CUSTOM_OBJECT_TABLE_VROM 0x80c5260 #define CUSTOM_OBJECT_TABLE_SIZE 0x41 #endif diff --git a/packages/core/lib/combo/custom/custom-objects-builder.ts b/packages/core/lib/combo/custom/custom-objects-builder.ts index 59b0a03b39..f1004bf7a6 100644 --- a/packages/core/lib/combo/custom/custom-objects-builder.ts +++ b/packages/core/lib/combo/custom/custom-objects-builder.ts @@ -58,9 +58,11 @@ export class CustomObjectsBuilder { //list = editor.stripList(list, 0x060242c8 - b, 0x060245a8 - b); editor.submitList(list); - const bSheath = 0x06015100; + const bSheath = 0x06015010; let listSheath = editor.listData(bSheath)!; listSheath = editor.stripList(listSheath, 0x06015130 - bSheath, 0x06015140 - bSheath); + listSheath = editor.stripList(listSheath, 0x060150b0 - bSheath, 0x06015108 - bSheath); + listSheath = editor.stripList(listSheath, 0x06015018 - bSheath, 0x06015098 - bSheath); editor.submitList(listSheath); return { name: 'EQ_SHIELD_DEKU', ...editor.build() }; From bd46c8d1e9739d3e1cea6f890e3f1f1754009c45 Mon Sep 17 00:00:00 2001 From: ZoeyZolotova Date: Mon, 27 Jan 2025 09:24:51 +1100 Subject: [PATCH 17/34] Fix Ganondorf and Ganon fight not allowing Return to Dungeon Entrance. (#825) --- CHANGELOG.md | 1 + packages/core/src/oot/play/play.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c1e30d05c..c40b7dfb72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ All notable changes to this project will be documented in this file. - Fix a small region issue near swamp spider house. - Fix a bug where magical rupee would sometimes require a scene reload to work properly. - Fix an odd interaction between open MM dungeons and the moon crash. +- Fix Ganondorf and Ganon fight not allowing Return to Dungeon Entrance. ## [27.0] - 2025-01-04 diff --git a/packages/core/src/oot/play/play.c b/packages/core/src/oot/play/play.c index 16a5dfc230..0e94433c42 100644 --- a/packages/core/src/oot/play/play.c +++ b/packages/core/src/oot/play/play.c @@ -511,6 +511,8 @@ static void Play_AfterInit(PlayState* play) case SCE_OOT_LAIR_MORPHA: case SCE_OOT_LAIR_BONGO_BONGO: case SCE_OOT_LAIR_TWINROVA: + case SCE_OOT_LAIR_GANONDORF: + case SCE_OOT_GANON_BATTLE_ARENA: if (!gSharedCustomSave.respawn[CUSTOM_RESPAWN_MODE_DUNGEON_ENTRANCE].playerParams) { /* Copy to the custom death respawn */ From 6d19556937d2f9e43a8ace30896cbcfe1d440224 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Mon, 27 Jan 2025 09:56:50 +0100 Subject: [PATCH 18/34] Fix FD mask item having weird colors sometimes --- CHANGELOG.md | 1 + packages/core/src/mm/objects/gi_mask03.S | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 packages/core/src/mm/objects/gi_mask03.S diff --git a/CHANGELOG.md b/CHANGELOG.md index c40b7dfb72..e5dd4dc248 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ All notable changes to this project will be documented in this file. ### Fixed +- Fix FD mask item having weird colors sometimes. - Fix a small region issue near swamp spider house. - Fix a bug where magical rupee would sometimes require a scene reload to work properly. - Fix an odd interaction between open MM dungeons and the moon crash. diff --git a/packages/core/src/mm/objects/gi_mask03.S b/packages/core/src/mm/objects/gi_mask03.S new file mode 100644 index 0000000000..35dfa28a18 --- /dev/null +++ b/packages/core/src/mm/objects/gi_mask03.S @@ -0,0 +1,7 @@ +#include + +/* Fix FD mask item having weird colors sometimes */ +PATCH_OBJECT 0x242, 0xae8 +.word 0xFC30FE04 +.word 0x5FFEF3F8 +PATCH_END From 47e59cf6232e38b99eb9beceb25e4e47d0eeef3c Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Mon, 27 Jan 2025 10:24:56 +0100 Subject: [PATCH 19/34] Fix a vanilla bug where the frozen link effect would sometimes get distorded --- CHANGELOG.md | 1 + packages/core/src/oot/actors/Player.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5dd4dc248..9db988747c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ All notable changes to this project will be documented in this file. ### Fixed +- Fix a vanilla bug where the frozen link effect would sometimes get distorded. - Fix FD mask item having weird colors sometimes. - Fix a small region issue near swamp spider house. - Fix a bug where magical rupee would sometimes require a scene reload to work properly. diff --git a/packages/core/src/oot/actors/Player.c b/packages/core/src/oot/actors/Player.c index bbd0857f1d..99772929cb 100644 --- a/packages/core/src/oot/actors/Player.c +++ b/packages/core/src/oot/actors/Player.c @@ -973,3 +973,16 @@ void Player_AfterBeginFaroresWindTransition(PlayState* play) } PATCH_CALL(0x8084e540, Player_AfterBeginFaroresWindTransition); + +/* Fixes a vanilla bug where the frozen link effect would sometimes get distorded */ +void Player_SetupMatrixFrozenEffect(float scale) +{ + Player* player; + + player = GET_PLAYER(gPlay); + Matrix_Translate(player->actor.world.pos.x, player->actor.world.pos.y, player->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateY(player->actor.world.rot.y * (M_PI / 0x8000), MTXMODE_APPLY); + Matrix_Scale(scale * player->actor.scale.x, scale * player->actor.scale.y, scale * player->actor.scale.z, MTXMODE_APPLY); +} + +PATCH_CALL(0x80848b10, Player_SetupMatrixFrozenEffect); From 999a18d4e10dbfe4941cb07f3640fec30f63acd4 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Mon, 27 Jan 2025 10:57:14 +0100 Subject: [PATCH 20/34] Add Ice Trap GI --- packages/core/include/combo/drawgi.h | 1 + packages/core/include/combo/item.h | 1 + packages/core/include/combo/save.h | 1 + packages/core/lib/combo/items/defs.ts | 2 +- packages/core/lib/combo/names.ts | 2 +- .../core/lib/combo/patch-build/randomizer.ts | 2 +- packages/core/src/common/drawgi.c | 20 +++++++++++++++++++ packages/core/src/common/item/item_add.c | 7 +++++++ packages/data/src/defs/drawgi.yml | 1 + packages/data/src/defs/gi.yml | 1 + packages/data/src/pool/pool_oot.csv | 14 ++++++------- 11 files changed, 42 insertions(+), 10 deletions(-) diff --git a/packages/core/include/combo/drawgi.h b/packages/core/include/combo/drawgi.h index e453ca81a7..e1c2602e82 100644 --- a/packages/core/include/combo/drawgi.h +++ b/packages/core/include/combo/drawgi.h @@ -83,6 +83,7 @@ void DrawGi_Clock(PlayState*, s16); void DrawGi_Rupee(PlayState*, s16 index, u8 param); void DrawGi_PondFish(PlayState*, s16 index, u8 param); void DrawGi_CustomShield(PlayState* play, s16 drawGiId, u8 param); +void DrawGi_TrapIce(PlayState* play, s16 drawGiId, u8 param); #endif diff --git a/packages/core/include/combo/item.h b/packages/core/include/combo/item.h index e10b3235ca..cd2303bd1b 100644 --- a/packages/core/include/combo/item.h +++ b/packages/core/include/combo/item.h @@ -110,6 +110,7 @@ #define IA_MM_NUT_UPGRADE 0x65 #define IA_MM_STONE_AGONY 0x66 #define IA_OOT_SPIN_UPGRADE 0x67 +#define IA_TRAP_ICE 0x68 #define IA_NONE 0xff #define ITT_NONE 0x00 diff --git a/packages/core/include/combo/save.h b/packages/core/include/combo/save.h index 6b96805291..e5e25ee132 100644 --- a/packages/core/include/combo/save.h +++ b/packages/core/include/combo/save.h @@ -43,6 +43,7 @@ typedef struct ALIGNED(16) u8 bombchuBagMm:2; u8 mmShieldIsDeku:1; u8 mmProgressiveShields:2; + u8 pendingIceTraps; #if defined(DEBUG) u8 cheats[4]; #endif diff --git a/packages/core/lib/combo/items/defs.ts b/packages/core/lib/combo/items/defs.ts index 28fd36c237..892097e44e 100644 --- a/packages/core/lib/combo/items/defs.ts +++ b/packages/core/lib/combo/items/defs.ts @@ -1,5 +1,5 @@ const ITEM_IDS = [ - 'OOT_ICE_TRAP', + 'OOT_TRAP_ICE', 'OOT_BOTTLE_BLUE_FIRE', 'OOT_DEFENSE_UPGRADE', 'MM_DEFENSE_UPGRADE', diff --git a/packages/core/lib/combo/names.ts b/packages/core/lib/combo/names.ts index d3281a74ca..a9c32e9744 100644 --- a/packages/core/lib/combo/names.ts +++ b/packages/core/lib/combo/names.ts @@ -272,7 +272,6 @@ const ITEM_NAMES: {[k in ItemID]: string} = { OOT_HEART_CONTAINER: "Heart Container (OoT)", OOT_HEART_PIECE: "Piece of Heart (OoT)", OOT_HOOKSHOT: "Progressive Hookshot (OoT)", - OOT_ICE_TRAP: "Ice Trap (OoT)", OOT_KEY_RING_BOTW: "Key Ring (Well)", OOT_KEY_RING_FIRE: "Key Ring (Fire)", OOT_KEY_RING_FOREST: "Key Ring (Forest)", @@ -820,6 +819,7 @@ const ITEM_NAMES: {[k in ItemID]: string} = { MM_TRAP_RUPOOR: "Rupoor (MM)", OOT_TRAP_RUPOOR: "Rupoor (OoT)", SHARED_TRAP_RUPOOR: "Rupoor", + OOT_TRAP_ICE: "Ice Trap", OOT_SOUL_MISC_GS: "Soul of Gold Skulltulas (OoT)", OOT_SOUL_MISC_BUSINESS_SCRUB: "Soul of Business Scrubs (OoT)", MM_SOUL_MISC_GS: "Soul of Gold Skulltulas (MM)", diff --git a/packages/core/lib/combo/patch-build/randomizer.ts b/packages/core/lib/combo/patch-build/randomizer.ts index 30552bb83c..238a03a66a 100644 --- a/packages/core/lib/combo/patch-build/randomizer.ts +++ b/packages/core/lib/combo/patch-build/randomizer.ts @@ -208,7 +208,7 @@ const SUBSTITUTIONS: {[k: string]: string} = { OOT_STRENGTH: "OOT_GORON_BRACELET", OOT_SCALE: "OOT_SCALE_SILVER", OOT_SHIELD: "OOT_PROGRESSIVE_SHIELD_DEKU", - OOT_ICE_TRAP: "OOT_RUPEE_BLUE", + //OOT_TRAP_ICE: "OOT_RUPEE_BLUE", MM_SWORD: "MM_SWORD_KOKIRI", MM_SHIELD: "MM_PROGRESSIVE_SHIELD_DEKU", MM_OCARINA: "MM_OCARINA_OF_TIME", diff --git a/packages/core/src/common/drawgi.c b/packages/core/src/common/drawgi.c index 666244f21c..290aad10ed 100644 --- a/packages/core/src/common/drawgi.c +++ b/packages/core/src/common/drawgi.c @@ -3,6 +3,14 @@ #include #include +#if defined(GAME_OOT) +# include +#endif + +#if defined(GAME_MM) +# include +#endif + #define M_PI 3.14159265358979323846 #define M_SQRT1_2 0.707106781186547524401 #define DLIST_RAW(x) (((u32)(x)) - 0x80000000) @@ -1534,3 +1542,15 @@ void DrawGi_CustomShield(PlayState* play, s16 index, u8 param) CLOSE_DISPS(); } + +void DrawGi_TrapIce(PlayState* play, s16 drawGiId, u8 param) +{ + static const float scale = 0.5f; + + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + OPEN_DISPS(play->state.gfxCtx); + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, Matrix_Finalize(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gEffIceFragment3DL); + CLOSE_DISPS(); +} diff --git a/packages/core/src/common/item/item_add.c b/packages/core/src/common/item/item_add.c index 2f72ce9837..64e2b46767 100644 --- a/packages/core/src/common/item/item_add.c +++ b/packages/core/src/common/item/item_add.c @@ -1450,6 +1450,12 @@ static int addItemGsTokenOcean(PlayState* play, u8 itemId, s16 gi, u16 param) return ++gMmSave.info.skullCountOcean; } +static int addItemIceTrap(PlayState* play, u8 itemId, s16 gi, u16 param) +{ + gSharedCustomSave.pendingIceTraps++; + return 0; +} + static void fillMagicOot(PlayState* play) { int level; @@ -1955,6 +1961,7 @@ static const AddItemFunc kAddItemHandlers[] = { addItemNutsUpgradeMm, addItemStoneAgonyMm, addItemSpinUpgradeOot, + addItemIceTrap, }; extern const u8 kAddItemFuncs[]; diff --git a/packages/data/src/defs/drawgi.yml b/packages/data/src/defs/drawgi.yml index 7b53ae52b8..2533da36cb 100644 --- a/packages/data/src/defs/drawgi.yml +++ b/packages/data/src/defs/drawgi.yml @@ -212,3 +212,4 @@ - { id: BOTTLE_BLUE_FIRE, func: BottleBlueFire, params: [0x6000670, 0x6000750] } - { id: CLOCK, func: Clock, params: [GI_CLOCK_0, GI_CLOCK_1, GI_CLOCK_2, GI_CLOCK_3] } - { id: POND_FISH, func: PondFish, params: [GI_POND_FISH_0] } +- { id: TRAP_ICE, func: TrapIce, params: [0] } diff --git a/packages/data/src/defs/gi.yml b/packages/data/src/defs/gi.yml index 06d6da416b..b3813b73ff 100644 --- a/packages/data/src/defs/gi.yml +++ b/packages/data/src/defs/gi.yml @@ -426,6 +426,7 @@ - { id: OOT_SWORD_GILDED, type: MAJOR, add: [OOT_SWORD_EXTRA, 2], flags: 0x80, draw: MM_SWORD_GILDED, object: [mm, 0x01fa], name: "the Gilded Sword" } - { id: OOT_SPIN_UPGRADE, type: MAJOR, add: OOT_SPIN_UPGRADE, flags: 0xa0, draw: [SPIN_UPGRADE, 1], object: [oot, 0x018d], name: "the Spin Attack Upgrade" } - { id: OOT_TRIFORCE_FULL, type: MAJOR, add: [ENDGAME, 0], flags: 0x80, draw: TRIFORCE_FULL, object: TRIFORCE, name: "the Triforce" } +- { id: OOT_TRAP_ICE, type: MINOR, add: TRAP_ICE, flags: 0x80, draw: TRAP_ICE, name: "an Ice Trap" } - { id: OOT_FAIRY_BIG, type: MINOR, add: OOT_FAIRY_BIG, flags: 0x80, draw: FAIRY_BIG, object: [oot, 0x0177], name: "a Big Fairy" } - { id: OOT_MASK_BLAST, type: MASK, add: [OOT_TRADE_CHILD, XITEM_OOT_CHILD_MASK_BLAST], flags: 0x80, draw: MM_MASK_BLAST, object: [mm, 0x026d], name: "the Blast Mask" } - { id: OOT_MASK_STONE, type: MASK, add: [OOT_TRADE_CHILD, XITEM_OOT_CHILD_MASK_STONE], flags: 0x80, draw: MM_MASK_STONE, object: [mm, 0x0254], name: "the Stone Mask" } diff --git a/packages/data/src/pool/pool_oot.csv b/packages/data/src/pool/pool_oot.csv index c827259b7e..e87077e4af 100644 --- a/packages/data/src/pool/pool_oot.csv +++ b/packages/data/src/pool/pool_oot.csv @@ -1597,7 +1597,7 @@ Spirit Temple Sun Block Room Torches, chest, NONE Spirit Temple Adult Silver Rupees, chest, NONE, TEMPLE_SPIRIT, 0x07, SMALL_KEY_SPIRIT Spirit Temple Adult Lullaby, chest, NONE, TEMPLE_SPIRIT, 0x04, COMPASS_SPIRIT Spirit Temple Adult Suns on Wall 1, chest, NONE, TEMPLE_SPIRIT, 0x0d, RECOVERY_HEART -Spirit Temple Adult Suns on Wall 2, chest, NONE, TEMPLE_SPIRIT, 0x0e, ICE_TRAP +Spirit Temple Adult Suns on Wall 2, chest, NONE, TEMPLE_SPIRIT, 0x0e, TRAP_ICE Spirit Temple Adult Invisible 1, chest, NONE, TEMPLE_SPIRIT, 0x14, RECOVERY_HEART Spirit Temple Adult Invisible 2, chest, NONE, TEMPLE_SPIRIT, 0x15, RECOVERY_HEART Spirit Temple Adult Late Sun on Wall, chest, NONE, TEMPLE_SPIRIT, 0x05, SMALL_KEY_SPIRIT @@ -1668,7 +1668,7 @@ Gerudo Training Grounds Entrance 2, chest, NONE Gerudo Training Grounds Stalfos, chest, NONE, GERUDO_TRAINING_GROUND, 0x00, SMALL_KEY_GTG Gerudo Training Grounds Near Block, chest, NONE, GERUDO_TRAINING_GROUND, 0x11, ARROWS_30 Gerudo Training Grounds Behind Block Invisible, chest, NONE, GERUDO_TRAINING_GROUND, 0x14, SMALL_KEY_GTG -Gerudo Training Grounds Behind Block Visible, chest, NONE, GERUDO_TRAINING_GROUND, 0x02, ICE_TRAP +Gerudo Training Grounds Behind Block Visible, chest, NONE, GERUDO_TRAINING_GROUND, 0x02, TRAP_ICE Gerudo Training Grounds Behind Block Enemy Back, chest, NONE, GERUDO_TRAINING_GROUND, 0x0e, RUPEE_BLUE Gerudo Training Grounds Behind Block Enemy Front, chest, NONE, GERUDO_TRAINING_GROUND, 0x0f, RUPEE_HUGE Gerudo Training Grounds Eye Statue, chest, NONE, GERUDO_TRAINING_GROUND, 0x03, SMALL_KEY_GTG @@ -1707,15 +1707,15 @@ Gerudo Training Grounds Wonder Item Eye Statue Room, wonder, NONE Gerudo Training Grounds Wonder Item Torch Slugs Room, wonder, NONE, GERUDO_TRAINING_GROUND, 0x00510, RUPEE_RED Gerudo Training Grounds Wonder Item Beamos Room, wonder, NONE, GERUDO_TRAINING_GROUND, 0x0070c, FLEXIBLE Ganon Castle Water Chest 1, chest, NONE, INSIDE_GANON_CASTLE, 0x06, RECOVERY_HEART -Ganon Castle Water Chest 2, chest, NONE, INSIDE_GANON_CASTLE, 0x07, ICE_TRAP +Ganon Castle Water Chest 2, chest, NONE, INSIDE_GANON_CASTLE, 0x07, TRAP_ICE Ganon Castle Forest Chest, chest, NONE, INSIDE_GANON_CASTLE, 0x09, RUPEE_BLUE Ganon Castle Light Chest Center, chest, NONE, INSIDE_GANON_CASTLE, 0x10, SMALL_KEY_GANON Ganon Castle Light Chest Around 1, chest, NONE, INSIDE_GANON_CASTLE, 0x0a, ARROWS_30 -Ganon Castle Light Chest Around 2, chest, NONE, INSIDE_GANON_CASTLE, 0x0b, ICE_TRAP +Ganon Castle Light Chest Around 2, chest, NONE, INSIDE_GANON_CASTLE, 0x0b, TRAP_ICE Ganon Castle Light Chest Around 3, chest, NONE, INSIDE_GANON_CASTLE, 0x0c, RUPEE_BLUE Ganon Castle Light Chest Around 4, chest, NONE, INSIDE_GANON_CASTLE, 0x0d, RECOVERY_HEART -Ganon Castle Light Chest Around 5, chest, NONE, INSIDE_GANON_CASTLE, 0x0e, ICE_TRAP -Ganon Castle Light Chest Around 6, chest, NONE, INSIDE_GANON_CASTLE, 0x0f, ICE_TRAP +Ganon Castle Light Chest Around 5, chest, NONE, INSIDE_GANON_CASTLE, 0x0e, TRAP_ICE +Ganon Castle Light Chest Around 6, chest, NONE, INSIDE_GANON_CASTLE, 0x0f, TRAP_ICE Ganon Castle Light Chest Lullaby, chest, NONE, INSIDE_GANON_CASTLE, 0x11, SMALL_KEY_GANON Ganon Castle Shadow Chest 1, chest, NONE, INSIDE_GANON_CASTLE, 0x08, RUPEE_BLUE Ganon Castle Shadow Chest 2, chest, NONE, INSIDE_GANON_CASTLE, 0x05, STRENGTH @@ -2497,7 +2497,7 @@ MQ Spirit Temple Lobby Front-Right Chest, chest, NONE MQ Spirit Temple Purple Leever Chest, chest, NONE, TEMPLE_SPIRIT, 0x04, RUPEE_PURPLE MQ Spirit Temple Symphony Room Chest, chest, MQ_SPIRIT_SYMPHONY, TEMPLE_SPIRIT, 0x07, RUPEE_PURPLE MQ Spirit Temple Beamos Room Chest, chest, NONE, TEMPLE_SPIRIT, 0x19, ARROWS_30 -MQ Spirit Temple Dinolfos Room Chest, chest, NONE, TEMPLE_SPIRIT, 0x18, ICE_TRAP +MQ Spirit Temple Dinolfos Room Chest, chest, NONE, TEMPLE_SPIRIT, 0x18, TRAP_ICE MQ Spirit Temple Boss Key Chest, chest, NONE, TEMPLE_SPIRIT, 0x05, BOSS_KEY_SPIRIT MQ Spirit Temple Topmost Chest, chest, NONE, TEMPLE_SPIRIT, 0x12, SMALL_KEY_SPIRIT MQ Spirit Temple GS Sun Block Room, gs, NONE, TEMPLE_SPIRIT, 0x38, GS_TOKEN From b087919630b8dc619c7fe8cfea5113cf105fe73b Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:11:08 +0100 Subject: [PATCH 21/34] Working in OoT --- packages/core/include/combo.h | 3 +++ packages/core/src/common/ice_trap.c | 31 +++++++++++++++++++++++++++++ packages/core/src/mm/play/play.c | 3 +++ packages/core/src/oot/play/play.c | 3 +++ packages/data/src/defs/gi.yml | 2 +- 5 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 packages/core/src/common/ice_trap.c diff --git a/packages/core/include/combo.h b/packages/core/include/combo.h index abbf5e6c37..0a83a5a87c 100644 --- a/packages/core/include/combo.h +++ b/packages/core/include/combo.h @@ -203,6 +203,9 @@ void comboClearCustomRespawn(CustomRespawnMode customRespawnMode); void LoadMmItemIcon(void* dst, int iconId); +/* Ice Traps */ +void Play_UpdateIceTrap(PlayState* play); + #else # include #endif diff --git a/packages/core/src/common/ice_trap.c b/packages/core/src/common/ice_trap.c new file mode 100644 index 0000000000..f93c084450 --- /dev/null +++ b/packages/core/src/common/ice_trap.c @@ -0,0 +1,31 @@ +#include + +#if defined(GAME_OOT) +# define APPLY_DAMAGE_ADDR 0x80835d08 +#endif + +#if defined(GAME_MM) +# define APPLY_DAMAGE_ADDR 0x00000000 +#endif + +void Play_UpdateIceTrap(PlayState* play) +{ + Player* player; + void (*Player_ApplyDamage)(PlayState* play, Player* this, s32 damageResponseType, f32 speed, f32 yVelocity, s16 yRot, s32 invincibilityTimer); + + if (!gSharedCustomSave.pendingIceTraps) + return; + if (gSaveContext.gameMode) + return; + + player = GET_PLAYER(play); + if (player->stateFlags1 & (PLAYER_ACTOR_STATE_CLIMB | PLAYER_ACTOR_STATE_DEATH | PLAYER_ACTOR_STATE_FROZEN | PLAYER_ACTOR_STATE_EPONA | PLAYER_ACTOR_STATE_GET_ITEM)) + return; + if (player->invincibilityTimer) + return; + + Player_ApplyDamage = OverlayAddr(APPLY_DAMAGE_ADDR); + player->actor.colChkInfo.damage = 0; + Player_ApplyDamage(play, player, 0x03, 0, 0, 0, 20); + gSharedCustomSave.pendingIceTraps--; +} diff --git a/packages/core/src/mm/play/play.c b/packages/core/src/mm/play/play.c index 215ebb0243..3d961836e1 100644 --- a/packages/core/src/mm/play/play.c +++ b/packages/core/src/mm/play/play.c @@ -810,7 +810,10 @@ void Play_MainWrapper(PlayState* play) Audio_DisplayMusicName(play); if (play->pauseCtx.state == 0) + { DrawGiSystem_Update(play); + Play_UpdateIceTrap(play); + } Debug_Update(); } diff --git a/packages/core/src/oot/play/play.c b/packages/core/src/oot/play/play.c index 0e94433c42..47f6c9b7f5 100644 --- a/packages/core/src/oot/play/play.c +++ b/packages/core/src/oot/play/play.c @@ -579,7 +579,10 @@ void Play_MainWrapper(PlayState* play) Audio_DisplayMusicName(play); if (play->pauseCtx.state == 0) + { DrawGiSystem_Update(play); + Play_UpdateIceTrap(play); + } Debug_Update(); } diff --git a/packages/data/src/defs/gi.yml b/packages/data/src/defs/gi.yml index b3813b73ff..258596c20c 100644 --- a/packages/data/src/defs/gi.yml +++ b/packages/data/src/defs/gi.yml @@ -426,7 +426,7 @@ - { id: OOT_SWORD_GILDED, type: MAJOR, add: [OOT_SWORD_EXTRA, 2], flags: 0x80, draw: MM_SWORD_GILDED, object: [mm, 0x01fa], name: "the Gilded Sword" } - { id: OOT_SPIN_UPGRADE, type: MAJOR, add: OOT_SPIN_UPGRADE, flags: 0xa0, draw: [SPIN_UPGRADE, 1], object: [oot, 0x018d], name: "the Spin Attack Upgrade" } - { id: OOT_TRIFORCE_FULL, type: MAJOR, add: [ENDGAME, 0], flags: 0x80, draw: TRIFORCE_FULL, object: TRIFORCE, name: "the Triforce" } -- { id: OOT_TRAP_ICE, type: MINOR, add: TRAP_ICE, flags: 0x80, draw: TRAP_ICE, name: "an Ice Trap" } +- { id: OOT_TRAP_ICE, type: MAJOR, add: TRAP_ICE, flags: 0x80, draw: TRAP_ICE, name: "an Ice Trap" } - { id: OOT_FAIRY_BIG, type: MINOR, add: OOT_FAIRY_BIG, flags: 0x80, draw: FAIRY_BIG, object: [oot, 0x0177], name: "a Big Fairy" } - { id: OOT_MASK_BLAST, type: MASK, add: [OOT_TRADE_CHILD, XITEM_OOT_CHILD_MASK_BLAST], flags: 0x80, draw: MM_MASK_BLAST, object: [mm, 0x026d], name: "the Blast Mask" } - { id: OOT_MASK_STONE, type: MASK, add: [OOT_TRADE_CHILD, XITEM_OOT_CHILD_MASK_STONE], flags: 0x80, draw: MM_MASK_STONE, object: [mm, 0x0254], name: "the Stone Mask" } From fe5eba7b8bda83bbda4b7f4f8735e5f352641495 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:18:29 +0100 Subject: [PATCH 22/34] Fixed GFX, works in MM --- packages/core/lib/combo/items/groups.ts | 1 + packages/core/src/common/drawgi.c | 2 ++ packages/core/src/common/ice_trap.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/core/lib/combo/items/groups.ts b/packages/core/lib/combo/items/groups.ts index 137f16af90..29e74b332a 100644 --- a/packages/core/lib/combo/items/groups.ts +++ b/packages/core/lib/combo/items/groups.ts @@ -220,6 +220,7 @@ export const TRAPS = new Set([ Items.OOT_TRAP_RUPOOR, Items.MM_TRAP_RUPOOR, Items.SHARED_TRAP_RUPOOR, + Items.OOT_TRAP_ICE, ]) export const JUNK = new Set([ diff --git a/packages/core/src/common/drawgi.c b/packages/core/src/common/drawgi.c index 290aad10ed..a5af572d00 100644 --- a/packages/core/src/common/drawgi.c +++ b/packages/core/src/common/drawgi.c @@ -1550,7 +1550,9 @@ void DrawGi_TrapIce(PlayState* play, s16 drawGiId, u8 param) Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL25_Xlu(play->state.gfxCtx); + gSPSegment(POLY_XLU_DISP++, 0x08, Gfx_TwoTexScroll(play->state.gfxCtx, G_TX_RENDERTILE, 0, (0 - play->gameplayFrames) % 128, 32, 32, 1, 0, (play->gameplayFrames * -2) % 128, 32, 32)); gSPMatrix(POLY_XLU_DISP++, Matrix_Finalize(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 50, 100, 255); gSPDisplayList(POLY_XLU_DISP++, gEffIceFragment3DL); CLOSE_DISPS(); } diff --git a/packages/core/src/common/ice_trap.c b/packages/core/src/common/ice_trap.c index f93c084450..4362c400c9 100644 --- a/packages/core/src/common/ice_trap.c +++ b/packages/core/src/common/ice_trap.c @@ -5,7 +5,7 @@ #endif #if defined(GAME_MM) -# define APPLY_DAMAGE_ADDR 0x00000000 +# define APPLY_DAMAGE_ADDR 0x80833b18 #endif void Play_UpdateIceTrap(PlayState* play) From 4b81ff7598b293f89db2743fa7e18225efb4f1d6 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:21:04 +0100 Subject: [PATCH 23/34] Fix ice trap GI height --- packages/core/src/common/drawgi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/src/common/drawgi.c b/packages/core/src/common/drawgi.c index a5af572d00..dc63c67e6d 100644 --- a/packages/core/src/common/drawgi.c +++ b/packages/core/src/common/drawgi.c @@ -1547,6 +1547,7 @@ void DrawGi_TrapIce(PlayState* play, s16 drawGiId, u8 param) { static const float scale = 0.5f; + Matrix_Translate(0.f, -25.f, 0.f, MTXMODE_APPLY); Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); OPEN_DISPS(play->state.gfxCtx); Gfx_SetupDL25_Xlu(play->state.gfxCtx); From a7c47d0bbfb134e24cc621e5e58097063f215dc2 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:32:00 +0100 Subject: [PATCH 24/34] New system for item cloaks --- .../core/lib/combo/patch-build/randomizer.ts | 12 +++++-- packages/core/src/common/item/item.c | 34 ++++++------------- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/packages/core/lib/combo/patch-build/randomizer.ts b/packages/core/lib/combo/patch-build/randomizer.ts index 238a03a66a..64ddc5c685 100644 --- a/packages/core/lib/combo/patch-build/randomizer.ts +++ b/packages/core/lib/combo/patch-build/randomizer.ts @@ -482,15 +482,23 @@ const gameChecks = (worldId: number, settings: Settings, game: Game, logic: Logi const key = checkKey(c); const itemGi = gi(settings, game, item.item, true); - const b = new Uint8Array(8); + const b = new Uint8Array(16); bufWriteU32BE(b, 0, key); bufWriteU16BE(b, 4, item.player + 1); bufWriteU16BE(b, 6, itemGi); + let cloakGi = 0xffff; + if (item.item === Items.OOT_TRAP_ICE) { + cloakGi = gi(settings, 'oot', Items.OOT_ARROW_LIGHT, false); + } + bufWriteU16BE(b, 8, cloakGi); buffers.push(b); } /* Sort by key ascending */ buffers.sort((a, b) => bufReadU32BE(a, 0) < bufReadU32BE(b, 0) ? -1 : 1); - return padBuffer16(concatUint8Arrays(buffers)); + const end = new Uint8Array(16); + end.fill(0xff); + buffers.push(end); + return concatUint8Arrays(buffers); }; const HINT_OFFSETS = { diff --git a/packages/core/src/common/item/item.c b/packages/core/src/common/item/item.c index 2617addfad..e47a6bf64d 100644 --- a/packages/core/src/common/item/item.c +++ b/packages/core/src/common/item/item.c @@ -173,6 +173,8 @@ typedef struct ComboOverrideData u32 key; s16 player; u16 value; + s16 giCloak; + s16 unused[3]; } ComboOverrideData; @@ -236,25 +238,10 @@ static u32 makeOverrideKey(const ComboItemQuery* q) static int overrideData(ComboOverrideData* data, u32 key) { - ComboOverrideData d; u32 min; u32 max; u32 cursor; - u32 ovData[2]; - -#if defined(DEBUG) && defined(DEBUG_MM_OVERRIDE) && defined(GAME_MM) - data->key = 0; - data->player = 1; - data->value = DEBUG_MM_OVERRIDE; - return 1; -#endif - -#if defined(DEBUG) && defined(DEBUG_OOT_OVERRIDE) && defined(GAME_OOT) - data->key = 0; - data->player = 1; - data->value = DEBUG_OOT_OVERRIDE; - return 1; -#endif + u32 ovData[4]; /* Check the cache */ for (int i = 0; i < ARRAY_COUNT(sComboOverridesCache); ++i) @@ -278,18 +265,19 @@ static int overrideData(ComboOverrideData* data, u32 key) /* Read from cart */ /* TODO: Have a generic helper for this */ ovData[0] = comboReadPhysU32(sComboOverridesDevAddr + cursor * sizeof(ComboOverrideData) + 0x00); - ovData[1] = comboReadPhysU32(sComboOverridesDevAddr + cursor * sizeof(ComboOverrideData) + 0x04); - memcpy(&d, ovData, sizeof(d)); - - if (d.key == key) + if (ovData[0] == key) { + ovData[1] = comboReadPhysU32(sComboOverridesDevAddr + cursor * sizeof(ComboOverrideData) + 0x04); + ovData[2] = comboReadPhysU32(sComboOverridesDevAddr + cursor * sizeof(ComboOverrideData) + 0x08); + ovData[3] = comboReadPhysU32(sComboOverridesDevAddr + cursor * sizeof(ComboOverrideData) + 0x0c); + /* Copy and add to cache */ - memcpy(data, &d, sizeof(*data)); - memcpy(&sComboOverridesCache[sComboOverridesCacheCursor], &d, sizeof(d)); + memcpy(data, ovData, sizeof(*data)); + memcpy(&sComboOverridesCache[sComboOverridesCacheCursor], data, sizeof(*data)); sComboOverridesCacheCursor = (sComboOverridesCacheCursor + 1) % ARRAY_COUNT(sComboOverridesCache); return 1; } - if (key > d.key) + if (key > ovData[0]) min = cursor + 1; else max = cursor; From a83e72d9cb62354c72a2daa4abc4b25997d897ca Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Mon, 27 Jan 2025 11:43:47 +0100 Subject: [PATCH 25/34] System is working --- packages/core/include/combo/draw.h | 1 + packages/core/include/combo/item.h | 1 + packages/core/include/combo/text.h | 1 + packages/core/lib/combo/patch-build/randomizer.ts | 2 +- packages/core/src/common/draw.c | 8 ++++++++ packages/core/src/common/item/item.c | 1 + packages/core/src/common/text/text.c | 4 ++++ packages/core/src/common/text/text_item_get.c | 2 +- packages/core/src/mm/actors/En/En_GirlA.c | 2 +- packages/core/src/oot/actors/En/En_GirlA.c | 2 +- 10 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/core/include/combo/draw.h b/packages/core/include/combo/draw.h index 7bd095052f..07b1d31577 100644 --- a/packages/core/include/combo/draw.h +++ b/packages/core/include/combo/draw.h @@ -13,6 +13,7 @@ typedef struct Actor Actor; void Draw_SetObjectSegment(GraphicsContext* gfx, void* buffer); void Draw_Gi(PlayState* play, Actor* actor, s16 gi, int flags); +void Draw_GiCloaked(PlayState* play, Actor* actor, s16 gi, s16 cloakGi, int flags); void Draw_Init2D(Gfx** dl); void Draw_Blit2D_RGBA32(Gfx** dl, u32 segAddr, int w, int h, float x, float y, float scale); void Draw_Blit2D_RGBA16(Gfx** dl, u32 segAddr, int w, int h, float x, float y, float scale); diff --git a/packages/core/include/combo/item.h b/packages/core/include/combo/item.h index cd2303bd1b..6e34c2e5dd 100644 --- a/packages/core/include/combo/item.h +++ b/packages/core/include/combo/item.h @@ -176,6 +176,7 @@ typedef struct ComboItemOverride u8 playerFrom; s16 giRaw; s16 gi; + s16 cloakGi; } ComboItemOverride; diff --git a/packages/core/include/combo/text.h b/packages/core/include/combo/text.h index 1c331071d9..e38f20f37a 100644 --- a/packages/core/include/combo/text.h +++ b/packages/core/include/combo/text.h @@ -58,6 +58,7 @@ #define TF_PROGRESSIVE (1 << 2) #define TF_SIGNAL (1 << 3) #define TF_PLURAL (1 << 4) +#define TF_NOCLOAK (1 << 5) #define TFS_CONFIRM (1 << 0) #define TFS_MUSHROOM (1 << 1) diff --git a/packages/core/lib/combo/patch-build/randomizer.ts b/packages/core/lib/combo/patch-build/randomizer.ts index 64ddc5c685..c88e07263a 100644 --- a/packages/core/lib/combo/patch-build/randomizer.ts +++ b/packages/core/lib/combo/patch-build/randomizer.ts @@ -486,7 +486,7 @@ const gameChecks = (worldId: number, settings: Settings, game: Game, logic: Logi bufWriteU32BE(b, 0, key); bufWriteU16BE(b, 4, item.player + 1); bufWriteU16BE(b, 6, itemGi); - let cloakGi = 0xffff; + let cloakGi = 0; if (item.item === Items.OOT_TRAP_ICE) { cloakGi = gi(settings, 'oot', Items.OOT_ARROW_LIGHT, false); } diff --git a/packages/core/src/common/draw.c b/packages/core/src/common/draw.c index 0fe64d4782..68e5c403ad 100644 --- a/packages/core/src/common/draw.c +++ b/packages/core/src/common/draw.c @@ -71,6 +71,14 @@ void Draw_Gi(PlayState* play, Actor* actor, s16 gi, int flags) drawGiParam(play, gi); } +void Draw_GiCloaked(PlayState* play, Actor* actor, s16 gi, s16 cloakGi, int flags) +{ + if (cloakGi && gi != GI_MM_SOLD_OUT) + gi = cloakGi; + + Draw_Gi(play, actor, gi, flags); +} + void comboPlayerDrawGI(PlayState* play, int drawGiMinusOne) { drawGiParamDrawId(play, (u8)(drawGiMinusOne + 1), playerDrawGiParam); diff --git a/packages/core/src/common/item/item.c b/packages/core/src/common/item/item.c index e47a6bf64d..8c8b4e6f85 100644 --- a/packages/core/src/common/item/item.c +++ b/packages/core/src/common/item/item.c @@ -315,6 +315,7 @@ void comboItemOverride(ComboItemOverride* dst, const ComboItemQuery* q) { dst->player = data.player; gi = (s16)data.value; + dst->cloakGi = data.giCloak; } if (q->ovFlags & OVF_RENEW) diff --git a/packages/core/src/common/text/text.c b/packages/core/src/common/text/text.c index 07efa9bccc..c0be58fe2d 100644 --- a/packages/core/src/common/text/text.c +++ b/packages/core/src/common/text/text.c @@ -1028,6 +1028,10 @@ void comboTextAppendItemNameOverrideEx(char** b, const ComboItemOverride* o, int gi = o->giRaw; else gi = o->gi; + + if (gi != GI_MM_SOLD_OUT && o->cloakGi && !(flags & TF_NOCLOAK)) + gi = o->cloakGi; + comboTextAppendItemNameEx(b, gi, flags, importance); if (o->player != PLAYER_SELF && o->player != PLAYER_ALL && o->player != gComboConfig.playerId) { diff --git a/packages/core/src/common/text/text_item_get.c b/packages/core/src/common/text/text_item_get.c index 98439318ba..d666a1bd9c 100644 --- a/packages/core/src/common/text/text_item_get.c +++ b/packages/core/src/common/text/text_item_get.c @@ -179,7 +179,7 @@ void comboTextHijackItemEx(PlayState* play, const ComboItemOverride* o, int coun comboTextAppendHeader(&b); start = b; comboTextAppendStr(&b, "You got "); - comboTextAppendItemNameOverride(&b, o, 0); + comboTextAppendItemNameOverride(&b, o, TF_NOCLOAK); comboTextAppendStr(&b, "!"); if (isSelf) { diff --git a/packages/core/src/mm/actors/En/En_GirlA.c b/packages/core/src/mm/actors/En/En_GirlA.c index b3c5694742..b9848bdf1e 100644 --- a/packages/core/src/mm/actors/En/En_GirlA.c +++ b/packages/core/src/mm/actors/En/En_GirlA.c @@ -12,7 +12,7 @@ void EnGirlA_Draw(Actor_EnGirlA* this, PlayState* play) EnGirlA_ItemOverride(&o, this); if (o.gi != GI_MM_SOLD_OUT) MatrixRotation(this->angle, 1); - Draw_Gi(play, &this->base, o.gi, 0); + Draw_GiCloaked(play, &this->base, o.gi, o.cloakGi, 0); } void EnGirlA_AfterHandler(Actor_EnGirlA* this, PlayState* play) diff --git a/packages/core/src/oot/actors/En/En_GirlA.c b/packages/core/src/oot/actors/En/En_GirlA.c index f384e11463..c865dfd166 100644 --- a/packages/core/src/oot/actors/En/En_GirlA.c +++ b/packages/core/src/oot/actors/En/En_GirlA.c @@ -18,7 +18,7 @@ void EnGirlA_Draw(Actor_EnGirlA* this, PlayState* play) if (o.gi != GI_MM_SOLD_OUT) Matrix_RotateY(((this->angle * 360.f) / 65536.f) * 0.017453292f, MTXMODE_APPLY); - Draw_Gi(play, &this->base, o.gi, 0); + Draw_GiCloaked(play, &this->base, o.gi, o.cloakGi, 0); } PATCH_FUNC(0x80864910, EnGirlA_Draw); From de5541a95e372e373d40913ff4eb178a0a4de56b Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Mon, 27 Jan 2025 12:18:35 +0100 Subject: [PATCH 26/34] Make ice traps rotate the other way around --- packages/core/src/common/actors/En_Elf.c | 2 +- packages/core/src/common/actors/En_Item00.c | 2 +- packages/core/src/common/draw.c | 31 +++++++++++++++++++ packages/core/src/mm/actors/Dm/Dm_Char02.c | 2 +- packages/core/src/mm/actors/Door/Door_Warp1.c | 13 +++----- packages/core/src/mm/actors/En/En_Col_Man.c | 2 +- packages/core/src/mm/actors/En/En_Elforg.c | 2 +- packages/core/src/mm/actors/En/En_Item00.c | 2 +- packages/core/src/mm/actors/En/En_Si.c | 2 +- .../core/src/mm/actors/Item/Item_B_Heart.c | 2 +- .../core/src/mm/actors/Obj/Obj_Moon_Stone.c | 2 +- .../core/src/oot/actors/Demo/Demo_Effect.c | 2 +- .../core/src/oot/actors/Door/Door_Warp1.c | 9 +++--- packages/core/src/oot/actors/En/En_Ex_Item.c | 2 +- packages/core/src/oot/actors/En/En_Ex_Ruppy.c | 2 +- packages/core/src/oot/actors/En/En_G_Switch.c | 2 +- packages/core/src/oot/actors/En/En_Item00.c | 2 +- packages/core/src/oot/actors/En/En_Si.c | 2 +- .../core/src/oot/actors/Item/Item_B_Heart.c | 2 +- .../core/src/oot/actors/Item/Item_Etcetera.c | 4 +-- .../core/src/oot/actors/Item/Item_Ocarina.c | 2 +- packages/core/src/oot/actors/Misc/Fishing.c | 2 +- 22 files changed, 60 insertions(+), 33 deletions(-) diff --git a/packages/core/src/common/actors/En_Elf.c b/packages/core/src/common/actors/En_Elf.c index c9c64e28d7..ac81c583d1 100644 --- a/packages/core/src/common/actors/En_Elf.c +++ b/packages/core/src/common/actors/En_Elf.c @@ -98,7 +98,7 @@ void EnElf_Draw(Actor_EnElf* this, PlayState* play) static const float scale = 25.0f; Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); - Draw_Gi(play, &this->base, this->extendedGiDraw, 0); + Draw_GiCloaked(play, &this->base, this->extendedGiDraw, o.cloakGi, 0); } #if defined(GAME_OOT) diff --git a/packages/core/src/common/actors/En_Item00.c b/packages/core/src/common/actors/En_Item00.c index 3d69ae48c6..b4e0de02a9 100644 --- a/packages/core/src/common/actors/En_Item00.c +++ b/packages/core/src/common/actors/En_Item00.c @@ -44,7 +44,7 @@ static void EnItem00_DrawXflag(Actor_EnItem00* this, PlayState* play) Matrix_Translate(this->base.world.pos.x, this->base.world.pos.y + 20.f, this->base.world.pos.z, MTXMODE_NEW); Matrix_Scale(0.35f, 0.35f, 0.35f, MTXMODE_APPLY); Matrix_RotateY(this->base.shape.rot.y * ((M_PI * 2.f) / 32767.f), MTXMODE_APPLY); - Draw_Gi(play, &this->base, gi, 0); + Draw_GiCloaked(play, &this->base, gi, o.cloakGi, 0); } static int EnItem00_XflagCanCollect(Actor_EnItem00* this, PlayState* play) diff --git a/packages/core/src/common/draw.c b/packages/core/src/common/draw.c index 68e5c403ad..b8ced5e640 100644 --- a/packages/core/src/common/draw.c +++ b/packages/core/src/common/draw.c @@ -71,10 +71,41 @@ void Draw_Gi(PlayState* play, Actor* actor, s16 gi, int flags) drawGiParam(play, gi); } +static float Draw_GetCurrentRotationY(void) +{ + Vec3f pointOrigin = { 0.f, 0.f, 0.f }; + Vec3f point = { 1.f, 0.f, 0.f }; + Vec3f resultOrigin; + Vec3f result; + float length; + float lengthInv; + + Matrix_MultVec3f(&point, &result); + Matrix_MultVec3f(&pointOrigin, &resultOrigin); + result.x -= resultOrigin.x; + result.z -= resultOrigin.z; + result.y = 0; + length = Math3D_Vec3fMagnitude(&result); + if (length < 0.00001f) + return 0.f; + lengthInv = 1.f / length; + result.x *= lengthInv; + result.y *= lengthInv; + result.z *= lengthInv; + + return Math_Atan2F(result.z, result.x); +} + void Draw_GiCloaked(PlayState* play, Actor* actor, s16 gi, s16 cloakGi, int flags) { + float rot; + if (cloakGi && gi != GI_MM_SOLD_OUT) + { gi = cloakGi; + rot = Draw_GetCurrentRotationY(); + Matrix_RotateY(-rot * 2, MTXMODE_APPLY); + } Draw_Gi(play, actor, gi, flags); } diff --git a/packages/core/src/mm/actors/Dm/Dm_Char02.c b/packages/core/src/mm/actors/Dm/Dm_Char02.c index cc456129cb..a44fab2571 100644 --- a/packages/core/src/mm/actors/Dm/Dm_Char02.c +++ b/packages/core/src/mm/actors/Dm/Dm_Char02.c @@ -72,5 +72,5 @@ void DmChar02_DrawOcarina(Actor* this, PlayState* play) DmChar02_ItemOverride(&o, NPC_MM_SKULL_KID_OCARINA); Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); Matrix_Translate(0.0f, 20.0f, 0.0f, MTXMODE_APPLY); - Draw_Gi(play, this, o.gi, DRAW_RAW); + Draw_GiCloaked(play, this, o.gi, o.cloakGi, DRAW_RAW); } diff --git a/packages/core/src/mm/actors/Door/Door_Warp1.c b/packages/core/src/mm/actors/Door/Door_Warp1.c index d06ffe1168..889e76bbbd 100644 --- a/packages/core/src/mm/actors/Door/Door_Warp1.c +++ b/packages/core/src/mm/actors/Door/Door_Warp1.c @@ -46,17 +46,15 @@ static const BlueWarpData* DoorWarp1_GetData(Actor* this, PlayState* play) return &kBlueWarpData[id]; } -static s16 DoorWarp1_GetGI(const BlueWarpData* data) +static void DoorWarp1_ItemOverride(ComboItemOverride* o, const BlueWarpData* data) { ComboItemQuery q = ITEM_QUERY_INIT; - ComboItemOverride o; q.ovType = OV_NPC; q.gi = data->gi; q.id = data->npc; - comboItemOverride(&o, &q); - return o.gi; + comboItemOverride(o, &q); } int DoorWarp1_Collide(Actor* this, PlayState* play) @@ -140,21 +138,20 @@ void DoorWarp1_AfterDraw(Actor* this, PlayState* play) { static const int kRotDivisor = 100; const BlueWarpData* data; + ComboItemOverride o; float angle; - s16 gi; data = DoorWarp1_GetData(this, play); if (data == NULL) return; if (gMmExtraBoss.items & (1 << data->index)) return; - gi = DoorWarp1_GetGI(data); - + DoorWarp1_ItemOverride(&o, data); angle = (play->state.frameCount % kRotDivisor) * (1.f / kRotDivisor) * M_PI * 2.f; Matrix_Translate(this->world.pos.x, this->world.pos.y + 35.f, this->world.pos.z, MTXMODE_NEW); Matrix_Scale(0.35f, 0.35f, 0.35f, MTXMODE_APPLY); Matrix_RotateY(angle, MTXMODE_APPLY); - Draw_Gi(play, this, gi, DRAW_RAW); + Draw_GiCloaked(play, this, o.gi, o.cloakGi, DRAW_RAW); } PATCH_FUNC(0x808b866c, DoorWarp1_ShouldTrigger); diff --git a/packages/core/src/mm/actors/En/En_Col_Man.c b/packages/core/src/mm/actors/En/En_Col_Man.c index aa77009e8d..0d2d810b8b 100644 --- a/packages/core/src/mm/actors/En/En_Col_Man.c +++ b/packages/core/src/mm/actors/En/En_Col_Man.c @@ -36,7 +36,7 @@ void EnColMan_DrawHeartPiece(Actor* this, PlayState* play) EnColMan_ItemOverride(&o); Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); - Draw_Gi(play, this, o.gi, 0); + Draw_GiCloaked(play, this, o.gi, o.cloakGi, 0); } PATCH_FUNC(0x80afe414, EnColMan_DrawHeartPiece); diff --git a/packages/core/src/mm/actors/En/En_Elforg.c b/packages/core/src/mm/actors/En/En_Elforg.c index caa4d9dc79..6f5ad4fb72 100644 --- a/packages/core/src/mm/actors/En/En_Elforg.c +++ b/packages/core/src/mm/actors/En/En_Elforg.c @@ -50,7 +50,7 @@ static void EnElforg_Draw(Actor* this, PlayState* play) Matrix_Translate(this->world.pos.x, this->world.pos.y, this->world.pos.z, MTXMODE_NEW); Matrix_Scale(0.35f, 0.35f, 0.35f, MTXMODE_APPLY); Matrix_RotateY(angle, MTXMODE_APPLY); - Draw_Gi(play, this, o.gi, 0); + Draw_GiCloaked(play, this, o.gi, o.cloakGi, 0); } void EnElforg_DrawWrapper(Actor* this, PlayState* play) diff --git a/packages/core/src/mm/actors/En/En_Item00.c b/packages/core/src/mm/actors/En/En_Item00.c index cb51dca106..ef0249a1b1 100644 --- a/packages/core/src/mm/actors/En/En_Item00.c +++ b/packages/core/src/mm/actors/En/En_Item00.c @@ -65,7 +65,7 @@ void EnItem00_DrawHeartPiece(Actor_EnItem00* this, PlayState* play) EnItem00_ItemQuery(&q, this, play, GI_OOT_HEART_PIECE); comboItemOverride(&o, &q); Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); - Draw_Gi(play, &this->base, o.gi, 0); + Draw_GiCloaked(play, &this->base, o.gi, o.cloakGi, 0); } PATCH_FUNC(0x800a75b8, EnItem00_DrawHeartPiece); diff --git a/packages/core/src/mm/actors/En/En_Si.c b/packages/core/src/mm/actors/En/En_Si.c index 5d594f69c6..ac41ce9a21 100644 --- a/packages/core/src/mm/actors/En/En_Si.c +++ b/packages/core/src/mm/actors/En/En_Si.c @@ -58,7 +58,7 @@ void EnSi_Draw(Actor* this, PlayState* play) ComboItemOverride o; EnSi_ItemOverride(&o, this, play); - Draw_Gi(play, this, o.gi, 0); + Draw_GiCloaked(play, this, o.gi, o.cloakGi, 0); } PATCH_FUNC(0x8098cd0c, EnSi_Draw); diff --git a/packages/core/src/mm/actors/Item/Item_B_Heart.c b/packages/core/src/mm/actors/Item/Item_B_Heart.c index c69420aecc..246a433cb8 100644 --- a/packages/core/src/mm/actors/Item/Item_B_Heart.c +++ b/packages/core/src/mm/actors/Item/Item_B_Heart.c @@ -29,7 +29,7 @@ void ItemBHeart_Draw(Actor* this, PlayState* play) ItemBHeart_ItemQuery(&q, play); comboItemOverride(&o, &q); - Draw_Gi(play, this, o.gi, DRAW_RAW); + Draw_GiCloaked(play, this, o.gi, o.cloakGi, DRAW_RAW); } PATCH_FUNC(0x808bcfc4, ItemBHeart_Draw); diff --git a/packages/core/src/mm/actors/Obj/Obj_Moon_Stone.c b/packages/core/src/mm/actors/Obj/Obj_Moon_Stone.c index 3248d353f1..de7de5c339 100644 --- a/packages/core/src/mm/actors/Obj/Obj_Moon_Stone.c +++ b/packages/core/src/mm/actors/Obj/Obj_Moon_Stone.c @@ -25,7 +25,7 @@ void ObjMoonStone_Draw(Actor* this, PlayState* play) ObjMoonStone_ItemQuery(&q, play); comboItemOverride(&o, &q); - Draw_Gi(play, this, o.gi, 0); + Draw_GiCloaked(play, this, o.gi, o.cloakGi, 0); } PATCH_FUNC(0x80c06910, ObjMoonStone_Draw); diff --git a/packages/core/src/oot/actors/Demo/Demo_Effect.c b/packages/core/src/oot/actors/Demo/Demo_Effect.c index 37710469ba..16d7db1105 100644 --- a/packages/core/src/oot/actors/Demo/Demo_Effect.c +++ b/packages/core/src/oot/actors/Demo/Demo_Effect.c @@ -48,7 +48,7 @@ static void DemoEffect_DrawSapphireInJabu(Actor* this, PlayState* play) Matrix_Translate(this->world.pos.x, this->world.pos.y, this->world.pos.z, MTXMODE_NEW); Matrix_Scale(0.35f, 0.35f, 0.35f, MTXMODE_APPLY); Matrix_RotateY(angle, MTXMODE_APPLY); - Draw_Gi(play, this, o.gi, 0); + Draw_GiCloaked(play, this, o.gi, o.cloakGi, 0); } void DemoEffect_DrawSpiritualLoader(Actor* this, PlayState* play) diff --git a/packages/core/src/oot/actors/Door/Door_Warp1.c b/packages/core/src/oot/actors/Door/Door_Warp1.c index ec8f156cd6..5808eaa5e2 100644 --- a/packages/core/src/oot/actors/Door/Door_Warp1.c +++ b/packages/core/src/oot/actors/Door/Door_Warp1.c @@ -86,17 +86,15 @@ int DoorWarp1_Collide(Actor* this, PlayState* play) return 0; } -static s16 DoorWarp1_GetGI(const BlueWarpData* data) +static void DoorWarp1_ItemOverride(ComboItemOverride* o, const BlueWarpData* data) { ComboItemQuery q = ITEM_QUERY_INIT; - ComboItemOverride o; q.ovType = OV_NPC; q.id = data->npc; q.gi = data->gi; comboItemOverride(&o, &q); - return o.gi; } int DoorWarp1_ShouldTrigger(Actor* this, PlayState* play) @@ -142,6 +140,7 @@ void DoorWarp1_AfterDrawWarp(Actor* this, PlayState* play) static const int kRotDivisor = 100; float angle; const BlueWarpData* data; + ComboItemOverride o; s16 gi; data = DoorWarp1_GetData(play); @@ -151,10 +150,10 @@ void DoorWarp1_AfterDrawWarp(Actor* this, PlayState* play) return; angle = (play->state.frameCount % kRotDivisor) * (1.f / kRotDivisor) * M_PI * 2.f; - gi = DoorWarp1_GetGI(data); + DoorWarp1_ItemOverride(&o, data); Matrix_Translate(this->world.pos.x, this->world.pos.y + 35.f, this->world.pos.z, MTXMODE_NEW); Matrix_Scale(0.35f, 0.35f, 0.35f, MTXMODE_APPLY); Matrix_RotateY(angle, MTXMODE_APPLY); - Draw_Gi(play, this, gi, DRAW_RAW); + Draw_GiCloaked(play, this, o.gi, o.cloakGi, DRAW_RAW); } diff --git a/packages/core/src/oot/actors/En/En_Ex_Item.c b/packages/core/src/oot/actors/En/En_Ex_Item.c index 4ba1f90a26..88227e9297 100644 --- a/packages/core/src/oot/actors/En/En_Ex_Item.c +++ b/packages/core/src/oot/actors/En/En_Ex_Item.c @@ -82,7 +82,7 @@ void EnExItem_Draw(Actor* actor, PlayState* play) comboItemOverride(&o, &q); scale = *(float*)(((char*)actor) + 0x154); Actor_SetScale(actor, scale); - Draw_Gi(play, actor, o.gi, 0); + Draw_GiCloaked(play, actor, o.gi, o.cloakGi, 0); } void EnExItem_GiveItem(Actor* actor, PlayState* play, s16 gi, float a, float b) diff --git a/packages/core/src/oot/actors/En/En_Ex_Ruppy.c b/packages/core/src/oot/actors/En/En_Ex_Ruppy.c index 956356a099..002fbb8f05 100644 --- a/packages/core/src/oot/actors/En/En_Ex_Ruppy.c +++ b/packages/core/src/oot/actors/En/En_Ex_Ruppy.c @@ -58,7 +58,7 @@ void EnExRuppy_Draw(Actor_EnExRuppy* this, PlayState* play) EnExRuppy_ItemQuery(&q, this, play); comboItemOverride(&o, &q); Matrix_Scale(25.0f, 25.0f, 25.0f, MTXMODE_APPLY); - Draw_Gi(play, &this->actor, o.gi, 0); + Draw_GiCloaked(play, &this->actor, o.gi, o.cloakGi, 0); } void EnExRuppy_HandlerCollected(Actor_EnExRuppy* this, PlayState* play) diff --git a/packages/core/src/oot/actors/En/En_G_Switch.c b/packages/core/src/oot/actors/En/En_G_Switch.c index e9320e01ea..81803b016b 100644 --- a/packages/core/src/oot/actors/En/En_G_Switch.c +++ b/packages/core/src/oot/actors/En/En_G_Switch.c @@ -153,7 +153,7 @@ void EnGSwitch_DrawSilverRupee(Actor* this, PlayState* play) EnGSwitch_ItemOverride(&o, this, play); Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); - Draw_Gi(play, this, o.gi, 0); + Draw_GiCloaked(play, this, o.gi, o.cloakGi, 0); } static const Gfx kPotDrawListNormalTop[] = { diff --git a/packages/core/src/oot/actors/En/En_Item00.c b/packages/core/src/oot/actors/En/En_Item00.c index 2dd4328b90..b9d66099e4 100644 --- a/packages/core/src/oot/actors/En/En_Item00.c +++ b/packages/core/src/oot/actors/En/En_Item00.c @@ -79,7 +79,7 @@ void EnItem00_DrawHeartPieceSmallKey(Actor_EnItem00* this, PlayState* play) EnItem00_ItemQuery(&q, this, play, -1); comboItemOverride(&o, &q); Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); - Draw_Gi(play, &this->base, o.gi, 0); + Draw_GiCloaked(play, &this->base, o.gi, o.cloakGi, 0); } PATCH_FUNC(0x80013498, EnItem00_DrawHeartPieceSmallKey); diff --git a/packages/core/src/oot/actors/En/En_Si.c b/packages/core/src/oot/actors/En/En_Si.c index 306b131773..1389018fa0 100644 --- a/packages/core/src/oot/actors/En/En_Si.c +++ b/packages/core/src/oot/actors/En/En_Si.c @@ -41,7 +41,7 @@ void EnSi_Draw(Actor* this, PlayState* play) ComboItemOverride o; EnSi_ItemOverride(&o, this); - Draw_Gi(play, this, o.gi, 0); + Draw_GiCloaked(play, this, o.gi, o.cloakGi, 0); } PATCH_CALL(0x80b4b3f8, EnSi_Draw); diff --git a/packages/core/src/oot/actors/Item/Item_B_Heart.c b/packages/core/src/oot/actors/Item/Item_B_Heart.c index 2b288c8336..3b80007190 100644 --- a/packages/core/src/oot/actors/Item/Item_B_Heart.c +++ b/packages/core/src/oot/actors/Item/Item_B_Heart.c @@ -29,7 +29,7 @@ static void ItemBHeart_Draw(Actor* this, PlayState* play) ItemBHeart_ItemQuery(&q, this, play); comboItemOverride(&o, &q); - Draw_Gi(play, this, o.gi, 0); + Draw_GiCloaked(play, this, o.gi, o.cloakGi, 0); } PATCH_FUNC(0x80909620, ItemBHeart_Draw); diff --git a/packages/core/src/oot/actors/Item/Item_Etcetera.c b/packages/core/src/oot/actors/Item/Item_Etcetera.c index a72e4c1a86..079816891b 100644 --- a/packages/core/src/oot/actors/Item/Item_Etcetera.c +++ b/packages/core/src/oot/actors/Item/Item_Etcetera.c @@ -58,7 +58,7 @@ void ItemEtcetera_Draw(Actor_ItemEtcetera* this, PlayState* play) ItemEtcetera_ItemQuery(&q, &this->base, this->gi); comboItemOverride(&o, &q); - Draw_Gi(play, &this->base, o.gi, 0); + Draw_GiCloaked(play, &this->base, o.gi, o.cloakGi, 0); } PATCH_FUNC(0x80a5e610, ItemEtcetera_Draw); @@ -99,7 +99,7 @@ void ItemEtcetera_DrawTreasureGame(Actor_ItemEtcetera* this, PlayState* play) ItemEtcetera_ItemQuery(&q, &this->base, gi); comboItemOverride(&o, &q); - Draw_Gi(play, &this->base, o.gi, 0); + Draw_GiCloaked(play, &this->base, o.gi, o.cloakGi, 0); } PATCH_FUNC(0x80a5e5b8, ItemEtcetera_DrawTreasureGame); diff --git a/packages/core/src/oot/actors/Item/Item_Ocarina.c b/packages/core/src/oot/actors/Item/Item_Ocarina.c index 270e7920dc..f67f171957 100644 --- a/packages/core/src/oot/actors/Item/Item_Ocarina.c +++ b/packages/core/src/oot/actors/Item/Item_Ocarina.c @@ -82,7 +82,7 @@ void ItemOcarina_Draw(Actor* this, PlayState* play) ComboItemOverride o; ItemOcarina_ItemOverride(&o, 0); - Draw_Gi(play, this, o.gi, 0); + Draw_GiCloaked(play, this, o.gi, o.cloakGi, 0); } PATCH_FUNC(0x80a2b7c0, ItemOcarina_Handler); diff --git a/packages/core/src/oot/actors/Misc/Fishing.c b/packages/core/src/oot/actors/Misc/Fishing.c index 09b70240cc..a351dbb1bf 100644 --- a/packages/core/src/oot/actors/Misc/Fishing.c +++ b/packages/core/src/oot/actors/Misc/Fishing.c @@ -94,7 +94,7 @@ void Fishing_DrawFish_SkelAnime(PlayState* play, void** skeleton, Vec3s* jointTa Matrix_MultVec3f(&mouthOffset, fishMouthPos); Matrix_Scale(56.0f, 56.0f, 56.0f, MTXMODE_APPLY); - Draw_Gi(play, this, o.gi, 0); + Draw_GiCloaked(play, this, o.gi, o.cloakGi, 0); } PATCH_CALL(0x80a405d8, Fishing_DrawFish_SkelAnime); From d64e4f69bf3e918cc75fd2fa71d5ac757b28384c Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Mon, 27 Jan 2025 12:44:59 +0100 Subject: [PATCH 27/34] Properly cloak CSMC --- packages/core/include/combo/csmc.h | 14 ++++----- packages/core/include/combo/draw.h | 2 +- .../core/src/common/actors/En_Tubo_Trap.c | 2 +- packages/core/src/common/cow.c | 2 +- packages/core/src/common/csmc/csmc_chest.c | 16 +++++----- packages/core/src/common/csmc/csmc_grass.c | 8 ++--- packages/core/src/common/csmc/csmc_gs.c | 8 ++--- packages/core/src/common/csmc/csmc_navi.c | 6 ++-- packages/core/src/common/csmc/csmc_pot.c | 8 ++--- packages/core/src/common/csmc/csmc_util.c | 9 +++++- packages/core/src/common/draw.c | 8 ++--- .../src/common/ovl/actors/En_Butte/En_Butte.c | 2 +- .../src/common/ovl/actors/Obj_Comb/Obj_Comb.c | 2 +- .../common/ovl/actors/Obj_Kibako/Obj_Kibako.c | 2 +- .../ovl/actors/Obj_Kibako2/Obj_Kibako2.c | 2 +- packages/core/src/mm/actors/En/En_Box.c | 19 +++++------- packages/core/src/mm/actors/En/En_Hit_Tag.c | 18 +++++++++--- .../src/mm/actors/En/En_Invisible_Ruppe.c | 2 +- packages/core/src/mm/actors/En/En_Sw.c | 2 +- .../core/src/mm/ovl/actors/En_Kusa/En_Kusa.c | 2 +- .../src/mm/ovl/actors/En_Kusa2/En_Kusa2.c | 2 +- .../ovl/actors/Obj_Flowerpot/Obj_Flowerpot.c | 29 ++++++++++++------- .../src/mm/ovl/actors/Obj_Grass/Obj_Grass.c | 2 +- .../actors/Obj_Grass_Carry/Obj_Grass_Carry.c | 2 +- .../mm/ovl/actors/Obj_Snowball/Obj_Snowball.c | 2 +- .../ovl/actors/Obj_Snowball2/Obj_Snowball2.c | 2 +- .../src/mm/ovl/actors/Obj_Taru/Obj_Taru.c | 2 +- .../src/mm/ovl/actors/Obj_Tsubo/Obj_Tsubo.c | 2 +- .../core/src/oot/actors/Bg/Bg_Mori_Hineri.c | 4 +-- .../core/src/oot/actors/Door/Door_Warp1.c | 3 +- packages/core/src/oot/actors/En/En_Box.c | 19 +++++------- packages/core/src/oot/actors/En/En_Sw.c | 2 +- .../core/src/oot/actors/En/En_Wonder_Item.c | 2 +- packages/core/src/oot/actors/Obj/Obj_Hana.c | 2 +- .../core/src/oot/ovl/actors/En_Kusa/En_Kusa.c | 2 +- .../src/oot/ovl/actors/Obj_Tsubo/Obj_Tsubo.c | 2 +- packages/data/src/defs/gi.yml | 2 +- 37 files changed, 117 insertions(+), 98 deletions(-) diff --git a/packages/core/include/combo/csmc.h b/packages/core/include/combo/csmc.h index 94805d874e..b50482b3b1 100644 --- a/packages/core/include/combo/csmc.h +++ b/packages/core/include/combo/csmc.h @@ -69,24 +69,24 @@ typedef struct Actor Actor; /* Generic */ void* csmcLoadTexture(u8 custom, u32 addr, int fmt, int bpp, int w, int h, int mirror); void* csmcLoadTextureEx(const CsmcDisplayList* dl); -int csmcFromItem(s16 gi); +int csmcFromItemCloaked(s16 gi, s16 cloakGi); int csmcEnabled(void); int csmcEnabledSkulltula(void); int csmcEnabledCow(void); /* Chest */ -void csmcChestInit(Actor* this, PlayState* play, s16 gi); -void csmcChestPreDraw(Actor* this, PlayState* play, s16 gi); -int csmcChestLarge(s16 gi); +void csmcChestInit(Actor* this, PlayState* play, s16 gi, s16 cloakGi); +void csmcChestPreDraw(Actor* this, PlayState* play, s16 gi, s16 cloakGi); +int csmcChestLarge(s16 gi, s16 cloakGi); /* Pots */ -void csmcPotPreDraw(Actor* this, PlayState* play, s16 gi, int def); +void csmcPotPreDraw(Actor* this, PlayState* play, s16 gi, s16 cloakGi, int def); /* Grass */ -void csmcGrassPreDraw(PlayState* play, s16 gi, int def, int alt, int direct); +void csmcGrassPreDraw(PlayState* play, s16 gi, s16 cloakGi, int def, int alt, int direct); /* GS */ -void csmcGsPreDraw(PlayState* play, s16 gi); +void csmcGsPreDraw(PlayState* play, s16 gi, s16 cloakGi); const Color_RGB8* csmcTypeColor(int type); diff --git a/packages/core/include/combo/draw.h b/packages/core/include/combo/draw.h index 07b1d31577..dea821c062 100644 --- a/packages/core/include/combo/draw.h +++ b/packages/core/include/combo/draw.h @@ -18,7 +18,7 @@ void Draw_Init2D(Gfx** dl); void Draw_Blit2D_RGBA32(Gfx** dl, u32 segAddr, int w, int h, float x, float y, float scale); void Draw_Blit2D_RGBA16(Gfx** dl, u32 segAddr, int w, int h, float x, float y, float scale); void Draw_Blit2D_IA4(Gfx** dl, u32 segAddr, int w, int h, float x, float y, float scale); -void Draw_GlitterGi(PlayState* play, Actor* actor, s16 gi); +void Draw_GlitterGi(PlayState* play, Actor* actor, s16 gi, s16 giCloak); void DrawGiSystem_Reset(PlayState* play); void DrawGiSystem_Update(PlayState* play); diff --git a/packages/core/src/common/actors/En_Tubo_Trap.c b/packages/core/src/common/actors/En_Tubo_Trap.c index 9c4dc28b99..1f29dcc157 100644 --- a/packages/core/src/common/actors/En_Tubo_Trap.c +++ b/packages/core/src/common/actors/En_Tubo_Trap.c @@ -51,7 +51,7 @@ static void EnTuboTrap_Draw(Actor_EnTuboTrap* this, PlayState* play) else o.gi = 0; - csmcPotPreDraw(&this->base, play, o.gi, CSMC_POT_NORMAL_DANGEON); + csmcPotPreDraw(&this->base, play, o.gi, o.cloakGi, CSMC_POT_NORMAL_DANGEON); /* Draw the pot */ Gfx_DrawDListOpa(play, (void*)ADDR_DLIST); diff --git a/packages/core/src/common/cow.c b/packages/core/src/common/cow.c index 9b062e51d1..f0280dbe19 100644 --- a/packages/core/src/common/cow.c +++ b/packages/core/src/common/cow.c @@ -194,7 +194,7 @@ static const Gfx* EnCow_RingList(PlayState* play, Actor* this) if (gi == GI_NONE) return NULL; - type = csmcFromItem(gi); + type = csmcFromItemCloaked(gi, o.cloakGi); if (type == CSMC_NORMAL && giRenew != GI_NONE) return kDlistColoredRingRenewable; diff --git a/packages/core/src/common/csmc/csmc_chest.c b/packages/core/src/common/csmc/csmc_chest.c index fb78dfc8be..36bbc85f4f 100644 --- a/packages/core/src/common/csmc/csmc_chest.c +++ b/packages/core/src/common/csmc/csmc_chest.c @@ -46,11 +46,11 @@ static const ChestCsmcData kCsmcData[] = { { 1, CUSTOM_CHEST_MAP_FRONT_ADDR, CUSTOM_CHEST_MAP_SIDE_ADDR }, }; -static int csmcChestId(s16 gi) +static int csmcChestId(s16 gi, s16 cloakGi) { int csmcId; - csmcId = csmcFromItem(gi); + csmcId = csmcFromItemCloaked(gi, cloakGi); switch (csmcId) { case CSMC_NORMAL: return CSMC_CHEST_NORMAL; @@ -84,14 +84,14 @@ static int csmcEnabledActor(Actor* this, PlayState* play) return 1; } -void csmcChestInit(Actor* this, PlayState* play, s16 gi) +void csmcChestInit(Actor* this, PlayState* play, s16 gi, s16 cloakGi) { int type; if (!csmcEnabledActor(this, play)) return; - type = csmcFromItem(gi); + type = csmcFromItemCloaked(gi, cloakGi); if (type == CSMC_MAJOR || type == CSMC_BOSS_KEY) { Actor_SetScale(this, 0.01f); @@ -125,14 +125,14 @@ void csmcChestInit(Actor* this, PlayState* play, s16 gi) } -void csmcChestPreDraw(Actor* this, PlayState* play, s16 gi) +void csmcChestPreDraw(Actor* this, PlayState* play, s16 gi, s16 cloakGi) { int type; const void* listFront; const void* listSide; if (csmcEnabledActor(this, play)) - type = csmcChestId(gi); + type = csmcChestId(gi, cloakGi); else type = CSMC_CHEST_NORMAL; @@ -147,11 +147,11 @@ void csmcChestPreDraw(Actor* this, PlayState* play, s16 gi) CLOSE_DISPS(); } -int csmcChestLarge(s16 gi) +int csmcChestLarge(s16 gi, s16 cloakGi) { if (!csmcEnabled()) return -1; - switch (csmcFromItem(gi)) + switch (csmcFromItemCloaked(gi, cloakGi)) { case CSMC_MAJOR: case CSMC_BOSS_KEY: diff --git a/packages/core/src/common/csmc/csmc_grass.c b/packages/core/src/common/csmc/csmc_grass.c index e7267f5b94..570265edac 100644 --- a/packages/core/src/common/csmc/csmc_grass.c +++ b/packages/core/src/common/csmc/csmc_grass.c @@ -43,7 +43,7 @@ static const CsmcDisplayList kGrassAltDlist[] = { { CUSTOM_GRASS_ALT_ADDR, kColorMap, CTF_CUSTOM_TEXTURE | CTF_COLOR | CTF_CLAMP, G_IM_FMT_RGBA, G_IM_SIZ_16b, 32, 32 }, }; -static int csmcGrassId(s16 gi, int def) +static int csmcGrassId(s16 gi, s16 giCloak, int def) { int csmcId; @@ -52,7 +52,7 @@ static int csmcGrassId(s16 gi, int def) if (!csmcEnabled()) return CSMC_GRASS_MAJOR; - csmcId = csmcFromItem(gi); + csmcId = csmcFromItemCloaked(gi, giCloak); switch (csmcId) { case CSMC_NORMAL: return def; @@ -68,7 +68,7 @@ static int csmcGrassId(s16 gi, int def) } } -void csmcGrassPreDraw(PlayState* play, s16 gi, int def, int alt, int direct) +void csmcGrassPreDraw(PlayState* play, s16 gi, s16 cloakGi, int def, int alt, int direct) { const CsmcDisplayList* dlists; int id; @@ -79,7 +79,7 @@ void csmcGrassPreDraw(PlayState* play, s16 gi, int def, int alt, int direct) else dlists = kGrassStandardDlist; - id = csmcGrassId(gi, def); + id = csmcGrassId(gi, cloakGi, def); list = csmcLoadTextureEx(&dlists[id]); OPEN_DISPS(play->state.gfxCtx); diff --git a/packages/core/src/common/csmc/csmc_gs.c b/packages/core/src/common/csmc/csmc_gs.c index 0399e91ffa..85686ccaf7 100644 --- a/packages/core/src/common/csmc/csmc_gs.c +++ b/packages/core/src/common/csmc/csmc_gs.c @@ -68,14 +68,14 @@ static const Gfx* const kCsmcGs[] = { kCsmcGsMap, }; -static int csmcGsId(s16 gi) +static int csmcGsId(s16 gi, s16 cloakGi) { int csmcId; if (gi == 0 || !csmcEnabledSkulltula()) return CSMC_GS_MAJOR; - csmcId = csmcFromItem(gi); + csmcId = csmcFromItemCloaked(gi, cloakGi); switch (csmcId) { case CSMC_NORMAL: return CSMC_GS_NORMAL; @@ -91,11 +91,11 @@ static int csmcGsId(s16 gi) } } -void csmcGsPreDraw(PlayState* play, s16 gi) +void csmcGsPreDraw(PlayState* play, s16 gi, s16 cloakGi) { int id; - id = csmcGsId(gi); + id = csmcGsId(gi, cloakGi); OPEN_DISPS(play->state.gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x0a, ((u32)kCsmcGs[id]) & 0xffffff); CLOSE_DISPS(); diff --git a/packages/core/src/common/csmc/csmc_navi.c b/packages/core/src/common/csmc/csmc_navi.c index 76dcc8c108..a823a4141b 100644 --- a/packages/core/src/common/csmc/csmc_navi.c +++ b/packages/core/src/common/csmc/csmc_navi.c @@ -32,7 +32,7 @@ static NaviColor sNaviColorList[] = { { { 252, 86, 3, 255 }, { 252, 86, 3, 0 } }, }; -static int csmcNaviId(s16 gi) +static int csmcNaviId(s16 gi, s16 cloakGi) { int csmcId; @@ -41,7 +41,7 @@ static int csmcNaviId(s16 gi) if (!csmcEnabled()) return CSMC_NORMAL; - csmcId = csmcFromItem(gi); + csmcId = csmcFromItemCloaked(gi, cloakGi); switch (csmcId) { case CSMC_NORMAL: return CSMC_NAVI_NORMAL; @@ -71,7 +71,7 @@ void Actor_AfterSetNaviToActor(TargetContext* targetCtx, Actor* actor, s32 actor if (comboXflagsGet(&shotSun->xflag)) q.ovFlags |= OVF_RENEW; comboItemOverride(&o, &q); - type = csmcNaviId(o.gi); + type = csmcNaviId(o.gi, o.cloakGi); NaviColor* naviColor = &sNaviColorList[type]; targetCtx->naviInner.r = naviColor->inner.r; targetCtx->naviInner.g = naviColor->inner.g; diff --git a/packages/core/src/common/csmc/csmc_pot.c b/packages/core/src/common/csmc/csmc_pot.c index 6cea1dd6ca..a2f2172662 100644 --- a/packages/core/src/common/csmc/csmc_pot.c +++ b/packages/core/src/common/csmc/csmc_pot.c @@ -214,7 +214,7 @@ static void loadTexture(int csmcPotId) } } -static int csmcPotId(s16 gi, int def) +static int csmcPotId(s16 gi, s16 cloakGi, int def) { int csmcId; @@ -223,7 +223,7 @@ static int csmcPotId(s16 gi, int def) if (!csmcEnabled()) return CSMC_POT_MAJOR; - csmcId = csmcFromItem(gi); + csmcId = csmcFromItemCloaked(gi, cloakGi); switch (csmcId) { case CSMC_NORMAL: return def; @@ -239,11 +239,11 @@ static int csmcPotId(s16 gi, int def) } } -void csmcPotPreDraw(Actor* this, PlayState* play, s16 gi, int def) +void csmcPotPreDraw(Actor* this, PlayState* play, s16 gi, s16 cloakGi, int def) { int type; - type = csmcPotId(gi, def); + type = csmcPotId(gi, cloakGi, def); loadTexture(type); OPEN_DISPS(play->state.gfxCtx); diff --git a/packages/core/src/common/csmc/csmc_util.c b/packages/core/src/common/csmc/csmc_util.c index 696a11459a..340cf26341 100644 --- a/packages/core/src/common/csmc/csmc_util.c +++ b/packages/core/src/common/csmc/csmc_util.c @@ -30,7 +30,7 @@ const Color_RGB8* csmcTypeColor(int type) } } -int csmcFromItem(s16 gi) +static int csmcFromItem(s16 gi) { if (gi == 0) return CSMC_NORMAL; @@ -90,6 +90,13 @@ int csmcFromItem(s16 gi) } } +int csmcFromItemCloaked(s16 gi, s16 cloakedGi) +{ + if (cloakedGi && cloakedGi != GI_MM_SOLD_OUT) + gi = cloakedGi; + return csmcFromItem(gi); +} + static int hasStoneAgonyForCsmc(void) { #if defined(GAME_MM) diff --git a/packages/core/src/common/draw.c b/packages/core/src/common/draw.c index b8ced5e640..6ec50765c0 100644 --- a/packages/core/src/common/draw.c +++ b/packages/core/src/common/draw.c @@ -253,14 +253,14 @@ static const Gfx kDlistGlitter[] = { gsSPEndDisplayList(), }; -static u32 Draw_GetGlitterColor(s16 gi) +static u32 Draw_GetGlitterColor(s16 gi, s16 cloakGi) { int type; if (!csmcEnabled()) type = CSMC_SPIDER; else - type = csmcFromItem(gi); + type = csmcFromItemCloaked(gi, cloakGi); switch (type) { @@ -277,7 +277,7 @@ static u32 Draw_GetGlitterColor(s16 gi) } } -void Draw_GlitterGi(PlayState* play, Actor* actor, s16 gi) +void Draw_GlitterGi(PlayState* play, Actor* actor, s16 gi, s16 giCloak) { void* tex; float alpha; @@ -288,7 +288,7 @@ void Draw_GlitterGi(PlayState* play, Actor* actor, s16 gi) u8 b; /* Get color */ - color = Draw_GetGlitterColor(gi); + color = Draw_GetGlitterColor(gi, giCloak); r = (color >> 16) & 0xff; g = (color >> 8) & 0xff; b = (color >> 0) & 0xff; diff --git a/packages/core/src/common/ovl/actors/En_Butte/En_Butte.c b/packages/core/src/common/ovl/actors/En_Butte/En_Butte.c index 8ae5dc9530..08dee44816 100644 --- a/packages/core/src/common/ovl/actors/En_Butte/En_Butte.c +++ b/packages/core/src/common/ovl/actors/En_Butte/En_Butte.c @@ -552,7 +552,7 @@ static void EnButte_DrawButterfly(Actor_EnButte* this, PlayState* play) } else if (csmcEnabled()) { - csmcType = csmcFromItem(o.gi); + csmcType = csmcFromItemCloaked(o.gi, o.cloakGi); } else { diff --git a/packages/core/src/common/ovl/actors/Obj_Comb/Obj_Comb.c b/packages/core/src/common/ovl/actors/Obj_Comb/Obj_Comb.c index 1e578df097..3b1111263f 100644 --- a/packages/core/src/common/ovl/actors/Obj_Comb/Obj_Comb.c +++ b/packages/core/src/common/ovl/actors/Obj_Comb/Obj_Comb.c @@ -859,7 +859,7 @@ static int ObjComb_CsmcType(Actor_ObjComb* this, PlayState* play) return CSMC_MAJOR; comboXflagItemOverride(&o, &this->xflag, 0); - return csmcFromItem(o.gi); + return csmcFromItemCloaked(o.gi, o.cloakGi); } static void ObjComb_Draw(Actor_ObjComb* this, PlayState* play) diff --git a/packages/core/src/common/ovl/actors/Obj_Kibako/Obj_Kibako.c b/packages/core/src/common/ovl/actors/Obj_Kibako/Obj_Kibako.c index 3cddc842e2..c2995e6baa 100644 --- a/packages/core/src/common/ovl/actors/Obj_Kibako/Obj_Kibako.c +++ b/packages/core/src/common/ovl/actors/Obj_Kibako/Obj_Kibako.c @@ -60,7 +60,7 @@ static int ObjKibako_CsmcType(Actor_ObjKibako* this) if (!csmcEnabled()) return o.gi ? CSMC_MAJOR : CSMC_NORMAL; - return csmcFromItem(o.gi); + return csmcFromItemCloaked(o.gi, o.cloakGi); } static void ObjKibako_DrawWithTexture(Actor_ObjKibako* this, PlayState* play, u32 dlist, u32 baseTex) diff --git a/packages/core/src/common/ovl/actors/Obj_Kibako2/Obj_Kibako2.c b/packages/core/src/common/ovl/actors/Obj_Kibako2/Obj_Kibako2.c index 5c9a179a5f..c9fc6cc5d8 100644 --- a/packages/core/src/common/ovl/actors/Obj_Kibako2/Obj_Kibako2.c +++ b/packages/core/src/common/ovl/actors/Obj_Kibako2/Obj_Kibako2.c @@ -578,7 +578,7 @@ static int ObjKibako2_CsmcType(Actor_ObjKibako2* this) if (!csmcEnabled()) return o.gi ? CSMC_MAJOR : CSMC_NORMAL; - return csmcFromItem(o.gi); + return csmcFromItemCloaked(o.gi, o.cloakGi); } static void ObjKibako2_PreDraw(PlayState* play, const Gfx* loader, void* tex1, void* tex2) diff --git a/packages/core/src/mm/actors/En/En_Box.c b/packages/core/src/mm/actors/En/En_Box.c index 88a408ef2a..d8c3af7572 100644 --- a/packages/core/src/mm/actors/En/En_Box.c +++ b/packages/core/src/mm/actors/En/En_Box.c @@ -49,15 +49,12 @@ static void EnBox_ItemQuery(ComboItemQuery* q, Actor* this, PlayState* play) } } -static s16 EnBox_Item(Actor* this, PlayState* play) +static void EnBox_ItemOverride(ComboItemOverride* o, Actor* this, PlayState* play) { ComboItemQuery q; - ComboItemOverride ov; EnBox_ItemQuery(&q, this, play); - comboItemOverride(&ov, &q); - - return ov.giRaw; + comboItemOverride(o, &q); } void EnBox_GiveItemDefaultRange(Actor* actor, PlayState* play, s16 gi) @@ -73,25 +70,25 @@ PATCH_CALL(0x80868fe0, EnBox_GiveItemDefaultRange); void EnBox_InitWrapper(Actor* this, PlayState* play) { ActorCallback init; - s16 gi; + ComboItemOverride o; /* Init the chest */ init = actorAddr(ACTOR_EN_BOX, 0x808680ac); init(this, play); /* Resize chest */ - gi = EnBox_Item(this, play); - csmcChestInit(this, play, gi); + EnBox_ItemOverride(&o, this, play); + csmcChestInit(this, play, o.giRaw, o.cloakGi); } void EnBox_DrawWrapper(Actor* this, PlayState* play) { ActorCallback draw; - s16 gi; + ComboItemOverride o; /* Prepare the segments */ - gi = EnBox_Item(this, play); - csmcChestPreDraw(this, play, gi); + EnBox_ItemOverride(&o, this, play); + csmcChestPreDraw(this, play, o.giRaw, o.cloakGi); /* Draw */ draw = actorAddr(ACTOR_EN_BOX, 0x808698f4); diff --git a/packages/core/src/mm/actors/En/En_Hit_Tag.c b/packages/core/src/mm/actors/En/En_Hit_Tag.c index 1a677ebaac..d075fd7ea7 100644 --- a/packages/core/src/mm/actors/En/En_Hit_Tag.c +++ b/packages/core/src/mm/actors/En/En_Hit_Tag.c @@ -12,8 +12,11 @@ static void EnHitTag_DrawGlitter(Actor_EnHitTag* this, PlayState* play) ComboItemOverride o; Xflag x; s16 giList[3]; + s16 giCloakList[3]; s16 gi; + s16 giCloak; u8 giCount; + int index; /* Get the gi list */ giCount = 0; @@ -26,7 +29,9 @@ static void EnHitTag_DrawGlitter(Actor_EnHitTag* this, PlayState* play) comboXflagItemOverride(&o, &x, 0); if (o.gi == 0) continue; - giList[giCount++] = o.gi; + giList[giCount] = o.gi; + giCloakList[giCount] = o.cloakGi; + giCount++; } if (giCount == 0) @@ -39,18 +44,23 @@ static void EnHitTag_DrawGlitter(Actor_EnHitTag* this, PlayState* play) { case 1: gi = giList[0]; + giCloak = giCloakList[0]; break; case 2: - gi = giList[(play->state.frameCount % 12) / 6]; + index = (play->state.frameCount % 12) / 6; + gi = giList[index]; + giCloak = giCloakList[index]; break; case 3: - gi = giList[(play->state.frameCount % 12) / 4]; + index = (play->state.frameCount % 12) / 4; + gi = giList[index]; + giCloak = giCloakList[index]; break; default: UNREACHABLE(); } - Draw_GlitterGi(play, &this->base, gi); + Draw_GlitterGi(play, &this->base, gi, giCloak); } static void EnHitTag_ItemDropCollectible(PlayState* play, const Vec3f* pos, int param) diff --git a/packages/core/src/mm/actors/En/En_Invisible_Ruppe.c b/packages/core/src/mm/actors/En/En_Invisible_Ruppe.c index 5666702bc6..6e13951dfc 100644 --- a/packages/core/src/mm/actors/En/En_Invisible_Ruppe.c +++ b/packages/core/src/mm/actors/En/En_Invisible_Ruppe.c @@ -16,7 +16,7 @@ static void EnInvisibleRupee_DrawGlitter(Actor_EnInvisibleRuppe* this, PlayState } comboXflagItemOverride(&o, &this->xflag, 0); - Draw_GlitterGi(play, &this->base, o.gi); + Draw_GlitterGi(play, &this->base, o.gi, o.cloakGi); } void EnInvisibleRupee_HandleExtended(Actor_EnInvisibleRuppe* this, PlayState* play) diff --git a/packages/core/src/mm/actors/En/En_Sw.c b/packages/core/src/mm/actors/En/En_Sw.c index 684cce2119..49d4e7667c 100644 --- a/packages/core/src/mm/actors/En/En_Sw.c +++ b/packages/core/src/mm/actors/En/En_Sw.c @@ -15,7 +15,7 @@ static void EnSw_GoldPreDraw1(Actor* this, PlayState* play, int unk) PreDraw1(this, play, unk); /* Inject */ - csmcGsPreDraw(play, o.gi); + csmcGsPreDraw(play, o.gi, o.cloakGi); } PATCH_CALL(0x808db928, EnSw_GoldPreDraw1); diff --git a/packages/core/src/mm/ovl/actors/En_Kusa/En_Kusa.c b/packages/core/src/mm/ovl/actors/En_Kusa/En_Kusa.c index eecab97eb0..6cd6e0ae75 100644 --- a/packages/core/src/mm/ovl/actors/En_Kusa/En_Kusa.c +++ b/packages/core/src/mm/ovl/actors/En_Kusa/En_Kusa.c @@ -746,7 +746,7 @@ void EnKusa_PreDraw(EnKusa* this, PlayState* play) alt = 0; else alt = 1; - csmcGrassPreDraw(play, o.gi, CSMC_GRASS_NORMAL, alt, 0); + csmcGrassPreDraw(play, o.gi, o.cloakGi, CSMC_GRASS_NORMAL, alt, 0); } void EnKusa_DrawBush(Actor* thisx, PlayState* play2) { diff --git a/packages/core/src/mm/ovl/actors/En_Kusa2/En_Kusa2.c b/packages/core/src/mm/ovl/actors/En_Kusa2/En_Kusa2.c index 5feec81050..c3610de382 100644 --- a/packages/core/src/mm/ovl/actors/En_Kusa2/En_Kusa2.c +++ b/packages/core/src/mm/ovl/actors/En_Kusa2/En_Kusa2.c @@ -1385,7 +1385,7 @@ static void EnKusa2_DrawImpl(EnKusa2* this, PlayState* play) o.gi = GI_NONE; /* Prepare */ - csmcGrassPreDraw(play, o.gi, CSMC_GRASS_NORMAL, 0, 0); + csmcGrassPreDraw(play, o.gi, o.cloakGi, CSMC_GRASS_NORMAL, 0, 0); /* Draw */ Gfx_DrawDListOpa(play, gKusaBushType1DL); diff --git a/packages/core/src/mm/ovl/actors/Obj_Flowerpot/Obj_Flowerpot.c b/packages/core/src/mm/ovl/actors/Obj_Flowerpot/Obj_Flowerpot.c index 3c524d431f..3e077cbae9 100644 --- a/packages/core/src/mm/ovl/actors/Obj_Flowerpot/Obj_Flowerpot.c +++ b/packages/core/src/mm/ovl/actors/Obj_Flowerpot/Obj_Flowerpot.c @@ -101,16 +101,25 @@ static int ObjFlowerpot_IsShuffled(Actor_ObjFlowerpot* this, int slice) return !!((this->isExtendedFlags & (1 << slice)) && (!comboXflagsGet(&xflags))); } -static s16 ObjFlowerpot_ShuffledItem(Actor_ObjFlowerpot* this, int slice) +static void ObjFlowerpot_ShuffledItemOverride(ComboItemOverride* o, Actor_ObjFlowerpot* this, int slice) { - ComboItemOverride o; Xflag xf; ObjFlowerpot_Xflag(&xf, slice, this); - comboXflagItemOverride(&o, &xf, 0); - if (o.gi && !comboXflagsGet(&xf)) - return o.gi; - return 0; + comboXflagItemOverride(o, &xf, 0); + if (comboXflagsGet(&xf)) + { + o->gi = 0; + o->cloakGi = 0; + } +} + +static s16 ObjFlowerpot_ShuffledItem(Actor_ObjFlowerpot* this, int slice) +{ + ComboItemOverride o; + + ObjFlowerpot_ShuffledItemOverride(&o, this, slice); + return o.gi; } static void ObjFlowerpot_Alias(Xflag* xf) @@ -729,14 +738,14 @@ void ObjFlowerpot_Update(Actor_ObjFlowerpot* this, PlayState* play) static int ObjFlowerpot_CsmcType(Actor_ObjFlowerpot* this, int slice) { - s16 gi; + ComboItemOverride o; - gi = ObjFlowerpot_ShuffledItem(this, slice); - if (gi == GI_NONE) + ObjFlowerpot_ShuffledItemOverride(&o, this, slice); + if (o.gi == GI_NONE) return CSMC_NORMAL; if (!csmcEnabled()) return CSMC_MAJOR; - return csmcFromItem(gi); + return csmcFromItemCloaked(o.gi, o.cloakGi); } static const Gfx sListLoaderPotDefault[] = { diff --git a/packages/core/src/mm/ovl/actors/Obj_Grass/Obj_Grass.c b/packages/core/src/mm/ovl/actors/Obj_Grass/Obj_Grass.c index b06ed6fffc..2089f39bb1 100644 --- a/packages/core/src/mm/ovl/actors/Obj_Grass/Obj_Grass.c +++ b/packages/core/src/mm/ovl/actors/Obj_Grass/Obj_Grass.c @@ -487,7 +487,7 @@ void ObjGrass_PreDraw(ObjGrassElement* grassElem, PlayState* play) comboXflagItemOverride(&o, &xflag, 0); else o.gi = 0; - csmcGrassPreDraw(play, o.gi, CSMC_GRASS_NORMAL, 0, 1); + csmcGrassPreDraw(play, o.gi, o.cloakGi, CSMC_GRASS_NORMAL, 0, 1); } void ObjGrass_DrawOpa(Actor* thisx, PlayState* play2) { diff --git a/packages/core/src/mm/ovl/actors/Obj_Grass_Carry/Obj_Grass_Carry.c b/packages/core/src/mm/ovl/actors/Obj_Grass_Carry/Obj_Grass_Carry.c index 1facb700e6..7664da4e60 100644 --- a/packages/core/src/mm/ovl/actors/Obj_Grass_Carry/Obj_Grass_Carry.c +++ b/packages/core/src/mm/ovl/actors/Obj_Grass_Carry/Obj_Grass_Carry.c @@ -372,7 +372,7 @@ void ObjGrassCarry_PreDraw(ObjGrassElement* grassElem, PlayState* play) comboXflagItemOverride(&o, &xflag, 0); else o.gi = 0; - csmcGrassPreDraw(play, o.gi, CSMC_GRASS_NORMAL, 0, 0); + csmcGrassPreDraw(play, o.gi, o.cloakGi, CSMC_GRASS_NORMAL, 0, 0); } void ObjGrassCarry_Draw(Actor* thisx, PlayState* play) { diff --git a/packages/core/src/mm/ovl/actors/Obj_Snowball/Obj_Snowball.c b/packages/core/src/mm/ovl/actors/Obj_Snowball/Obj_Snowball.c index 0d945f07a9..fd63e3e9f9 100644 --- a/packages/core/src/mm/ovl/actors/Obj_Snowball/Obj_Snowball.c +++ b/packages/core/src/mm/ovl/actors/Obj_Snowball/Obj_Snowball.c @@ -919,7 +919,7 @@ static int ObjSnowball_CsmcType(Actor_ObjSnowball* this) return CSMC_MAJOR; comboXflagItemOverride(&o, &this->xflag, 0); - return csmcFromItem(o.gi); + return csmcFromItemCloaked(o.gi, o.cloakGi); } void ObjSnowball_Draw(Actor_ObjSnowball* this, PlayState* play) { diff --git a/packages/core/src/mm/ovl/actors/Obj_Snowball2/Obj_Snowball2.c b/packages/core/src/mm/ovl/actors/Obj_Snowball2/Obj_Snowball2.c index 9eb105f06f..ef89cfc92d 100644 --- a/packages/core/src/mm/ovl/actors/Obj_Snowball2/Obj_Snowball2.c +++ b/packages/core/src/mm/ovl/actors/Obj_Snowball2/Obj_Snowball2.c @@ -693,7 +693,7 @@ static int ObjSnowball2_CsmcType(Actor_ObjSnowball2* this) return CSMC_MAJOR; comboXflagItemOverride(&o, &this->xflag, 0); - return csmcFromItem(o.gi); + return csmcFromItemCloaked(o.gi, o.cloakGi); } void ObjSnowball2_Draw(Actor_ObjSnowball2* this, PlayState* play) { diff --git a/packages/core/src/mm/ovl/actors/Obj_Taru/Obj_Taru.c b/packages/core/src/mm/ovl/actors/Obj_Taru/Obj_Taru.c index 18399595d3..6e8522203a 100644 --- a/packages/core/src/mm/ovl/actors/Obj_Taru/Obj_Taru.c +++ b/packages/core/src/mm/ovl/actors/Obj_Taru/Obj_Taru.c @@ -300,7 +300,7 @@ static int ObjTaru_CsmcType(Actor_ObjTaru* this) return CSMC_MAJOR; comboXflagItemOverride(&o, &this->xflag, 0); - return csmcFromItem(o.gi); + return csmcFromItemCloaked(o.gi, o.cloakGi); } static const Gfx sListLoaderTextureDefault[] = { diff --git a/packages/core/src/mm/ovl/actors/Obj_Tsubo/Obj_Tsubo.c b/packages/core/src/mm/ovl/actors/Obj_Tsubo/Obj_Tsubo.c index f3a6fd927d..d61a8231fe 100644 --- a/packages/core/src/mm/ovl/actors/Obj_Tsubo/Obj_Tsubo.c +++ b/packages/core/src/mm/ovl/actors/Obj_Tsubo/Obj_Tsubo.c @@ -884,7 +884,7 @@ void ObjTsubo_Draw(Actor_ObjTsubo* this, PlayState* play) else o.gi = 0; - csmcPotPreDraw(&this->actor, play, o.gi, type); + csmcPotPreDraw(&this->actor, play, o.gi, o.cloakGi, type); Gfx_DrawDListOpa(play, sPotTypeData[OBJ_TSUBO_GET_TYPE(&this->actor)].modelDL); } diff --git a/packages/core/src/oot/actors/Bg/Bg_Mori_Hineri.c b/packages/core/src/oot/actors/Bg/Bg_Mori_Hineri.c index 2ee472e9e4..f7c0985a6c 100644 --- a/packages/core/src/oot/actors/Bg/Bg_Mori_Hineri.c +++ b/packages/core/src/oot/actors/Bg/Bg_Mori_Hineri.c @@ -32,11 +32,11 @@ void BgMoriHineri_DrawWrapper(Actor* this, PlayState* play) /* Init CSMC */ BgMoriHineri_ItemOverride(&o, 0); - csmcChestPreDraw(this, play, o.gi); + csmcChestPreDraw(this, play, o.gi, o.cloakGi); /* Check for CSMC and small chest */ sIsSmallChest = 0; - if (csmcChestLarge(o.gi) == 0) + if (csmcChestLarge(o.gi, o.cloakGi) == 0) { sIsSmallChest = 1; f = actorAddr(0x068, 0x80913d74); diff --git a/packages/core/src/oot/actors/Door/Door_Warp1.c b/packages/core/src/oot/actors/Door/Door_Warp1.c index 5808eaa5e2..60b8456f44 100644 --- a/packages/core/src/oot/actors/Door/Door_Warp1.c +++ b/packages/core/src/oot/actors/Door/Door_Warp1.c @@ -94,7 +94,7 @@ static void DoorWarp1_ItemOverride(ComboItemOverride* o, const BlueWarpData* dat q.id = data->npc; q.gi = data->gi; - comboItemOverride(&o, &q); + comboItemOverride(o, &q); } int DoorWarp1_ShouldTrigger(Actor* this, PlayState* play) @@ -141,7 +141,6 @@ void DoorWarp1_AfterDrawWarp(Actor* this, PlayState* play) float angle; const BlueWarpData* data; ComboItemOverride o; - s16 gi; data = DoorWarp1_GetData(play); if (!data) diff --git a/packages/core/src/oot/actors/En/En_Box.c b/packages/core/src/oot/actors/En/En_Box.c index 835c1786a6..e9bac71278 100644 --- a/packages/core/src/oot/actors/En/En_Box.c +++ b/packages/core/src/oot/actors/En/En_Box.c @@ -21,15 +21,12 @@ static void EnBox_ItemQuery(ComboItemQuery* q, Actor* this, PlayState* play, s16 } } -static s16 EnBox_Item(Actor* this, PlayState* play, s16 gi) +static void EnBox_ItemOverride(ComboItemOverride* o, Actor* this, PlayState* play, s16 gi) { ComboItemQuery q; - ComboItemOverride o; EnBox_ItemQuery(&q, this, play, gi); - comboItemOverride(&o, &q); - - return o.giRaw; + comboItemOverride(o, &q); } static s16 EnBox_GetGI(Actor* this) @@ -50,25 +47,25 @@ PATCH_CALL(0x808696bc, EnBox_GiveItem); void EnBox_InitWrapper(Actor* this, PlayState* play) { ActorCallback init; - s16 gi; + ComboItemOverride o; /* Init the chest */ init = actorAddr(ACTOR_EN_BOX, 0x808687e8); init(this, play); /* Resize chest */ - gi = EnBox_Item(this, play, EnBox_GetGI(this)); - csmcChestInit(this, play, gi); + EnBox_ItemOverride(&o, this, play, EnBox_GetGI(this)); + csmcChestInit(this, play, o.giRaw, o.cloakGi); } void EnBox_DrawWrapper(Actor* this, PlayState* play) { ActorCallback draw; - s16 gi; + ComboItemOverride o; /* Prepare the segments */ - gi = EnBox_Item(this, play, EnBox_GetGI(this)); - csmcChestPreDraw(this, play, gi); + EnBox_ItemOverride(&o, this, play, EnBox_GetGI(this)); + csmcChestPreDraw(this, play, o.giRaw, o.cloakGi); /* Draw */ draw = actorAddr(ACTOR_EN_BOX, 0x80869e68); diff --git a/packages/core/src/oot/actors/En/En_Sw.c b/packages/core/src/oot/actors/En/En_Sw.c index 6792d0eb07..b271d3f32b 100644 --- a/packages/core/src/oot/actors/En/En_Sw.c +++ b/packages/core/src/oot/actors/En/En_Sw.c @@ -15,7 +15,7 @@ static void EnSw_GoldPreDraw1(Actor* this, PlayState* play, int unk) PreDraw1(this, play, unk); /* Inject */ - csmcGsPreDraw(play, o.gi); + csmcGsPreDraw(play, o.gi, o.cloakGi); } PATCH_CALL(0x809488c0, EnSw_GoldPreDraw1); diff --git a/packages/core/src/oot/actors/En/En_Wonder_Item.c b/packages/core/src/oot/actors/En/En_Wonder_Item.c index d152f93451..54b99113a2 100644 --- a/packages/core/src/oot/actors/En/En_Wonder_Item.c +++ b/packages/core/src/oot/actors/En/En_Wonder_Item.c @@ -82,7 +82,7 @@ static void EnWonderItem_DrawGlitter(Actor_EnWonderItem* this, PlayState* play) } comboXflagItemOverride(&o, &this->xflag, 0); - Draw_GlitterGi(play, &this->base, o.gi); + Draw_GlitterGi(play, &this->base, o.gi, o.cloakGi); } static void EnWonderItem_DropCustomDecoy(Actor_EnWonderItem* this, PlayState* play) diff --git a/packages/core/src/oot/actors/Obj/Obj_Hana.c b/packages/core/src/oot/actors/Obj/Obj_Hana.c index ab58cd2d17..e9fdc1c401 100644 --- a/packages/core/src/oot/actors/Obj/Obj_Hana.c +++ b/packages/core/src/oot/actors/Obj/Obj_Hana.c @@ -7,7 +7,7 @@ void ObjHana_DrawWrapper(Actor* this, PlayState* play) ActorFunc ObjHana_Draw; if ((this->params & 0x3) == 0x2) - csmcGrassPreDraw(play, 0, CSMC_GRASS_NORMAL, 0, 0); + csmcGrassPreDraw(play, 0, 0, CSMC_GRASS_NORMAL, 0, 0); /* Draw */ ObjHana_Draw = actorAddr(ACTOR_OBJ_HANA, 0x80abc1c8); diff --git a/packages/core/src/oot/ovl/actors/En_Kusa/En_Kusa.c b/packages/core/src/oot/ovl/actors/En_Kusa/En_Kusa.c index 75b82b29f9..a11b82f40b 100644 --- a/packages/core/src/oot/ovl/actors/En_Kusa/En_Kusa.c +++ b/packages/core/src/oot/ovl/actors/En_Kusa/En_Kusa.c @@ -574,7 +574,7 @@ void EnKusa_Draw(Actor* thisx, PlayState* play) alt = 0; else alt = 1; - csmcGrassPreDraw(play, o.gi, CSMC_GRASS_NORMAL, alt, 0); + csmcGrassPreDraw(play, o.gi, o.cloakGi, CSMC_GRASS_NORMAL, alt, 0); /* Draw the actor */ EnKusa_DrawImpl(this, play); diff --git a/packages/core/src/oot/ovl/actors/Obj_Tsubo/Obj_Tsubo.c b/packages/core/src/oot/ovl/actors/Obj_Tsubo/Obj_Tsubo.c index 9a1dae7654..c24d499d8e 100644 --- a/packages/core/src/oot/ovl/actors/Obj_Tsubo/Obj_Tsubo.c +++ b/packages/core/src/oot/ovl/actors/Obj_Tsubo/Obj_Tsubo.c @@ -470,7 +470,7 @@ void ObjTsubo_Draw(Actor_ObjTsubo* this, PlayState* play) type = CSMC_POT_NORMAL; else type = CSMC_POT_NORMAL_DANGEON; - csmcPotPreDraw(&this->actor, play, o.gi, type); + csmcPotPreDraw(&this->actor, play, o.gi, o.cloakGi, type); Gfx_DrawDListOpa(play, D_80BA1B84[(this->actor.params >> 8) & 1]); } diff --git a/packages/data/src/defs/gi.yml b/packages/data/src/defs/gi.yml index 258596c20c..b3813b73ff 100644 --- a/packages/data/src/defs/gi.yml +++ b/packages/data/src/defs/gi.yml @@ -426,7 +426,7 @@ - { id: OOT_SWORD_GILDED, type: MAJOR, add: [OOT_SWORD_EXTRA, 2], flags: 0x80, draw: MM_SWORD_GILDED, object: [mm, 0x01fa], name: "the Gilded Sword" } - { id: OOT_SPIN_UPGRADE, type: MAJOR, add: OOT_SPIN_UPGRADE, flags: 0xa0, draw: [SPIN_UPGRADE, 1], object: [oot, 0x018d], name: "the Spin Attack Upgrade" } - { id: OOT_TRIFORCE_FULL, type: MAJOR, add: [ENDGAME, 0], flags: 0x80, draw: TRIFORCE_FULL, object: TRIFORCE, name: "the Triforce" } -- { id: OOT_TRAP_ICE, type: MAJOR, add: TRAP_ICE, flags: 0x80, draw: TRAP_ICE, name: "an Ice Trap" } +- { id: OOT_TRAP_ICE, type: MINOR, add: TRAP_ICE, flags: 0x80, draw: TRAP_ICE, name: "an Ice Trap" } - { id: OOT_FAIRY_BIG, type: MINOR, add: OOT_FAIRY_BIG, flags: 0x80, draw: FAIRY_BIG, object: [oot, 0x0177], name: "a Big Fairy" } - { id: OOT_MASK_BLAST, type: MASK, add: [OOT_TRADE_CHILD, XITEM_OOT_CHILD_MASK_BLAST], flags: 0x80, draw: MM_MASK_BLAST, object: [mm, 0x026d], name: "the Blast Mask" } - { id: OOT_MASK_STONE, type: MASK, add: [OOT_TRADE_CHILD, XITEM_OOT_CHILD_MASK_STONE], flags: 0x80, draw: MM_MASK_STONE, object: [mm, 0x0254], name: "the Stone Mask" } From 0e9550d4ea73864e0af09bb3c656c55408682642 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Mon, 27 Jan 2025 13:05:26 +0100 Subject: [PATCH 28/34] Fully working --- packages/core/lib/combo/patch-build/index.ts | 2 +- .../core/lib/combo/patch-build/randomizer.ts | 31 +++++++++++++++---- packages/core/src/mm/actors/En/En_GirlA.c | 16 ++++++++-- packages/core/src/oot/actors/En/En_GirlA.c | 16 ++++++++-- 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/packages/core/lib/combo/patch-build/index.ts b/packages/core/lib/combo/patch-build/index.ts index 9cc2653596..c95cb69f93 100644 --- a/packages/core/lib/combo/patch-build/index.ts +++ b/packages/core/lib/combo/patch-build/index.ts @@ -222,7 +222,7 @@ export async function buildPatchfiles(args: BuildPatchfileIn): Promise { +function makeCloakGi(key: number, seed: string, settings: Settings, logic: LogicResult): number { + const random = new Random(); + random.seed(key.toString(16) + '\x00' + seed); + + for (;;) { + const locs = [...logic.items.keys()]; + const loc = sample(random, locs); + const item = logic.items.get(loc)!; + + if (!ItemHelpers.isItemMajor(item.item) && !ItemHelpers.isSilverRupee(item.item) && !ItemHelpers.isKey(item.item) && !ItemHelpers.isBossKey(item.item)) continue; + if (ItemGroups.JUNK.has(item.item)) continue; + if (!isLocationFullyShuffled(settings, logic.fixedLocations, logic.items, loc, { songs: true, noPlando: true })) continue; + + return gi(settings, 'oot', item.item, false); + } +} + +const gameChecks = (worldId: number, opts: Options, settings: Settings, game: Game, logic: LogicResult): Uint8Array => { const buffers: Uint8Array[] = []; const world = logic.worlds[worldId]; for (const locId in world.checks) { @@ -488,7 +507,7 @@ const gameChecks = (worldId: number, settings: Settings, game: Game, logic: Logi bufWriteU16BE(b, 6, itemGi); let cloakGi = 0; if (item.item === Items.OOT_TRAP_ICE) { - cloakGi = gi(settings, 'oot', Items.OOT_ARROW_LIGHT, false); + cloakGi = makeCloakGi(key, opts.seed, settings, logic); } bufWriteU16BE(b, 8, cloakGi); buffers.push(b); @@ -1179,11 +1198,11 @@ const randomizerStartingItems = (world: number, logic: LogicResult): Uint8Array return toU16Buffer([...ids, ...ids2, 0xffff, 0xffff]); }; -export function patchRandomizer(worldId: number, logic: LogicResult, settings: Settings, patchfile: Patchfile) { +export function patchRandomizer(worldId: number, logic: LogicResult, options: Options, settings: Settings, patchfile: Patchfile) { patchfile.addNewFile({ vrom: 0xf0200000, data: randomizerData(worldId, logic), compressed: true }); patchfile.addNewFile({ vrom: 0xf0300000, data: randomizerStartingItems(worldId, logic), compressed: false }); - patchfile.addNewFile({ vrom: 0xf0400000, data: gameChecks(worldId, settings, 'oot', logic), compressed: false }); - patchfile.addNewFile({ vrom: 0xf0500000, data: gameChecks(worldId, settings, 'mm', logic), compressed: false }); + patchfile.addNewFile({ vrom: 0xf0400000, data: gameChecks(worldId, options, settings, 'oot', logic), compressed: false }); + patchfile.addNewFile({ vrom: 0xf0500000, data: gameChecks(worldId, options, settings, 'mm', logic), compressed: false }); patchfile.addNewFile({ vrom: 0xf0600000, data: gameHints(settings, 'oot', logic.hints[worldId]), compressed: true }); patchfile.addNewFile({ vrom: 0xf0700000, data: gameHints(settings, 'mm', logic.hints[worldId]), compressed: true }); patchfile.addNewFile({ vrom: 0xf0800000, data: gameEntrances(worldId, 'oot', logic), compressed: true }); diff --git a/packages/core/src/mm/actors/En/En_GirlA.c b/packages/core/src/mm/actors/En/En_GirlA.c index b9848bdf1e..1cc7e84d62 100644 --- a/packages/core/src/mm/actors/En/En_GirlA.c +++ b/packages/core/src/mm/actors/En/En_GirlA.c @@ -11,8 +11,20 @@ void EnGirlA_Draw(Actor_EnGirlA* this, PlayState* play) Shop_UpdateItem(play, this); EnGirlA_ItemOverride(&o, this); if (o.gi != GI_MM_SOLD_OUT) - MatrixRotation(this->angle, 1); - Draw_GiCloaked(play, &this->base, o.gi, o.cloakGi, 0); + { + if (!o.cloakGi) + { + MatrixRotation(this->angle, 1); + Draw_Gi(play, &this->base, o.gi, 0); + } + else + { + MatrixRotation(-this->angle, 1); + Draw_Gi(play, &this->base, o.cloakGi, 0); + } + } + else + Draw_Gi(play, &this->base, o.gi, 0); } void EnGirlA_AfterHandler(Actor_EnGirlA* this, PlayState* play) diff --git a/packages/core/src/oot/actors/En/En_GirlA.c b/packages/core/src/oot/actors/En/En_GirlA.c index c865dfd166..9c948000ed 100644 --- a/packages/core/src/oot/actors/En/En_GirlA.c +++ b/packages/core/src/oot/actors/En/En_GirlA.c @@ -17,8 +17,20 @@ void EnGirlA_Draw(Actor_EnGirlA* this, PlayState* play) EnGirlA_ItemOverride(&o, this); if (o.gi != GI_MM_SOLD_OUT) - Matrix_RotateY(((this->angle * 360.f) / 65536.f) * 0.017453292f, MTXMODE_APPLY); - Draw_GiCloaked(play, &this->base, o.gi, o.cloakGi, 0); + { + if (!o.cloakGi) + { + Matrix_RotateY(((this->angle * 360.f) / 65536.f) * 0.017453292f, MTXMODE_APPLY); + Draw_Gi(play, &this->base, o.gi, 0); + } + else + { + Matrix_RotateY(((-this->angle * 360.f) / 65536.f) * 0.017453292f, MTXMODE_APPLY); + Draw_Gi(play, &this->base, o.cloakGi, 0); + } + } + else + Draw_Gi(play, &this->base, o.gi, 0); } PATCH_FUNC(0x80864910, EnGirlA_Draw); From 92f6b0cdb1685e002e97bf9919883b4707122c3d Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Mon, 27 Jan 2025 13:05:54 +0100 Subject: [PATCH 29/34] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9db988747c..39e2c246a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. ### Added +- Add Ice Traps. - Add the ability to shuffle extra merchants in OoT. - Add the ability to shuffle merchant prices in OoT. - Implement the Deku Shield in MM. From dfff9262375d7b6841a80a2c48ce234d9a125810 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:07:04 +0100 Subject: [PATCH 30/34] Add a cloakIceTraps setting --- packages/core/lib/combo/patch-build/randomizer.ts | 2 +- packages/core/lib/combo/settings/data.ts | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/core/lib/combo/patch-build/randomizer.ts b/packages/core/lib/combo/patch-build/randomizer.ts index fbb682c66b..b5a7331ee8 100644 --- a/packages/core/lib/combo/patch-build/randomizer.ts +++ b/packages/core/lib/combo/patch-build/randomizer.ts @@ -506,7 +506,7 @@ const gameChecks = (worldId: number, opts: Options, settings: Settings, game: Ga bufWriteU16BE(b, 4, item.player + 1); bufWriteU16BE(b, 6, itemGi); let cloakGi = 0; - if (item.item === Items.OOT_TRAP_ICE) { + if (item.item === Items.OOT_TRAP_ICE && settings.cloakIceTraps) { cloakGi = makeCloakGi(key, opts.seed, settings, logic); } bufWriteU16BE(b, 8, cloakGi); diff --git a/packages/core/lib/combo/settings/data.ts b/packages/core/lib/combo/settings/data.ts index 62c166f009..3ccc1ace59 100644 --- a/packages/core/lib/combo/settings/data.ts +++ b/packages/core/lib/combo/settings/data.ts @@ -1356,6 +1356,14 @@ export const SETTINGS = [{ default: false, description: 'Enables CAMC for shuffled Cows', cond: (x: any) => x.csmc !== 'never', +}, { + key: 'cloakIceTraps', + name: 'Cloak Ice Traps', + category: 'main.misc', + type: 'boolean', + default: true, + description: 'Makes Ice Traps look like different items.', + cond: hasOoT, }, { key: 'blastMaskCooldown', name: 'Blast Mask Cooldown', From de3bd1c5222562b7eb9d046ce07b91cc6c6ccf79 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:07:50 +0100 Subject: [PATCH 31/34] Don't cloak ice traps in blitz --- packages/core/lib/combo/presets.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/lib/combo/presets.ts b/packages/core/lib/combo/presets.ts index e0337b0c34..ba0deae4fd 100644 --- a/packages/core/lib/combo/presets.ts +++ b/packages/core/lib/combo/presets.ts @@ -13,6 +13,7 @@ const BLITZ_BASE: PartialDeep = { tingleShuffle: 'starting', openMaskShop: true, hintImportance: true, + cloakIceTraps: false, strayFairyChestShuffle: 'starting', mapCompassShuffle: 'starting', smallKeyShuffleMm: 'removed', From 548a0748461f5af47b5985efc56990449ed679f2 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Tue, 28 Jan 2025 07:21:19 +0100 Subject: [PATCH 32/34] Fix issues & crashes related to cloaked items --- packages/core/src/common/actors/En_Elf.c | 6 +++++- packages/core/src/common/actors/En_Item00.c | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/core/src/common/actors/En_Elf.c b/packages/core/src/common/actors/En_Elf.c index ac81c583d1..92a5c02c89 100644 --- a/packages/core/src/common/actors/En_Elf.c +++ b/packages/core/src/common/actors/En_Elf.c @@ -87,18 +87,22 @@ void EnElf_Draw(Actor_EnElf* this, PlayState* play) { ComboItemQuery q; ComboItemOverride o; + s16 cloakGi; if (!this->itemGiven) { EnElf_ItemQuery(&q, this); comboItemOverride(&o, &q); this->extendedGiDraw = o.gi; + cloakGi = o.cloakGi; } + else + cloakGi = GI_NONE; static const float scale = 25.0f; Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); - Draw_GiCloaked(play, &this->base, this->extendedGiDraw, o.cloakGi, 0); + Draw_GiCloaked(play, &this->base, this->extendedGiDraw, cloakGi, 0); } #if defined(GAME_OOT) diff --git a/packages/core/src/common/actors/En_Item00.c b/packages/core/src/common/actors/En_Item00.c index b4e0de02a9..254d90d121 100644 --- a/packages/core/src/common/actors/En_Item00.c +++ b/packages/core/src/common/actors/En_Item00.c @@ -14,6 +14,7 @@ void EnItem00_AliasFreestandingRupee(Xflag* xflag); void EnItem00_AliasFreestandingHeart(Xflag* xflag); + void EnItem00_InitWrapper(Actor_EnItem00* this, PlayState* play) { /* Forward */ @@ -31,20 +32,25 @@ static void EnItem00_DrawXflag(Actor_EnItem00* this, PlayState* play) { ComboItemOverride o; s16 gi; + s16 cloakGi; if (this->isExtendedCollected) + { gi = this->xflagGi; + cloakGi = GI_NONE; + } else { comboXflagItemOverride(&o, &this->xflag, 0); gi = o.gi; + cloakGi = o.cloakGi; this->xflagGi = gi; } Matrix_Translate(this->base.world.pos.x, this->base.world.pos.y + 20.f, this->base.world.pos.z, MTXMODE_NEW); Matrix_Scale(0.35f, 0.35f, 0.35f, MTXMODE_APPLY); Matrix_RotateY(this->base.shape.rot.y * ((M_PI * 2.f) / 32767.f), MTXMODE_APPLY); - Draw_GiCloaked(play, &this->base, gi, o.cloakGi, 0); + Draw_GiCloaked(play, &this->base, gi, cloakGi, 0); } static int EnItem00_XflagCanCollect(Actor_EnItem00* this, PlayState* play) From 7bdcd0241ea6dff2dbe00b51e0ddad3951546361 Mon Sep 17 00:00:00 2001 From: Nax <4265415+Nax@users.noreply.github.com> Date: Tue, 28 Jan 2025 08:29:54 +0100 Subject: [PATCH 33/34] Fix the twinmold blue warp item being gigantic when giant mask is equipped --- CHANGELOG.md | 1 + packages/core/src/mm/actors/Door/Door_Warp1.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39e2c246a3..baf14e9724 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ All notable changes to this project will be documented in this file. ### Fixed +- Fix the twinmold blue warp item being gigantic when giant mask is equipped. - Fix a vanilla bug where the frozen link effect would sometimes get distorded. - Fix FD mask item having weird colors sometimes. - Fix a small region issue near swamp spider house. diff --git a/packages/core/src/mm/actors/Door/Door_Warp1.c b/packages/core/src/mm/actors/Door/Door_Warp1.c index 889e76bbbd..cabf75ab32 100644 --- a/packages/core/src/mm/actors/Door/Door_Warp1.c +++ b/packages/core/src/mm/actors/Door/Door_Warp1.c @@ -139,17 +139,24 @@ void DoorWarp1_AfterDraw(Actor* this, PlayState* play) static const int kRotDivisor = 100; const BlueWarpData* data; ComboItemOverride o; + Player* player; float angle; + float scale; + float giantScale; + player = GET_PLAYER(play); data = DoorWarp1_GetData(this, play); if (data == NULL) return; if (gMmExtraBoss.items & (1 << data->index)) return; + DoorWarp1_ItemOverride(&o, data); angle = (play->state.frameCount % kRotDivisor) * (1.f / kRotDivisor) * M_PI * 2.f; - Matrix_Translate(this->world.pos.x, this->world.pos.y + 35.f, this->world.pos.z, MTXMODE_NEW); - Matrix_Scale(0.35f, 0.35f, 0.35f, MTXMODE_APPLY); + giantScale = (player->currentMask == PLAYER_MASK_GIANT) ? 0.1f : 1.f; + scale = 0.35f * giantScale; + Matrix_Translate(this->world.pos.x, this->world.pos.y + 35.f * giantScale, this->world.pos.z, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); Matrix_RotateY(angle, MTXMODE_APPLY); Draw_GiCloaked(play, this, o.gi, o.cloakGi, DRAW_RAW); } From f715f3d2b76747123d0f92870d29bfb84a9636f4 Mon Sep 17 00:00:00 2001 From: XenoWars Date: Tue, 28 Jan 2025 12:55:26 -0500 Subject: [PATCH 34/34] Fix Hylian Shield macro in OOT --- packages/data/src/macros/macros_oot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/data/src/macros/macros_oot.yml b/packages/data/src/macros/macros_oot.yml index 064b115d97..b55e9d4f1d 100644 --- a/packages/data/src/macros/macros_oot.yml +++ b/packages/data/src/macros/macros_oot.yml @@ -117,7 +117,7 @@ # Shields "has_shield_deku": "age_shield_child && (renewable(SHIELD_DEKU) || renewable(SHARED_SHIELD_DEKU) || event(SHIELD_DEKU) || has(SHIELD, 1) || has(SHARED_SHIELD, 1))" -"has_shield_hylian": "renewable(SHIELD_HYLIAN) || renewable(SHIELD_HYLIAN) || has(SHIELD, 2) || has(SHARED_SHIELD, 2)" +"has_shield_hylian": "renewable(SHARED_SHIELD_HYLIAN) || renewable(SHIELD_HYLIAN) || has(SHIELD, 2) || has(SHARED_SHIELD, 2)" "has_shield": "has_shield_hylian || has_mirror_shield || has_shield_deku" "has_shield_for_scrubs": "(is_adult && has_shield_hylian) || has_shield_deku" "has_mirror_shield_raw_nonshared": "cond(setting(progressiveShieldsOot, progressive), has(SHIELD, 3), has(SHIELD_MIRROR))"