Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Fishing Hints #733

Merged
merged 4 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions code/include/z3D/z3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -536,13 +536,15 @@ typedef struct GameState {
/* 0x04 */ void (*main)(struct GameState*);
/* 0x08 */ void (*destroy)(struct GameState*); // "cleanup"
/* 0x0C */ void (*init)(struct GameState*);
// TODO
/* 0x10 */ u32 size;
/* 0x14 */ char unk_14[0xED];
/* 0x101*/ u8 running;
} GameState;
_Static_assert(sizeof(GameState) == 0x104, "GameState size");

// Global Context (ram start: 0871E840)
typedef struct GlobalContext {
// /* 0x0000 */ GameState state;
/* 0x0000 */ char unk_0[0x0104];
/* 0x0000 */ GameState state;
/* 0x0104 */ s16 sceneNum;
/* 0x0106 */ char unk_106[0x0012];
/* 0x0118 */ SubGlobalContext_118 sub118;
Expand Down
5 changes: 5 additions & 0 deletions code/src/actor.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#include "shabom.h"
#include "anubis.h"
#include "link_puppet.h"
#include "fishing.h"

#define OBJECT_GI_KEY 170
#define OBJECT_GI_BOSSKEY 185
Expand Down Expand Up @@ -154,6 +155,10 @@ void Actor_Init() {
gActorOverlayTable[0xF1].initInfo->destroy = ItemOcarina_rDestroy;
gActorOverlayTable[0xF1].initInfo->draw = ItemOcarina_rDraw;

gActorOverlayTable[0xFE].initInfo->init = Fishing_rInit;
gActorOverlayTable[0xFE].initInfo->update = Fishing_rUpdateFish;
gActorOverlayTable[0xFE].initInfo->draw = Fishing_rDrawFish;

gActorOverlayTable[0xFF].initInfo->update = ObjOshihiki_rUpdate;

gActorOverlayTable[0x104].initInfo->init = BgSpot01Idomizu_rInit;
Expand Down
35 changes: 35 additions & 0 deletions code/src/fishing.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,40 @@
#include "z3D/z3D.h"
#include "fishing.h"
#include "models.h"
#include "settings.h"

u32 isFishing(void) {
return gSaveContext.equips.buttonItems[0] == ITEM_FISHING_POLE && gGlobalContext->sceneNum == 73;
}

static s32 rewardObtained(void) {
u8 obtainedRewardFlag = gSaveContext.linkAge == AGE_ADULT ? 0x8 : 0x4;
return gSaveContext.fishingStats.flags & obtainedRewardFlag;
}

void Fishing_rInit(Actor* thisx, GlobalContext* globalCtx) {
u16 baseItemId = gSaveContext.linkAge == AGE_ADULT ? GI_SCALE_GOLD : GI_HEART_PIECE;
Fishing_Init(thisx, globalCtx);
if (gSettingsContext.fishingHints && thisx->params == EN_FISH_AQUARIUM && !rewardObtained()) {
Model_SpawnByActor(thisx, globalCtx, baseItemId);
}
}

void Fishing_rUpdateFish(Actor* thisx, GlobalContext* globalCtx) {
Fishing_UpdateFish(thisx, globalCtx);
if (gSettingsContext.fishingHints && thisx->params == EN_FISH_AQUARIUM && !rewardObtained()) {
thisx->textId = 0x40AE; // custom text, overrides vanilla "pond owner" record text
}
}

void Fishing_rDrawFish(Actor* thisx, GlobalContext* globalCtx) {
static s16 sPrizeRotation = 0x8000; // used because shape.rot.y is reset between update cycles

if (gSettingsContext.fishingHints && thisx->params == EN_FISH_AQUARIUM && !rewardObtained()) {
sPrizeRotation += 0x100;
thisx->shape.rot.y = sPrizeRotation;
Model_DrawByActor(thisx);
} else {
Fishing_DrawFish(thisx, globalCtx);
}
}
16 changes: 16 additions & 0 deletions code/src/fishing.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef _FISHING_H_
#define _FISHING_H_

#include "z3D/z3D.h"

#define Fishing_Init ((ActorFunc)GAME_ADDR(0x1C0AD8))
#define Fishing_UpdateFish ((ActorFunc)GAME_ADDR(0x1F9ACC))
#define Fishing_DrawFish ((ActorFunc)GAME_ADDR(0x1F98B4))

#define EN_FISH_AQUARIUM 200 // param for record fish in tank.

void Fishing_rInit(Actor* thisx, GlobalContext* globalCtx);
void Fishing_rUpdateFish(Actor* thisx, GlobalContext* globalCtx);
void Fishing_rDrawFish(Actor* thisx, GlobalContext* globalCtx);

#endif //_FISHING_H_
4 changes: 4 additions & 0 deletions code/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,8 @@ void after_GlobalContext_Update() {
}

Multiplayer_Sync_Update();

if (gGlobalContext->state.running == 0) {
Model_DestroyAll();
}
}
1 change: 1 addition & 0 deletions code/src/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ typedef struct {
u8 sheikHints;
u8 dampeHint;
u8 skulltulaHints;
u8 fishingHints;
u8 compassesShowReward;
u8 compassesShowWotH;
u8 mapsShowDungeonMode;
Expand Down
10 changes: 10 additions & 0 deletions source/custom_messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,16 @@ void CreateAlwaysIncludedMessages() {
};
CreateMessageFromTextObject(0x9003, 0, 2, 3, AddColorsAndFormat(triforceMsg, { QM_RED, QM_RED }));
}

if (Settings::FishingHints) {
Text aquariumText =
Text{ /*english*/ "You can have this if you catch a fish to put in the aquarium.",
/*french */ "Tu peux avoir ce qu'il y a dans cet aquarium si tu pêches un poisson pour le remplacer.",
/*spanish*/ "Puedes tener esto si pescas un pez para ponerlo en el acuario.",
/*italian*/ "Puoi avere questo se catturi un pesce da mettere nell'acquario.",
/*german */ "Das kannst du haben, wenn du einen Fisch für das Aquarium fängst." };
CreateMessageFromTextObject(0x40AE, 0, 2, 3, AddColorsAndFormat(aquariumText, {}));
}
}

