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

New QoL setting : textbox to equip new swords/shields/tunic when finding them #2335

Open
wants to merge 3 commits into
base: Dev
Choose a base branch
from
Open
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
1,129 changes: 581 additions & 548 deletions ASM/build/asm_symbols.txt

Large diffs are not rendered by default.

Binary file modified ASM/build/bundle.o
Binary file not shown.
1,033 changes: 529 additions & 504 deletions ASM/build/c_symbols.txt

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions ASM/c/item_effects.c
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
#include "trade_quests.h"
#include "bg_gate_shutter.h"
#include "save.h"
#include "message.h"

#define rupee_cap ((uint16_t*)0x800F8CEC)
volatile uint8_t MAX_RUPEES = 0;
@@ -50,6 +51,7 @@ void give_tycoon_wallet(z64_file_t* save, int16_t arg1, int16_t arg2) {

void give_biggoron_sword(z64_file_t* save, int16_t arg1, int16_t arg2) {
save->bgs_flag = 1; // Set flag to make the sword durable
equip_biggoron_sword_message(save, arg1, arg2);
}

void give_bottle(z64_file_t* save, int16_t bottle_item_id, int16_t arg2) {
13 changes: 7 additions & 6 deletions ASM/c/item_table.c
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
#include "dungeon_info.h"
#include "item_effects.h"
#include "item_upgrades.h"
#include "message.h"
#include "save.h"
#include "util.h"
#include "z64.h"
@@ -68,13 +69,13 @@ item_row_t item_table[GI_RANDO_MAX] = {
[GI_EYE_DROPS] = ITEM_ROW(0x53, GILDED_CHEST, 0x36, -1, 0x000E, 0x013F, 0x52, no_upgrade, trade_quest_upgrade, 0x36, -1, NULL), // Eye Drops
[GI_CLAIM_CHECK] = ITEM_ROW(0x53, GILDED_CHEST, 0x37, -1, 0x000A, 0x0142, 0x55, no_upgrade, trade_quest_upgrade, 0x37, -1, NULL), // Claim Check

[GI_SWORD_KOKIRI] = ITEM_ROW(0x53, GILDED_CHEST, 0x3B, -1, 0x00A4, 0x018D, 0x74, no_upgrade, no_effect, -1, -1, NULL), // Kokiri Sword
[GI_SWORD_KOKIRI] = ITEM_ROW(0x53, GILDED_CHEST, 0x3B, -1, 0x00A4, 0x018D, 0x74, no_upgrade, equip_kokiri_sword_message, -1, -1, NULL), // Kokiri Sword
[GI_SWORD_KNIFE] = ITEM_ROW(0x53, GILDED_CHEST, 0x3D, -1, 0x004B, 0x00F8, 0x43, no_upgrade, no_effect, -1, -1, NULL), // Giant's Knife
[GI_SHIELD_DEKU] = ITEM_ROW(0x53, BROWN_CHEST, 0x3E, -1, 0x90AD, 0x00CB, 0x1D, no_upgrade, no_effect, -1, -1, NULL), // Deku Shield
[GI_SHIELD_HYLIAN] = ITEM_ROW(0x53, BROWN_CHEST, 0x3F, -1, 0x90AE, 0x00DC, 0x2C, no_upgrade, no_effect, -1, -1, NULL), // Hylian Shield
[GI_SHIELD_MIRROR] = ITEM_ROW(0x53, GILDED_CHEST, 0x40, -1, 0x004E, 0x00EE, 0x3A, no_upgrade, no_effect, -1, -1, NULL), // Mirror Shield
[GI_TUNIC_GORON] = ITEM_ROW(0x53, GILDED_CHEST, 0x42, -1, 0x90AF, 0x00F2, 0x3C, no_upgrade, no_effect, -1, -1, NULL), // Goron Tunic
[GI_TUNIC_ZORA] = ITEM_ROW(0x53, GILDED_CHEST, 0x43, -1, 0x90B0, 0x00F2, 0x3D, no_upgrade, no_effect, -1, -1, NULL), // Zora Tunic
[GI_SHIELD_DEKU] = ITEM_ROW(0x53, BROWN_CHEST, 0x3E, -1, 0x90AD, 0x00CB, 0x1D, no_upgrade, equip_deku_shield_message, -1, -1, NULL), // Deku Shield
[GI_SHIELD_HYLIAN] = ITEM_ROW(0x53, BROWN_CHEST, 0x3F, -1, 0x90AE, 0x00DC, 0x2C, no_upgrade, equip_hylian_shield_message, -1, -1, NULL), // Hylian Shield
[GI_SHIELD_MIRROR] = ITEM_ROW(0x53, GILDED_CHEST, 0x40, -1, 0x004E, 0x00EE, 0x3A, no_upgrade, equip_mirror_shield_message, -1, -1, NULL), // Mirror Shield
[GI_TUNIC_GORON] = ITEM_ROW(0x53, GILDED_CHEST, 0x42, -1, 0x90AF, 0x00F2, 0x3C, no_upgrade, equip_goron_tunic_message, -1, -1, NULL), // Goron Tunic
[GI_TUNIC_ZORA] = ITEM_ROW(0x53, GILDED_CHEST, 0x43, -1, 0x90B0, 0x00F2, 0x3D, no_upgrade, equip_zora_tunic_message, -1, -1, NULL), // Zora Tunic
[GI_BOOTS_IRON] = ITEM_ROW(0x53, GILDED_CHEST, 0x45, -1, 0x0053, 0x0118, 0x47, no_upgrade, no_effect, -1, -1, NULL), // Iron Boots
[GI_BOOTS_HOVER] = ITEM_ROW(0x53, GILDED_CHEST, 0x46, -1, 0x0054, 0x0157, 0x5F, no_upgrade, no_effect, -1, -1, NULL), // Hover Boots
[GI_QUIVER_40] = ITEM_ROW(0x53, GILDED_CHEST, 0x4B, -1, 0x0056, 0x00BE, 0x16, no_upgrade, no_effect, -1, -1, NULL), // Big Quiver
238 changes: 237 additions & 1 deletion ASM/c/message.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "message.h"
#include "z64.h"
#include "stdbool.h"
#include "save.h"
#include "dungeon_info.h"
@@ -242,6 +241,150 @@ void treasure_chest_game_message() {
}
}

extern uint8_t EQUIPMENT_TEXTBOX;
uint8_t kokiri_sword_message = 0;
uint8_t biggoron_sword_message = 0;
uint8_t deku_shield_message = 0;
uint8_t hylian_shield_message = 0;
uint8_t mirror_shield_message = 0;
uint8_t goron_tunic_message = 0;
uint8_t zora_tunic_message = 0;

void manage_kokiri_sword_message() {
if (kokiri_sword_message == 1 &&
z64_MessageGetState(((uint8_t *)(&z64_game)) + 0x20D8) == 0) {
z64_DisplayTextbox(&z64_game, 0x045E, 0);
kokiri_sword_message = 2;
}
if (kokiri_sword_message == 2) {
MessageContext *msgCtx = &(z64_game.msgContext);
z64_link.common.frozen = 10;
if (Message_ShouldAdvance(&z64_game)) {
if (msgCtx->choiceIndex == 0) {
z64_file.button_items[0] = Z64_ITEM_KOKIRI_SWORD;
Interface_LoadItemIcon1(&z64_game, 0);
Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_KOKIRI);
}
kokiri_sword_message = 0;
}
}
}

void manage_biggoron_sword_message() {
if (biggoron_sword_message == 1 &&
z64_MessageGetState(((uint8_t *)(&z64_game)) + 0x20D8) == 0) {
z64_DisplayTextbox(&z64_game, 0x045E, 0);
biggoron_sword_message = 2;
}
if (biggoron_sword_message == 2) {
MessageContext *msgCtx = &(z64_game.msgContext);
z64_link.common.frozen = 10;
if (Message_ShouldAdvance(&z64_game)) {
if (msgCtx->choiceIndex == 0) {
z64_file.button_items[0] = Z64_ITEM_BIGGORON_SWORD;
Interface_LoadItemIcon1(&z64_game, 0);
Inventory_ChangeEquipment(EQUIP_TYPE_SWORD, EQUIP_VALUE_SWORD_BIGGORON);
}
biggoron_sword_message = 0;
}
}
}

void manage_deku_shield_message() {
if (deku_shield_message == 1 &&
z64_MessageGetState(((uint8_t *)(&z64_game)) + 0x20D8) == 0) {
z64_DisplayTextbox(&z64_game, 0x045E, 0);
deku_shield_message = 2;
}
if (deku_shield_message == 2) {
MessageContext *msgCtx = &(z64_game.msgContext);
z64_link.common.frozen = 10;
if (Message_ShouldAdvance(&z64_game)) {
if (msgCtx->choiceIndex == 0) {
Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_DEKU);
Player_SetEquipmentData(&z64_game, &z64_link);
}
deku_shield_message = 0;
}
}
}

