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
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ namespace GameInteractionEffect {
// MARK: - FreezePlayer
GameInteractionEffectQueryResult FreezePlayer::CanBeApplied() {
Player* player = GET_PLAYER(gPlayState);
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
} else {
return GameInteractionEffectQueryResult::Possible;
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
152 changes: 151 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,154 @@ 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));
}
}
if (enabledAddTraps.size() == 0) {
enabledAddTraps.push_back(ADD_ICE_TRAP);
}
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::OnItemReceive>([](GetItemEntry itemEntry) {
if (!CVarGetInteger("gAddTraps.enabled", 0) || itemEntry.modIndex != MOD_RANDOMIZER || itemEntry.getItemId != RG_ICE_TRAP) {
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 +770,5 @@ void InitMods() {
RegisterBonkDamage();
RegisterMenuPathFix();
RegisterMirrorModeHandler();
RegisterAltTrapTypes();
}
1 change: 0 additions & 1 deletion soh/soh/Enhancements/randomizer/savefile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ void StartingItemGive(GetItemEntry getItemEntry) {
} else if (getItemEntry.modIndex == MOD_RANDOMIZER) {
if (getItemEntry.getItemId == RG_ICE_TRAP) {
gSaveContext.pendingIceTrapCount++;
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnItemReceive>(getItemEntry);
} else {
Randomizer_Item_Give(NULL, getItemEntry);
}
Expand Down
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
9 changes: 6 additions & 3 deletions soh/src/overlays/actors/ovl_En_Box/z_en_box.c
Original file line number Diff line number Diff line change
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
4 changes: 0 additions & 4 deletions soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c
Original file line number Diff line number Diff line change
Expand Up @@ -982,10 +982,6 @@ void EnGirlA_ItemGive_Randomizer(PlayState* play, EnGirlA* this) {
Randomizer_Item_Give(play, getItemEntry);
}

if (getItemEntry.itemId == GI_ICE_TRAP || getItemEntry.itemId == RG_ICE_TRAP) {
GameInteractor_ExecuteOnItemReceiveHooks(getItemEntry);
}

Flags_SetRandomizerInf(shopItemIdentity.randomizerInf);
Rupees_ChangeBy(-this->basePrice);
}
Expand Down
15 changes: 6 additions & 9 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_ExecuteOnItemReceiveHooks(ItemTable_RetrieveEntry(MOD_RANDOMIZER, RG_ICE_TRAP));
if (CVarGetInteger("gAddTraps.enabled", 0)) return;
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 @@ -6354,7 +6356,6 @@ s32 func_8083E5A8(Player* this, PlayState* play) {
Player_SetPendingFlag(this, play);
Message_StartTextbox(play, 0xF8, NULL);
Audio_PlayFanfare(NA_BGM_SMALL_ITEM_GET);
GameInteractor_ExecuteOnItemReceiveHooks(this->getItemEntry);
gSaveContext.pendingIceTrapCount++;
return 1;
}
Expand Down Expand Up @@ -12783,7 +12784,6 @@ s32 func_8084DFF4(PlayState* play, Player* this) {
this->unk_862 = 0;
gSaveContext.pendingIceTrapCount++;
Player_SetPendingFlag(this, play);
GameInteractor_ExecuteOnItemReceiveHooks(giEntry);
}

this->getItemId = GI_NONE;
Expand Down Expand Up @@ -12942,7 +12942,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 @@ -12952,15 +12951,13 @@ void func_8084E6D4(Player* this, PlayState* play) {
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x,
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);
} 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;
}
Expand Down