diff --git a/include/functions.h b/include/functions.h index 9f162985de..48eef2922e 100644 --- a/include/functions.h +++ b/include/functions.h @@ -2145,7 +2145,7 @@ void Interface_ChangeAlpha(u16 param_1); // void func_80112C0C(void); u32 Item_Give(GlobalContext* globalCtx, u8 param_2); // void func_801143CC(void); -// void func_80114978(void); +UNK_TYPE func_80114978(UNK_TYPE arg0); // void func_801149A0(void); // void func_80114A9C(void); // void func_80114B84(void); @@ -2164,7 +2164,7 @@ void func_80115844(GlobalContext* globalCtx, s16 param_2); void func_80115908(GlobalContext* globalCtx, u8 param_2); void func_801159c0(s16 param_1); void func_801159EC(s16 arg0); -// void func_80115A14(void); +void func_80115A14(s32 arg0, s16 arg1); // void Parameter_AddMagic(void); // void func_80115D5C(void); // void func_80115DB4(void); diff --git a/include/macros.h b/include/macros.h index 0108ccf687..1e42fbc5d1 100644 --- a/include/macros.h +++ b/include/macros.h @@ -9,18 +9,19 @@ #define HW_REG(reg, type) *(volatile type*)((reg) | 0xa0000000) -// TODO: After uintptr_t cast change should have an AVOID_UB target that just toggles the KSEG0 bit in the address rather than add/sub 0x80000000 +// TODO: After uintptr_t cast change should have an AVOID_UB target that just toggles the KSEG0 bit in the address +// rather than add/sub 0x80000000 #define PHYSICAL_TO_VIRTUAL(addr) ((uintptr_t)(addr) + 0x80000000) -#define PHYSICAL_TO_VIRTUAL2(addr) ((uintptr_t)(addr) - 0x80000000) -#define VIRTUAL_TO_PHYSICAL(addr) (uintptr_t)((u8*)(addr) - 0x80000000) +#define PHYSICAL_TO_VIRTUAL2(addr) ((uintptr_t)(addr)-0x80000000) +#define VIRTUAL_TO_PHYSICAL(addr) (uintptr_t)((u8*)(addr)-0x80000000) #define SEGMENTED_TO_VIRTUAL(addr) (void*)(PHYSICAL_TO_VIRTUAL(gSegments[SEGMENT_NUMBER(addr)]) + SEGMENT_OFFSET(addr)) // Currently most often called ctxt in MM, TODO: Refactor names when its used #define ACTIVE_CAM globalCtx->cameraPtrs[globalCtx->activeCamera] -#define SET_NEXT_GAMESTATE(curState, newInit, newStruct) \ - (curState)->nextGameStateInit = (GameStateFunc)newInit; \ - (curState)->nextGameStateSize = sizeof(newStruct); +#define SET_NEXT_GAMESTATE(curState, newInit, newStruct) \ + (curState)->nextGameStateInit = (GameStateFunc)newInit; \ + (curState)->nextGameStateSize = sizeof(newStruct); #define PLAYER ((ActorPlayer*)globalCtx->actorCtx.actorList[ACTORCAT_PLAYER].first) @@ -31,28 +32,43 @@ #define CURRENT_DAY (gSaveContext.day % 5) -#define SQ(x) ((x)*(x)) -#define DECR(x) ((x) == 0 ? 0 : ((x) -= 1)) +#define SLOT(item) gItemSlots[item] +#define AMMO(item) gSaveContext.inventory.ammo[SLOT(item)] +#define INV_CONTENT(item) gSaveContext.inventory.items[SLOT(item)] + +#define ALL_EQUIP_VALUE_VOID(equip) \ + ((((void)0, gSaveContext.inventory.equipment) & gEquipMasks[equip]) >> gEquipShifts[equip]) +#define CUR_EQUIP_VALUE_VOID(equip) \ + ((((void)0, gSaveContext.equips.equipment) & gEquipMasks[equip]) >> gEquipShifts[equip]) +#define CUR_UPG_VALUE_VOID(upg) \ + ((((void)0, gSaveContext.inventory.upgrades) & gUpgradeMasks[upg]) >> gUpgradeShifts[upg]) + +#define ALL_EQUIP_VALUE(equip) ((gSaveContext.inventory.equipment & gEquipMasks[equip]) >> gEquipShifts[equip]) +#define CUR_EQUIP_VALUE(equip) ((gSaveContext.equips.equipment & gEquipMasks[equip]) >> gEquipShifts[equip]) +#define CUR_UPG_VALUE(upg) ((gSaveContext.inventory.upgrades & gUpgradeMasks[upg]) >> gUpgradeShifts[upg]) + +#define CAPACITY(upg, value) gUpgradeCapacities[upg][value] +#define CUR_CAPACITY(upg) CAPACITY(upg, CUR_UPG_VALUE(upg) - 4) #define CHECK_BTN_ALL(state, combo) (~((state) | ~(combo)) == 0) #define CHECK_BTN_ANY(state, combo) (((state) & (combo)) != 0) extern GraphicsContext* __gfxCtx; -#define WORK_DISP __gfxCtx->work.p -#define POLY_OPA_DISP __gfxCtx->polyOpa.p -#define POLY_XLU_DISP __gfxCtx->polyXlu.p -#define OVERLAY_DISP __gfxCtx->overlay.p +#define WORK_DISP __gfxCtx->work.p +#define POLY_OPA_DISP __gfxCtx->polyOpa.p +#define POLY_XLU_DISP __gfxCtx->polyXlu.p +#define OVERLAY_DISP __gfxCtx->overlay.p // __gfxCtx shouldn't be used directly. // Use the DISP macros defined above when writing to display buffers. #define OPEN_DISPS(gfxCtx) \ { \ GraphicsContext* __gfxCtx = gfxCtx; \ - s32 __dispPad; \ + s32 __dispPad; -#define CLOSE_DISPS(gfxCtx) \ - } \ +#define CLOSE_DISPS(gfxCtx) \ + } \ (void)0 /** @@ -66,30 +82,31 @@ extern GraphicsContext* __gfxCtx; * `cbnz` blue component of color vertex, or z component of normal vertex * `a` alpha */ -#define VTX(x,y,z,s,t,crnx,cgny,cbnz,a) { { { x, y, z }, 0, { s, t }, { crnx, cgny, cbnz, a } } } +#define VTX(x, y, z, s, t, crnx, cgny, cbnz, a) \ + { { { x, y, z }, 0, { s, t }, { crnx, cgny, cbnz, a } }, } -#define VTX_T(x,y,z,s,t,cr,cg,cb,a) { { x, y, z }, 0, { s, t }, { cr, cg, cb, a } } +#define VTX_T(x, y, z, s, t, cr, cg, cb, a) \ + { { x, y, z }, 0, { s, t }, { cr, cg, cb, a }, } -#define GRAPH_ALLOC(gfxCtx, size) \ - ((void *) ((gfxCtx)->polyOpa.d = (Gfx*)((u8*)(gfxCtx)->polyOpa.d - (size)))) +#define GRAPH_ALLOC(gfxCtx, size) ((void*)((gfxCtx)->polyOpa.d = (Gfx*)((u8*)(gfxCtx)->polyOpa.d - (size)))) #define ALIGN8(val) (((val) + 7) & ~7) #define ALIGN16(val) (((val) + 0xF) & ~0xF) -#define SQ(x) ((x)*(x)) -#define ABS(x) ((x) >= 0 ? (x) : -(x)) -#define ABS_ALT(x) ((x) < 0 ? -(x) : (x)) -#define DECR(x) ((x) == 0 ? 0 : ((x) -= 1)) +#define SQ(x) ((x) * (x)) +#define ABS(x) ((x) >= 0 ? (x) : -(x)) +#define ABS_ALT(x) ((x) < 0 ? -(x) : (x)) +#define DECR(x) ((x) == 0 ? 0 : ((x) -= 1)) #define CLAMP(x, min, max) ((x) < (min) ? (min) : (x) > (max) ? (max) : (x)) -#define CLAMP_MAX(x, max) ((x) > (max) ? (max) : (x)) -#define CLAMP_MIN(x, min) ((x) < (min) ? (min) : (x)) +#define CLAMP_MAX(x, max) ((x) > (max) ? (max) : (x)) +#define CLAMP_MIN(x, min) ((x) < (min) ? (min) : (x)) -#define SWAP(type, a, b) \ -{ \ - type _temp = (a); \ - (a) = (b); \ - (b) = _temp; \ -} +#define SWAP(type, a, b) \ + { \ + type _temp = (a); \ + (a) = (b); \ + (b) = _temp; \ + } #endif // _MACROS_H_ diff --git a/include/z64item.h b/include/z64item.h index f4ca2da67c..3d8c96340f 100644 --- a/include/z64item.h +++ b/include/z64item.h @@ -7,44 +7,122 @@ // TODO fill out these enums typedef enum { + /* 0x1 */ EQUIP_SHIELD = 0x1 +} EquipmentType; + +typedef enum { + /* 0x0 */ UPG_QUIVER, + /* 0x1 */ UPG_BOMB_BAG, + /* 0x4 */ UPG_WALLET = 0x4, + /* 0x6 */ UPG_STICK = 0x6, + /* 0x7 */ UPG_NUTS +} UpgradeType; + +typedef enum { + /* 0x01 */ ITEM_BOW = 0x01, + /* 0x06 */ ITEM_BOMB = 0x06, + /* 0x07 */ ITEM_BOMBCHU, + /* 0x08 */ ITEM_STICK, + /* 0x09 */ ITEM_NUT, + /* 0x10 */ ITEM_SWORD_GREAT_FAIRY = 0x10, + /* 0x12 */ ITEM_BOTTLE = 0x12, + /* 0x13 */ ITEM_POTION_RED, + /* 0x14 */ ITEM_POTION_GREEN, + /* 0x15 */ ITEM_POTION_BLUE, + /* 0x16 */ ITEM_FAIRY, + /* 0x38 */ ITEM_MASK_ALL_NIGHT = 0x38, + /* 0x3B */ ITEM_MASK_GARO = 0x3B, + /* 0x4D */ ITEM_SWORD_KOKIRI = 0x4D, + /* 0x4E */ ITEM_SWORD_RAZOR, + /* 0x4F */ ITEM_SWORD_GILDED, + /* 0x51 */ ITEM_SHIELD_HERO = 0x51, + /* 0x52 */ ITEM_SHIELD_MIRROR, + /* 0x56 */ ITEM_BOMB_BAG_20 = 0x56, + /* 0x57 */ ITEM_BOMB_BAG_30, + /* 0x58 */ ITEM_BOMB_BAG_40, /* 0x78 */ ITEM_KEY_SMALL = 0x78, - /* 0x79 */ ITEM_MAGIC_SMALL = 0x79, - /* 0x7A */ ITEM_MAGIC_LARGE = 0x7A, + /* 0x79 */ ITEM_MAGIC_SMALL, + /* 0x7A */ ITEM_MAGIC_LARGE, /* 0x83 */ ITEM_HEART = 0x83, - /* 0x84 */ ITEM_RUPEE_GREEN = 0x84, - /* 0x85 */ ITEM_RUPEE_BLUE = 0x85, - /* 0x86 */ ITEM_RUPEE_10 = 0x86, - /* 0x87 */ ITEM_RUPEE_RED = 0x87, - /* 0x88 */ ITEM_RUPEE_PURPLE = 0x88, - /* 0x89 */ ITEM_RUPEE_100 = 0x89, - /* 0x8A */ ITEM_RUPEE_ORANGE = 0x8A, - /* 0x8F */ ITEM_BOMBS_5 = 0x8F, - /* 0x90 */ ITEM_BOMBS_10 = 0x90, - /* 0x91 */ ITEM_BOMBS_20 = 0x91, - /* 0x92 */ ITEM_BOMBS_30 = 0x92, - /* 0x93 */ ITEM_ARROWS_10 = 0x93, - /* 0x94 */ ITEM_ARROWS_30 = 0x94, - /* 0x95 */ ITEM_ARROWS_40 = 0x95, - /* 0x96 */ ITEM_ARROWS_50 = 0x96 + /* 0x84 */ ITEM_RUPEE_GREEN, + /* 0x85 */ ITEM_RUPEE_BLUE, + /* 0x86 */ ITEM_RUPEE_10, + /* 0x87 */ ITEM_RUPEE_RED, + /* 0x88 */ ITEM_RUPEE_PURPLE, + /* 0x89 */ ITEM_RUPEE_100, + /* 0x8A */ ITEM_RUPEE_ORANGE, + /* 0x8D */ ITEM_NUTS_5 = 0x8D, + /* 0x8E */ ITEM_NUTS_10, + /* 0x8F */ ITEM_BOMBS_5, + /* 0x90 */ ITEM_BOMBS_10, + /* 0x91 */ ITEM_BOMBS_20, + /* 0x92 */ ITEM_BOMBS_30, + /* 0x93 */ ITEM_ARROWS_10, + /* 0x94 */ ITEM_ARROWS_30, + /* 0x95 */ ITEM_ARROWS_40, + /* 0x96 */ ITEM_ARROWS_50, + /* 0x98 */ ITEM_BOMBCHUS_10 = 0x98, + /* 0xFF */ ITEM_NONE = 0xFF } ItemID; typedef enum { /* 0x00 */ GI_NONE, /* 0x0C */ GI_HEART_PIECE = 0x0C, - /* 0x0D */ GI_HEART_CONTAINER = 0x0D, + /* 0x0D */ GI_HEART_CONTAINER, + /* 0x16 */ GI_BOMBS_10 = 0x16, /* 0x19 */ GI_STICKS_1 = 0x19, + /* 0x1A */ GI_BOMBCHUS_10, + /* 0x1B */ GI_BOMB_BAG_20, + /* 0x1C */ GI_BOMB_BAG_30, + /* 0x1D */ GI_BOMB_BAG_40, + /* 0x1E */ GI_ARROWS_SMALL, + /* 0x1F */ GI_ARROWS_MEDIUM, + /* 0x20 */ GI_ARROWS_LARGE, /* 0x28 */ GI_NUTS_1 = 0x28, /* 0x2A */ GI_NUTS_10 = 0x2A, /* 0x32 */ GI_SHIELD_HERO = 0x32, + /* 0x33 */ GI_SHIELD_MIRROR, /* 0x3C */ GI_KEY_SMALL = 0x3C, /* 0x3E */ GI_MAP = 0x3E, - /* 0x3F */ GI_COMPASS = 0x3F + /* 0x3F */ GI_COMPASS, + /* 0x5B */ GI_POTION_RED = 0x5B, + /* 0x5C */ GI_POTION_GREEN, + /* 0x5D */ GI_POTION_BLUE, + /* 0x5E */ GI_FAIRY, + /* 0x7E */ GI_MASK_ALL_NIGHT = 0x7E, + /* 0x9B */ GI_SWORD_GREAT_FAIRY = 0x9B, + /* 0x9C */ GI_SWORD_KOKIRI, + /* 0x9D */ GI_SWORD_RAZOR, + /* 0x9E */ GI_SWORD_GILDED, + /* 0x9F */ GI_SHIELD_HERO_2, // Code that treats this as hero's shield is unused, so take with a grain of salt + /* 0xA9 */ GI_BOTTLE = 0xA9 } GetItemID; typedef enum { + /* 0x00 */ GID_BOTTLE, /* 0x0A */ GID_COMPASS = 0x0A, - /* 0x1B */ GID_DUNGEON_MAP = 0x1B, - /* 0x27 */ GID_SHIELD_HERO = 0x27 + /* 0x10 */ GID_MASK_ALL_NIGHT = 0x10, + /* 0x11 */ GID_NUTS, + /* 0x17 */ GID_BOMB_BAG_20 = 0x17, + /* 0x18 */ GID_BOMB_BAG_30, + /* 0x19 */ GID_BOMB_BAG_40, + /* 0x1A */ GID_STICK = 0x1A, + /* 0x1B */ GID_DUNGEON_MAP, + /* 0x1E */ GID_BOMB = 0x1E, + /* 0x23 */ GID_ARROWS_SMALL = 0x23, + /* 0x24 */ GID_ARROWS_MEDIUM, + /* 0x25 */ GID_ARROWS_LARGE, + /* 0x26 */ GID_BOMBCHU, + /* 0x27 */ GID_SHIELD_HERO, + /* 0x30 */ GID_POTION_GREEN = 0x30, + /* 0x31 */ GID_POTION_RED, + /* 0x32 */ GID_POTION_BLUE, + /* 0x33 */ GID_SHIELD_MIRROR, + /* 0x3B */ GID_FAIRY = 0x3B, + /* 0x55 */ GID_SWORD_KOKIRI = 0x55, + /* 0x66 */ GID_SWORD_RAZOR = 0x66, + /* 0x67 */ GID_SWORD_GILDED, + /* 0x68 */ GID_SWORD_GREAT_FAIRY } GetItemDrawID; #endif diff --git a/linker_scripts/code_script.txt b/linker_scripts/code_script.txt index b0509a2f89..61a0dfad3d 100644 --- a/linker_scripts/code_script.txt +++ b/linker_scripts/code_script.txt @@ -841,9 +841,9 @@ SECTIONS ovl_En_GirlA : AT(RomLocation) { build/src/overlays/actors/ovl_En_GirlA/z_en_girla.o(.text) - build/asm/overlays/ovl_En_GirlA_data.o(.data) + build/src/overlays/actors/ovl_En_GirlA/z_en_girla.o(.data) build/src/overlays/actors/ovl_En_GirlA/z_en_girla.o(.rodata) - build/asm/overlays/ovl_En_GirlA_rodata.o(.rodata) + build/src/overlays/actors/ovl_En_GirlA/z_en_girla_overlay.o(.ovl) } SegmentEnd = .; SegmentSize = SegmentEnd - SegmentStart; diff --git a/src/code/z_en_item00.c b/src/code/z_en_item00.c index 5e496d7ac9..bffd14ba26 100644 --- a/src/code/z_en_item00.c +++ b/src/code/z_en_item00.c @@ -816,16 +816,14 @@ s16 func_800A7650(s16 dropId) { s16 healthCapacity; if ((((dropId == ITEM00_BOMBS_A) || (dropId == ITEM00_BOMBS_0) || (dropId == ITEM00_BOMBS_B)) && - (gSaveContext.inventory.items[gItemSlots[6]] == 0xFF)) || + (INV_CONTENT(ITEM_BOMB) == ITEM_NONE)) || (((dropId == ITEM00_ARROWS_10) || (dropId == ITEM00_ARROWS_30) || (dropId == ITEM00_ARROWS_40) || (dropId == ITEM00_ARROWS_50)) && - (gSaveContext.inventory.items[gItemSlots[1]] == 0xFF)) || + (INV_CONTENT(ITEM_BOW) == ITEM_NONE)) || (((dropId == ITEM00_MAGIC_LARGE) || (dropId == ITEM00_MAGIC_SMALL)) && (gSaveContext.magicLevel == 0))) { return ITEM00_NO_DROP; } - ; - if (dropId == ITEM00_HEART) { healthCapacity = gSaveContext.healthCapacity; if (healthCapacity == gSaveContext.health) { @@ -1125,11 +1123,11 @@ void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3 params = 0xD0; dropId = ITEM00_MAGIC_LARGE; dropQuantity = 1; - } else if (gSaveContext.inventory.ammo[gItemSlots[1]] < 6) { + } else if (AMMO(ITEM_BOW) < 6) { params = 0xA0; dropId = ITEM00_ARROWS_30; dropQuantity = 1; - } else if (gSaveContext.inventory.ammo[gItemSlots[6]] < 6) { + } else if (AMMO(ITEM_BOMB) < 6) { params = 0xB0; dropId = ITEM00_BOMBS_A; dropQuantity = 1; diff --git a/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c b/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c index e4ba4d8f44..eac90b2806 100644 --- a/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c +++ b/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c @@ -424,7 +424,7 @@ void EnGinkoMan_WaitForDialogueInput(EnGinkoMan* this, GlobalContext* globalCtx) func_800BDC5C(&this->skelAnime, animations, GINKO_FLOORSMACKING); func_801518B0(globalCtx, 0x476, &this->actor); this->curTextId = 0x476; // you dont have enough deposited to withdrawl - } else if (D_801C1E2C[(gSaveContext.inventory.upgrades & gUpgradeMasks[4]) >> gUpgradeShifts[4]] < (globalCtx->msgCtx.bankRupeesSelected + gSaveContext.rupees)) { + } else if (D_801C1E2C[CUR_UPG_VALUE(UPG_WALLET)] < (globalCtx->msgCtx.bankRupeesSelected + gSaveContext.rupees)) { // check if wallet is big enough play_sound(NA_SE_SY_ERROR); func_801518B0(globalCtx, 0x475, &this->actor); @@ -532,7 +532,7 @@ void EnGinkoMan_BankAward(EnGinkoMan* this, GlobalContext* globalCtx) { EnGinkoMan_SetupBankAward2(this); } else if (this->curTextId == 0x45B) { // "Whats this, you already saved up 200?" if (!(gSaveContext.weekEventReg[10] & 8)) { - func_800B8A1C(&this->actor, globalCtx, ((u32)(gSaveContext.inventory.upgrades & gUpgradeMasks[4]) >> gUpgradeShifts[4]) + 8, 500.0f, 100.0f); + func_800B8A1C(&this->actor, globalCtx, CUR_UPG_VALUE(UPG_WALLET) + 8, 500.0f, 100.0f); } else { func_800B8A1C(&this->actor, globalCtx, 2, 500.0f, 100.0f); } diff --git a/src/overlays/actors/ovl_En_GirlA/z_en_girla.c b/src/overlays/actors/ovl_En_GirlA/z_en_girla.c index efb74adaad..a15988845a 100644 --- a/src/overlays/actors/ovl_En_GirlA/z_en_girla.c +++ b/src/overlays/actors/ovl_En_GirlA/z_en_girla.c @@ -1,3 +1,9 @@ +/* + * File: z_en_girla.c + * Overlay: obj_En_Girla + * Description: Shop Items + */ + #include "z_en_girla.h" #define FLAGS 0x00000019 @@ -7,8 +13,44 @@ void EnGirlA_Init(Actor* thisx, GlobalContext* globalCtx); void EnGirlA_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnGirlA_Update(Actor* thisx, GlobalContext* globalCtx); +void EnGirlA_Draw(Actor* thisx, GlobalContext* globalCtx); + +void EnGirlA_InitalUpdate(EnGirlA* this, GlobalContext* globalCtx); +void EnGirlA_Update2(EnGirlA* this, GlobalContext* globalCtx); + +s32 EnGirlA_CanBuyPotionRed(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyPotionGreen(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyPotionBlue(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyArrows(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyNuts(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyShieldHero(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyStick(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyMaskAllNight(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyBombBagCuriosityShop(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyBombBag20BombShop(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyBombBag30BombShop(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyBombchus(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyBombs(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyBottle(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuySword(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyShieldMirror(GlobalContext* globalCtx, EnGirlA* this); +s32 EnGirlA_CanBuyFairy(GlobalContext* globalCtx, EnGirlA* this); + +void EnGirlA_BuyBottleItem(GlobalContext* globalCtx, EnGirlA* this); +void EnGirlA_BuyArrows(GlobalContext* globalCtx, EnGirlA* this); +void EnGirlA_BuyNuts(GlobalContext* globalCtx, EnGirlA* this); +void EnGirlA_BuyShieldHero(GlobalContext* globalCtx, EnGirlA* this); +void EnGirlA_BuyStick(GlobalContext* globalCtx, EnGirlA* this); +void EnGirlA_BuyMaskAllNight(GlobalContext* globalCtx, EnGirlA* this); +void EnGirlA_BuyBombBag(GlobalContext* globalCtx, EnGirlA* this); +void EnGirlA_BuyBombchus(GlobalContext* globalCtx, EnGirlA* this); +void EnGirlA_BuyBombs(GlobalContext* globalCtx, EnGirlA* this); +void EnGirlA_BuyBottle(GlobalContext* globalCtx, EnGirlA* this); +void EnGirlA_BuySword(GlobalContext* globalCtx, EnGirlA* this); +void EnGirlA_BuyShieldMirror(GlobalContext* globalCtx, EnGirlA* this); + +void EnGirlA_BuyFanfare(GlobalContext* globalCtx, EnGirlA* this); -/* const ActorInit En_GirlA_InitVars = { ACTOR_EN_GIRLA, ACTORCAT_PROP, @@ -20,90 +62,544 @@ const ActorInit En_GirlA_InitVars = { (ActorFunc)EnGirlA_Update, (ActorFunc)NULL, }; -*/ -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80863870.asm") +static ShopItemEntry sShopItemEntries[] = { + { OBJECT_GI_LIQUID, GID_POTION_RED, func_800B8050, 1, 0X083F, 0X0840, GI_POTION_RED, EnGirlA_CanBuyPotionRed, + EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, + { OBJECT_GI_LIQUID, GID_POTION_GREEN, func_800B8050, 1, 0X0841, 0X0842, GI_POTION_GREEN, EnGirlA_CanBuyPotionGreen, + EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, + { OBJECT_GI_LIQUID, GID_POTION_BLUE, func_800B8050, 1, 0X0843, 0X0844, GI_POTION_BLUE, EnGirlA_CanBuyPotionBlue, + EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, + { OBJECT_GI_BOTTLE_04, GID_FAIRY, func_800B8050, 1, 0X06B6, 0X06B7, GI_FAIRY, EnGirlA_CanBuyFairy, + EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, + { OBJECT_GI_ARROW, GID_ARROWS_LARGE, func_800B8050, 50, 0X06BA, 0X06BB, GI_ARROWS_LARGE, EnGirlA_CanBuyArrows, + EnGirlA_BuyArrows, EnGirlA_BuyFanfare }, + { OBJECT_GI_LIQUID, GID_POTION_GREEN, func_800B8050, 1, 0X06B2, 0X06B3, GI_POTION_GREEN, EnGirlA_CanBuyPotionGreen, + EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, + { OBJECT_GI_SHIELD_2, GID_SHIELD_HERO, func_800B8050, 1, 0X06AE, 0X06AF, GI_SHIELD_HERO, EnGirlA_CanBuyShieldHero, + EnGirlA_BuyShieldHero, EnGirlA_BuyFanfare }, + { OBJECT_GI_STICK, GID_STICK, NULL, 1, 0X06B4, 0X06B5, GI_STICKS_1, EnGirlA_CanBuyStick, EnGirlA_BuyStick, + EnGirlA_BuyFanfare }, + { OBJECT_GI_ARROW, GID_ARROWS_MEDIUM, func_800B8050, 30, 0X06B8, 0X06B9, GI_ARROWS_MEDIUM, EnGirlA_CanBuyArrows, + EnGirlA_BuyArrows, EnGirlA_BuyFanfare }, + { OBJECT_GI_NUTS, GID_NUTS, func_800B8118, 10, 0X06B0, 0X06B1, GI_NUTS_10, EnGirlA_CanBuyNuts, EnGirlA_BuyNuts, + EnGirlA_BuyFanfare }, + { OBJECT_GI_LIQUID, GID_POTION_RED, func_800B8050, 1, 0X06AC, 0X06AD, GI_POTION_RED, EnGirlA_CanBuyPotionRed, + EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, + { OBJECT_GI_BOTTLE_04, GID_FAIRY, func_800B8050, 1, 0X06D3, 0X06D4, GI_FAIRY, EnGirlA_CanBuyFairy, + EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, + { OBJECT_GI_ARROW, GID_ARROWS_MEDIUM, func_800B8050, 30, 0X06D5, 0X06D6, GI_ARROWS_MEDIUM, EnGirlA_CanBuyArrows, + EnGirlA_BuyArrows, EnGirlA_BuyFanfare }, + { OBJECT_GI_ARROW, GID_ARROWS_LARGE, func_800B8050, 50, 0X06D7, 0X06D8, GI_ARROWS_LARGE, EnGirlA_CanBuyArrows, + EnGirlA_BuyArrows, EnGirlA_BuyFanfare }, + { OBJECT_GI_LIQUID, GID_POTION_GREEN, func_800B8050, 1, 0X06CF, 0X06D0, GI_POTION_GREEN, EnGirlA_CanBuyPotionGreen, + EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, + { OBJECT_GI_NUTS, GID_NUTS, func_800B8118, 10, 0X06CD, 0X06CE, GI_NUTS_10, EnGirlA_CanBuyNuts, EnGirlA_BuyNuts, + EnGirlA_BuyFanfare }, + { OBJECT_GI_STICK, GID_STICK, NULL, 1, 0X06D1, 0X06D2, GI_STICKS_1, EnGirlA_CanBuyStick, EnGirlA_BuyStick, + EnGirlA_BuyFanfare }, + { OBJECT_GI_SHIELD_2, GID_SHIELD_HERO, func_800B8050, 1, 0X06CB, 0X06CC, GI_SHIELD_HERO, EnGirlA_CanBuyShieldHero, + EnGirlA_BuyShieldHero, EnGirlA_BuyFanfare }, + { OBJECT_GI_LIQUID, GID_POTION_RED, func_800B8050, 1, 0X06C9, 0X06CA, GI_POTION_RED, EnGirlA_CanBuyPotionRed, + EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, + { OBJECT_GI_MASK06, GID_MASK_ALL_NIGHT, func_800B8050, 1, 0X29D9, 0X29DA, GI_MASK_ALL_NIGHT, + EnGirlA_CanBuyMaskAllNight, EnGirlA_BuyMaskAllNight, EnGirlA_BuyFanfare }, + { OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_20, func_800B8050, 1, 0X29DB, 0X29DC, GI_BOMB_BAG_20, + EnGirlA_CanBuyBombBagCuriosityShop, EnGirlA_BuyBombBag, EnGirlA_BuyFanfare }, + { OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_30, func_800B8050, 2, 0X29DB, 0X29DC, GI_BOMB_BAG_30, + EnGirlA_CanBuyBombBagCuriosityShop, EnGirlA_BuyBombBag, EnGirlA_BuyFanfare }, + { OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_40, func_800B8050, 3, 0X29DB, 0X29DC, GI_BOMB_BAG_40, + EnGirlA_CanBuyBombBagCuriosityShop, EnGirlA_BuyBombBag, EnGirlA_BuyFanfare }, + { OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_20, func_800B8050, 1, 0X0654, 0X0655, GI_BOMB_BAG_20, + EnGirlA_CanBuyBombBag20BombShop, EnGirlA_BuyBombBag, EnGirlA_BuyFanfare }, + { OBJECT_GI_BOMBPOUCH, GID_BOMB_BAG_30, func_800B8050, 2, 0X0656, 0X0657, GI_BOMB_BAG_30, + EnGirlA_CanBuyBombBag30BombShop, EnGirlA_BuyBombBag, EnGirlA_BuyFanfare }, + { OBJECT_GI_BOMB_2, GID_BOMBCHU, func_800B8050, 10, 0X0652, 0X0653, GI_BOMBCHUS_10, EnGirlA_CanBuyBombchus, + EnGirlA_BuyBombchus, EnGirlA_BuyFanfare }, + { OBJECT_GI_BOMB_1, GID_BOMB, func_800B8050, 10, 0X0650, 0X0651, GI_BOMBS_10, EnGirlA_CanBuyBombs, EnGirlA_BuyBombs, + EnGirlA_BuyFanfare }, + { OBJECT_GI_SHIELD_2, GID_SHIELD_HERO, func_800B8050, 1, 0X12DB, 0X12DC, GI_SHIELD_HERO, EnGirlA_CanBuyShieldHero, + EnGirlA_BuyShieldHero, EnGirlA_BuyFanfare }, + { OBJECT_GI_ARROW, GID_ARROWS_SMALL, func_800B8050, 10, 0X12DD, 0X12DE, GI_ARROWS_SMALL, EnGirlA_CanBuyArrows, + EnGirlA_BuyArrows, EnGirlA_BuyFanfare }, + { OBJECT_GI_LIQUID, GID_POTION_RED, func_800B8050, 1, 0X12DF, 0X12E0, GI_POTION_RED, EnGirlA_CanBuyPotionRed, + EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, + { OBJECT_GI_BOMB_1, GID_BOMB, func_800B8050, 10, 0X0BC5, 0X0BC6, GI_BOMBS_10, EnGirlA_CanBuyBombs, EnGirlA_BuyBombs, + EnGirlA_BuyFanfare }, + { OBJECT_GI_ARROW, GID_ARROWS_SMALL, func_800B8050, 10, 0X0BC7, 0X0BC8, GI_ARROWS_SMALL, EnGirlA_CanBuyArrows, + EnGirlA_BuyArrows, EnGirlA_BuyFanfare }, + { OBJECT_GI_LIQUID, GID_POTION_RED, func_800B8050, 1, 0X0BC9, 0X0BCA, GI_POTION_RED, EnGirlA_CanBuyPotionRed, + EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, + { OBJECT_GI_BOMB_1, GID_BOMB, func_800B8050, 10, 0X0BCB, 0X0BCC, GI_BOMBS_10, EnGirlA_CanBuyBombs, EnGirlA_BuyBombs, + EnGirlA_BuyFanfare }, + { OBJECT_GI_ARROW, GID_ARROWS_SMALL, func_800B8050, 10, 0X0BCD, 0X0BCE, GI_ARROWS_SMALL, EnGirlA_CanBuyArrows, + EnGirlA_BuyArrows, EnGirlA_BuyFanfare }, + { OBJECT_GI_LIQUID, GID_POTION_RED, func_800B8050, 1, 0X0BCF, 0X0BD0, GI_POTION_RED, EnGirlA_CanBuyPotionRed, + EnGirlA_BuyBottleItem, EnGirlA_BuyFanfare }, + { OBJECT_GI_BOTTLE, GID_BOTTLE, func_800B8050, 1, 0X29F8, 0X29F9, GI_BOTTLE, EnGirlA_CanBuyBottle, + EnGirlA_BuyBottle, EnGirlA_BuyFanfare }, + { OBJECT_GI_SWORD_4, GID_SWORD_GREAT_FAIRY, func_800B8050, 4, 0X29F2, 0X29F3, GI_SWORD_GREAT_FAIRY, + EnGirlA_CanBuySword, EnGirlA_BuySword, EnGirlA_BuyFanfare }, + { OBJECT_GI_SWORD_1, GID_SWORD_KOKIRI, func_800B8050, 1, 0X29F4, 0X29F5, GI_SWORD_KOKIRI, EnGirlA_CanBuySword, + EnGirlA_BuySword, EnGirlA_BuyFanfare }, + { OBJECT_GI_SWORD_2, GID_SWORD_RAZOR, func_800B8050, 2, 0X29F4, 0X29F5, GI_SWORD_RAZOR, EnGirlA_CanBuySword, + EnGirlA_BuySword, EnGirlA_BuyFanfare }, + { OBJECT_GI_SWORD_3, GID_SWORD_GILDED, func_800B8050, 3, 0X29F4, 0X29F5, GI_SWORD_GILDED, EnGirlA_CanBuySword, + EnGirlA_BuySword, EnGirlA_BuyFanfare }, + { OBJECT_GI_SHIELD_2, GID_SHIELD_HERO, func_800B8050, 1, 0X29F6, 0X29F7, GI_SHIELD_HERO_2, EnGirlA_CanBuyShieldHero, + EnGirlA_BuyShieldHero, EnGirlA_BuyFanfare }, + { OBJECT_GI_SHIELD_3, GID_SHIELD_MIRROR, func_800B8050, 1, 0X29F6, 0X29F7, GI_SHIELD_MIRROR, + EnGirlA_CanBuyShieldMirror, EnGirlA_BuyShieldMirror, EnGirlA_BuyFanfare }, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_8086387C.asm") +void EnGirlA_SetupAction(EnGirlA* this, EnGirlAActionFunc action) { + this->actionFunc = action; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/EnGirlA_Init.asm") +void EnGirlA_InitObjIndex(EnGirlA* this, GlobalContext* globalCtx) { + s16 params = this->actor.params; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/EnGirlA_Destroy.asm") + //! @bug: Condition is impossible + if (params >= 43 && params < 0) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80863950.asm") + this->objIndex = Object_GetIndex(&globalCtx->objectCtx, sShopItemEntries[params].objectId); + if (this->objIndex < 0) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_808639B0.asm") + this->actor.params = params; + this->mainActionFunc = EnGirlA_InitalUpdate; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80863A10.asm") +void EnGirlA_Init(Actor* thisx, GlobalContext* globalCtx) { + EnGirlA* this = THIS; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80863AAC.asm") + EnGirlA_InitObjIndex(this, globalCtx); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80863B4C.asm") +void EnGirlA_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80863C08.asm") +s32 EnGirlA_CanBuyPotionRed(GlobalContext* globalCtx, EnGirlA* this) { + if (!func_80114E90()) { + return CANBUY_RESULT_NEED_EMPTY_BOTTLE; + } + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + return CANBUY_RESULT_SUCCESS; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80863C6C.asm") +s32 EnGirlA_CanBuyPotionGreen(GlobalContext* globalCtx, EnGirlA* this) { + if (!func_80114E90()) { + return CANBUY_RESULT_NEED_EMPTY_BOTTLE; + } + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + return CANBUY_RESULT_SUCCESS; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80863D28.asm") +s32 EnGirlA_CanBuyPotionBlue(GlobalContext* globalCtx, EnGirlA* this) { + if (!(gSaveContext.weekEventReg[53] & 8)) { + return CANBUY_RESULT_CANT_GET_NOW; + } + if (!func_80114E90()) { + return CANBUY_RESULT_NEED_EMPTY_BOTTLE; + } + if (!(gSaveContext.weekEventReg[53] & 0x10)) { + return CANBUY_RESULT_SUCCESS; + } + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + return CANBUY_RESULT_SUCCESS; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80863D60.asm") +s32 EnGirlA_CanBuyArrows(GlobalContext* globalCtx, EnGirlA* this) { + if (CUR_UPG_VALUE_VOID(UPG_QUIVER) == 0) { + return CANBUY_RESULT_NO_ROOM_2; + } + if (AMMO(ITEM_BOW) >= CUR_CAPACITY(UPG_QUIVER)) { + return CANBUY_RESULT_NO_ROOM_3; + } + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + return CANBUY_RESULT_SUCCESS; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80863DC8.asm") +s32 EnGirlA_CanBuyNuts(GlobalContext* globalCtx, EnGirlA* this) { + if (CUR_CAPACITY(UPG_NUTS) != 0 && AMMO(ITEM_NUT) >= CUR_CAPACITY(UPG_NUTS)) { + return CANBUY_RESULT_NO_ROOM; + } + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + if (func_80114978(ITEM_NUT) == ITEM_NONE) { + return CANBUY_RESULT_SUCCESS_FANFARE; + } + return CANBUY_RESULT_SUCCESS; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80863E48.asm") +s32 EnGirlA_CanBuyShieldHero(GlobalContext* globalCtx, EnGirlA* this) { + if (CUR_EQUIP_VALUE_VOID(EQUIP_SHIELD) != 0) { + return CANBUY_RESULT_NO_ROOM; + } + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + return CANBUY_RESULT_SUCCESS_FANFARE; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80863EC8.asm") +s32 EnGirlA_CanBuyStick(GlobalContext* globalCtx, EnGirlA* this) { + if (CUR_CAPACITY(UPG_STICK) != 0 && AMMO(ITEM_STICK) >= CUR_CAPACITY(UPG_STICK)) { + return CANBUY_RESULT_NO_ROOM; + } + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + if (func_80114978(ITEM_STICK) == ITEM_NONE) { + return CANBUY_RESULT_SUCCESS_FANFARE; + } + return CANBUY_RESULT_SUCCESS; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80863F94.asm") +s32 EnGirlA_CanBuyMaskAllNight(GlobalContext* globalCtx, EnGirlA* this) { + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + return CANBUY_RESULT_SUCCESS; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80864034.asm") +s32 EnGirlA_CanBuyBombBagCuriosityShop(GlobalContext* globalCtx, EnGirlA* this) { + if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) >= 2) { + return CANBUY_RESULT_CANT_GET_NOW; + } + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + return CANBUY_RESULT_SUCCESS; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_8086406C.asm") +s32 EnGirlA_CanBuyBombBag20BombShop(GlobalContext* globalCtx, EnGirlA* this) { + if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) == 1) { + return CANBUY_RESULT_ALREADY_HAVE; + } + if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) >= 2) { + return CANBUY_RESULT_HAVE_BETTER; + } + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + return CANBUY_RESULT_SUCCESS_FANFARE; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_808640A4.asm") +s32 EnGirlA_CanBuyBombBag30BombShop(GlobalContext* globalCtx, EnGirlA* this) { + if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) == 2) { + return CANBUY_RESULT_ALREADY_HAVE; + } + if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) == 3) { + return CANBUY_RESULT_HAVE_BETTER; + } + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + return CANBUY_RESULT_SUCCESS_FANFARE; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80864108.asm") +s32 EnGirlA_CanBuyBombchus(GlobalContext* globalCtx, EnGirlA* this) { + if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) == 0) { + return CANBUY_RESULT_CANT_GET_NOW; + } + if (AMMO(ITEM_BOMBCHU) >= CUR_CAPACITY(UPG_BOMB_BAG)) { + return CANBUY_RESULT_NO_ROOM; + } + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + if (func_80114978(ITEM_BOMBCHU) == ITEM_NONE) { + return CANBUY_RESULT_SUCCESS_FANFARE; + } + return CANBUY_RESULT_SUCCESS; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80864168.asm") +s32 EnGirlA_CanBuyBombs(GlobalContext* globalCtx, EnGirlA* this) { + if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) == 0) { + return CANBUY_RESULT_CANT_GET_NOW; + } + if (AMMO(ITEM_BOMB) >= CUR_CAPACITY(UPG_BOMB_BAG)) { + return CANBUY_RESULT_NO_ROOM; + } + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + return CANBUY_RESULT_SUCCESS; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80864210.asm") +s32 EnGirlA_CanBuyBottle(GlobalContext* globalCtx, EnGirlA* this) { + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + return CANBUY_RESULT_SUCCESS_FANFARE; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_8086425C.asm") +s32 EnGirlA_CanBuySword(GlobalContext* globalCtx, EnGirlA* this) { + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + return CANBUY_RESULT_SUCCESS_FANFARE; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_808642D4.asm") +s32 EnGirlA_CanBuyShieldMirror(GlobalContext* globalCtx, EnGirlA* this) { + if (CUR_EQUIP_VALUE_VOID(EQUIP_SHIELD) != 0) { + return CANBUY_RESULT_NO_ROOM; + } + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + return CANBUY_RESULT_SUCCESS_FANFARE; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80864320.asm") +s32 EnGirlA_CanBuyFairy(GlobalContext* globalCtx, EnGirlA* this) { + if (!func_80114E90()) { + return CANBUY_RESULT_NEED_EMPTY_BOTTLE; + } + if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + return CANBUY_RESULT_NEED_RUPEES; + } + return CANBUY_RESULT_SUCCESS; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_8086436C.asm") +void EnGirlA_BuyBottleItem(GlobalContext* globalCtx, EnGirlA* this) { + switch (this->actor.params) { + case 0: + case 10: + case 18: + case 29: + case 32: + case 35: + Item_Give(globalCtx, ITEM_POTION_RED); + break; + case 1: + case 5: + case 14: + Item_Give(globalCtx, ITEM_POTION_GREEN); + break; + case 2: + Item_Give(globalCtx, ITEM_POTION_BLUE); + break; + case 3: + case 11: + Item_Give(globalCtx, ITEM_FAIRY); + break; + } + func_801159EC(-globalCtx->msgCtx.unk1206C); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_808643B8.asm") +void EnGirlA_BuyArrows(GlobalContext* globalCtx, EnGirlA* this) { + func_80115A14(ITEM_BOW, this->itemParams); + func_801159EC(-globalCtx->msgCtx.unk1206C); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_8086444C.asm") +void EnGirlA_BuyNuts(GlobalContext* globalCtx, EnGirlA* this) { + switch (this->itemParams) { + case 5: + Item_Give(globalCtx, ITEM_NUTS_5); + break; + case 10: + Item_Give(globalCtx, ITEM_NUTS_10); + break; + } + func_801159EC(-globalCtx->msgCtx.unk1206C); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_808644A4.asm") +void EnGirlA_BuyShieldHero(GlobalContext* globalCtx, EnGirlA* this) { + Item_Give(globalCtx, ITEM_SHIELD_HERO); + func_801159EC(-globalCtx->msgCtx.unk1206C); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80864558.asm") +void EnGirlA_BuyStick(GlobalContext* globalCtx, EnGirlA* this) { + Item_Give(globalCtx, ITEM_STICK); + func_801159EC(-globalCtx->msgCtx.unk1206C); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_808645A4.asm") +void EnGirlA_BuyMaskAllNight(GlobalContext* globalCtx, EnGirlA* this) { + Item_Give(globalCtx, ITEM_MASK_ALL_NIGHT); + func_801159EC(-globalCtx->msgCtx.unk1206C); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80864658.asm") +void EnGirlA_BuyBombBag(GlobalContext* globalCtx, EnGirlA* this) { + //! @bug: Bomb Bag parameters in sShopItemEntries are 1 2 3, not 20 21 22 + switch (this->itemParams) { + case 20: + Item_Give(globalCtx, ITEM_BOMB_BAG_20); + break; + case 21: + Item_Give(globalCtx, ITEM_BOMB_BAG_30); + break; + case 22: + Item_Give(globalCtx, ITEM_BOMB_BAG_40); + break; + } + func_801159EC(-globalCtx->msgCtx.unk1206C); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_808646A4.asm") +void EnGirlA_BuyBombchus(GlobalContext* globalCtx, EnGirlA* this) { + if (this->itemParams == 10) { + Item_Give(globalCtx, ITEM_BOMBCHUS_10); + } + func_801159EC(-globalCtx->msgCtx.unk1206C); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_808646E4.asm") +void EnGirlA_BuyBombs(GlobalContext* globalCtx, EnGirlA* this) { + switch (this->itemParams) { + case 5: + Item_Give(globalCtx, ITEM_BOMBS_5); + break; + case 10: + Item_Give(globalCtx, ITEM_BOMBS_10); + break; + case 20: + Item_Give(globalCtx, ITEM_BOMBS_20); + break; + case 30: + Item_Give(globalCtx, ITEM_BOMBS_30); + break; + } + func_801159EC(-globalCtx->msgCtx.unk1206C); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_808646F4.asm") +void EnGirlA_BuyBottle(GlobalContext* globalCtx, EnGirlA* this) { + Item_Give(globalCtx, ITEM_BOTTLE); + func_801159EC(-globalCtx->msgCtx.unk1206C); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_8086472C.asm") +void EnGirlA_BuySword(GlobalContext* globalCtx, EnGirlA* this) { + switch (this->itemParams) { + case 1: + Item_Give(globalCtx, ITEM_SWORD_KOKIRI); + break; + case 2: + Item_Give(globalCtx, ITEM_SWORD_RAZOR); + break; + case 3: + Item_Give(globalCtx, ITEM_SWORD_GILDED); + break; + case 4: + Item_Give(globalCtx, ITEM_SWORD_GREAT_FAIRY); + break; + } + func_801159EC(-globalCtx->msgCtx.unk1206C); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80864744.asm") +void EnGirlA_BuyShieldMirror(GlobalContext* globalCtx, EnGirlA* this) { + Item_Give(globalCtx, ITEM_SHIELD_MIRROR); + func_801159EC(-globalCtx->msgCtx.unk1206C); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80864760.asm") +// Fanfare is handled by ovl_en_ossan +void EnGirlA_BuyFanfare(GlobalContext* globalCtx, EnGirlA* this) { + func_801159EC(-globalCtx->msgCtx.unk1206C); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_80864774.asm") +void EnGirlA_DoNothing(EnGirlA* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_808648F8.asm") +void EnGirlA_InitItem(GlobalContext* globalCtx, EnGirlA* this) { + ShopItemEntry* shopItem = &sShopItemEntries[this->actor.params]; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/EnGirlA_Update.asm") + this->actor.textId = shopItem->descriptionTextId; + this->isOutOfStock = false; + this->actor.draw = EnGirlA_Draw; +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_GirlA_0x80863870/func_808649C8.asm") +void EnGirlA_Bought(GlobalContext* globalCtx, EnGirlA* this) { + this->isOutOfStock = true; + this->actor.draw = NULL; +} + +void EnGirlA_Restock(GlobalContext* globalCtx, EnGirlA* this) { + this->isOutOfStock = false; + this->actor.draw = EnGirlA_Draw; +} + +// Left over from OOT +s32 EnGirlA_TrySetMaskItemDescription(EnGirlA* this, GlobalContext* globalCtx) { + return false; +} + +void EnGirlA_InitalUpdate(EnGirlA* this, GlobalContext* globalCtx) { + s16 params = this->actor.params; + ShopItemEntry* shopItem = &sShopItemEntries[params]; + + if (Object_IsLoaded(&globalCtx->objectCtx, this->objIndex)) { + this->actor.flags &= ~0x10; + this->actor.objBankIndex = this->objIndex; + this->actor.textId = shopItem->descriptionTextId; + this->choiceTextId = shopItem->choiceTextId; + + // EnGirlA_TrySetMaskItemDescription always returns false + if (!EnGirlA_TrySetMaskItemDescription(this, globalCtx)) { + EnGirlA_InitItem(globalCtx, this); + } + + this->boughtFunc = EnGirlA_Bought; + this->restockFunc = EnGirlA_Restock; + this->getItemId = shopItem->getItemId; + this->canBuyFunc = shopItem->canBuyFunc; + this->buyFunc = shopItem->buyFunc; + this->buyFanfareFunc = shopItem->buyFanfareFunc; + this->unk1C0 = 0; + this->itemParams = shopItem->params; + this->drawFunc = shopItem->drawFunc; + this->getItemDrawId = shopItem->getItemDrawId; + this->actor.flags &= ~1; + Actor_SetScale(&this->actor, 0.25f); + this->actor.shape.yOffset = 24.0f; + this->actor.shape.shadowScale = 4.0f; + this->actor.floorHeight = this->actor.home.pos.y; + this->actor.gravity = 0.0f; + EnGirlA_SetupAction(this, EnGirlA_DoNothing); + this->isInitialized = true; + this->mainActionFunc = EnGirlA_Update2; + this->isSelected = false; + this->rotY = 0; + this->initialRotY = this->actor.shape.rot.y; + } +} + +void EnGirlA_Update2(EnGirlA* this, GlobalContext* globalCtx) { + Actor_SetScale(&this->actor, 0.25f); + this->actor.shape.yOffset = 24.0f; + this->actor.shape.shadowScale = 4.0f; + EnGirlA_TrySetMaskItemDescription(this, globalCtx); + this->actionFunc(this, globalCtx); + Actor_SetHeight(&this->actor, 5.0f); + this->actor.shape.rot.x = 0; + if (this->isSelected) { + this->rotY += 0x1F4; + } else { + Math_SmoothStepToS(&this->rotY, 0, 0xA, 0x7D0, 0); + } +} + +void EnGirlA_Update(Actor* thisx, GlobalContext* globalCtx) { + EnGirlA* this = THIS; + + this->mainActionFunc(this, globalCtx); +} + +void EnGirlA_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnGirlA* this = THIS; + + Matrix_RotateY(this->rotY, MTXMODE_APPLY); + if (this->drawFunc != NULL) { + this->drawFunc(&this->actor, globalCtx, 0); + } + GetItem_Draw(globalCtx, this->getItemDrawId); +} diff --git a/src/overlays/actors/ovl_En_GirlA/z_en_girla.h b/src/overlays/actors/ovl_En_GirlA/z_en_girla.h index fc3dce21bd..b4ad8ba70e 100644 --- a/src/overlays/actors/ovl_En_GirlA/z_en_girla.h +++ b/src/overlays/actors/ovl_En_GirlA/z_en_girla.h @@ -5,11 +5,61 @@ struct EnGirlA; +typedef void (*EnGirlAActionFunc)(struct EnGirlA*, GlobalContext*); +typedef void (*EnGirlADrawFunc)(struct Actor*, GlobalContext*, s32); +typedef s32 (*EnGirlACanBuyFunc)(GlobalContext*, struct EnGirlA*); +typedef void (*EnGirlAShopActionFunc)(GlobalContext*, struct EnGirlA*); // Buying/Restocking + +typedef struct ShopItemEntry { + /* 0x00 */ s16 objectId; + /* 0x02 */ s16 getItemDrawId; + /* 0x04 */ EnGirlADrawFunc drawFunc; + /* 0x08 */ s16 params; + /* 0x0A */ u16 descriptionTextId; + /* 0x0C */ u16 choiceTextId; + /* 0x10 */ s32 getItemId; + /* 0x14 */ EnGirlACanBuyFunc canBuyFunc; + /* 0x18 */ EnGirlAShopActionFunc buyFunc; + /* 0x1C */ EnGirlAShopActionFunc buyFanfareFunc; +} ShopItemEntry; // size = 0x20 + typedef struct EnGirlA { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x88]; + /* 0x144 */ char unk144[0x44]; + /* 0x188 */ EnGirlAActionFunc actionFunc; + /* 0x18C */ s8 objIndex; + /* 0x190 */ EnGirlAActionFunc mainActionFunc; + /* 0x194 */ s32 isInitialized; + /* 0x198 */ u16 choiceTextId; + /* 0x19C */ s32 getItemId; + /* 0x1A0 */ s16 isOutOfStock; + /* 0x1A4 */ EnGirlAShopActionFunc boughtFunc; + /* 0x1A8 */ EnGirlAShopActionFunc restockFunc; + /* 0x1AC */ s16 isSelected; + /* 0x1AE */ s16 initialRotY; + /* 0x1B0 */ s16 rotY; + /* 0x1B4 */ EnGirlACanBuyFunc canBuyFunc; + /* 0x1B8 */ EnGirlAShopActionFunc buyFunc; + /* 0x1BC */ EnGirlAShopActionFunc buyFanfareFunc; + /* 0x1C0 */ s16 unk1C0; + /* 0x1C2 */ s16 itemParams; + /* 0x1C4 */ s16 getItemDrawId; + /* 0x1C8 */ EnGirlADrawFunc drawFunc; } EnGirlA; // size = 0x1CC +typedef enum { + /* 0 */ CANBUY_RESULT_SUCCESS_FANFARE, + /* 1 */ CANBUY_RESULT_SUCCESS, + /* 2 */ CANBUY_RESULT_NO_ROOM, + /* 3 */ CANBUY_RESULT_NEED_EMPTY_BOTTLE, + /* 4 */ CANBUY_RESULT_NEED_RUPEES, + /* 5 */ CANBUY_RESULT_CANT_GET_NOW, + /* 6 */ CANBUY_RESULT_NO_ROOM_2, + /* 7 */ CANBUY_RESULT_NO_ROOM_3, + /* 8 */ CANBUY_RESULT_ALREADY_HAVE, + /* 9 */ CANBUY_RESULT_HAVE_BETTER +} EnGirlACanBuyResult; + extern const ActorInit En_GirlA_InitVars; #endif // Z_EN_GIRLA_H diff --git a/src/overlays/actors/ovl_En_In/z_en_in.c b/src/overlays/actors/ovl_En_In/z_en_in.c index 7432e5b424..ff4d06f9b4 100644 --- a/src/overlays/actors/ovl_En_In/z_en_in.c +++ b/src/overlays/actors/ovl_En_In/z_en_in.c @@ -894,7 +894,7 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { case 0x347A: func_808F30B0(&this->skelAnime, 1); func_808F30B0(&this->unk4A4->skelAnime, 7); - if (gSaveContext.inventory.items[gItemSlots[59]] == 59) { + if (INV_CONTENT(ITEM_MASK_GARO) == ITEM_MASK_GARO) { func_800E8EA0(globalCtx, &this->actor, 0x347E); ret = false; } else { @@ -1085,7 +1085,7 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { case 0x349D: func_808F30B0(&this->skelAnime, 1); func_808F30B0(&this->unk4A4->skelAnime, 7); - if (gSaveContext.inventory.items[gItemSlots[59]] == 59) { + if (INV_CONTENT(ITEM_MASK_GARO) == ITEM_MASK_GARO) { func_800E8EA0(globalCtx, &this->actor, 0x34A1); ret = false; } else { diff --git a/tables/functions.txt b/tables/functions.txt index 1060406472..c20d46b6d0 100644 --- a/tables/functions.txt +++ b/tables/functions.txt @@ -4908,49 +4908,49 @@ 0x8086333C:("EnTest_Update",), 0x808634B8:("func_808634B8",), 0x808636A8:("EnTest_Draw",), - 0x80863870:("func_80863870",), - 0x8086387C:("func_8086387C",), + 0x80863870:("EnGirlA_SetupAction",), + 0x8086387C:("EnGirlA_InitObjIndex",), 0x80863920:("EnGirlA_Init",), 0x80863940:("EnGirlA_Destroy",), - 0x80863950:("func_80863950",), - 0x808639B0:("func_808639B0",), - 0x80863A10:("func_80863A10",), - 0x80863AAC:("func_80863AAC",), - 0x80863B4C:("func_80863B4C",), - 0x80863C08:("func_80863C08",), - 0x80863C6C:("func_80863C6C",), - 0x80863D28:("func_80863D28",), - 0x80863D60:("func_80863D60",), - 0x80863DC8:("func_80863DC8",), - 0x80863E48:("func_80863E48",), - 0x80863EC8:("func_80863EC8",), - 0x80863F94:("func_80863F94",), - 0x80864034:("func_80864034",), - 0x8086406C:("func_8086406C",), - 0x808640A4:("func_808640A4",), - 0x80864108:("func_80864108",), - 0x80864168:("func_80864168",), - 0x80864210:("func_80864210",), - 0x8086425C:("func_8086425C",), - 0x808642D4:("func_808642D4",), - 0x80864320:("func_80864320",), - 0x8086436C:("func_8086436C",), - 0x808643B8:("func_808643B8",), - 0x8086444C:("func_8086444C",), - 0x808644A4:("func_808644A4",), - 0x80864558:("func_80864558",), - 0x808645A4:("func_808645A4",), - 0x80864658:("func_80864658",), - 0x808646A4:("func_808646A4",), - 0x808646E4:("func_808646E4",), - 0x808646F4:("func_808646F4",), - 0x8086472C:("func_8086472C",), - 0x80864744:("func_80864744",), - 0x80864760:("func_80864760",), - 0x80864774:("func_80864774",), - 0x808648F8:("func_808648F8",), + 0x80863950:("EnGirlA_CanBuyPotionRed",), + 0x808639B0:("EnGirlA_CanBuyPotionGreen",), + 0x80863A10:("EnGirlA_CanBuyPotionBlue",), + 0x80863AAC:("EnGirlA_CanBuyArrows",), + 0x80863B4C:("EnGirlA_CanBuyNuts",), + 0x80863C08:("EnGirlA_CanBuyShieldHero",), + 0x80863C6C:("EnGirlA_CanBuyStick",), + 0x80863D28:("EnGirlA_CanBuyMaskAllNight",), + 0x80863D60:("EnGirlA_CanBuyBombBagCuriosityShop",), + 0x80863DC8:("EnGirlA_CanBuyBombBag20BombShop",), + 0x80863E48:("EnGirlA_CanBuyBombBag30BombShop",), + 0x80863EC8:("EnGirlA_CanBuyBombchus",), + 0x80863F94:("EnGirlA_CanBuyBombs",), + 0x80864034:("EnGirlA_CanBuyBottle",), + 0x8086406C:("EnGirlA_CanBuySword",), + 0x808640A4:("EnGirlA_CanBuyShieldMirror",), + 0x80864108:("EnGirlA_CanBuyFairy",), + 0x80864168:("EnGirlA_BuyBottleItem",), + 0x80864210:("EnGirlA_BuyArrows",), + 0x8086425C:("EnGirlA_BuyNuts",), + 0x808642D4:("EnGirlA_BuyShieldHero",), + 0x80864320:("EnGirlA_BuyStick",), + 0x8086436C:("EnGirlA_BuyMaskAllNight",), + 0x808643B8:("EnGirlA_BuyBombBag",), + 0x8086444C:("EnGirlA_BuyBombchus",), + 0x808644A4:("EnGirlA_BuyBombs",), + 0x80864558:("EnGirlA_BuyBottle",), + 0x808645A4:("EnGirlA_BuySword",), + 0x80864658:("EnGirlA_BuyShieldMirror",), + 0x808646A4:("EnGirlA_BuyFanfare",), + 0x808646E4:("EnGirlA_DoNothing",), + 0x808646F4:("EnGirlA_InitItem",), + 0x8086472C:("EnGirlA_Bought",), + 0x80864744:("EnGirlA_Restock",), + 0x80864760:("EnGirlA_TrySetMaskItemDescription",), + 0x80864774:("EnGirlA_InitalUpdate",), + 0x808648F8:("EnGirlA_Update2",), 0x808649A4:("EnGirlA_Update",), - 0x808649C8:("func_808649C8",), + 0x808649C8:("EnGirlA_Draw",), 0x80865370:("EnPart_Init",), 0x80865380:("EnPart_Destroy",), 0x80865390:("func_80865390",),