void manage_hylian_shield_message() {
if (hylian_shield_message == 1 &&
z64_MessageGetState(((uint8_t *)(&z64_game)) + 0x20D8) == 0) {
z64_DisplayTextbox(&z64_game, 0x045E, 0);
hylian_shield_message = 2;
}
if (hylian_shield_message == 2) {
MessageContext *msgCtx = &(z64_game.msgContext);
z64_link.common.frozen = 10;
if (Message_ShouldAdvance(&z64_game)) {
if (msgCtx->choiceIndex == 0) {
Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_HYLIAN);
Player_SetEquipmentData(&z64_game, &z64_link);
}
hylian_shield_message = 0;
}
}
}

void manage_mirror_shield_message() {
if (mirror_shield_message == 1 &&
z64_MessageGetState(((uint8_t *)(&z64_game)) + 0x20D8) == 0) {
z64_DisplayTextbox(&z64_game, 0x045E, 0);
mirror_shield_message = 2;
}
if (mirror_shield_message == 2) {
MessageContext *msgCtx = &(z64_game.msgContext);
z64_link.common.frozen = 10;
if (Message_ShouldAdvance(&z64_game)) {
if (msgCtx->choiceIndex == 0) {
Inventory_ChangeEquipment(EQUIP_TYPE_SHIELD, EQUIP_VALUE_SHIELD_MIRROR);
Player_SetEquipmentData(&z64_game, &z64_link);
}
mirror_shield_message = 0;
}
}
}

