mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-21 23:58:51 -05:00
V1 - Chestapalooza (#2922)
* V1- Adds additional trap variants to Chests * Create and use OnTrapProcessed hook * Update naming for Traps, extends to NPC and Token Rewards. New Hook for Rando traps. Restore Vanilla code for ice traps. * Update soh/src/overlays/actors/ovl_player_actor/z_player.c Co-authored-by: Garrett Cox <garrettjcox@gmail.com> * More tweaks, remove processed trap hook --------- Co-authored-by: Garrett Cox <garrettjcox@gmail.com>
This commit is contained in:
parent
bea24fcde7
commit
0e7c658523
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
void GameInteractor::RawAction::BurnPlayer() {
|
||||
|
@ -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"
|
||||
@ -16,7 +17,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;
|
||||
@ -600,6 +601,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;
|
||||
|
||||
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();
|
||||
@ -622,5 +771,6 @@ void InitMods() {
|
||||
RegisterBonkDamage();
|
||||
RegisterMenuPathFix();
|
||||
RegisterMirrorModeHandler();
|
||||
RegisterAltTrapTypes();
|
||||
NameTag_RegisterHooks();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -1101,6 +1101,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();
|
||||
}
|
||||
|
||||
|
@ -627,9 +627,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) {
|
||||
|
@ -988,10 +988,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);
|
||||
}
|
||||
|
@ -6326,6 +6326,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);
|
||||
@ -6361,7 +6363,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;
|
||||
}
|
||||
@ -12790,7 +12791,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;
|
||||
@ -12949,7 +12949,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);
|
||||
@ -12959,15 +12958,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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user