Merge 1a3cf88d76
into 897d3efbd0
This commit is contained in:
commit
8b2e96166a
|
@ -1117,6 +1117,7 @@ void func_8008EC70(Player* player);
|
|||
void Player_SetEquipmentData(PlayState* play, Player* player);
|
||||
void Player_UpdateBottleHeld(PlayState* play, Player* player, s32 item, s32 actionParam);
|
||||
void func_80837C0C(PlayState* play, Player* this, s32 arg2, f32 arg3, f32 arg4, s16 arg5, s32 arg6);
|
||||
void Player_StartTalking(PlayState* play, Actor* actor);
|
||||
void func_8008EDF0(Player* player);
|
||||
void func_8008EE08(Player* player);
|
||||
void func_8008EEAC(PlayState* play, Actor* actor);
|
||||
|
|
|
@ -1481,8 +1481,10 @@ typedef struct PlayState {
|
|||
/* 0x1242B */ u8 unk_1242B;
|
||||
/* 0x1242C */ SceneTableEntry* loadedScene;
|
||||
/* 0x12430 */ char unk_12430[0xE8];
|
||||
} PlayState; // size = 0x12518
|
||||
|
||||
// New members for banker overlay
|
||||
/* 0x12518 */ s16 value;
|
||||
/* 0x1251A */ s16 selectedDigit;
|
||||
} PlayState; // size = 0x1251C
|
||||
typedef struct {
|
||||
/* 0x0000 */ GameState state;
|
||||
/* 0x00A8 */ View view;
|
||||
|
|
|
@ -324,6 +324,12 @@ typedef struct {
|
|||
/* */ u8 mqDungeonCount;
|
||||
/* */ u16 adultTradeItems;
|
||||
/* */ u8 triforcePiecesCollected;
|
||||
/* */ s32 playerBalance;
|
||||
/* */ u8 hasWarpTransfer;
|
||||
/* */ u8 hasFee;
|
||||
/* */ u8 hasPieceOfHeart;
|
||||
/* */ u8 excessRupees;
|
||||
/* */ u8 rupeesFee;
|
||||
// #endregion
|
||||
} SaveContext; // size = 0x1428
|
||||
|
||||
|
|
|
@ -0,0 +1,323 @@
|
|||
#include <stdlib.h>
|
||||
#include "z64.h"
|
||||
#include "macros.h"
|
||||
#include "libultraship/libultra/gbi.h"
|
||||
#include "../soh/assets/textures/parameter_static/parameter_static.h"
|
||||
#include "variables.h"
|
||||
#include "custom-message/CustomMessageTypes.h"
|
||||
#include "functions.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
||||
|
||||
#include "luslog.h"
|
||||
|
||||
#define DIGIT_WIDTH 8
|
||||
#define DIGIT_HEIGHT 16
|
||||
#define HUNDREDS_OFFSET -16
|
||||
#define TENS_OFFSET 8
|
||||
#define ONES_OFFSET 8
|
||||
#define BLINK_DURATION 10
|
||||
#define COOLDOWN_FRAMES 3
|
||||
#define FADE_DURATION 5
|
||||
|
||||
static s16 bankerValue = 0;
|
||||
static s16 selectedDigit = 0;
|
||||
static s16 blinkTimer = 0;
|
||||
static bool isGivingHeart = false;
|
||||
static bool isGivingCharm = false;
|
||||
static bool canContinue = false;
|
||||
static bool prevTextboxHeart = false;
|
||||
/*static*/ bool prevTextboxCharm = false; //Temporarily global until GI_PIRATE_CHARM is implemented
|
||||
static Actor* bankerActor = NULL;
|
||||
static s16 OptionChoice = -1;
|
||||
static s16 fadeTimer = 0;
|
||||
|
||||
extern const char* digitTextures[];
|
||||
|
||||
Color_RGBA8 highlightColor = { 255, 255, 0, 255 };
|
||||
|
||||
void UpdateBankerOverlay(PlayState* play, Gfx** gfx, s16 value, s16 selectedDigit) {
|
||||
s16 posX = 160 - 76;
|
||||
s16 posY = 180 - 20;
|
||||
s16 digits[3] = {value / 100, (value % 100) / 10, value % 10};
|
||||
s16 offsets[3] = {HUNDREDS_OFFSET, TENS_OFFSET, ONES_OFFSET};
|
||||
if (fadeTimer < FADE_DURATION) {
|
||||
fadeTimer++;
|
||||
}
|
||||
for (int i = 0; i < 3; i++) {
|
||||
posX += offsets[i];
|
||||
s16 digit = digits[i];
|
||||
bool isSelected = selectedDigit == 2 - i;
|
||||
gDPPipeSync((*gfx)++);
|
||||
gDPLoadTextureBlock((*gfx)++, ((u8*)digitTextures[digit]), G_IM_FMT_I, G_IM_SIZ_8b, DIGIT_WIDTH, DIGIT_HEIGHT, 0,
|
||||
G_TX_WRAP | G_TX_NOMIRROR, G_TX_WRAP | G_TX_NOMIRROR, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD,
|
||||
G_TX_NOLOD);
|
||||
u8 fadeAlpha = fadeTimer < FADE_DURATION ? (255 * fadeTimer) / FADE_DURATION : 255;
|
||||
Color_RGBA8 primColor = isSelected && blinkTimer < BLINK_DURATION ?
|
||||
(Color_RGBA8){highlightColor.r, highlightColor.g, highlightColor.b, fadeAlpha} :
|
||||
(Color_RGBA8){255, 255, 255, fadeAlpha};
|
||||
gDPSetPrimColor((*gfx)++, 0, 0, primColor.r, primColor.g, primColor.b, primColor.a);
|
||||
gDPSetCombineMode((*gfx)++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
||||
gDPSetRenderMode((*gfx)++, G_RM_XLU_SURF, G_RM_XLU_SURF2);
|
||||
gSPTextureRectangle((*gfx)++, posX << 2, posY << 2, (posX + DIGIT_WIDTH) << 2, (posY + DIGIT_HEIGHT) << 2,
|
||||
G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
|
||||
}
|
||||
}
|
||||
|
||||
s16 CalculateSelectedValue(s16 value, s16 selectedDigit, bool increase, s16 min, s16 max) {
|
||||
s16 digitValues[3];
|
||||
digitValues[0] = value % 10;
|
||||
digitValues[1] = (value / 10) % 10;
|
||||
digitValues[2] = value / 100;
|
||||
if (increase) {
|
||||
digitValues[selectedDigit] = (digitValues[selectedDigit] + 1) % 10;
|
||||
} else {
|
||||
digitValues[selectedDigit] = (digitValues[selectedDigit] + 9) % 10;
|
||||
}
|
||||
s16 newValue = digitValues[2] * 100 + digitValues[1] * 10 + digitValues[0];
|
||||
return (newValue < min) ? min : (newValue > max) ? max : newValue;
|
||||
}
|
||||
|
||||
void ProcessInput(PlayState* play, s16* value, s16* selectedDigit) {
|
||||
static s16 inputCooldownTimer = 0;
|
||||
Input* input = &play->state.input[0];
|
||||
bool playSound = false;
|
||||
if (play->msgCtx.textId != TEXT_BANKER_WITHDRAWAL_AMOUNT && play->msgCtx.textId != TEXT_BANKER_DEPOSIT_AMOUNT) {
|
||||
return;
|
||||
}
|
||||
if (inputCooldownTimer > 0) {
|
||||
inputCooldownTimer--;
|
||||
return;
|
||||
} if (abs(input->rel.stick_y) > 30) {
|
||||
*value = CalculateSelectedValue(*value, *selectedDigit, input->rel.stick_y > 0, 0, 999);
|
||||
bankerValue = *value;
|
||||
playSound = true;
|
||||
}
|
||||
if (abs(input->rel.stick_x) > 30) {
|
||||
*selectedDigit = (input->rel.stick_x < 0) ? (*selectedDigit + 1) % 3 : (*selectedDigit - 1 + 3) % 3;
|
||||
playSound = true;
|
||||
}
|
||||
if (playSound) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
}
|
||||
inputCooldownTimer = playSound ? COOLDOWN_FRAMES : 0;
|
||||
}
|
||||
|
||||
static void HandleBankerInteraction(PlayState* play, MessageContext* msgCtx) {
|
||||
uint16_t currentTextId = msgCtx->textId;
|
||||
|
||||
if (msgCtx->msgMode != MSGMODE_TEXT_DONE && msgCtx->msgMode != MSGMODE_TEXT_CLOSING) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Message_ShouldAdvance(play)) {
|
||||
return;
|
||||
}
|
||||
|
||||
s16 nextTextId;
|
||||
|
||||
switch (currentTextId) {
|
||||
case TEXT_BEGGAR_VANILLA:
|
||||
canContinue = false;
|
||||
Actor* playerActor = &GET_PLAYER(play)->actor;
|
||||
Actor* foundActor = Actor_FindNearby(play, playerActor, ACTOR_EN_HY, ACTORCAT_NPC, 80.0f);
|
||||
if (foundActor != NULL) {
|
||||
bankerActor = foundActor;
|
||||
}
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_OPTIONS);
|
||||
break;
|
||||
|
||||
case TEXT_BANKER_OPTIONS:
|
||||
if (msgCtx->choiceIndex == 0 || msgCtx->choiceIndex == 1) {
|
||||
OptionChoice = msgCtx->choiceIndex;
|
||||
if (gSaveContext.hasFee == 0) {
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_TRANSACTION_FEE);
|
||||
} else {
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_BALANCE);
|
||||
}
|
||||
} else if (msgCtx->choiceIndex == 2) {
|
||||
Message_CloseTextbox(play);
|
||||
}
|
||||
fadeTimer = 0;
|
||||
break;
|
||||
|
||||
case TEXT_BANKER_BALANCE:
|
||||
if (gSaveContext.playerBalance >= 200 && !gSaveContext.hasWarpTransfer) {
|
||||
gSaveContext.hasWarpTransfer = 1;
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_REWARD_WARP_TRANSFER_INTRO);
|
||||
} else if (gSaveContext.playerBalance >= 1000 && !gSaveContext.hasFee) {
|
||||
gSaveContext.hasFee = 1;
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_REWARD_FEE);
|
||||
} else if (gSaveContext.playerBalance >= 5000 && !gSaveContext.hasPieceOfHeart) {
|
||||
gSaveContext.hasPieceOfHeart = 1;
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_REWARD_PIECE_OF_HEART);
|
||||
} else {
|
||||
nextTextId = (OptionChoice == 0) ? TEXT_BANKER_DEPOSIT_AMOUNT : TEXT_BANKER_WITHDRAWAL_AMOUNT;
|
||||
Message_StartTextbox(play, nextTextId, bankerActor);
|
||||
}
|
||||
break;
|
||||
|
||||
case TEXT_BANKER_WITHDRAWAL_AMOUNT:
|
||||
if (bankerValue == 0) {
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_ERROR_ZERO_AMOUNT);
|
||||
} else if (bankerValue + (gSaveContext.hasFee ? 0 : gSaveContext.rupeesFee) > gSaveContext.playerBalance) {
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_ERROR_INSUFFICIENT_BALANCE);
|
||||
} else if (bankerValue + gSaveContext.rupees > CUR_CAPACITY(UPG_WALLET)) {
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_ERROR_WALLET_FULL);
|
||||
} else {
|
||||
Rupees_ChangeBy(bankerValue);
|
||||
gSaveContext.playerBalance -= bankerValue + (gSaveContext.hasFee ? 0 : gSaveContext.rupeesFee);
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_WITHDRAWAL_CONFIRM);
|
||||
}
|
||||
break;
|
||||
|
||||
case TEXT_BANKER_DEPOSIT_AMOUNT:
|
||||
if (bankerValue == 0) {
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_ERROR_ZERO_AMOUNT);
|
||||
} else if ((gSaveContext.playerBalance + bankerValue) > 5000) {
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_ERROR_MAX_BALANCE);
|
||||
} else if (bankerValue > gSaveContext.rupees) {
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_ERROR_INSUFFICIENT_BALANCE);
|
||||
} else if (gSaveContext.hasFee == 0 && (gSaveContext.playerBalance + bankerValue - gSaveContext.rupeesFee) < 1) {
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_ERROR_DEPOSIT_NOT_WORTHWHILE);
|
||||
} else {
|
||||
Rupees_ChangeBy(-bankerValue);
|
||||
gSaveContext.playerBalance += bankerValue - (gSaveContext.hasFee ? 0 : gSaveContext.rupeesFee);
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_DEPOSIT_CONFIRM);
|
||||
}
|
||||
break;
|
||||
|
||||
case TEXT_BANKER_WITHDRAWAL_CONFIRM:
|
||||
case TEXT_BANKER_DEPOSIT_CONFIRM:
|
||||
bankerValue = 0;
|
||||
canContinue = true;
|
||||
if (gSaveContext.playerBalance >= 200 && !gSaveContext.hasWarpTransfer) {
|
||||
gSaveContext.hasWarpTransfer = 1;
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_REWARD_WARP_TRANSFER_INTRO);
|
||||
} else if (gSaveContext.playerBalance >= 1000 && !gSaveContext.hasFee) {
|
||||
gSaveContext.hasFee = 1;
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_REWARD_FEE);
|
||||
} else if (gSaveContext.playerBalance >= 5000 && !gSaveContext.hasPieceOfHeart) {
|
||||
gSaveContext.hasPieceOfHeart = 1;
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_REWARD_PIECE_OF_HEART);
|
||||
}
|
||||
break;
|
||||
|
||||
case TEXT_BANKER_REWARD_WARP_TRANSFER_INTRO:
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_REWARD_WARP_TRANSFER_ITEM);
|
||||
break;
|
||||
|
||||
case TEXT_BANKER_REWARD_WARP_TRANSFER_ITEM:
|
||||
Message_CloseTextbox(play);
|
||||
isGivingCharm = true;
|
||||
break;
|
||||
//TEXT_BLUE_RUPEE is a placeholder for TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_1. GI_PIRATE_CHARM has not been implemented yet.
|
||||
case TEXT_BLUE_RUPEE:
|
||||
Message_CloseTextbox(play);
|
||||
prevTextboxCharm = true;
|
||||
break;
|
||||
|
||||
case TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_2:
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_3);
|
||||
break;
|
||||
|
||||
case TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_3:
|
||||
if (gSaveContext.playerBalance >= 1000 && !gSaveContext.hasFee) {
|
||||
gSaveContext.hasFee = 1;
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_REWARD_FEE);
|
||||
} else if (canContinue) {
|
||||
canContinue = false;
|
||||
} else {
|
||||
nextTextId = (OptionChoice == 0) ? TEXT_BANKER_DEPOSIT_AMOUNT : TEXT_BANKER_WITHDRAWAL_AMOUNT;
|
||||
Message_StartTextbox(play, nextTextId, bankerActor);
|
||||
}
|
||||
break;
|
||||
|
||||
case TEXT_BANKER_REWARD_FEE:
|
||||
if (gSaveContext.playerBalance >= 5000 && !gSaveContext.hasPieceOfHeart) {
|
||||
gSaveContext.hasPieceOfHeart = 1;
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_REWARD_PIECE_OF_HEART);
|
||||
} else if (canContinue) {
|
||||
canContinue = false;
|
||||
} else {
|
||||
nextTextId = (OptionChoice == 0) ? TEXT_BANKER_DEPOSIT_AMOUNT : TEXT_BANKER_WITHDRAWAL_AMOUNT;
|
||||
Message_StartTextbox(play, nextTextId, bankerActor);
|
||||
}
|
||||
break;
|
||||
|
||||
case TEXT_BANKER_REWARD_PIECE_OF_HEART:
|
||||
Message_CloseTextbox(play);
|
||||
isGivingHeart = true;
|
||||
break;
|
||||
|
||||
case TEXT_HEART_PIECE:
|
||||
Message_CloseTextbox(play);
|
||||
prevTextboxHeart = true;
|
||||
break;
|
||||
|
||||
case TEXT_BANKER_ERROR_ZERO_AMOUNT:
|
||||
case TEXT_BANKER_ERROR_INSUFFICIENT_BALANCE:
|
||||
case TEXT_BANKER_ERROR_WALLET_FULL:
|
||||
case TEXT_BANKER_ERROR_MAX_BALANCE:
|
||||
case TEXT_BANKER_ERROR_DEPOSIT_NOT_WORTHWHILE:
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_OPTIONS);
|
||||
break;
|
||||
|
||||
case TEXT_BANKER_TRANSACTION_FEE:
|
||||
if (msgCtx->choiceIndex == 0) {
|
||||
Message_ContinueTextbox(play, TEXT_BANKER_BALANCE);
|
||||
} else if (msgCtx->choiceIndex == 1) {
|
||||
Message_CloseTextbox(play);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawBankerOverlay(PlayState* play, Gfx** gfx) {
|
||||
UpdateBankerOverlay(play, gfx, bankerValue, selectedDigit);
|
||||
}
|
||||
|
||||
void BankerMain(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
static s16 prevMsgMode = MSGMODE_NONE;
|
||||
bool isMsgModeActive = play->msgCtx.msgMode != MSGMODE_NONE;
|
||||
bool wasMsgModeActive = prevMsgMode != MSGMODE_NONE;
|
||||
if (!isMsgModeActive && !wasMsgModeActive) {
|
||||
return;
|
||||
}
|
||||
if (isMsgModeActive) {
|
||||
ProcessInput(play, &bankerValue, &selectedDigit);
|
||||
blinkTimer = (blinkTimer + 1) % (BLINK_DURATION * 2);
|
||||
bool isBankerTextId = play->msgCtx.textId == TEXT_BANKER_WITHDRAWAL_AMOUNT || play->msgCtx.textId == TEXT_BANKER_DEPOSIT_AMOUNT;
|
||||
if (isBankerTextId) {
|
||||
Gfx** gfx = &gfxCtx->overlay.p;
|
||||
}
|
||||
}
|
||||
if (wasMsgModeActive && !isMsgModeActive) {
|
||||
if (isGivingHeart) {
|
||||
isGivingHeart = GiveItemEntryWithoutActor(play, ItemTable_Retrieve(GI_HEART_PIECE)) ? false : true;
|
||||
} else if (isGivingCharm) {
|
||||
//GI_RUPEE_BLUE is a placeholder for GI_PIRATE_CHARM, which has not been implemented yet.
|
||||
isGivingCharm = GiveItemEntryWithoutActor(play, ItemTable_Retrieve(GI_RUPEE_BLUE)) ? false : true;
|
||||
} else if (!canContinue && prevTextboxHeart) {
|
||||
s16 nextTextId = OptionChoice == 0 ? TEXT_BANKER_DEPOSIT_AMOUNT : TEXT_BANKER_WITHDRAWAL_AMOUNT;
|
||||
bankerActor->textId = nextTextId;
|
||||
Player_StartTalking(play, bankerActor);
|
||||
Message_StartTextbox(play, nextTextId, bankerActor);
|
||||
prevTextboxHeart = false;
|
||||
canContinue = true;
|
||||
} else if (prevTextboxCharm) {
|
||||
s16 charmTextID = TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_2;
|
||||
bankerActor->textId = charmTextID;
|
||||
Player_StartTalking(play, bankerActor);
|
||||
Message_StartTextbox(play, charmTextID, bankerActor);
|
||||
prevTextboxCharm = false;
|
||||
}
|
||||
}
|
||||
prevMsgMode = play->msgCtx.msgMode;
|
||||
if (isMsgModeActive) {
|
||||
HandleBankerInteraction(play, &play->msgCtx);
|
||||
}
|
||||
}
|
|
@ -71,6 +71,30 @@ typedef enum {
|
|||
TEXT_BEAN_SALESMAN_SET_A_BEAN_TO_C = 0x406A,
|
||||
TEXT_BEAN_SALESMAN_SOLD_OUT = 0x406B,
|
||||
TEXT_BEAN_SALESMAN_WANT_TO_PLANT = 0x406C,
|
||||
TEXT_BEGGAR_VANILLA = 0x70ED, //Please...with [C]... Please sell me something... Please...with [C]...
|
||||
TEXT_BANKER_GREETING = 0x9303,
|
||||
TEXT_BANKER_OPTIONS = 0x9304,
|
||||
TEXT_BANKER_BALANCE = 0x9305,
|
||||
TEXT_BANKER_WITHDRAWAL_AMOUNT = 0x9306,
|
||||
TEXT_BANKER_WITHDRAWAL_CONFIRM = 0x9307,
|
||||
TEXT_BANKER_DEPOSIT_AMOUNT = 0x9308,
|
||||
TEXT_BANKER_DEPOSIT_CONFIRM = 0x9309,
|
||||
TEXT_BANKER_REWARD_WARP_TRANSFER_INTRO = 0x9310,
|
||||
TEXT_BANKER_REWARD_WARP_TRANSFER_ITEM = 0x9311,
|
||||
TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_1 = 0x9312,
|
||||
TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_2 = 0x9313,
|
||||
TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_3 = 0x9314,
|
||||
TEXT_BANKER_REWARD_FEE = 0x9315,
|
||||
TEXT_BANKER_REWARD_PIECE_OF_HEART = 0x9316,
|
||||
TEXT_BANKER_ERROR_ZERO_AMOUNT = 0x9400,
|
||||
TEXT_BANKER_ERROR_INSUFFICIENT_BALANCE = 0x9401,
|
||||
TEXT_BANKER_ERROR_WALLET_FULL = 0x9402,
|
||||
TEXT_BANKER_ERROR_MAX_BALANCE = 0x9403,
|
||||
TEXT_BANKER_ERROR_DEPOSIT_NOT_WORTHWHILE = 0x9404,
|
||||
TEXT_BANKER_TRANSACTION_FEE = 0x9405,
|
||||
TEXT_BANKER_EXCESS = 0x9406,
|
||||
TEXT_BANKER_EXCESS_FULL = 0x9407,
|
||||
TEXT_BANKER_EXCESS_FEE = 0x9408,
|
||||
} TextIDs;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -402,6 +402,35 @@ void DrawInfoTab() {
|
|||
ImGui::InputScalar("Rupees", ImGuiDataType_S16, &gSaveContext.rupees);
|
||||
UIWidgets::InsertHelpHoverText("Current rupees");
|
||||
|
||||
if (CVarGetInteger("gBanker", 0)) {
|
||||
ImGui::InputScalar("Bank Balance", ImGuiDataType_S32, &gSaveContext.playerBalance);
|
||||
UIWidgets::InsertHelpHoverText("Current bank balance");
|
||||
if (gSaveContext.playerBalance > 5000) {
|
||||
gSaveContext.playerBalance = 5000;
|
||||
}
|
||||
bool rewardsStatus[] = {
|
||||
gSaveContext.hasWarpTransfer,
|
||||
gSaveContext.hasFee,
|
||||
gSaveContext.hasPieceOfHeart
|
||||
};
|
||||
const char* labels[] = {"Warp Transfer", "Transaction Fee", "Bank Heart Piece Reward"};
|
||||
const char* helpTexts[] = {
|
||||
"If checked, will have ability to warp transfer.",
|
||||
"If checked, will not be charged a fee.",
|
||||
"If checked, won't received Heart Piece reward."
|
||||
};
|
||||
for (int i = 0; i < sizeof(rewardsStatus)/sizeof(rewardsStatus[0]); ++i) {
|
||||
if (ImGui::Checkbox(labels[i], &rewardsStatus[i])) {
|
||||
switch (i) {
|
||||
case 0: gSaveContext.hasWarpTransfer = rewardsStatus[i] ? 1 : 0; break;
|
||||
case 1: gSaveContext.hasFee = rewardsStatus[i] ? 1 : 0; break;
|
||||
case 2: gSaveContext.hasPieceOfHeart = rewardsStatus[i] ? 1 : 0; break;
|
||||
}
|
||||
}
|
||||
UIWidgets::InsertHelpHoverText(helpTexts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const uint16_t dayTimeMin = 0;
|
||||
const uint16_t dayTimeMax = 0xFFFF;
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 15);
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include "objects/object_link_boy/object_link_boy.h"
|
||||
#include "objects/object_link_child/object_link_child.h"
|
||||
|
||||
#include "custom-message/CustomMessageTypes.h"
|
||||
|
||||
extern "C" {
|
||||
#include <z64.h>
|
||||
#include "align_asset_macro.h"
|
||||
|
@ -42,6 +44,11 @@ extern SaveContext gSaveContext;
|
|||
extern PlayState* gPlayState;
|
||||
extern void Overlay_DisplayText(float duration, const char* text);
|
||||
uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum);
|
||||
|
||||
extern int balanceUpdated;
|
||||
extern int balanceMaxed;
|
||||
extern int balanceWasMaxed;
|
||||
extern bool prevTextboxCharm; //This will be removed later once TEXT_PIRATE_CHARM has been implemented
|
||||
}
|
||||
|
||||
// GreyScaleEndDlist
|
||||
|
@ -1394,6 +1401,23 @@ void RegisterPauseMenuHooks() {
|
|||
});
|
||||
}
|
||||
|
||||
void RegisterBankUpdate() {
|
||||
auto handleBankUpdate = []() {
|
||||
if (prevTextboxCharm) { //This will be removed when TEXT_PIRATE_CHARM has been implemented. TEXT_BLUE_RUPEE is being used as a placeholder in banker.c and conflicts with this logic.
|
||||
return;
|
||||
}
|
||||
uint16_t messageIndex = gPlayState->msgCtx.textId;
|
||||
bool isBankerActive = CVarGetInteger("gBanker", 0);
|
||||
bool isRupeeMessage = (messageIndex == TEXT_BLUE_RUPEE) || (messageIndex == TEXT_RED_RUPEE) || (messageIndex == TEXT_PURPLE_RUPEE) || (messageIndex == TEXT_HUGE_RUPEE);
|
||||
if (isBankerActive && isRupeeMessage && balanceUpdated && Message_ShouldAdvance(gPlayState)) {
|
||||
uint16_t messageToShow = balanceWasMaxed ? TEXT_BANKER_EXCESS_FULL : TEXT_BANKER_EXCESS;
|
||||
Message_ContinueTextbox(gPlayState, messageToShow);
|
||||
balanceMaxed = balanceUpdated = balanceWasMaxed = 0;
|
||||
}
|
||||
};
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnDialogMessage>(handleBankUpdate);
|
||||
}
|
||||
|
||||
void InitMods() {
|
||||
RegisterTTS();
|
||||
RegisterInfiniteMoney();
|
||||
|
@ -1433,4 +1457,5 @@ void InitMods() {
|
|||
RegisterPatchHandHandler();
|
||||
RegisterHurtContainerModeHandler();
|
||||
RegisterPauseMenuHooks();
|
||||
RegisterBankUpdate();
|
||||
}
|
||||
|
|
|
@ -178,6 +178,8 @@ typedef enum {
|
|||
HEART_CONTAINER,
|
||||
ICE_TRAP,
|
||||
MILK,
|
||||
PIRATES_CHARM,
|
||||
|
||||
|
||||
BOMBS_5,
|
||||
BOMBS_10,
|
||||
|
|
|
@ -299,7 +299,7 @@ void InitTrickNames() {
|
|||
Text{"Cave Charm", "Charme de grotte", "Amuleto de la cueva"},
|
||||
Text{"Stone of Agahnim", "Fragment d'Agahnim", "Piedra de Agahnim"},
|
||||
Text{"Shard of Agony", "Fragment de Souffrance", "Piedra de la Agonía"},
|
||||
Text{"Pirate's Charm", "Pierre de Pirate", "Amuleto Pirata"}};
|
||||
Text{"Stone of Misery", "Pierre de Misère", "Piedra de la Miseria"}};
|
||||
trickNameTable[GI_DINS_FIRE] = {
|
||||
Text{"Eldin's Fire", "Feu d'Eldin", "Fuego de Eldin"},
|
||||
Text{"Din's Blaze", "Flamme de Din", "Poder de Din"},
|
||||
|
|
|
@ -1272,6 +1272,7 @@ typedef enum {
|
|||
RG_HEART_CONTAINER,
|
||||
RG_ICE_TRAP,
|
||||
RG_MILK,
|
||||
RG_PIRATES_CHARM,
|
||||
RG_BOMBS_5,
|
||||
RG_BOMBS_10,
|
||||
RG_BOMBS_20,
|
||||
|
|
|
@ -2618,7 +2618,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
|||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_CONTAINER);
|
||||
messageEntry.Replace("{{heartContainerCount}}", std::to_string(gSaveContext.sohStats.heartContainers + 1));
|
||||
}
|
||||
if (textId == TEXT_HEART_PIECE && CVarGetInteger("gInjectItemCounts", 0)) {
|
||||
if (textId == TEXT_HEART_PIECE && (CVarGetInteger("gInjectItemCounts", 0) || CVarGetInteger("gBanker", 0))) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_HEART_PIECE);
|
||||
messageEntry.Replace("{{heartPieceCount}}", std::to_string(gSaveContext.sohStats.heartPieces + 1));
|
||||
}
|
||||
|
@ -2628,6 +2628,91 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
|
|||
if (textId == TEXT_FISHERMAN_LEAVE && CVarGetInteger("gQuitFishingAtDoor", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_FISHERMAN_LEAVE);
|
||||
}
|
||||
if (textId == TEXT_BEGGAR_VANILLA && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_GREETING);
|
||||
}
|
||||
if (textId == TEXT_BANKER_OPTIONS && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_OPTIONS);
|
||||
}
|
||||
if (textId == TEXT_BANKER_BALANCE && CVarGetInteger("gBanker", 0)) {
|
||||
s32 playerBalance = gSaveContext.playerBalance;
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_BALANCE);
|
||||
messageEntry.Replace("{{playerBalance}}", std::to_string(playerBalance));
|
||||
}
|
||||
if (textId == TEXT_BANKER_WITHDRAWAL_AMOUNT && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_WITHDRAWAL_AMOUNT);
|
||||
}
|
||||
if (textId == TEXT_BANKER_WITHDRAWAL_CONFIRM && CVarGetInteger("gBanker", 0)) {
|
||||
s32 playerBalance = gSaveContext.playerBalance;
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_WITHDRAWAL_CONFIRM);
|
||||
messageEntry.Replace("{{playerBalance}}", std::to_string(playerBalance));
|
||||
}
|
||||
if (textId == TEXT_BANKER_DEPOSIT_AMOUNT && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_DEPOSIT_AMOUNT);
|
||||
}
|
||||
if (textId == TEXT_BANKER_DEPOSIT_CONFIRM && CVarGetInteger("gBanker", 0)) {
|
||||
s32 playerBalance = gSaveContext.playerBalance;
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_DEPOSIT_CONFIRM);
|
||||
messageEntry.Replace("{{playerBalance}}", std::to_string(playerBalance));
|
||||
}
|
||||
if (textId == TEXT_BANKER_REWARD_WARP_TRANSFER_INTRO && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_REWARD_WARP_TRANSFER_INTRO);
|
||||
}
|
||||
if (textId == TEXT_BANKER_REWARD_WARP_TRANSFER_ITEM && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_REWARD_WARP_TRANSFER_ITEM);
|
||||
}
|
||||
if (textId == TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_1 && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_1);
|
||||
}
|
||||
if (textId == TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_2 && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_2);
|
||||
}
|
||||
if (textId == TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_3 && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_3);
|
||||
}
|
||||
if (textId == TEXT_BANKER_REWARD_FEE && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_REWARD_FEE);
|
||||
}
|
||||
if (textId == TEXT_BANKER_REWARD_PIECE_OF_HEART && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_REWARD_PIECE_OF_HEART);
|
||||
}
|
||||
if (textId == TEXT_BANKER_ERROR_ZERO_AMOUNT && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_ERROR_ZERO_AMOUNT);
|
||||
}
|
||||
if (textId == TEXT_BANKER_ERROR_INSUFFICIENT_BALANCE && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_ERROR_INSUFFICIENT_BALANCE);
|
||||
}
|
||||
if (textId == TEXT_BANKER_ERROR_WALLET_FULL && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_ERROR_WALLET_FULL);
|
||||
}
|
||||
if (textId == TEXT_BANKER_ERROR_MAX_BALANCE && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_ERROR_MAX_BALANCE);
|
||||
}
|
||||
if (textId == TEXT_BANKER_ERROR_DEPOSIT_NOT_WORTHWHILE && CVarGetInteger("gBanker", 0)) {
|
||||
s32 rupeesFee = gSaveContext.rupeesFee;
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_ERROR_DEPOSIT_NOT_WORTHWHILE);
|
||||
messageEntry.Replace("{{rupeesFee}}", std::to_string(rupeesFee));
|
||||
}
|
||||
if (textId == TEXT_BANKER_TRANSACTION_FEE && CVarGetInteger("gBanker", 0)) {
|
||||
s32 rupeesFee = gSaveContext.rupeesFee;
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_TRANSACTION_FEE);
|
||||
messageEntry.Replace("{{rupeesFee}}", std::to_string(rupeesFee));
|
||||
}
|
||||
if (textId == TEXT_BANKER_EXCESS && CVarGetInteger("gBanker", 0)) {
|
||||
s32 playerBalance = gSaveContext.playerBalance;
|
||||
s32 excessRupees = gSaveContext.excessRupees;
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_EXCESS);
|
||||
messageEntry.Replace("{{playerBalance}}", std::to_string(playerBalance));
|
||||
messageEntry.Replace("{{excessRupees}}", std::to_string(excessRupees));
|
||||
}
|
||||
if (textId == TEXT_BANKER_EXCESS_FULL && CVarGetInteger("gBanker", 0)) {
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_EXCESS_FULL);
|
||||
}
|
||||
if (textId == TEXT_BANKER_EXCESS_FEE && CVarGetInteger("gBanker", 0)) {
|
||||
s32 rupeesFee = gSaveContext.rupeesFee;
|
||||
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, TEXT_BANKER_EXCESS_FEE);
|
||||
messageEntry.Replace("{{rupeesFee}}", std::to_string(rupeesFee));
|
||||
}
|
||||
font->charTexBuf[0] = (messageEntry.GetTextBoxType() << 4) | messageEntry.GetTextBoxPosition();
|
||||
switch (gSaveContext.language) {
|
||||
case LANGUAGE_FRA:
|
||||
|
|
|
@ -616,6 +616,9 @@ void SaveManager::InitFileNormal() {
|
|||
gSaveContext.pendingSaleMod = MOD_NONE;
|
||||
gSaveContext.isBossRushPaused = 0;
|
||||
gSaveContext.pendingIceTrapCount = 0;
|
||||
gSaveContext.playerBalance = 0;
|
||||
gSaveContext.excessRupees = 0;
|
||||
gSaveContext.rupeesFee = 5;
|
||||
|
||||
// Init with normal quest unless only an MQ rom is provided
|
||||
gSaveContext.questId = OTRGlobals::Instance->HasOriginal() ? QUEST_NORMAL : QUEST_MASTER;
|
||||
|
@ -736,6 +739,9 @@ void SaveManager::InitFileDebug() {
|
|||
gSaveContext.entranceIndex = ENTR_HYRULE_FIELD_0;
|
||||
gSaveContext.magicLevel = 0;
|
||||
gSaveContext.sceneFlags[5].swch = 0x40000000;
|
||||
gSaveContext.playerBalance = 999;
|
||||
gSaveContext.excessRupees = 0;
|
||||
gSaveContext.rupeesFee = 5;
|
||||
}
|
||||
|
||||
void SaveManager::InitFileMaxed() {
|
||||
|
@ -1314,6 +1320,11 @@ void SaveManager::LoadBaseVersion1() {
|
|||
SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) {
|
||||
SaveManager::Instance->LoadData("", gSaveContext.randomizerInf[i]);
|
||||
});
|
||||
SaveManager::Instance->LoadData("playerBalance", gSaveContext.playerBalance);
|
||||
SaveManager::Instance->LoadData("hasWarpTransfer", gSaveContext.hasWarpTransfer);
|
||||
SaveManager::Instance->LoadData("hasFee", gSaveContext.hasFee);
|
||||
SaveManager::Instance->LoadData("hasPieceOfHeart", gSaveContext.hasPieceOfHeart);
|
||||
SaveManager::Instance->LoadData("rupeesFee", gSaveContext.rupeesFee);
|
||||
}
|
||||
|
||||
void SaveManager::LoadBaseVersion2() {
|
||||
|
@ -1529,6 +1540,12 @@ void SaveManager::LoadBaseVersion2() {
|
|||
});
|
||||
});
|
||||
}
|
||||
SaveManager::Instance->LoadData("playerBalance", gSaveContext.playerBalance);
|
||||
SaveManager::Instance->LoadData("hasWarpTransfer", gSaveContext.hasWarpTransfer);
|
||||
SaveManager::Instance->LoadData("hasFee", gSaveContext.hasFee);
|
||||
SaveManager::Instance->LoadData("hasPieceOfHeart", gSaveContext.hasPieceOfHeart);
|
||||
SaveManager::Instance->LoadData("excessRupees", gSaveContext.excessRupees);
|
||||
SaveManager::Instance->LoadData("rupeesFee", gSaveContext.rupeesFee);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1751,6 +1768,12 @@ void SaveManager::LoadBaseVersion3() {
|
|||
SaveManager::Instance->LoadData("tempCollectFlags", gSaveContext.backupFW.tempCollectFlags);
|
||||
});
|
||||
SaveManager::Instance->LoadData("dogParams", gSaveContext.dogParams);
|
||||
SaveManager::Instance->LoadData("playerBalance", gSaveContext.playerBalance);
|
||||
SaveManager::Instance->LoadData("hasWarpTransfer", gSaveContext.hasWarpTransfer);
|
||||
SaveManager::Instance->LoadData("hasFee", gSaveContext.hasFee);
|
||||
SaveManager::Instance->LoadData("hasPieceOfHeart", gSaveContext.hasPieceOfHeart);
|
||||
SaveManager::Instance->LoadData("excessRupees", gSaveContext.excessRupees);
|
||||
SaveManager::Instance->LoadData("rupeesFee", gSaveContext.rupeesFee);
|
||||
}
|
||||
|
||||
void SaveManager::LoadBaseVersion4() {
|
||||
|
@ -1932,6 +1955,12 @@ void SaveManager::LoadBaseVersion4() {
|
|||
SaveManager::Instance->LoadData("tempCollectFlags", gSaveContext.backupFW.tempCollectFlags);
|
||||
});
|
||||
SaveManager::Instance->LoadData("dogParams", gSaveContext.dogParams);
|
||||
SaveManager::Instance->LoadData("playerBalance", gSaveContext.playerBalance);
|
||||
SaveManager::Instance->LoadData("hasWarpTransfer", gSaveContext.hasWarpTransfer);
|
||||
SaveManager::Instance->LoadData("hasFee", gSaveContext.hasFee);
|
||||
SaveManager::Instance->LoadData("hasPieceOfHeart", gSaveContext.hasPieceOfHeart);
|
||||
SaveManager::Instance->LoadData("excessRupees", gSaveContext.excessRupees);
|
||||
SaveManager::Instance->LoadData("rupeesFee", gSaveContext.rupeesFee);
|
||||
}
|
||||
|
||||
void SaveManager::SaveBase(SaveContext* saveContext, int sectionID, bool fullSave) {
|
||||
|
@ -2101,6 +2130,12 @@ void SaveManager::SaveBase(SaveContext* saveContext, int sectionID, bool fullSav
|
|||
SaveManager::Instance->SaveData("tempCollectFlags", saveContext->backupFW.tempCollectFlags);
|
||||
});
|
||||
SaveManager::Instance->SaveData("dogParams", saveContext->dogParams);
|
||||
SaveManager::Instance->SaveData("playerBalance", saveContext->playerBalance);
|
||||
SaveManager::Instance->SaveData("hasWarpTransfer", saveContext->hasWarpTransfer);
|
||||
SaveManager::Instance->SaveData("hasFee", saveContext->hasFee);
|
||||
SaveManager::Instance->SaveData("hasPieceOfHeart", saveContext->hasPieceOfHeart);
|
||||
SaveManager::Instance->SaveData("excessRupees", saveContext->excessRupees);
|
||||
SaveManager::Instance->SaveData("rupeesFee", saveContext->rupeesFee);
|
||||
}
|
||||
|
||||
// Load a string into a char array based on size and ensuring it is null terminated when overflowed
|
||||
|
|
|
@ -667,6 +667,11 @@ void DrawEnhancementsMenu() {
|
|||
"- Not within range of Ocarina playing spots");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Pause Warp", "gPauseWarp", true, false);
|
||||
UIWidgets::Tooltip("Selection of warp song in pause menu initiates warp. Disables song playback.");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Skip water take breath animation", "gSkipSwimDeepEndAnim", true, false);
|
||||
UIWidgets::Tooltip("Skips Link's taking breath animation after coming up from water. This setting does not interfere with getting items from underwater.");
|
||||
UIWidgets::PaddedEnhancementCheckbox("Open Bank Account", "gBanker", true, false);
|
||||
UIWidgets::Tooltip("Allows the player to visit the beggar NPC to make a withdrawal."
|
||||
"All excess rupees from checks will autoomatically warped to the bank.");
|
||||
|
||||
ImGui::EndTable();
|
||||
ImGui::EndMenu();
|
||||
|
|
|
@ -13,7 +13,7 @@ extern "C" MessageTableEntry* sNesMessageEntryTablePtr;
|
|||
extern "C" MessageTableEntry* sGerMessageEntryTablePtr;
|
||||
extern "C" MessageTableEntry* sFraMessageEntryTablePtr;
|
||||
extern "C" MessageTableEntry* sStaffMessageEntryTablePtr;
|
||||
//extern "C" MessageTableEntry* _message_0xFFFC_nes;
|
||||
//extern "C" MessageTableEntry* _message_0xFFFC_nes;
|
||||
|
||||
static void SetMessageEntry(MessageTableEntry& entry, const SOH::MessageEntry& msgEntry) {
|
||||
entry.textId = msgEntry.id;
|
||||
|
@ -187,4 +187,142 @@ extern "C" void OTRMessage_Init()
|
|||
CustomMessage("Hey! Hey!&You can't take the rod out of here!&I'm serious!^Do you want to quit?&\x1B&%gYes&No%w",
|
||||
"Hey! Hey!&Du kannst die Angel doch nicht&einfach mitnehmen!&Ganz im Ernst!^Möchtest du aufhören?&\x1B&%gJa&Nein%w", //TODO Used AI translation as placeholder
|
||||
"Holà! Holà!&Les cannes ne sortent pas d'ici!&Je suis sérieux!^Voulez-vous arrêter?&\x1B&%gOui&Non%w")); //TODO Used AI translation as placeholder
|
||||
}
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_GREETING,
|
||||
CustomMessage("Hey there, @! You&making a deposit? Or are you&here to make a withdrawal?",
|
||||
"Hallo, @! Machen Sie&eine Einzahlung? Oder sind Sie&hier, um eine Auszahlung&vorzunehmen?",
|
||||
"Salut, @! Vous&effectuez un dépôt ? Ou êtes-vous&ici pour effectuer un retrait?"));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_OPTIONS,
|
||||
CustomMessage("What would you like to do?" "\x1C" "&%gDeposit Rupees&%gWithdrawal Rupees&%gNothing%w",
|
||||
"Was würdest du gern tun?" "\x1C" "&%gRubine einzahlen&%gRubine abheben&%gNichts%w",
|
||||
"Qu'est-ce que tu aimerais faire?" "\x1C" "&%gDéposer des rubis&%gRetirer des rubis&%gRien%w"));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_BALANCE,
|
||||
CustomMessage("If I remember, as of your last &warp transfer your balance is&%y{{playerBalance}}%w rupees.",
|
||||
"Wenn ich mich erinnere, betrug Ihr&Guthaben bei Ihrem letzten&Warp-Transfer %y{{playerBalance}}%w Rupien.",
|
||||
"Si je me souviens bien, lors de&votre dernier transfert Warp,&votre solde était de %y{{playerBalance}}%w roupies."));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_WITHDRAWAL_AMOUNT,
|
||||
CustomMessage("\x08Select Withdrawal Amount:& rupees.&Set the amount with \xAA and&press \x9F to decide.\x0A",
|
||||
"\x08" "Auszahlungsbetrag:& Rubine.&Wählen Sie den Betrag mit \xAA.&Drücken Sie \x9F, um zu entscheiden.\x0A",
|
||||
"\x08Sélectionnez le montant du retrait:& Roupies.&Réglez le montant avec \xAA et&appuyez sur \x9F pour décider.\x0A"));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_WITHDRAWAL_CONFIRM,
|
||||
CustomMessage("Here are your rupees. Your new&balance is %y{{playerBalance}}%w rupees. See you&later!",
|
||||
"Hier sind deine Rupien. Ihr neues&Guthaben beträgt %y{{playerBalance}}%w Rupien.&Bis später!",
|
||||
"Voici vos roupies. Votre nouveau&solde est de %y{{playerBalance}}%w roupies. À plus&tard!"));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_DEPOSIT_AMOUNT,
|
||||
CustomMessage("\x08Select Deposit Amount:& rupees.&Set the amount with \xAA and press&\x9F to decide.\x0A",
|
||||
"\x08" "Einzahlungsbetrag:& Rubine.&Wählen Sie den Betrag mit \xAA.&Drücken Sie \x9F, um zu entscheiden.\x0A",
|
||||
"\x08Sélectionnez le montant du dépôt:& Roupies.&Réglez le montant avec \xAA et&appuyez sur \x9F pour décider.\x0A"));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_DEPOSIT_CONFIRM,
|
||||
CustomMessage("You've deposited your rupees. Your&new balance is %y{{playerBalance}}%w rupees. See&you later!",
|
||||
"Sie haben Ihre Rupien eingezahlt.&Ihr neues Guthaben beträgt %y{{playexrBalance}}%w&Rupien. Bis später!",
|
||||
"Vous avez déposé vos roupies.&Votre nouveau solde est de %y{{playerBalance}}%w&roupies. À plus tard!"));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_REWARD_WARP_TRANSFER_INTRO,
|
||||
CustomMessage("Ho ho! Your savings have reached&%y200%w rupees! A fine achievement,&young spender!",
|
||||
"Ho ho! Ihre Ersparnisse haben %y200%w&Rupien erreicht! Eine tolle Leistung,&junger Spender!",
|
||||
"Ho ho! Vos économies ont atteint&%y200%w roupies! Une belle réussite,&jeune dépensier!"));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_REWARD_WARP_TRANSFER_ITEM,
|
||||
CustomMessage("To reward your thriftiness, I've got&a special trinket for you...The&%rPirate's Charm%w!",
|
||||
"Um deine Sparsamkeit zu belohnen,&habe ich ein besonderes&Schmuckstück für dich... den&%rPiratenzauber%w!",
|
||||
"Pour récompenser votre économie,&j'ai un bijou spécial pour vous... Le&%rCharme du Pirate%w!"));
|
||||
CustomMessageManager::Instance->CreateGetItemMessage(
|
||||
//ITEM_RUPEE_BLUE is a placeholder for ITEM_PIRATE_CHARM which has not been implemented yet.
|
||||
customMessageTableID, (GetItemID)TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_1, ITEM_RUPEE_BLUE,
|
||||
CustomMessage("This charm, infused with pirate&magic, can warp your treasures&directly to the bank! No more&heavy wallets for you!",
|
||||
"Dieser mit Piratenmagie&durchdrungene Zauber kann Ihre&Schätze direkt an die Bank bringen!&Keine schweren Geldbörsen mehr!",
|
||||
"Ce charme, imprégné de magie&pirate, peut transférer vos trésors&directement à la banque! Fini les&portefeuilles lourds pour vous!",
|
||||
TEXTBOX_TYPE_BLUE));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_2,
|
||||
CustomMessage("And that's not all! It also lets me&whisper your new balance to you&through the winds, once a %bwarp&transfer%w is complete.",
|
||||
"Außerdem kann ich Ihnen Ihr neues&Gleichgewicht durch den Wind&zuflüstern, sobald ein %bWarp-Transfer%w&abgeschlossen ist.",
|
||||
"Cela me permet également de vous&murmurer votre nouvel équilibre à&travers les vents, une fois le&%btransfert de distorsion%w terminé."));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_REWARD_WARP_TRANSFER_LORE_3,
|
||||
CustomMessage("I've taken to calling it a %bwarp&transfer%w. A fitting name, don't you&think? It's quite the convenience!",
|
||||
"Ich habe angefangen, es einen&%bWarp-Transfer%w zu nennen. Ein&passender Name, finden Sie nicht?&Das ist wirklich praktisch!",
|
||||
"J'ai pris l'habitude de l'appeler&%btransfert de distorsion%w. Un nom&approprié, vous ne trouvez pas?&C'est tout à fait pratique!"));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_REWARD_FEE,
|
||||
CustomMessage("Wow, over %y1000%w rupees saved! To&thank you, I'm dropping all&withdrawal and deposit fees!",
|
||||
"Wow, über %y1000%w Rupien gespart!&Als Dankeschön verzichte ich auf&alle Abhebungs- und&Einzahlungsgebühren!",
|
||||
"Wow, plus de %y1000%w roupies&économisées! Pour vous remercier,&je supprime tous les frais de&retrait et de dépôt!"));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_REWARD_PIECE_OF_HEART,
|
||||
CustomMessage("Astounding! A whopping %y5000%w&rupees saved! For such a feat, a&%rPiece of Heart%w is yours!",
|
||||
"Erstaunlich! Satte %y5000%w Rupien&gespart! Für eine solche Leistung&gehört Ihnen ein %rStück Herz%w!",
|
||||
"Étonnant! Un énorme %y5000%w roupies&économisées! Pour un tel exploit,&un %rFragment de Coeur%w!"));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_ERROR_ZERO_AMOUNT,
|
||||
CustomMessage(
|
||||
"Eh, @? You can't&deposit the air in your pockets!&Come back when you've got some&real Rupees.",
|
||||
"Äh, @? Sie können die&Luft nicht in Ihren Taschen&deponieren! Kommen Sie zurück,&wenn Sie echte Rupien haben.",
|
||||
"Hein, @? Vous ne&pouvez pas déposer l'air dans vos&poches ! Revenez quand vous&aurez de vrais rubis."
|
||||
));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_ERROR_INSUFFICIENT_BALANCE,
|
||||
CustomMessage(
|
||||
"Oh, @! It seems your&balance is running low. You need&more Rupees in the bank to make&this withdrawal.",
|
||||
"Oh, @! Es scheint, dass&Ihr Guthaben zur Neige geht. Für&diese Auszahlung benötigen Sie&mehr Rupien auf der Bank.",
|
||||
"Oh, @! Il semble que&votre solde soit faible. Vous avez&besoin de plus de roupies en&banque pour effectuer ce retrait."
|
||||
));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_ERROR_WALLET_FULL,
|
||||
CustomMessage(
|
||||
"Whoa there, @! That&amount's too hefty for your wallet.&Trim it down a bit, eh?",
|
||||
"Wow, @! Dieser Betrag&ist zu hoch für Ihren Geldbeutel.&Reduzieren Sie es ein wenig, oder?",
|
||||
"Waouh, @! Ce montant&est trop lourd pour votre&portefeuille. Réduisez-le un peu,&hein?"
|
||||
));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_ERROR_MAX_BALANCE,
|
||||
CustomMessage(
|
||||
"Woah, @! The bank's&max capacity is %y5000%w Rupees. I&don't have enough room for that&amount!",
|
||||
"Boah, @! Die maximale&Kapazität der Bank beträgt %y5000%w&Rupien. Ich habe nicht genug Platz&für diese Menge!",
|
||||
"Waouh, @! La capacité&maximale de la banque est de&%y5000%w roupies. Je n'ai pas assez de&place pour ce montant!"
|
||||
));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_ERROR_DEPOSIT_NOT_WORTHWHILE,
|
||||
CustomMessage(
|
||||
"Hold up, @! There's a %y{{rupeesFee}}%w&Rupee handling fee. You'd lose&Rupees, not gain! Deposit more to&make it worthwhile.",
|
||||
"Warte, @! Es fällt eine&Bearbeitungsgebühr von %y{{rupeesFee}}%w Rupien&an. Du würdest Rubine verlieren!&Zahlen Sie bitte mehr ein.",
|
||||
"Tenir bon, @! Il y a des&frais de traitement de %y{{rupeesFee}}%w roupies.&Vous perdriez des rubis! Déposez&davantage s'il vous plaît."
|
||||
));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_TRANSACTION_FEE,
|
||||
CustomMessage(
|
||||
"Ah, @! There's a %y{{rupeesFee}}%w&Rupee fee. Is that okay?\x1B&%gProceed&%gNevermind%w",
|
||||
"Ach, @! Es fällt eine&Gebühr von %y{{rupeesFee}}%w Rupien an. Okay?\x1B&%gWeiter&%gNichts tun%w",
|
||||
"Ah, @! Il y a des&frais de %y{{rupeesFee}}%w roupies. Est-ce OK?\x1B&%gProcéder&%gPas grave%w"
|
||||
));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_EXCESS,
|
||||
CustomMessage(
|
||||
"Hey @! Banker here!&Your wallet is full. Warping over&%y{{excessRupees}}%w rupees!&Your new balance is %y{{playerBalance}}%w.",
|
||||
"Hey @! Banker hier!&Ihr Geldbeutel ist voll. Warping&über %y{{excessRupees}}%w Rupien!&Ihr neues Guthaben beträgt %y{{playerBalance}}%w.",
|
||||
"Hé @! Banquier ici!&Votre portefeuille est plein.&Déformation de plus de %y{{excessRupees}}%w roupies!&Votre nouveau solde est de %y{{playerBalance}}%w.",
|
||||
TEXTBOX_TYPE_BLUE
|
||||
));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_EXCESS_FULL,
|
||||
CustomMessage(
|
||||
"Hey @! Banker here!&I can't do a warp transfer when&your account is maxed out. Come&make a withdrawal!",
|
||||
"Hey @! Banker hier!&Ich kann keine Warp-Überweisung&durchführen, wenn Ihr Konto voll&ist. Machen Sie eine Auszahlung!",
|
||||
"Hé @! Banquier ici! Je&ne peux pas effectuer de transfert&Warp lorsque votre compte est au&maximum. Venez faire un retrait!",
|
||||
TEXTBOX_TYPE_BLUE
|
||||
));
|
||||
CustomMessageManager::Instance->CreateMessage(
|
||||
customMessageTableID, TEXT_BANKER_EXCESS_FEE,
|
||||
CustomMessage(
|
||||
"Hey @! Banker here!&There's a %y{{rupeesFee}}%w Rupee fee for warp&transfers. Your account doesn't&have enough to cover it.",
|
||||
"Hey @! Banker hier! Es&gibt eine Gebühr von %y{{rupeesFee}}%w Rupien für&Warp-Überweisungen. Ihr Konto hat&nicht genug, um sie zu decken.",
|
||||
"Hé @! Banquier ici! Il y&a des frais de %y{{rupeesFee}}%w roupies pour les&transferts Warp. Votre compte n'a&pas assez pour les couvrir.",
|
||||
TEXTBOX_TYPE_BLUE
|
||||
));
|
||||
}
|
|
@ -30,6 +30,10 @@
|
|||
// So, when indexing into it with a item button index, we need to adjust
|
||||
#define BUTTON_STATUS_INDEX(button) ((button) >= 4) ? ((button) + 1) : (button)
|
||||
|
||||
int balanceUpdated = 0;
|
||||
int balanceMaxed = 0;
|
||||
int balanceWasMaxed = 0;
|
||||
|
||||
s16 Top_HUD_Margin = 0;
|
||||
s16 Left_HUD_Margin = 0;
|
||||
s16 Right_HUD_Margin = 0;
|
||||
|
@ -6550,34 +6554,49 @@ void Interface_Update(PlayState* play) {
|
|||
(play->transitionMode == TRANS_MODE_OFF) && !Play_InCsMode(play)) {}
|
||||
|
||||
if (gSaveContext.rupeeAccumulator != 0) {
|
||||
if (gSaveContext.rupeeAccumulator > 0) {
|
||||
if (gSaveContext.rupeeAccumulator > 0) {
|
||||
if (gSaveContext.rupees < CUR_CAPACITY(UPG_WALLET)) {
|
||||
gSaveContext.rupeeAccumulator--;
|
||||
gSaveContext.rupees++;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
} else {
|
||||
// "Rupee Amount MAX = %d"
|
||||
osSyncPrintf("ルピー数MAX = %d\n", CUR_CAPACITY(UPG_WALLET));
|
||||
gSaveContext.rupees = CUR_CAPACITY(UPG_WALLET);
|
||||
gSaveContext.rupeeAccumulator--;
|
||||
gSaveContext.rupees++;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
} else {
|
||||
balanceWasMaxed = (gSaveContext.playerBalance == 5000) ? 1 : 0;
|
||||
if (CVarGetInteger("gBanker", 0) && gSaveContext.hasWarpTransfer) {
|
||||
int rupeesToAdd = gSaveContext.rupeeAccumulator;
|
||||
if (gSaveContext.playerBalance + rupeesToAdd > 5000) {
|
||||
rupeesToAdd = 5000 - gSaveContext.playerBalance;
|
||||
balanceMaxed = 1;
|
||||
}
|
||||
gSaveContext.playerBalance += rupeesToAdd;
|
||||
osSyncPrintf("Added %d rupees to bank balance. New balance = %d\n", rupeesToAdd,
|
||||
gSaveContext.playerBalance);
|
||||
gSaveContext.excessRupees = rupeesToAdd;
|
||||
gSaveContext.rupeeAccumulator = 0;
|
||||
}
|
||||
} else if (gSaveContext.rupees != 0) {
|
||||
if (gSaveContext.rupeeAccumulator <= -50) {
|
||||
gSaveContext.rupeeAccumulator += 10;
|
||||
gSaveContext.rupees -= 10;
|
||||
|
||||
if (gSaveContext.rupees < 0) {
|
||||
gSaveContext.rupees = 0;
|
||||
balanceUpdated = 1;
|
||||
} else {
|
||||
// "Rupee Amount MAX = %d"
|
||||
osSyncPrintf("ルピー数MAX = %d\n", CUR_CAPACITY(UPG_WALLET));
|
||||
gSaveContext.rupees = CUR_CAPACITY(UPG_WALLET);
|
||||
gSaveContext.rupeeAccumulator = 0;
|
||||
}
|
||||
}
|
||||
} else if (gSaveContext.rupees != 0) {
|
||||
if (gSaveContext.rupeeAccumulator <= -50) {
|
||||
gSaveContext.rupeeAccumulator += 10;
|
||||
gSaveContext.rupees -= 10;
|
||||
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
if (gSaveContext.rupees < 0) {
|
||||
gSaveContext.rupees = 0;
|
||||
}
|
||||
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
} else {
|
||||
gSaveContext.rupeeAccumulator++;
|
||||
gSaveContext.rupees--;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
}
|
||||
} else {
|
||||
gSaveContext.rupeeAccumulator++;
|
||||
gSaveContext.rupees--;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
}
|
||||
} else {
|
||||
gSaveContext.rupeeAccumulator = 0;
|
||||
gSaveContext.rupeeAccumulator = 0;
|
||||
}
|
||||
if (gSaveContext.rupeeAccumulator == 0 && gSaveContext.pendingSale != ITEM_NONE) {
|
||||
u16 tempSaleItem = gSaveContext.pendingSale;
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
//For Banker enhancement
|
||||
#include "soh/Enhancements/custom-message/CustomMessageTypes.h"
|
||||
void DrawBankerOverlay(PlayState* play, Gfx** gfx);
|
||||
|
||||
void* D_8012D1F0 = NULL;
|
||||
//UNK_TYPE D_8012D1F4 = 0; // unused
|
||||
Input* D_8012D1F8 = NULL;
|
||||
|
@ -1470,6 +1474,20 @@ void Play_DrawOverlayElements(PlayState* play) {
|
|||
|
||||
Message_Draw(play);
|
||||
|
||||
//Banker code start
|
||||
static s16 delayTimer = 15;
|
||||
if (play->msgCtx.textId == TEXT_BANKER_WITHDRAWAL_AMOUNT || play->msgCtx.textId == TEXT_BANKER_DEPOSIT_AMOUNT) {
|
||||
Gfx** gfx = &play->state.gfxCtx->overlay.p;
|
||||
if (delayTimer > 0) {
|
||||
delayTimer--;
|
||||
return;
|
||||
}
|
||||
DrawBankerOverlay(play, gfx);
|
||||
} else {
|
||||
delayTimer = 15;
|
||||
}
|
||||
//Banker code end
|
||||
|
||||
if (play->gameOverCtx.state != GAMEOVER_INACTIVE) {
|
||||
GameOver_FadeInLights(play);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ void func_80A7127C(EnHy* this, PlayState* play);
|
|||
void EnHy_DoNothing(EnHy* this, PlayState* play);
|
||||
void func_80A714C4(EnHy* this, PlayState* play);
|
||||
|
||||
extern void BankerMain(PlayState* play, GraphicsContext* gfxCtx);
|
||||
|
||||
const ActorInit En_Hy_InitVars = {
|
||||
ACTOR_EN_HY,
|
||||
ACTORCAT_NPC,
|
||||
|
@ -1105,6 +1107,13 @@ void func_80A71530(EnHy* this, PlayState* play) {
|
|||
void EnHy_Update(Actor* thisx, PlayState* play) {
|
||||
EnHy* this = (EnHy*)thisx;
|
||||
|
||||
//Banker Enhancement Hook Start
|
||||
//(Might end up using the hook system, but this was a niche use case so I didn't bother.)
|
||||
if (this->actor.id == 366 && this->actor.params == 1925 && CVarGetInteger("gBanker", 0)) {
|
||||
BankerMain(play, play->state.gfxCtx);
|
||||
}
|
||||
//Banker Enhancement Hook End
|
||||
|
||||
if (this->actionFunc != EnHy_InitImpl) {
|
||||
gSegments[6] = VIRTUAL_TO_PHYSICAL(play->objectCtx.status[this->objBankIndexOsAnime].segment);
|
||||
SkelAnime_Update(&this->skelAnime);
|
||||
|
|
Loading…
Reference in New Issue