void manage_goron_tunic_message() {
if (goron_tunic_message == 1 &&
z64_MessageGetState(((uint8_t *)(&z64_game)) + 0x20D8) == 0) {
z64_DisplayTextbox(&z64_game, 0x045E, 0);
goron_tunic_message = 2;
}
if (goron_tunic_message == 2) {
MessageContext *msgCtx = &(z64_game.msgContext);
z64_link.common.frozen = 10;
if (Message_ShouldAdvance(&z64_game)) {
if (msgCtx->choiceIndex == 0) {
Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_GORON);
Player_SetEquipmentData(&z64_game, &z64_link);
}
goron_tunic_message = 0;
}
}
}

void manage_zora_tunic_message() {
if (zora_tunic_message == 1 &&
z64_MessageGetState(((uint8_t *)(&z64_game)) + 0x20D8) == 0) {
z64_DisplayTextbox(&z64_game, 0x045E, 0);
zora_tunic_message = 2;
}
if (zora_tunic_message == 2) {
MessageContext *msgCtx = &(z64_game.msgContext);
z64_link.common.frozen = 10;
if (Message_ShouldAdvance(&z64_game)) {
if (msgCtx->choiceIndex == 0) {
Inventory_ChangeEquipment(EQUIP_TYPE_TUNIC, EQUIP_VALUE_TUNIC_ZORA);
Player_SetEquipmentData(&z64_game, &z64_link);
}
zora_tunic_message = 0;
}
}
}

