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

V1 - Chestapalooza #2922

Merged
merged 9 commits into from
Aug 30, 2023
1 change: 1 addition & 0 deletions soh/soh/Enhancements/game-interactor/GameInteractor.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ class GameInteractor {
DEFINE_HOOK(OnExitGame, void(int32_t fileNum));
DEFINE_HOOK(OnGameFrameUpdate, void());
DEFINE_HOOK(OnItemReceive, void(GetItemEntry itemEntry));
DEFINE_HOOK(OnTrapProcessed, void());
DEFINE_HOOK(OnSaleEnd, void(GetItemEntry itemEntry));
DEFINE_HOOK(OnTransitionEnd, void(int16_t sceneNum));
DEFINE_HOOK(OnSceneInit, void(int16_t sceneNum));
Expand Down
4 changes: 4 additions & 0 deletions soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnItemReceive>(itemEntry);
}

void GameInteractor_ExecuteOnTrapProcessedHooks() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnTrapProcessed>();
}

void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSaleEnd>(itemEntry);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ void GameInteractor_ExecuteOnLoadGame(int32_t fileNum);
void GameInteractor_ExecuteOnExitGame(int32_t fileNum);
void GameInteractor_ExecuteOnGameFrameUpdate();
void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry);
void GameInteractor_ExecuteOnTrapProcessedHooks();
void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry);
void GameInteractor_ExecuteOnTransitionEndHooks(int16_t sceneNum);
void GameInteractor_ExecuteOnSceneInit(int16_t sceneNum);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ void GameInteractor::RawAction::ForceEquipBoots(int8_t boots) {
}

void GameInteractor::RawAction::FreezePlayer() {
gSaveContext.pendingIceTrapCount++;
Player* player = GET_PLAYER(gPlayState);
player->actor.colChkInfo.damage = 0;
func_80837C0C(gPlayState, player, 3, 0, 0, 0, 0);
Comment on lines +106 to +108
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change was required because the ice traps can now be processed by game interactor, so this caused a infinite loop of ice traps. Not sure if there is a better way to handle this..

}

void GameInteractor::RawAction::BurnPlayer() {
Expand Down
149 changes: 148 additions & 1 deletion soh/soh/Enhancements/mods.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "mods.h"
#include <libultraship/bridge.h>
#include "game-interactor/GameInteractor.h"
#include "soh/Enhancements/randomizer/3drando/random.hpp"
#include "tts/tts.h"
#include "soh/Enhancements/boss-rush/BossRushTypes.h"
#include "soh/Enhancements/enhancementTypes.h"
Expand All @@ -15,7 +16,7 @@ extern "C" {
#include "functions.h"
extern SaveContext gSaveContext;
extern PlayState* gPlayState;

extern void Overlay_DisplayText(float duration, const char* text);
uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum);
}
bool performDelayedSave = false;
Expand Down Expand Up @@ -599,6 +600,151 @@ void RegisterMirrorModeHandler() {
});
}

typedef enum {
ADD_ICE_TRAP,
ADD_BURN_TRAP,
ADD_SHOCK_TRAP,
ADD_KNOCK_TRAP,
ADD_SPEED_TRAP,
ADD_BOMB_TRAP,
ADD_VOID_TRAP,
ADD_AMMO_TRAP,
ADD_KILL_TRAP,
ADD_TELEPORT_TRAP,
ADD_TRAP_MAX
} AltTrapType;

const char* altTrapTypeCvars[] = {
"gAddTraps.Ice",
"gAddTraps.Burn",
"gAddTraps.Shock",
"gAddTraps.Knock",
"gAddTraps.Speed",
"gAddTraps.Bomb",
"gAddTraps.Void",
"gAddTraps.Ammo",
"gAddTraps.Kill",
"gAddTraps.Tele"
};

