/* GameInteractionEffects is used in conjunction with GameInteractor. It's intended to be used in places that want to interact with the game while having checks built-in for if said effect is able to be executed. Effects that can last for a certain amount of time (timed effects) have functions to both enable and disable said effect. */ #include "GameInteractionEffect.h" #include "GameInteractor.h" #include extern "C" { #include #include "variables.h" #include "functions.h" #include "macros.h" extern PlayState* gPlayState; } GameInteractionEffectQueryResult GameInteractionEffectBase::Apply() { GameInteractionEffectQueryResult result = CanBeApplied(); if (result != GameInteractionEffectQueryResult::Possible) { return result; } _Apply(); return result; } /// For most effects, CanBeRemoved is the same as CanBeApplied. When its not: please override `CanBeRemoved`. GameInteractionEffectQueryResult RemovableGameInteractionEffect::CanBeRemoved() { return CanBeApplied(); } GameInteractionEffectQueryResult RemovableGameInteractionEffect::Remove() { GameInteractionEffectQueryResult result = CanBeRemoved(); if (result != GameInteractionEffectQueryResult::Possible) { return result; } _Remove(); return result; } namespace GameInteractionEffect { // MARK: - Flags GameInteractionEffectQueryResult SetSceneFlag::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } return GameInteractionEffectQueryResult::Possible; } void SetSceneFlag::_Apply() { GameInteractor::RawAction::SetSceneFlag(parameters[0], parameters[1], parameters[2]); } GameInteractionEffectQueryResult UnsetSceneFlag::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } return GameInteractionEffectQueryResult::Possible; } void UnsetSceneFlag::_Apply() { GameInteractor::RawAction::UnsetSceneFlag(parameters[0], parameters[1], parameters[2]); } GameInteractionEffectQueryResult SetFlag::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } return GameInteractionEffectQueryResult::Possible; } void SetFlag::_Apply() { GameInteractor::RawAction::SetFlag(parameters[0], parameters[1]); } GameInteractionEffectQueryResult UnsetFlag::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } return GameInteractionEffectQueryResult::Possible; } void UnsetFlag::_Apply() { GameInteractor::RawAction::UnsetFlag(parameters[0], parameters[1]); } // MARK: - ModifyHeartContainers GameInteractionEffectQueryResult ModifyHeartContainers::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else if ( (parameters[0] > 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) > 0x140)) || (parameters[0] < 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) < 0x10)) ) { return GameInteractionEffectQueryResult::NotPossible; } return GameInteractionEffectQueryResult::Possible; } void ModifyHeartContainers::_Apply() { GameInteractor::RawAction::AddOrRemoveHealthContainers(parameters[0]); } // MARK: - FillMagic GameInteractionEffectQueryResult FillMagic::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else if (!gSaveContext.isMagicAcquired || gSaveContext.magic >= ((gSaveContext.isDoubleMagicAcquired + 1) * 48)) { return GameInteractionEffectQueryResult::NotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void FillMagic::_Apply() { GameInteractor::RawAction::AddOrRemoveMagic(96); } // MARK: - EmptyMagic GameInteractionEffectQueryResult EmptyMagic::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else if (!gSaveContext.isMagicAcquired || gSaveContext.magic <= 0) { return GameInteractionEffectQueryResult::NotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void EmptyMagic::_Apply() { GameInteractor::RawAction::AddOrRemoveMagic(-96); } // MARK: - ModifyRupees GameInteractionEffectQueryResult ModifyRupees::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else if ( (parameters[0] < 0 && gSaveContext.rupees <= 0) || (parameters[0] > 0 && gSaveContext.rupees >= CUR_CAPACITY(UPG_WALLET)) ) { return GameInteractionEffectQueryResult::NotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void ModifyRupees::_Apply() { Rupees_ChangeBy(parameters[0]); } // MARK: - NoUI GameInteractionEffectQueryResult NoUI::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void NoUI::_Apply() { GameInteractor::State::NoUIActive = 1; } void NoUI::_Remove() { GameInteractor::State::NoUIActive = 0; } // MARK: - ModifyGravity GameInteractionEffectQueryResult ModifyGravity::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void ModifyGravity::_Apply() { GameInteractor::State::GravityLevel = (GIGravityLevel)parameters[0]; } void ModifyGravity::_Remove() { GameInteractor::State::GravityLevel = GI_GRAVITY_LEVEL_NORMAL; } // MARK: - ModifyHealth GameInteractionEffectQueryResult ModifyHealth::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else if ( (parameters[0] > 0 && gSaveContext.health == gSaveContext.healthCapacity) || (parameters[0] < 0 && (gSaveContext.health + (16 * parameters[0]) <= 0)) ) { return GameInteractionEffectQueryResult::NotPossible; } return GameInteractionEffectQueryResult::Possible; } void ModifyHealth::_Apply() { GameInteractor::RawAction::HealOrDamagePlayer(parameters[0]); } // MARK: - SetPlayerHealth GameInteractionEffectQueryResult SetPlayerHealth::CanBeApplied() { Player* player = GET_PLAYER(gPlayState); if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void SetPlayerHealth::_Apply() { GameInteractor::RawAction::SetPlayerHealth(parameters[0]); } // MARK: - FreezePlayer GameInteractionEffectQueryResult FreezePlayer::CanBeApplied() { Player* player = GET_PLAYER(gPlayState); if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void FreezePlayer::_Apply() { GameInteractor::RawAction::FreezePlayer(); } // MARK: - BurnPlayer GameInteractionEffectQueryResult BurnPlayer::CanBeApplied() { Player* player = GET_PLAYER(gPlayState); if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void BurnPlayer::_Apply() { GameInteractor::RawAction::BurnPlayer(); } // MARK: - ElectrocutePlayer GameInteractionEffectQueryResult ElectrocutePlayer::CanBeApplied() { Player* player = GET_PLAYER(gPlayState); if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || !PlayerGrounded(player)) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void ElectrocutePlayer::_Apply() { GameInteractor::RawAction::ElectrocutePlayer(); } // MARK: - KnockbackPlayer GameInteractionEffectQueryResult KnockbackPlayer::CanBeApplied() { Player* player = GET_PLAYER(gPlayState); if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused() || player->stateFlags2 & PLAYER_STATE2_CRAWLING) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void KnockbackPlayer::_Apply() { GameInteractor::RawAction::KnockbackPlayer(parameters[0]); } // MARK: - ModifyLinkSize GameInteractionEffectQueryResult ModifyLinkSize::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void ModifyLinkSize::_Apply() { GameInteractor::State::LinkSize = (GILinkSize)parameters[0]; } void ModifyLinkSize::_Remove() { GameInteractor::State::LinkSize = GI_LINK_SIZE_RESET; } // MARK: - InvisibleLink GameInteractionEffectQueryResult InvisibleLink::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void InvisibleLink::_Apply() { GameInteractor::RawAction::SetLinkInvisibility(true); } void InvisibleLink::_Remove() { GameInteractor::RawAction::SetLinkInvisibility(false); } // MARK: - PacifistMode GameInteractionEffectQueryResult PacifistMode::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void PacifistMode::_Apply() { GameInteractor::State::SetPacifistMode(true); } void PacifistMode::_Remove() { GameInteractor::State::SetPacifistMode(false); } // MARK: - DisableZTargeting GameInteractionEffectQueryResult DisableZTargeting::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void DisableZTargeting::_Apply() { GameInteractor::State::DisableZTargetingActive = 1; } void DisableZTargeting::_Remove() { GameInteractor::State::DisableZTargetingActive = 0; } // MARK: - WeatherRainstorm GameInteractionEffectQueryResult WeatherRainstorm::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void WeatherRainstorm::_Apply() { GameInteractor::RawAction::SetWeatherStorm(true); } void WeatherRainstorm::_Remove() { GameInteractor::RawAction::SetWeatherStorm(false); } // MARK: - ReverseControls GameInteractionEffectQueryResult ReverseControls::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void ReverseControls::_Apply() { GameInteractor::State::ReverseControlsActive = 1; } void ReverseControls::_Remove() { GameInteractor::State::ReverseControlsActive = 0; } // MARK: - ForceEquipBoots GameInteractionEffectQueryResult ForceEquipBoots::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void ForceEquipBoots::_Apply() { GameInteractor::RawAction::ForceEquipBoots(parameters[0]); } void ForceEquipBoots::_Remove() { GameInteractor::RawAction::ForceEquipBoots(EQUIP_VALUE_BOOTS_KOKIRI); } // MARK: - ModifyRunSpeedModifier GameInteractionEffectQueryResult ModifyRunSpeedModifier::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void ModifyRunSpeedModifier::_Apply() { GameInteractor::State::RunSpeedModifier = parameters[0]; } void ModifyRunSpeedModifier::_Remove() { GameInteractor::State::RunSpeedModifier = 0; } // MARK: - OneHitKO GameInteractionEffectQueryResult OneHitKO::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void OneHitKO::_Apply() { GameInteractor::State::OneHitKOActive = 1; } void OneHitKO::_Remove() { GameInteractor::State::OneHitKOActive = 0; } // MARK: - ModifyDefenseModifier GameInteractionEffectQueryResult ModifyDefenseModifier::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void ModifyDefenseModifier::_Apply() { GameInteractor::State::DefenseModifier = parameters[0]; } void ModifyDefenseModifier::_Remove() { GameInteractor::State::DefenseModifier = 0; } // MARK: - GiveOrTakeShield GameInteractionEffectQueryResult GiveOrTakeShield::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else if ((parameters[0] > 0 && ((gBitFlags[parameters[0] - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_TYPE_SHIELD]) & gSaveContext.inventory.equipment)) || (parameters[0] < 0 && !((gBitFlags[(parameters[0] * -1) - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_TYPE_SHIELD]) & gSaveContext.inventory.equipment))) { return GameInteractionEffectQueryResult::NotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void GiveOrTakeShield::_Apply() { GameInteractor::RawAction::GiveOrTakeShield(parameters[0]); } // MARK: - TeleportPlayer GameInteractionEffectQueryResult TeleportPlayer::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void TeleportPlayer::_Apply() { GameInteractor::RawAction::TeleportPlayer(parameters[0]); } // MARK: - ClearAssignedButtons GameInteractionEffectQueryResult ClearAssignedButtons::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void ClearAssignedButtons::_Apply() { GameInteractor::RawAction::ClearAssignedButtons(parameters[0]); } // MARK: - SetTimeOfDay GameInteractionEffectQueryResult SetTimeOfDay::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void SetTimeOfDay::_Apply() { GameInteractor::RawAction::SetTimeOfDay(parameters[0]); } // MARK: - SetCollisionViewer GameInteractionEffectQueryResult SetCollisionViewer::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void SetCollisionViewer::_Apply() { GameInteractor::RawAction::SetCollisionViewer(true); } void SetCollisionViewer::_Remove() { GameInteractor::RawAction::SetCollisionViewer(false); } // MARK: - SetCosmeticsColor GameInteractionEffectQueryResult SetCosmeticsColor::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void SetCosmeticsColor::_Apply() { GameInteractor::RawAction::SetCosmeticsColor(parameters[0], parameters[1]); } // MARK: - RandomizeCosmetics GameInteractionEffectQueryResult RandomizeCosmetics::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void RandomizeCosmetics::_Apply() { GameInteractor::RawAction::RandomizeCosmeticsColors(true); } // MARK: - PressButton GameInteractionEffectQueryResult PressButton::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void PressButton::_Apply() { GameInteractor::RawAction::EmulateButtonPress(parameters[0]); } // MARK: - PressRandomButton GameInteractionEffectQueryResult PressRandomButton::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void PressRandomButton::_Apply() { GameInteractor::RawAction::EmulateRandomButtonPress(parameters[0]); } // MARK: - AddOrTakeAmmo GameInteractionEffectQueryResult AddOrTakeAmmo::CanBeApplied() { if (!GameInteractor::IsSaveLoaded()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else if (!GameInteractor::CanAddOrTakeAmmo(parameters[0], parameters[1])) { return GameInteractionEffectQueryResult::NotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void AddOrTakeAmmo::_Apply() { GameInteractor::RawAction::AddOrTakeAmmo(parameters[0], parameters[1]); } // MARK: - RandomBombFuseTimer GameInteractionEffectQueryResult RandomBombFuseTimer::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void RandomBombFuseTimer::_Apply() { GameInteractor::State::RandomBombFuseTimerActive = 1; } void RandomBombFuseTimer::_Remove() { GameInteractor::State::RandomBombFuseTimerActive = 0; } // MARK: - DisableLedgeGrabs GameInteractionEffectQueryResult DisableLedgeGrabs::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void DisableLedgeGrabs::_Apply() { GameInteractor::State::DisableLedgeGrabsActive = 1; } void DisableLedgeGrabs::_Remove() { GameInteractor::State::DisableLedgeGrabsActive = 0; } // MARK: - RandomWind GameInteractionEffectQueryResult RandomWind::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void RandomWind::_Apply() { GameInteractor::RawAction::SetRandomWind(true); } void RandomWind::_Remove() { GameInteractor::RawAction::SetRandomWind(false); } // MARK: - RandomBonks GameInteractionEffectQueryResult RandomBonks::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void RandomBonks::_Apply() { GameInteractor::State::RandomBonksActive = 1; } void RandomBonks::_Remove() { GameInteractor::State::RandomBonksActive = 0; } // MARK: - PlayerInvincibility GameInteractionEffectQueryResult PlayerInvincibility::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void PlayerInvincibility::_Apply() { GameInteractor::RawAction::SetPlayerInvincibility(true); } void PlayerInvincibility::_Remove() { GameInteractor::RawAction::SetPlayerInvincibility(false); } // MARK: - SlipperyFloor GameInteractionEffectQueryResult SlipperyFloor::CanBeApplied() { if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) { return GameInteractionEffectQueryResult::TemporarilyNotPossible; } else { return GameInteractionEffectQueryResult::Possible; } } void SlipperyFloor::_Apply() { GameInteractor::State::SlipperyFloorActive = 1; } void SlipperyFloor::_Remove() { GameInteractor::State::SlipperyFloorActive = 0; } }