// Function to display custom textboxes ingame.
void display_misc_messages() {
if (z64_MessageGetState(((uint8_t *)(&z64_game)) + 0x20D8) == 0) {
@@ -257,4 +400,97 @@ void display_misc_messages() {
treasure_chest_game_show_message = 0;
}
}
if (EQUIPMENT_TEXTBOX & 1 << 0) {
manage_deku_shield_message();
manage_hylian_shield_message();
manage_mirror_shield_message();
}
if (EQUIPMENT_TEXTBOX & 1 << 1) {
manage_kokiri_sword_message();
manage_biggoron_sword_message();
}
if (EQUIPMENT_TEXTBOX & 1 << 2) {
manage_goron_tunic_message();
manage_zora_tunic_message();
}
}

void equip_kokiri_sword_message(z64_file_t* save, int16_t arg1, int16_t arg2) {
if (LINK_IS_ADULT) {
return;
}
// If kokiri sword is already equipped.
if (z64_file.equip_sword == 1) {
return;
}
kokiri_sword_message = 1;
}

void equip_biggoron_sword_message(z64_file_t* save, int16_t arg1, int16_t arg2) {
if (!LINK_IS_ADULT) {
return;
}
// If biggoron sword is already equipped.
if (z64_file.equip_sword == 3) {
return;
}
biggoron_sword_message = 1;
}

void equip_deku_shield_message(z64_file_t* save, int16_t arg1, int16_t arg2) {
if (LINK_IS_ADULT) {
return;
}
// If a deku shield is already equipped.
if (z64_file.equip_shield == 1) {
return;
}
deku_shield_message = 1;
}

void equip_hylian_shield_message(z64_file_t* save, int16_t arg1, int16_t arg2) {
// Only ask for child if he has no shield equipped at all.
if (!LINK_IS_ADULT) {
if (z64_file.equip_shield == 1) {
return;
}
}
// If a hylian shield or mirror shield is already equipped.
if (z64_file.equip_shield > 1) {
return;
}
hylian_shield_message = 1;
}

void equip_mirror_shield_message(z64_file_t* save, int16_t arg1, int16_t arg2) {
if (!LINK_IS_ADULT) {
return;
}
// If mirror shield is already equipped.
if (z64_file.equip_shield == 3) {
return;
}
mirror_shield_message = 1;
}

void equip_goron_tunic_message(z64_file_t* save, int16_t arg1, int16_t arg2) {
if (!LINK_IS_ADULT) {
return;
}
// If a goron tunic is already equipped.
if (z64_file.equip_tunic == 2) {
return;
}
goron_tunic_message = 1;
}

void equip_zora_tunic_message(z64_file_t* save, int16_t arg1, int16_t arg2) {
if (!LINK_IS_ADULT) {
return;
}
// If a zora tunic is already equipped.
if (z64_file.equip_tunic == 3) {
return;
}
zora_tunic_message = 1;
}
13 changes: 13 additions & 0 deletions ASM/c/message.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
#ifndef MESSAGE_H
#define MESSAGE_H

#include "z64.h"

void Inventory_ChangeEquipment(int16_t equipment, uint16_t value);
uint8_t Message_ShouldAdvance(z64_game_t* play);
void Player_SetEquipmentData(z64_game_t* play, z64_link_t* player);

void equip_kokiri_sword_message(z64_file_t* save, int16_t arg1, int16_t arg2);
void equip_biggoron_sword_message(z64_file_t* save, int16_t arg1, int16_t arg2);
void equip_deku_shield_message(z64_file_t* save, int16_t arg1, int16_t arg2);
void equip_hylian_shield_message(z64_file_t* save, int16_t arg1, int16_t arg2);
void equip_mirror_shield_message(z64_file_t* save, int16_t arg1, int16_t arg2);
void equip_goron_tunic_message(z64_file_t* save, int16_t arg1, int16_t arg2);
void equip_zora_tunic_message(z64_file_t* save, int16_t arg1, int16_t arg2);
void display_misc_messages();

