Skip to content

Commit

Permalink
More decomp actor work (#36)
Browse files Browse the repository at this point in the history
* More decomp actor work.

* Formatting fixes.

Fix refill bottle logic to ensure we give a refill when requested.

* Finalize bottle logic to not give the refill if user does not have an empty bottle.

* Update to get Ingo bros to not give rewards after the first time. Same with medigoron and powder kegs.
  • Loading branch information
PhlexPlexico committed Mar 10, 2024
1 parent 9bf63d4 commit 5746138
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 84 deletions.
26 changes: 16 additions & 10 deletions code/include/game/actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,21 @@ namespace game::act {
};
static_assert(sizeof(PosRot) == 0x14);

using ActorShadowFunc = void(Actor* self, void* lightMapper, GlobalContext* gctx);
struct ActorShape {
z3dVec3s rot;
s16 face;
float y_offset;
ActorShadowFunc* shadow_draw;
float shadow_scale;
u8 shadow_alpha;
u8 feet_floor_flags;
u8 field_16;
u8 field_17;
z3dVec3f feet_pos[2];
};
static_assert(sizeof(ActorShape) == 0x30);

struct Actor {
enum class Flag : u32 {
Targetable = 0x1,
Expand Down Expand Up @@ -259,16 +274,7 @@ namespace game::act {
DamageType damage_type;
u8 field_BE;
u8 field_BF;
// u16 field_C0;
// u16 angle;
z3dVec3s angle;
// u16 field_C4;
u8 gap_C6[2];
float field_C8;
u32 field_CC;
float field_D0;
u8 field_D4;
u8 gap_D5[27];
ActorShape actor_shape;
z3dVec3f field_F0;
u32 field_FC;
z3dVec3f field_100;
Expand Down
3 changes: 2 additions & 1 deletion code/include/rnd/savefile.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ namespace rnd {
BitField<43, 1, u64> bottleChateuGiven;
BitField<44, 1, u64> bottleRedPotionGiven;
BitField<45, 2, u64> progressiveSwordUpgrade;
BitField<46, 18, u64> unused;
BitField<46, 1, u64> enInMysteryMilkGiven;
BitField<45, 17, u64> unused;
};
GivenItemRegister givenItemChecks;
union FairyCollectRegister {
Expand Down
100 changes: 50 additions & 50 deletions code/mm.ld
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ SECTIONS{
*(.patch_Gfx_Update)
}

.patch_FixSurroundSound 0x1404E8 : {
*(.patch_FixSurroundSound)
}

.patch_RemoveCouplesMaskMessage 0x1867C4 : {
*(.patch_RemoveCouplesMaskMessage)
}

.patch_RemoveSOHCutesceneAfterMessage 0x186810 : {
*(.patch_RemoveSOHCutesceneAfterMessage)
}
Expand Down Expand Up @@ -67,9 +75,17 @@ SECTIONS{
*(.patch_RemoveMysteryMilkTimer)
}

.patch_GetCustomText 0x1BDE78 : {
*(.patch_GetCustomText)
}

.patch_DoNotResetTempleFlags 0x1C936C : {
*(.patch_DoNotResetTempleFlags)
}
}

.patch_DoNotResetPermFlags 0x1C9348 : {
*(.patch_DoNotResetPermFlags)
}

.patch_DoNotRemoveTradeItems 0x1c9aa8 : {
*(.patch_DoNotRemoveTradeItems)
Expand All @@ -95,10 +111,22 @@ SECTIONS{
*(.patch_RemoveSwordFlagsOnReset)
}

.patch_OverrideBomberTextID 0x1D2764 : {
*(.patch_OverrideBomberTextID)
}

.patch_ISGCrouchStabOne 0x1D32E0 : {
*(.patch_ISGCrouchStabOne)
}

.patch_RemoveDekuMaskCheckSoT 0x1D8008 : {
*(.patch_RemoveDekuMaskCheckSoT)
}

.patch_RemoveMysteryMilkSoSCheck 0x1D79F8 : {
*(.patch_RemoveMysteryMilkSoSCheck)
}

.patch_DoNotForceMaskChange 0x1DB314 : {
*(.patch_DoNotForceMaskChange)
}
Expand All @@ -107,10 +135,18 @@ SECTIONS{
*(.patch_HandleFastMaskTransforms)
}

.patch_ISGCrouchStabTwo 0x1DBEA4 : {
*(.patch_ISGCrouchStabTwo)
}

.patch_RemoveMysteryMilkUsabilityCheck 0x1E04D8 : {
*(.patch_RemoveMysteryMilkUsabilityCheck)
}

.patch_OcarinaDive 0x1E1F0C : {
*(.patch_OcarinaDive)
}

.patch_ByPassMaskEquipmentChecks 0x1E770C : {
*(.patch_ByPassMaskEquipmentChecks)
}
Expand Down Expand Up @@ -167,6 +203,18 @@ SECTIONS{
*(.patch_ZoraBarrierCheckMagicAcquired)
}

.patch_RemoveRSHealthOne 0x20826C : {
*(.patch_RemoveRazordSwordHealth)
}

.patch_RemoveRSHealthTwo 0x20843C : {
*(.patch_RemoveRazordSwordHealthTwo)
}

.patch_OverrideItemIdIndex 0x21D124 : {
*(.patch_OverrideItemIdIndex)
}

.patch_ChangeTriggerAandRToA 0x220EFC : {
*(.patch_ChangeTriggerAandRToA)
}
Expand Down Expand Up @@ -199,54 +247,10 @@ SECTIONS{
*(.patch_DisableMilkTimer)
}

.patch_FixSurroundSound 0x1404E8 : {
*(.patch_FixSurroundSound)
}

.patch_DoNotResetPermFlags 0x1C9348 : {
*(.patch_DoNotResetPermFlags)
}

.patch_OcarinaDive 0x1E1F0C : {
*(.patch_OcarinaDive)
}

.patch_GetCustomText 0x1BDE78 : {
*(.patch_GetCustomText)
}

.patch_OverrideBomberTextID 0x1D2764 : {
*(.patch_OverrideBomberTextID)
}

.patch_ISGCrouchStabOne 0x1D32E0 : {
*(.patch_ISGCrouchStabOne)
}

.patch_RemoveMysteryMilkSoSCheck 0x1D79F8 : {
*(.patch_RemoveMysteryMilkSoSCheck)
}

.patch_ISGCrouchStabTwo 0x1DBEA4 : {
*(.patch_ISGCrouchStabTwo)
}

.patch_RemoveRSHealthOne 0x20826C : {
*(.patch_RemoveRazordSwordHealth)
}

.patch_RemoveRSHealthTwo 0x20843C : {
*(.patch_RemoveRazordSwordHealthTwo)
}

.patch_RemoveRSHealthThree 0x235800 : {
*(.patch_RemoveRazordSwordHealthThree)
}

.patch_OverrideItemIdIndex 0x21d124 : {
*(.patch_OverrideItemIdIndex)
}

.patch_RemoveRemainsStateCheck 0x22B7BC : {
*(.patch_RemoveRemainsStateCheck)
}
Expand All @@ -267,7 +271,7 @@ SECTIONS{
*(.patch_OverrideItemID)
}

.patch_EnteringLocation 0x23aa54 : {
.patch_EnteringLocation 0x23AA54 : {
*(.patch_EnteringLocation)
}

Expand Down Expand Up @@ -398,10 +402,6 @@ SECTIONS{
.patch_GibdoMaskGiveItem 0x41DC48 : {
*(.patch_GibdoMaskGiveItem)
}
/*0x46E228*/
.patch_RemoveCouplesMaskMessage 0x1867C4 : {
*(.patch_RemoveCouplesMaskMessage)
}

.patch_OverrideBankerWalletReward 0x459044 : {
*(.patch_OverrideProgessiveWalletTwo)
Expand Down
90 changes: 71 additions & 19 deletions code/source/rnd/item_override.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ namespace rnd {
rItemOverrides[0].value.looksLikeItemId = 0x26;
rItemOverrides[1].key.scene = 0x6F;
rItemOverrides[1].key.type = ItemOverride_Type::OVR_COLLECTABLE;
rItemOverrides[1].value.getItemId = 0x01;
rItemOverrides[1].value.looksLikeItemId = 0x01;
rItemOverrides[1].value.getItemId = 0x0C;
rItemOverrides[1].value.looksLikeItemId = 0x0C;
rItemOverrides[2].key.scene = 0x12;
rItemOverrides[2].key.type = ItemOverride_Type::OVR_COLLECTABLE;
rItemOverrides[2].value.getItemId = 0x37;
Expand Down Expand Up @@ -452,6 +452,8 @@ namespace rnd {
gExtSaveData.givenItemChecks.bgDyYoseizoGivenItem = 1;
} else if (storedActorId == game::act::Id::EnIn && storedGetItemId == GetItemID::GI_MASK_GARO) {
gExtSaveData.givenItemChecks.enInGivenItem = 1;
} else if (storedActorId == game::act::Id::EnIn && storedGetItemId == GetItemID::GI_BOTTLE_MYSTERY_MILK) {
gExtSaveData.givenItemChecks.enInMysteryMilkGiven = 1;
} else if (storedActorId == game::act::Id::EnHs) {
gExtSaveData.givenItemChecks.enHsGivenItem = 1;
} else if (storedActorId == game::act::Id::EnHgo) {
Expand Down Expand Up @@ -500,6 +502,8 @@ namespace rnd {
gExtSaveData.givenItemChecks.bottleChateuGiven = 1;
} else if (storedGetItemId == GetItemID::GI_BOTTLE_SEAHORSE) {
gExtSaveData.givenItemChecks.bottleSeahorseGiven = 1;
} else if (storedGetItemId == GetItemID::GI_BOTTLE_POTION_RED) {
gExtSaveData.givenItemChecks.bottleRedPotionGiven = 1;
}
}

Expand Down Expand Up @@ -585,6 +589,12 @@ namespace rnd {
return 0x00;
}

bool ItemOverride_IsItemObtained(ItemOverride override) {
ItemRow* itemToBeGiven = ItemTable_GetItemRow(override.value.getItemId);
return (game::HasMask((game::ItemId)itemToBeGiven->itemId) || game::HasItem((game::ItemId)itemToBeGiven->itemId) ||
(itemToBeGiven->itemId > 0x49 && itemToBeGiven->itemId < 0x9E));
}

extern "C" {
bool ItemOverride_CheckAromaGivenItem() {
if (gExtSaveData.givenItemChecks.enAlGivenItem > 0)
Expand Down Expand Up @@ -612,8 +622,8 @@ namespace rnd {
rnd::util::Print("%s: Active item row item ID is %#04x and key flag is %#04x\n", __func__,
rActiveItemRow->itemId, rActiveItemOverride.key.flag);
#endif
// Only set if we're not a trade item or bottled item.
if ((rActiveItemRow->itemId < 0x12 || rActiveItemRow->itemId > 0x30) && (rActiveItemRow->itemId < 0x9F)) {
// Only set if we're not a trade item.
if ((rActiveItemRow->itemId < 0x28 || rActiveItemRow->itemId > 0x30) && (rActiveItemRow->itemId < 0x9F)) {
gExtSaveData.chestRewarded[rActiveItemOverride.key.scene][rActiveItemOverride.key.flag] = 1;
}
}
Expand Down Expand Up @@ -651,7 +661,7 @@ namespace rnd {
if (override.key.all != 0) {
// Override the stored get item if we are a bottled item.
if (override.value.getItemId == 0x59 || override.value.getItemId == 0x60 || override.value.getItemId == 0x6A ||
override.value.getItemId == 0x6E || override.value.getItemId == 0x6F || override.value.getItemId == 0x70) {
override.value.getItemId == 0x6E || override.value.getItemId == 0x6F) {
storedGetItemId = (GetItemID) override.value.getItemId;
}
}
Expand All @@ -666,19 +676,55 @@ namespace rnd {
// Override was already given, check to see if the item exists in inventory, if it does
// then we give a blue rupee. Only check for inventory items. If an item is a heart piece
// do not give multiples.
// Only do this for items that are not bottle refills.
// Bottle logic is taken care of in the ItemUpgrade function for each bottle.
ItemRow* itemToBeGiven = ItemTable_GetItemRow(override.value.getItemId);
if (game::HasMask((game::ItemId)itemToBeGiven->itemId) || game::HasItem((game::ItemId)itemToBeGiven->itemId) ||
itemToBeGiven->itemId > 0x49) {
if (ItemOverride_IsItemObtained(override)) {
// Do a secondary check as well for bottled items, and check to see if we have an empty bottle in our inventory.
// If we don't, then do not give the item as we don't want to override items in users inventories.
override.value.getItemId = 0x02;
override.value.looksLikeItemId = 0x02;
} else if (override.value.getItemId == 0x59 || override.value.getItemId == 0x60 ||
override.value.getItemId == 0x6A || override.value.getItemId == 0x6E ||
override.value.getItemId == 0x6F) {
switch (override.value.getItemId) {
case 0x59:
if (gExtSaveData.givenItemChecks.bottleRedPotionGiven == 1 && !game::HasBottle(game::ItemId::Bottle)) {
override.value.getItemId = 0x02;
override.value.looksLikeItemId = 0x02;
}
break;
case 0x60:
if (gExtSaveData.givenItemChecks.bottleMilkGiven == 1 && !game::HasBottle(game::ItemId::Bottle)) {
override.value.getItemId = 0x02;
override.value.looksLikeItemId = 0x02;
}
break;
case 0x6A:
if (gExtSaveData.givenItemChecks.bottleGoldDustGiven == 1 && !game::HasBottle(game::ItemId::Bottle)) {
override.value.getItemId = 0x02;
override.value.looksLikeItemId = 0x02;
}
break;
case 0x6E:
if (gExtSaveData.givenItemChecks.bottleSeahorseGiven == 1 && !game::HasBottle(game::ItemId::Bottle)) {
override.value.getItemId = 0x02;
override.value.looksLikeItemId = 0x02;
}
break;
case 0x6F:
if (gExtSaveData.givenItemChecks.bottleChateuGiven == 1 && !game::HasBottle(game::ItemId::Bottle)) {
override.value.getItemId = 0x02;
override.value.looksLikeItemId = 0x02;
}
break;
default:
break;
}
}
}

// This check is mainly to ensure we do not have repeatable progressive items within these base items.
// This is to ensure fairness and allows us to place these items without second guessing in logic.
// Let's be a bit rude and give them fishing passes.
// XXX: This may be simplified with the IsItemObtained checks as well.
if (override.value.getItemId > 0x45 || override.value.getItemId < 0x4A) {
if (incomingGetItemId == (s16)GetItemID::GI_MOONS_TEAR &&
gExtSaveData.givenItemChecks.enObjMoonStoneGivenItem == 1) {
Expand Down Expand Up @@ -707,7 +753,20 @@ namespace rnd {
return;
}
}

if (incomingGetItemId == 0x70 || incomingGetItemId == 0x94) {
// If we've completed the milk quest, make sure we're not a heart piece
// or any way to cheese the game.
if (gExtSaveData.givenItemChecks.enInMysteryMilkGiven == 1 && ItemOverride_IsItemObtained(override)) {
override.value.getItemId = 0x02;
override.value.looksLikeItemId = 0x02;
}
} else if (incomingGetItemId == (s16)GetItemID::GI_POWDER_KEG &&
(gctx->scene == game::SceneId::GoronVillageWinter || gctx->scene == game::SceneId::GoronVillageSpring) &&
gExtSaveData.givenItemChecks.enGoGivenItem == 1) {
// Also check if we are not the powder keg area as to avoid getting multiple items.
override.value.getItemId = 0x02;
override.value.looksLikeItemId = 0x02;
}
ItemOverride_Activate(override);
s16 baseItemId = rActiveItemRow->baseItemId;

Expand Down Expand Up @@ -762,7 +821,7 @@ namespace rnd {
void ItemOverride_GetSoHItem(game::GlobalContext* gctx, game::act::Actor* fromActor, s16 incomingItemId) {
game::act::Player* link = gctx->GetPlayerActor();
// Run only once. Once the get item is assigned, we shouldn't have to worry about running it again.
// This is mainly prevalent when the item override is in a calc function (Anju).
// This is mainly prevalent when the item override is in a calc function (Anju & Kafei).
if (link->get_item_id != 0x00)
return;
if (incomingItemId == 0x7A) {
Expand Down Expand Up @@ -855,7 +914,6 @@ namespace rnd {
if (gctx->scene == game::SceneId::GoronVillageWinter || gctx->scene == game::SceneId::GoronVillageSpring) {
return givenItems.enGoGivenItem ? (int) currentItem
: (int)0xFF;

}

return game::HasItem((game::ItemId)currentItem) ? (int) currentItem
Expand Down Expand Up @@ -936,11 +994,5 @@ namespace rnd {
u32 ItemOverride_GetOshExtData() {
return (u32)gExtSaveData.givenItemChecks.enOshGivenItem;
}

void DebugStatement(game::ItemId curItemSlot) {
#if defined ENABLE_DEBUG || defined DEBUG_PRINT
rnd::util::Print("%s: Current item slot is %#04x\n", __func__, curItemSlot);
#endif
}
}
} // namespace rnd
Loading

0 comments on commit 5746138

Please sign in to comment.