std::vector<AltTrapType> getEnabledAddTraps () {
std::vector<AltTrapType> enabledAddTraps;
for (int i = 0; i < ADD_TRAP_MAX; i++) {
if (CVarGetInteger(altTrapTypeCvars[i], 0)) {
enabledAddTraps.push_back(static_cast<AltTrapType>(i));
}
}
return enabledAddTraps;
};

void RegisterAltTrapTypes() {
static AltTrapType roll = ADD_TRAP_MAX;
static int statusTimer = -1;
static int eventTimer = -1;
Caladius marked this conversation as resolved.
Show resolved Hide resolved

GameInteractor::Instance->RegisterGameHook<GameInteractor::OnTrapProcessed>([]() {
if (!CVarGetInteger("gAddTraps.enabled", 0)) {
return;
}
roll = RandomElement(getEnabledAddTraps());
switch (roll) {
case ADD_ICE_TRAP:
GameInteractor::RawAction::FreezePlayer();
break;
case ADD_BURN_TRAP:
GameInteractor::RawAction::BurnPlayer();
break;
case ADD_SHOCK_TRAP:
GameInteractor::RawAction::ElectrocutePlayer();
break;
case ADD_KNOCK_TRAP:
eventTimer = 3;
break;
case ADD_SPEED_TRAP:
Audio_PlaySoundGeneral(NA_SE_VO_KZ_MOVE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
GameInteractor::State::RunSpeedModifier = -2;
statusTimer = 200;
Overlay_DisplayText(10, "Speed Decreased!");
break;
case ADD_BOMB_TRAP:
eventTimer = 3;
break;
case ADD_VOID_TRAP:
Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
eventTimer = 3;
break;
case ADD_AMMO_TRAP:
eventTimer = 3;
Overlay_DisplayText(5, "Ammo Halved!");
break;
case ADD_KILL_TRAP:
GameInteractor::RawAction::SetPlayerHealth(0);
break;
case ADD_TELEPORT_TRAP:
eventTimer = 3;
break;
}
});
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerUpdate>([]() {
Player* player = GET_PLAYER(gPlayState);
if (statusTimer == 0) {
GameInteractor::State::RunSpeedModifier = 0;
}
if (eventTimer == 0) {
switch (roll) {
case ADD_KNOCK_TRAP:
GameInteractor::RawAction::KnockbackPlayer(1);
break;
case ADD_BOMB_TRAP:
GameInteractor::RawAction::SpawnActor(ACTOR_EN_BOM, 1);
break;
case ADD_VOID_TRAP:
Play_TriggerRespawn(gPlayState);
break;
case ADD_AMMO_TRAP:
AMMO(ITEM_STICK) = AMMO(ITEM_STICK) * 0.5;
AMMO(ITEM_NUT) = AMMO(ITEM_NUT) * 0.5;
AMMO(ITEM_SLINGSHOT) = AMMO(ITEM_SLINGSHOT) * 0.5;
AMMO(ITEM_BOW) = AMMO(ITEM_BOW) * 0.5;
AMMO(ITEM_BOMB) = AMMO(ITEM_BOMB) * 0.5;
AMMO(ITEM_BOMBCHU) = AMMO(ITEM_BOMBCHU) * 0.5;
Audio_PlaySoundGeneral(NA_SE_VO_FR_SMILE_0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
break;
case ADD_TELEPORT_TRAP:
int entrance;
int index = 1 + rand() % 10;
switch (index) {
case 1:
entrance = GI_TP_DEST_SERENADE;
break;
case 2:
entrance = GI_TP_DEST_REQUIEM;
break;
case 3:
entrance = GI_TP_DEST_BOLERO;
break;
case 4:
entrance = GI_TP_DEST_MINUET;
break;
case 5:
entrance = GI_TP_DEST_NOCTURNE;
break;
case 6:
entrance = GI_TP_DEST_PRELUDE;
break;
default:
entrance = GI_TP_DEST_LINKSHOUSE;
break;
}
GameInteractor::RawAction::TeleportPlayer(entrance);
break;
}
}
statusTimer--;
eventTimer--;
});
}

void InitMods() {
RegisterTTS();
RegisterInfiniteMoney();
Expand All @@ -621,4 +767,5 @@ void InitMods() {
RegisterBonkDamage();
RegisterMenuPathFix();
RegisterMirrorModeHandler();
RegisterAltTrapTypes();
}
33 changes: 33 additions & 0 deletions soh/soh/SohMenuBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,39 @@ void DrawEnhancementsMenu() {
UIWidgets::PaddedEnhancementCheckbox("Shadow Tag Mode", "gShadowTag", true, false);
UIWidgets::Tooltip("A wallmaster follows Link everywhere, don't get caught!");

UIWidgets::Spacer(0);

UIWidgets::PaddedEnhancementCheckbox("Additional Traps", "gAddTraps.enabled", true, false);
UIWidgets::Tooltip("Enables additional Trap variants.");

if (CVarGetInteger("gAddTraps.enabled", 0)) {
UIWidgets::PaddedSeparator();
if (ImGui::BeginMenu("Trap Options")) {
ImGui::Text("Tier 1 Traps:");
UIWidgets::Spacer(0);
UIWidgets::PaddedEnhancementCheckbox("Freeze Traps", "gAddTraps.Ice", true, false);
UIWidgets::PaddedEnhancementCheckbox("Burn Traps", "gAddTraps.Burn", true, false);
UIWidgets::PaddedEnhancementCheckbox("Shock Traps", "gAddTraps.Shock", true, false);

UIWidgets::PaddedSeparator();
ImGui::Text("Tier 2 Traps:");
UIWidgets::Spacer(0);
UIWidgets::PaddedEnhancementCheckbox("Knockback Traps", "gAddTraps.Knock", true, false);
UIWidgets::PaddedEnhancementCheckbox("Speed Traps", "gAddTraps.Speed", true, false);
UIWidgets::PaddedEnhancementCheckbox("Bomb Traps", "gAddTraps.Bomb", true, false);

UIWidgets::PaddedSeparator();
ImGui::Text("Tier 3 Traps:");
UIWidgets::Spacer(0);
UIWidgets::PaddedEnhancementCheckbox("Void Traps", "gAddTraps.Void", true, false);
UIWidgets::PaddedEnhancementCheckbox("Ammo Traps", "gAddTraps.Ammo", true, false);
UIWidgets::PaddedEnhancementCheckbox("Death Traps", "gAddTraps.Kill", true, false);
UIWidgets::PaddedEnhancementCheckbox("Teleport Traps", "gAddTraps.Tele", true, false);

ImGui::EndMenu();
}
}

ImGui::EndMenu();
}

Expand Down
11 changes: 7 additions & 4 deletions soh/src/overlays/actors/ovl_En_Box/z_en_box.c
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ void EnBox_SpawnIceSmoke(EnBox* this, PlayState* play) {
if (Rand_ZeroOne() < 0.3f) {
f0 = 2.0f * Rand_ZeroOne() - 1.0f;
pos = this->dyna.actor.world.pos;
if (this->type == ENBOX_TYPE_SMALL || this->type == ENBOX_TYPE_6 || this->type == ENBOX_TYPE_ROOM_CLEAR_SMALL ||
if (this->type == ENBOX_TYPE_SMALL || this->type == ENBOX_TYPE_6 || this->type == ENBOX_TYPE_ROOM_CLEAR_SMALL ||
Caladius marked this conversation as resolved.
Show resolved Hide resolved
this->type == ENBOX_TYPE_SWITCH_FLAG_FALL_SMALL) {
pos.x += f0 * 10.0f * Math_SinS(this->dyna.actor.world.rot.y + 0x4000);
pos.z += f0 * 10.0f * Math_CosS(this->dyna.actor.world.rot.y + 0x4000);
Expand Down Expand Up @@ -626,9 +626,12 @@ void EnBox_Update(Actor* thisx, PlayState* play) {
}

if (((!gSaveContext.n64ddFlag && ((this->dyna.actor.params >> 5 & 0x7F) == 0x7C)) ||
(gSaveContext.n64ddFlag && ABS(sItem.getItemId) == RG_ICE_TRAP)) &&
this->actionFunc == EnBox_Open && this->skelanime.curFrame > 45 &&
this->iceSmokeTimer < 100) EnBox_SpawnIceSmoke(this, play);
(gSaveContext.n64ddFlag && ABS(sItem.getItemId) == RG_ICE_TRAP)) &&
this->actionFunc == EnBox_Open && this->skelanime.curFrame > 45 && this->iceSmokeTimer < 100) {
if (!CVarGetInteger("gAddTraps.enabled", 0)) {
EnBox_SpawnIceSmoke(this, play);
}
}
}

void EnBox_UpdateSizeAndTexture(EnBox* this, PlayState* play) {
Expand Down
17 changes: 9 additions & 8 deletions soh/src/overlays/actors/ovl_player_actor/z_player.c
Original file line number Diff line number Diff line change
Expand Up @@ -6319,6 +6319,8 @@ s32 func_8083E5A8(Player* this, PlayState* play) {

if(gSaveContext.pendingIceTrapCount) {
gSaveContext.pendingIceTrapCount--;
GameInteractor_ExecuteOnTrapProcessedHooks();
if (CVarGetInteger("gChestTraps.enabled", 0)) return;
Caladius marked this conversation as resolved.
Show resolved Hide resolved
this->stateFlags1 &= ~(PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD);
this->actor.colChkInfo.damage = 0;
func_80837C0C(play, this, 3, 0.0f, 0.0f, 0, 20);
Expand Down Expand Up @@ -12942,7 +12944,6 @@ void func_8084E6D4(Player* this, PlayState* play) {
}
} else {
func_80832DBC(this);

if ((this->getItemId == GI_ICE_TRAP && !gSaveContext.n64ddFlag) ||
(gSaveContext.n64ddFlag && (this->getItemId == RG_ICE_TRAP || this->getItemEntry.getItemId == RG_ICE_TRAP))) {
this->stateFlags1 &= ~(PLAYER_STATE1_GETTING_ITEM | PLAYER_STATE1_ITEM_OVER_HEAD);
Expand All @@ -12953,22 +12954,22 @@ void func_8084E6D4(Player* this, PlayState* play) {
this->actor.world.pos.y + 100.0f, this->actor.world.pos.z, 0, 0, 0, 0, true);
func_8083C0E8(this, play);
GameInteractor_ExecuteOnItemReceiveHooks(this->getItemEntry);
} else if (gSaveContext.n64ddFlag) {
gSaveContext.pendingIceTrapCount++;
Player_SetPendingFlag(this, play);
func_8083C0E8(this, play);
GameInteractor_ExecuteOnItemReceiveHooks(this->getItemEntry);
} else {
this->actor.colChkInfo.damage = 0;
func_80837C0C(play, this, 3, 0.0f, 0.0f, 0, 20);
GameInteractor_ExecuteOnItemReceiveHooks(this->getItemEntry);
this->getItemId = GI_NONE;
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
// Gameplay stats: Increment Ice Trap count
gSaveContext.sohStats.count[COUNT_ICE_TRAPS]++;
}
return;
}

if (this->skelAnime.animation == &gPlayerAnim_link_normal_box_kick) {
func_808322D0(play, this, &gPlayerAnim_link_demo_get_itemB);
func_808322D0(play, this, &gPlayerAnim_link_demo_get_itemB);
} else {
func_808322D0(play, this, &gPlayerAnim_link_demo_get_itemA);
func_808322D0(play, this, &gPlayerAnim_link_demo_get_itemA);
}

this->unk_850 = 2;
Expand Down