#endif
39 changes: 39 additions & 0 deletions ASM/c/z64.h
Original file line number Diff line number Diff line change
@@ -577,6 +577,45 @@ typedef enum {
/* 0x03 */ RESPAWN_MODE_MAX
} RespawnMode;

typedef enum EquipmentType {
/* 0 */ EQUIP_TYPE_SWORD,
/* 1 */ EQUIP_TYPE_SHIELD,
/* 2 */ EQUIP_TYPE_TUNIC,
/* 3 */ EQUIP_TYPE_BOOTS,
/* 4 */ EQUIP_TYPE_MAX
} EquipmentType;

typedef enum EquipValueSword {
/* 0 */ EQUIP_VALUE_SWORD_NONE,
/* 1 */ EQUIP_VALUE_SWORD_KOKIRI,
/* 2 */ EQUIP_VALUE_SWORD_MASTER,
/* 3 */ EQUIP_VALUE_SWORD_BIGGORON,
/* 4 */ EQUIP_VALUE_SWORD_MAX
} EquipValueSword;

typedef enum EquipValueShield {
/* 0 */ EQUIP_VALUE_SHIELD_NONE,
/* 1 */ EQUIP_VALUE_SHIELD_DEKU,
/* 2 */ EQUIP_VALUE_SHIELD_HYLIAN,
/* 3 */ EQUIP_VALUE_SHIELD_MIRROR,
/* 4 */ EQUIP_VALUE_SHIELD_MAX
} EquipValueShield;

typedef enum EquipValueTunic {
/* 0 */ EQUIP_VALUE_TUNIC_NONE,
/* 1 */ EQUIP_VALUE_TUNIC_KOKIRI,
/* 2 */ EQUIP_VALUE_TUNIC_GORON,
/* 3 */ EQUIP_VALUE_TUNIC_ZORA,
/* 4 */ EQUIP_VALUE_TUNIC_MAX
} EquipValueTunic;

typedef enum EquipValueBoots {
/* 0 */ EQUIP_VALUE_BOOTS_NONE,
/* 1 */ EQUIP_VALUE_BOOTS_KOKIRI,
/* 2 */ EQUIP_VALUE_BOOTS_IRON,
/* 3 */ EQUIP_VALUE_BOOTS_HOVER,
/* 4 */ EQUIP_VALUE_BOOTS_MAX
} EquipValueBoots;
typedef struct {
/* 0x00 */ z64_xyzf_t pos;
/* 0x0C */ int16_t yaw;
3 changes: 3 additions & 0 deletions ASM/ootSymbols.ld
Original file line number Diff line number Diff line change
@@ -17,10 +17,13 @@ Flags_UnsetTempClear = 0x800206C8;
Flags_GetCollectible = 0x800206E8;
Flags_SetCollectible = 0x8002071C;
Actor_SetColorFilter = 0x80027090;
Player_SetEquipmentData = 0x80079764;
z64_Gfx_SetupDL_42Opa = 0x8007E868;
Inventory_ChangeEquipment = 0x80081130;
Audio_StopCurrentMusic = 0x800C7684;
sprintf = 0x800CE7b4;
Fault_AddHungupAndCrashImpl = 0x800AF564;
Message_ShouldAdvance = 0x800D6110;
z64_ItemIcons = 0x800F8D2C;
z64_SfxDefaultPos = 0x80104394;
z64_SfxDefaultFreqAndVolScale = 0x801043A0;
2 changes: 2 additions & 0 deletions ASM/src/config.asm
Original file line number Diff line number Diff line change
@@ -211,6 +211,8 @@ SHUFFLE_SILVER_RUPEES:
.byte 0x00
CFG_DUNGEON_INFO_SILVER_RUPEES:
.byte 0x00
EQUIPMENT_TEXTBOX:
.byte 0x00
CUSTOM_KEY_MODELS:
.byte 0x00
SHUFFLE_OCARINA_BUTTONS:
Loading