std::vector<Text> CreateBaseCompassTexts() {
Expand Down
2 changes: 2 additions & 0 deletions source/descriptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,8 @@ string_view dampeHintDesc = "Reading Dampe's diary will reveal the l
string_view skulltulaHintDesc = "Talking to a cursed House of Skulltula resident\n"//
"will tell you the reward they will give you for\n"//
"removing their curse."; //
string_view fishingHintsDesc = "The aquarium at the fishing pond will show what\n"//
"reward you can win as your current age."; //
/*------------------------------ //
| MAP AND COMPASS GIVES INFO | //
------------------------------*/ //
Expand Down
1 change: 1 addition & 0 deletions source/descriptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ extern string_view totAltarHintsDesc;
extern string_view ganonHintsDesc;
extern string_view dampeHintDesc;
extern string_view skulltulaHintDesc;
extern string_view fishingHintsDesc;

extern string_view compassesShowRewardsDesc;
extern string_view compassesShowWotHDesc;
Expand Down
5 changes: 4 additions & 1 deletion source/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ Option ToTAltarHints = Option::Bool(2, "Temple of Time Altar",{"Off", "On"
Option GanonHints = Option::Bool(2, "Ganondorf", {"Off", "On"}, {ganonHintsDesc});
Option DampeHint = Option::Bool(2, "Dampe's Diary", {"Off", "On"}, {dampeHintDesc});
Option SkulltulaHints = Option::Bool(2, "House of Skulltula", {"Off", "On"}, {skulltulaHintDesc});
Option FishingHints = Option::Bool(2, "Fishing Prizes", {"Off", "On"}, {fishingHintsDesc});
Option ClearerHints = Option::U8 ("Hint Clarity", {"Obscure", "Ambiguous", "Clear"}, {obscureHintsDesc, ambiguousHintsDesc, clearHintsDesc});
Option CompassesShowReward = Option::U8 ("Compasses Show Rewards", {"No", "Yes"}, {compassesShowRewardsDesc});
Option CompassesShowWotH = Option::U8 ("Compasses Show WotH", {"No", "Yes"}, {compassesShowWotHDesc}, OptionCategory::Setting, ON);
Expand All @@ -360,6 +361,7 @@ std::vector<Option *> miscOptions = {
&GanonHints,
&DampeHint,
&SkulltulaHints,
&FishingHints,
&ClearerHints,
&CompassesShowReward,
&CompassesShowWotH,
Expand Down Expand Up @@ -1521,6 +1523,7 @@ SettingsContext FillContext() {
(!StartingLightArrows || (ShuffleMasterSword && !StartingMasterSword)));
ctx.dampeHint = DampeHint ? 1 : 0;
ctx.skulltulaHints = SkulltulaHints ? 1 : 0;
ctx.fishingHints = FishingHints ? 1 : 0;
ctx.compassesShowReward = CompassesShowReward.Value<u8>();
ctx.compassesShowWotH = CompassesShowWotH.Value<u8>();
ctx.mapsShowDungeonMode = MapsShowDungeonMode.Value<u8>();
Expand Down Expand Up @@ -2388,7 +2391,7 @@ void ForceChange(u32 kDown, Option* currentSetting) {
}

// Manage toggle for misc hints options
ToggleSet(miscOptions, &MiscHints, &ToTAltarHints, &SkulltulaHints);
ToggleSet(miscOptions, &MiscHints, &ToTAltarHints, &FishingHints);

if (ChestAppearance.IsNot(CHESTAPPEARANCE_VANILLA)) {
ChestAgony.Unhide();
Expand Down
1 change: 1 addition & 0 deletions source/settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,7 @@ extern Option ToTAltarHints;
extern Option GanonHints;
extern Option DampeHint;
extern Option SkulltulaHints;
extern Option FishingHints;
extern Option CompassesShowReward;
extern Option CompassesShowWotH;
extern Option MapsShowDungeonMode;
Expand Down