mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-06-23 01:29:51 -04:00
Merge branch 'develop' into christmas-tree
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
#include <libultraship/libultra.h>
|
||||
|
||||
const char gBuildVersion[] = "@PROJECT_BUILD_NAME@ (@CMAKE_PROJECT_VERSION_MAJOR@.@CMAKE_PROJECT_VERSION_MINOR@.@CMAKE_PROJECT_VERSION_PATCH@)";
|
||||
const int gBuildVersionMajor = @CMAKE_PROJECT_VERSION_MAJOR@;
|
||||
const int gBuildVersionMinor = @CMAKE_PROJECT_VERSION_MINOR@;
|
||||
const int gBuildVersionPatch = @CMAKE_PROJECT_VERSION_PATCH@;
|
||||
const u16 gBuildVersionMajor = @CMAKE_PROJECT_VERSION_MAJOR@;
|
||||
const u16 gBuildVersionMinor = @CMAKE_PROJECT_VERSION_MINOR@;
|
||||
const u16 gBuildVersionPatch = @CMAKE_PROJECT_VERSION_PATCH@;
|
||||
const char gBuildTeam[] = "@PROJECT_TEAM@";
|
||||
const char gBuildDate[] = __DATE__ " " __TIME__;
|
||||
const char gBuildMakeOption[] = "";
|
||||
|
||||
|
||||
@@ -204,6 +204,17 @@ u8 Inventory_DeleteEquipment(PlayState* play, s16 equipment) {
|
||||
|
||||
if (equipment == EQUIP_TYPE_TUNIC) {
|
||||
gSaveContext.equips.equipment |= EQUIP_VALUE_TUNIC_KOKIRI << (EQUIP_TYPE_TUNIC * 4);
|
||||
// non-vanilla: remove goron and zora tunics from item buttons if assignable tunics is on
|
||||
if (CVarGetInteger("gAssignableTunicsAndBoots", 0) && equipValue != EQUIP_VALUE_TUNIC_KOKIRI) {
|
||||
ItemID item = (equipValue == EQUIP_VALUE_TUNIC_GORON ? ITEM_TUNIC_GORON : ITEM_TUNIC_ZORA);
|
||||
for (int i = 1; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
|
||||
if (gSaveContext.equips.buttonItems[i] == item) {
|
||||
gSaveContext.equips.buttonItems[i] = ITEM_NONE;
|
||||
gSaveContext.equips.cButtonSlots[i - 1] = SLOT_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
// end non-vanilla
|
||||
}
|
||||
|
||||
if (equipment == EQUIP_TYPE_SWORD) {
|
||||
|
||||
@@ -601,13 +601,24 @@ void HealthMeter_Draw(PlayState* play) {
|
||||
|
||||
{
|
||||
Mtx* matrix = Graph_Alloc(gfxCtx, sizeof(Mtx));
|
||||
Matrix_SetTranslateScaleMtx2(matrix,
|
||||
HeartsScale+(HeartsScale/3) - ((HeartsScale/3) * sp144),
|
||||
HeartsScale+(HeartsScale/3) - ((HeartsScale/3) * sp144),
|
||||
HeartsScale+(HeartsScale/3) - ((HeartsScale/3) * sp144),
|
||||
-130+offsetX, //Pos X
|
||||
(-94+offsetY) *-1, //Pos Y
|
||||
0.0f);
|
||||
|
||||
if (CVarGetInteger("gNoHUDHeartAnimation", 0)) {
|
||||
Matrix_SetTranslateScaleMtx2(matrix,
|
||||
HeartsScale, // Scale X
|
||||
HeartsScale, // Scale Y
|
||||
HeartsScale, // Scale Z
|
||||
-130 + offsetX, // Pos X
|
||||
(-94 + offsetY) * -1, // Pos Y
|
||||
0.0f);
|
||||
} else {
|
||||
Matrix_SetTranslateScaleMtx2(matrix, HeartsScale + (HeartsScale / 3) - ((HeartsScale / 3) * sp144),
|
||||
HeartsScale + (HeartsScale / 3) - ((HeartsScale / 3) * sp144),
|
||||
HeartsScale + (HeartsScale / 3) - ((HeartsScale / 3) * sp144),
|
||||
-130 + offsetX, // Pos X
|
||||
(-94 + offsetY) * -1, // Pos Y
|
||||
0.0f);
|
||||
}
|
||||
|
||||
gSPMatrix(OVERLAY_DISP++, matrix, G_MTX_MODELVIEW | G_MTX_LOAD);
|
||||
gSPVertex(OVERLAY_DISP++, sp154, 4, 0);
|
||||
gSP1Quadrangle(OVERLAY_DISP++, 0, 2, 3, 1, 0);
|
||||
|
||||
@@ -1469,6 +1469,7 @@ void Inventory_SwapAgeEquipment(void) {
|
||||
gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER;
|
||||
} else {
|
||||
gSaveContext.equips.buttonItems[0] = ITEM_NONE;
|
||||
Flags_SetInfTable(INFTABLE_SWORDLESS);
|
||||
}
|
||||
|
||||
if (gSaveContext.inventory.items[SLOT_NUT] != ITEM_NONE) {
|
||||
|
||||
+28
-1
@@ -33,6 +33,7 @@ u64 D_801614D0[0xA00];
|
||||
#endif
|
||||
|
||||
PlayState* gPlayState;
|
||||
s16 firstInit = 0;
|
||||
|
||||
s16 gEnPartnerId;
|
||||
s16 gEnChristmasTreeId;
|
||||
@@ -492,6 +493,12 @@ void Play_Init(GameState* thisx) {
|
||||
}
|
||||
}
|
||||
|
||||
// Properly initialize the frame counter so it doesn't use garbage data
|
||||
if (!firstInit) {
|
||||
play->gameplayFrames = 0;
|
||||
firstInit = 1;
|
||||
}
|
||||
|
||||
// Invalid entrance, so immediately exit the game to opening title
|
||||
if (gSaveContext.entranceIndex == -1) {
|
||||
gSaveContext.entranceIndex = 0;
|
||||
@@ -1210,7 +1217,7 @@ void Play_Update(PlayState* play) {
|
||||
play->gameplayFrames++;
|
||||
// Gameplay stat tracking
|
||||
if (!gSaveContext.sohStats.gameComplete &&
|
||||
(!IS_BOSS_RUSH || (IS_BOSS_RUSH && !gSaveContext.isBossRushPaused))) {
|
||||
(!IS_BOSS_RUSH || !gSaveContext.isBossRushPaused)) {
|
||||
gSaveContext.sohStats.playTimer++;
|
||||
gSaveContext.sohStats.sceneTimer++;
|
||||
gSaveContext.sohStats.roomTimer++;
|
||||
@@ -2337,8 +2344,28 @@ void Play_PerformSave(PlayState* play) {
|
||||
if (play != NULL && gSaveContext.fileNum != 0xFF) {
|
||||
Play_SaveSceneFlags(play);
|
||||
gSaveContext.savedSceneNum = play->sceneNum;
|
||||
|
||||
// Track values from temp B
|
||||
uint8_t prevB = gSaveContext.equips.buttonItems[0];
|
||||
uint8_t prevStatus = gSaveContext.buttonStatus[0];
|
||||
|
||||
// Replicate the B button restore from minigames/epona that kaleido does
|
||||
if (gSaveContext.equips.buttonItems[0] == ITEM_SLINGSHOT ||
|
||||
gSaveContext.equips.buttonItems[0] == ITEM_BOW ||
|
||||
gSaveContext.equips.buttonItems[0] == ITEM_BOMBCHU ||
|
||||
gSaveContext.equips.buttonItems[0] == ITEM_FISHING_POLE ||
|
||||
(gSaveContext.equips.buttonItems[0] == ITEM_NONE && !Flags_GetInfTable(INFTABLE_SWORDLESS))) {
|
||||
|
||||
gSaveContext.equips.buttonItems[0] = gSaveContext.buttonStatus[0];
|
||||
Interface_RandoRestoreSwordless();
|
||||
}
|
||||
|
||||
Save_SaveFile();
|
||||
|
||||
// Restore temp B values back
|
||||
gSaveContext.equips.buttonItems[0] = prevB;
|
||||
gSaveContext.buttonStatus[0] = prevStatus;
|
||||
|
||||
uint8_t triforceHuntCompleted =
|
||||
IS_RANDO &&
|
||||
gSaveContext.triforcePiecesCollected == Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED) &&
|
||||
|
||||
@@ -1212,11 +1212,7 @@ void func_8009AFE0(PlayState* play) {
|
||||
|
||||
{ s32 pad[2]; }
|
||||
|
||||
if (ResourceMgr_IsGameMasterQuest()) {
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sThievesHideoutEntranceTextures_MQ[gSaveContext.nightFlag]));
|
||||
} else {
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sThievesHideoutEntranceTextures[gSaveContext.nightFlag]));
|
||||
}
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sThievesHideoutEntranceTextures[gSaveContext.nightFlag]));
|
||||
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
@@ -1673,11 +1669,7 @@ void func_8009D31C(PlayState* play) {
|
||||
|
||||
{ s32 pad[2]; }
|
||||
|
||||
if (ResourceMgr_IsGameMasterQuest()) {
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sLonLonHouseEntranceTextures_MQ[gSaveContext.nightFlag]));
|
||||
} else {
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sLonLonHouseEntranceTextures[gSaveContext.nightFlag]));
|
||||
}
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sLonLonHouseEntranceTextures[gSaveContext.nightFlag]));
|
||||
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 128, 128, 128, 128);
|
||||
@@ -1709,13 +1701,8 @@ void func_8009D438(PlayState* play) {
|
||||
var = gSaveContext.nightFlag;
|
||||
}
|
||||
|
||||
if (ResourceMgr_IsGameMasterQuest()) {
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sGuardHouseView1Textures_MQ[var]));
|
||||
gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(sGuardHouseView2Textures_MQ[var]));
|
||||
} else {
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sGuardHouseView1Textures[var]));
|
||||
gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(sGuardHouseView2Textures[var]));
|
||||
}
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sGuardHouseView1Textures[var]));
|
||||
gSPSegment(POLY_OPA_DISP++, 0x09, SEGMENTED_TO_VIRTUAL(sGuardHouseView2Textures[var]));
|
||||
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 128, 128, 128, 128);
|
||||
@@ -1859,11 +1846,7 @@ void func_8009DD5C(PlayState* play) {
|
||||
|
||||
{ s32 pad[2]; }
|
||||
|
||||
if (ResourceMgr_IsGameMasterQuest()) {
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sKakarikoWindowTextures_MQ[gSaveContext.nightFlag]));
|
||||
} else {
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sKakarikoWindowTextures[gSaveContext.nightFlag]));
|
||||
}
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sKakarikoWindowTextures[gSaveContext.nightFlag]));
|
||||
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 128, 128, 128, 128);
|
||||
@@ -1998,12 +1981,8 @@ void func_8009E730(PlayState* play) {
|
||||
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 128, 128, 128, 128);
|
||||
|
||||
if (ResourceMgr_IsGameMasterQuest()) {
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sZorasDomainEntranceTextures_MQ[gSaveContext.nightFlag]));
|
||||
} else {
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sZorasDomainEntranceTextures[gSaveContext.nightFlag]));
|
||||
}
|
||||
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sZorasDomainEntranceTextures[gSaveContext.nightFlag]));
|
||||
|
||||
{ s32 pad[2]; }
|
||||
|
||||
@@ -2136,11 +2115,7 @@ void func_8009F1B4(PlayState* play) {
|
||||
|
||||
{ s32 pad[2]; }
|
||||
|
||||
if (ResourceMgr_IsGameMasterQuest()) {
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_8012A380_MQ[gSaveContext.nightFlag]));
|
||||
} else {
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_8012A380[gSaveContext.nightFlag]));
|
||||
}
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_8012A380[gSaveContext.nightFlag]));
|
||||
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
@@ -2273,11 +2248,7 @@ void func_8009F9D0(PlayState* play) {
|
||||
gDPPipeSync(POLY_XLU_DISP++);
|
||||
gDPSetEnvColor(POLY_XLU_DISP++, 128, 128, 128, 128);
|
||||
|
||||
if (ResourceMgr_IsGameMasterQuest()) {
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sGoronCityEntranceTextures_MQ[gSaveContext.nightFlag]));
|
||||
} else {
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sGoronCityEntranceTextures[gSaveContext.nightFlag]));
|
||||
}
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sGoronCityEntranceTextures[gSaveContext.nightFlag]));
|
||||
|
||||
{ s32 pad[2]; }
|
||||
|
||||
@@ -2295,11 +2266,7 @@ void func_8009FB74(PlayState* play) {
|
||||
|
||||
{ s32 pad[2]; }
|
||||
|
||||
if (ResourceMgr_IsGameMasterQuest()) {
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sLonLonRanchWindowTextures_MQ[gSaveContext.nightFlag]));
|
||||
} else {
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sLonLonRanchWindowTextures[gSaveContext.nightFlag]));
|
||||
}
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sLonLonRanchWindowTextures[gSaveContext.nightFlag]));
|
||||
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, 128, 128, 128, 128);
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
void Save_LoadFile(void);
|
||||
|
||||
void BossRush_InitSave(void);
|
||||
|
||||
/**
|
||||
* Initialize new save.
|
||||
* This save has an empty inventory with 3 hearts and single magic.
|
||||
@@ -33,6 +35,7 @@ void Sram_InitDebugSave(void) {
|
||||
|
||||
void Sram_InitBossRushSave(void) {
|
||||
Save_InitFile(false);
|
||||
BossRush_InitSave();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,11 +224,15 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) {
|
||||
|
||||
gSaveContext.n64ddFlag = fileChooseCtx->n64ddFlag;
|
||||
|
||||
if (fileChooseCtx->questType[fileChooseCtx->buttonIndex] == QUEST_RANDOMIZER &&
|
||||
u8 currentQuest = fileChooseCtx->questType[fileChooseCtx->buttonIndex];
|
||||
|
||||
if (currentQuest == QUEST_RANDOMIZER &&
|
||||
strnlen(CVarGetString("gSpoilerLog", ""), 1) != 0) {
|
||||
gSaveContext.questId = QUEST_RANDOMIZER;
|
||||
|
||||
Randomizer_InitSaveFile();
|
||||
} else if (currentQuest == QUEST_MASTER) {
|
||||
gSaveContext.questId = QUEST_MASTER;
|
||||
}
|
||||
|
||||
Save_SaveFile();
|
||||
|
||||
@@ -88,6 +88,7 @@ Gfx gKeyTreasureChestChestFrontDL[128] = {0};
|
||||
Gfx gChristmasRedTreasureChestChestFrontDL[128] = {0};
|
||||
Gfx gChristmasGreenTreasureChestChestFrontDL[128] = {0};
|
||||
u8 hasCreatedRandoChestTextures = 0;
|
||||
u8 hasCustomChestDLs = 0;
|
||||
u8 hasChristmasChestTexturesAvailable = 0;
|
||||
|
||||
void EnBox_SetupAction(EnBox* this, EnBoxActionFunc actionFunc) {
|
||||
@@ -690,7 +691,7 @@ void EnBox_UpdateSizeAndTexture(EnBox* this, PlayState* play) {
|
||||
}
|
||||
|
||||
// Change texture
|
||||
if (!isVanilla && (csmc == CSMC_BOTH || csmc == CSMC_TEXTURE)) {
|
||||
if (!isVanilla && hasCreatedRandoChestTextures && !hasCustomChestDLs && (csmc == CSMC_BOTH || csmc == CSMC_TEXTURE)) {
|
||||
switch (getItemCategory) {
|
||||
case ITEM_CATEGORY_MAJOR:
|
||||
this->boxBodyDL = gGoldTreasureChestChestFrontDL;
|
||||
@@ -725,7 +726,7 @@ void EnBox_UpdateSizeAndTexture(EnBox* this, PlayState* play) {
|
||||
}
|
||||
}
|
||||
|
||||
if (CVarGetInteger("gLetItSnow", 0) && hasChristmasChestTexturesAvailable) {
|
||||
if (CVarGetInteger("gLetItSnow", 0) && hasChristmasChestTexturesAvailable && hasCreatedRandoChestTextures && !hasCustomChestDLs) {
|
||||
if (this->dyna.actor.scale.x == 0.01f) {
|
||||
this->boxBodyDL = gChristmasRedTreasureChestChestFrontDL;
|
||||
this->boxLidDL = gChristmasRedTreasureChestChestSideAndLidDL;
|
||||
@@ -767,7 +768,18 @@ void EnBox_UpdateSizeAndTexture(EnBox* this, PlayState* play) {
|
||||
}
|
||||
|
||||
void EnBox_CreateExtraChestTextures() {
|
||||
// Don't patch textures for custom chest models, as they do not import textures the exact same way as vanilla chests
|
||||
// OTRTODO: Make it so model packs can provide a unique DL per chest type, instead of us copying the brown chest and attempting to patch
|
||||
if (ResourceMgr_FileIsCustomByName(gTreasureChestChestFrontDL) ||
|
||||
ResourceMgr_FileIsCustomByName(gTreasureChestChestSideAndLidDL)) {
|
||||
hasCustomChestDLs = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
hasCustomChestDLs = 0;
|
||||
|
||||
if (hasCreatedRandoChestTextures) return;
|
||||
|
||||
Gfx gTreasureChestChestTextures[] = {
|
||||
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, gSkullTreasureChestFrontTex),
|
||||
gsDPSetTextureImage(G_IM_FMT_RGBA, G_IM_SIZ_16b, 1, gSkullTreasureChestSideAndTopTex),
|
||||
|
||||
@@ -510,58 +510,60 @@ void UseItem(uint8_t usedItem, u8 started, Actor* thisx, PlayState* play) {
|
||||
|
||||
if (this->usedItem != 0xFF && this->itemTimer <= 0) {
|
||||
switch (usedItem) {
|
||||
case SLOT_STICK:
|
||||
case ITEM_STICK:
|
||||
UseDekuStick(this, play, started);
|
||||
break;
|
||||
case SLOT_BOMB:
|
||||
case ITEM_BOMB:
|
||||
UseBombs(this, play, started);
|
||||
break;
|
||||
case SLOT_BOMBCHU:
|
||||
case ITEM_BOMBCHU:
|
||||
UseBombchus(this, play, started);
|
||||
break;
|
||||
case SLOT_NUT:
|
||||
case ITEM_NUT:
|
||||
UseNuts(this, play, started);
|
||||
break;
|
||||
case SLOT_BOW:
|
||||
case ITEM_BOW:
|
||||
UseBow(this, play, started, 0);
|
||||
break;
|
||||
case SLOT_ARROW_FIRE:
|
||||
case ITEM_ARROW_FIRE:
|
||||
UseBow(this, play, started, 1);
|
||||
break;
|
||||
case SLOT_ARROW_ICE:
|
||||
case ITEM_ARROW_ICE:
|
||||
UseBow(this, play, started, 2);
|
||||
break;
|
||||
case SLOT_ARROW_LIGHT:
|
||||
case ITEM_ARROW_LIGHT:
|
||||
UseBow(this, play, started, 3);
|
||||
break;
|
||||
case SLOT_SLINGSHOT:
|
||||
case ITEM_SLINGSHOT:
|
||||
UseSlingshot(this, play, started);
|
||||
break;
|
||||
case SLOT_OCARINA:
|
||||
case ITEM_OCARINA_FAIRY:
|
||||
case ITEM_OCARINA_TIME:
|
||||
UseOcarina(this, play, started);
|
||||
break;
|
||||
case SLOT_HOOKSHOT:
|
||||
case ITEM_HOOKSHOT:
|
||||
case ITEM_LONGSHOT:
|
||||
UseHookshot(this, play, started);
|
||||
break;
|
||||
case SLOT_DINS_FIRE:
|
||||
case ITEM_DINS_FIRE:
|
||||
UseSpell(this, play, started, 1);
|
||||
break;
|
||||
case SLOT_NAYRUS_LOVE:
|
||||
case ITEM_NAYRUS_LOVE:
|
||||
UseSpell(this, play, started, 2);
|
||||
break;
|
||||
case SLOT_FARORES_WIND:
|
||||
case ITEM_FARORES_WIND:
|
||||
UseSpell(this, play, started, 3);
|
||||
break;
|
||||
case SLOT_HAMMER:
|
||||
case ITEM_HAMMER:
|
||||
UseHammer(this, play, started);
|
||||
break;
|
||||
case SLOT_BOOMERANG:
|
||||
case ITEM_BOOMERANG:
|
||||
UseBoomerang(this, play, started);
|
||||
break;
|
||||
case SLOT_LENS:
|
||||
case ITEM_LENS:
|
||||
UseLens(this, play, started);
|
||||
break;
|
||||
case SLOT_BEAN:
|
||||
case ITEM_BEAN:
|
||||
UseBeans(this, play, started);
|
||||
break;
|
||||
}
|
||||
@@ -685,39 +687,35 @@ void EnPartner_Update(Actor* thisx, PlayState* play) {
|
||||
uint8_t released = 0;
|
||||
uint8_t current = 0;
|
||||
|
||||
uint16_t partnerButtons[7] = { BTN_CLEFT, BTN_CDOWN, BTN_CRIGHT, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT};
|
||||
uint8_t buttonMax = 3;
|
||||
if (CVarGetInteger("gDpadEquips", 0) != 0) {
|
||||
buttonMax = ARRAY_COUNT(gSaveContext.equips.cButtonSlots);
|
||||
}
|
||||
|
||||
if (this->usedItem == 0xFF && this->itemTimer <= 0) {
|
||||
if (CHECK_BTN_ALL(sControlInput.press.button, BTN_CLEFT)) {
|
||||
this->usedItem = gSaveContext.equips.cButtonSlots[0];
|
||||
this->usedItemButton = 0;
|
||||
pressed = 1;
|
||||
} else if (CHECK_BTN_ALL(sControlInput.press.button, BTN_CDOWN)) {
|
||||
this->usedItem = gSaveContext.equips.cButtonSlots[1];
|
||||
this->usedItemButton = 1;
|
||||
pressed = 1;
|
||||
} else if (CHECK_BTN_ALL(sControlInput.press.button, BTN_CRIGHT)) {
|
||||
this->usedItem = gSaveContext.equips.cButtonSlots[2];
|
||||
this->usedItemButton = 2;
|
||||
pressed = 1;
|
||||
for (uint8_t i = 0; i < buttonMax; i++) {
|
||||
if (CHECK_BTN_ALL(sControlInput.press.button, partnerButtons[i])) {
|
||||
this->usedItem = gSaveContext.equips.buttonItems[i+1];
|
||||
this->usedItemButton = i;
|
||||
pressed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this->usedItem != 0xFF) {
|
||||
if (CHECK_BTN_ALL(sControlInput.cur.button, BTN_CLEFT) && this->usedItemButton == 0) {
|
||||
current = 1;
|
||||
} else if (CHECK_BTN_ALL(sControlInput.cur.button, BTN_CDOWN) && this->usedItemButton == 1) {
|
||||
current = 1;
|
||||
} else if (CHECK_BTN_ALL(sControlInput.cur.button, BTN_CRIGHT) && this->usedItemButton == 2) {
|
||||
current = 1;
|
||||
for (uint8_t i = 0; i < buttonMax; i++) {
|
||||
if (CHECK_BTN_ALL(sControlInput.cur.button, partnerButtons[i]) && this->usedItemButton == i) {
|
||||
current = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this->usedItem != 0xFF) {
|
||||
if (CHECK_BTN_ALL(sControlInput.rel.button, BTN_CLEFT) && this->usedItemButton == 0) {
|
||||
released = 1;
|
||||
} else if (CHECK_BTN_ALL(sControlInput.rel.button, BTN_CDOWN) && this->usedItemButton == 1) {
|
||||
released = 1;
|
||||
} else if (CHECK_BTN_ALL(sControlInput.rel.button, BTN_CRIGHT) && this->usedItemButton == 2) {
|
||||
released = 1;
|
||||
for (uint8_t i = 0; i < buttonMax; i++) {
|
||||
if (CHECK_BTN_ALL(sControlInput.rel.button, partnerButtons[i]) && this->usedItemButton == i) {
|
||||
released = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10101,6 +10101,55 @@ void func_80847BA0(PlayState* play, Player* this) {
|
||||
|
||||
D_808535F0 = func_80041DB8(&play->colCtx, this->actor.wallPoly, this->actor.wallBgId);
|
||||
|
||||
if (CVarGetInteger("gFixVineFall", 0)) {
|
||||
/* This fixes the "started climbing a wall and then immediately fell off" bug.
|
||||
* The main idea is if a climbing wall is detected, double-check that it will
|
||||
* still be valid once climbing begins by doing a second raycast with a small
|
||||
* margin to make sure it still hits a climbable poly. Then update the flags
|
||||
* in D_808535F0 again and proceed as normal.
|
||||
*/
|
||||
if (D_808535F0 & 8) {
|
||||
Vec3f checkPosA;
|
||||
Vec3f checkPosB;
|
||||
f32 yawCos;
|
||||
f32 yawSin;
|
||||
s32 hitWall;
|
||||
|
||||
/* Angle the raycast slightly out towards the side based on the angle of
|
||||
* attack the player takes coming at the climb wall. This is necessary because
|
||||
* the player's XZ position actually wobbles very slightly while climbing
|
||||
* due to small rounding errors in the sin/cos lookup tables. This wobble
|
||||
* can cause wall checks while climbing to be slightly left or right of
|
||||
* the wall check to start the climb. By adding this buffer it accounts for
|
||||
* any possible wobble. The end result is the player has to be further than
|
||||
* some epsilon distance from the edge of the climbing poly to actually
|
||||
* start the climb. I divide it by 2 to make that epsilon slightly smaller,
|
||||
* mainly for visuals. Using the full sp9A leaves a noticeable gap on
|
||||
* the edges that can't be climbed. But with the half distance it looks like
|
||||
* the player is climbing right on the edge, and still works.
|
||||
*/
|
||||
yawCos = Math_CosS(this->actor.wallYaw - (sp9A / 2) + 0x8000);
|
||||
yawSin = Math_SinS(this->actor.wallYaw - (sp9A / 2) + 0x8000);
|
||||
checkPosA.x = this->actor.world.pos.x + (-20.0f * yawSin);
|
||||
checkPosA.z = this->actor.world.pos.z + (-20.0f * yawCos);
|
||||
checkPosB.x = this->actor.world.pos.x + (50.0f * yawSin);
|
||||
checkPosB.z = this->actor.world.pos.z + (50.0f * yawCos);
|
||||
checkPosB.y = checkPosA.y = this->actor.world.pos.y + 26.0f;
|
||||
|
||||
hitWall = BgCheck_EntityLineTest1(&play->colCtx, &checkPosA, &checkPosB,
|
||||
&D_80858AA8, &spA0, true, false, false, true, &sp9C);
|
||||
|
||||
if (hitWall) {
|
||||
this->actor.wallPoly = spA0;
|
||||
this->actor.wallBgId = sp9C;
|
||||
this->actor.wallYaw = Math_Atan2S(spA0->normal.z, spA0->normal.x);
|
||||
sp9A = this->actor.shape.rot.y - (s16)(this->actor.wallYaw + 0x8000);
|
||||
|
||||
D_808535F0 = func_80041DB8(&play->colCtx, this->actor.wallPoly, this->actor.wallBgId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
D_80853608 = ABS(sp9A);
|
||||
|
||||
sp9A = this->currentYaw - (s16)(this->actor.wallYaw + 0x8000);
|
||||
@@ -15120,6 +15169,10 @@ void func_80852C50(PlayState* play, Player* this, CsCmdActorAction* arg2) {
|
||||
|
||||
sp24 = D_808547C4[this->unk_446];
|
||||
func_80852B4C(play, this, linkCsAction, &D_80854E50[ABS(sp24)]);
|
||||
|
||||
if (CVarGetInteger("gFixEyesOpenWhileSleeping", 0) && (play->csCtx.linkAction->action == 28 || play->csCtx.linkAction->action == 29)) {
|
||||
this->skelAnime.jointTable[22].x = 8;
|
||||
}
|
||||
}
|
||||
|
||||
void func_80852E14(Player* this, PlayState* play) {
|
||||
|
||||
@@ -1293,8 +1293,6 @@ void FileChoose_UpdateQuestMenu(GameState* thisx) {
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
|
||||
gSaveContext.questId = this->questType[this->buttonIndex];
|
||||
|
||||
gSaveContext.isBossRushPaused = false;
|
||||
|
||||
if (this->questType[this->buttonIndex] == QUEST_BOSSRUSH) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
this->prevConfigMode = this->configMode;
|
||||
@@ -2819,10 +2817,6 @@ void FileChoose_ConfirmFile(GameState* thisx) {
|
||||
if (this->confirmButtonIndex == FS_BTN_CONFIRM_YES) {
|
||||
func_800AA000(300.0f, 180, 20, 100);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
// Reset Boss Rush because it's only ever saved in memory.
|
||||
if (IS_BOSS_RUSH) {
|
||||
gSaveContext.questId = QUEST_NORMAL;
|
||||
}
|
||||
this->selectMode = SM_FADE_OUT;
|
||||
func_800F6964(0xF);
|
||||
} else {
|
||||
|
||||
@@ -4290,6 +4290,8 @@ void KaleidoScope_Update(PlayState* play)
|
||||
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ENTRANCES)) {
|
||||
Grotto_ForceGrottoReturn();
|
||||
}
|
||||
// Reset frame counter to prevent autosave on respawn
|
||||
play->gameplayFrames = 0;
|
||||
gSaveContext.nextTransitionType = 2;
|
||||
gSaveContext.health = CVarGetInteger("gFullHealthSpawn", 0) ? gSaveContext.healthCapacity : 0x30;
|
||||
Audio_QueueSeqCmd(0xF << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0xA);
|
||||
@@ -4307,9 +4309,6 @@ void KaleidoScope_Update(PlayState* play)
|
||||
osSyncPrintf(VT_RST);
|
||||
} else {
|
||||
play->state.running = 0;
|
||||
if (IS_BOSS_RUSH) {
|
||||
gSaveContext.questId = QUEST_NORMAL;
|
||||
}
|
||||
SET_NEXT_GAMESTATE(&play->state, Opening_Init, OpeningContext);
|
||||
GameInteractor_ExecuteOnExitGame(gSaveContext.fileNum);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user