Fix memory leaks in debugconsole & CrowdControl (#6383)

This commit is contained in:
Philip Dubé 2026-03-21 18:32:55 +00:00 committed by GitHub
parent b8634f1d8b
commit 43f77c13fb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 237 additions and 205 deletions

View file

@ -110,8 +110,8 @@ static bool ActorSpawnHandler(std::shared_ptr<Ship::Console> Console, const std:
static bool KillPlayerHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>&,
std::string* output) {
GameInteractionEffectBase* effect = new GameInteractionEffect::SetPlayerHealth();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = 0;
GameInteractionEffect::SetPlayerHealth effect;
effect.parameters[0] = 0;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
INFO_MESSAGE("[SOH] You've met with a terrible fate, haven't you?");
@ -142,8 +142,8 @@ static bool SetPlayerHealthHandler(std::shared_ptr<Ship::Console> Console, const
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::SetPlayerHealth();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = health;
GameInteractionEffect::SetPlayerHealth effect;
effect.parameters[0] = health;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
INFO_MESSAGE("[SOH] Player health updated to %d", health);
@ -159,7 +159,6 @@ static bool LoadSceneHandler(std::shared_ptr<Ship::Console> Console, const std::
gSaveContext.respawnFlag = 0;
gSaveContext.seqId = 0xFF;
gSaveContext.gameMode = GAMEMODE_NORMAL;
return 0;
}
@ -257,9 +256,9 @@ static bool AddAmmoHandler(std::shared_ptr<Ship::Console> Console, const std::ve
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::AddOrTakeAmmo();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = amount;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[1] = it->second;
GameInteractionEffect::AddOrTakeAmmo effect;
effect.parameters[0] = amount;
effect.parameters[1] = it->second;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
@ -298,9 +297,9 @@ static bool TakeAmmoHandler(std::shared_ptr<Ship::Console> Console, const std::v
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::AddOrTakeAmmo();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = -amount;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[1] = it->second;
GameInteractionEffect::AddOrTakeAmmo effect;
effect.parameters[0] = -amount;
effect.parameters[1] = it->second;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
@ -354,7 +353,6 @@ static bool BottleHandler(std::shared_ptr<Ship::Console> Console, const std::vec
return 1;
}
// I dont think you can do OOB with just this
gSaveContext.inventory.items[0x11 + slot] = it->second;
return 0;
@ -612,7 +610,7 @@ static bool InvisibleHandler(std::shared_ptr<Ship::Console> Console, const std::
return 1;
}
RemovableGameInteractionEffect* effect = new GameInteractionEffect::InvisibleLink();
GameInteractionEffect::InvisibleLink effect;
GameInteractionEffectQueryResult result =
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
@ -639,8 +637,8 @@ static bool GiantLinkHandler(std::shared_ptr<Ship::Console> Console, const std::
return 1;
}
RemovableGameInteractionEffect* effect = new GameInteractionEffect::ModifyLinkSize();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = GI_LINK_SIZE_GIANT;
GameInteractionEffect::ModifyLinkSize effect;
effect.parameters[0] = GI_LINK_SIZE_GIANT;
GameInteractionEffectQueryResult result =
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
@ -667,8 +665,8 @@ static bool MinishLinkHandler(std::shared_ptr<Ship::Console> Console, const std:
return 1;
}
RemovableGameInteractionEffect* effect = new GameInteractionEffect::ModifyLinkSize();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = GI_LINK_SIZE_MINISH;
GameInteractionEffect::ModifyLinkSize effect;
effect.parameters[0] = GI_LINK_SIZE_MINISH;
GameInteractionEffectQueryResult result =
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
@ -700,8 +698,8 @@ static bool AddHeartContainerHandler(std::shared_ptr<Ship::Console> Console, con
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyHeartContainers();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = hearts;
GameInteractionEffect::ModifyHeartContainers effect;
effect.parameters[0] = hearts;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
INFO_MESSAGE("[SOH] Added %d heart containers", hearts);
@ -732,8 +730,8 @@ static bool RemoveHeartContainerHandler(std::shared_ptr<Ship::Console> Console,
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyHeartContainers();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = -hearts;
GameInteractionEffect::ModifyHeartContainers effect;
effect.parameters[0] = -hearts;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
INFO_MESSAGE("[SOH] Removed %d heart containers", hearts);
@ -751,10 +749,10 @@ static bool GravityHandler(std::shared_ptr<Ship::Console> Console, const std::ve
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyGravity();
GameInteractionEffect::ModifyGravity effect;
try {
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] =
effect.parameters[0] =
Ship::Math::clamp(std::stoi(args[1], nullptr, 10), GI_GRAVITY_LEVEL_LIGHT, GI_GRAVITY_LEVEL_HEAVY);
} catch (std::invalid_argument const& ex) {
ERROR_MESSAGE("[SOH] Gravity value must be a number.");
@ -786,7 +784,7 @@ static bool NoUIHandler(std::shared_ptr<Ship::Console> Console, const std::vecto
return 1;
}
RemovableGameInteractionEffect* effect = new GameInteractionEffect::NoUI();
GameInteractionEffect::NoUI effect;
GameInteractionEffectQueryResult result =
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
@ -801,7 +799,7 @@ static bool NoUIHandler(std::shared_ptr<Ship::Console> Console, const std::vecto
static bool FreezeHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args,
std::string* output) {
GameInteractionEffectBase* effect = new GameInteractionEffect::FreezePlayer();
GameInteractionEffect::FreezePlayer effect;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
@ -819,10 +817,10 @@ static bool DefenseModifierHandler(std::shared_ptr<Ship::Console> Console, const
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyDefenseModifier();
GameInteractionEffect::ModifyDefenseModifier effect;
try {
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = std::stoi(args[1], nullptr, 10);
effect.parameters[0] = std::stoi(args[1], nullptr, 10);
} catch (std::invalid_argument const& ex) {
ERROR_MESSAGE("[SOH] Defense modifier value must be a number.");
return 1;
@ -830,8 +828,7 @@ static bool DefenseModifierHandler(std::shared_ptr<Ship::Console> Console, const
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
INFO_MESSAGE("[SOH] Defense modifier set to %d",
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0]);
INFO_MESSAGE("[SOH] Defense modifier set to %d", effect.parameters[0]);
return 0;
} else {
INFO_MESSAGE("[SOH] Command failed: Could not set defense modifier.");
@ -845,7 +842,7 @@ static bool DamageHandler(std::shared_ptr<Ship::Console> Console, const std::vec
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyHealth();
GameInteractionEffect::ModifyHealth effect;
try {
int value = std::stoi(args[1], nullptr, 10);
@ -854,7 +851,7 @@ static bool DamageHandler(std::shared_ptr<Ship::Console> Console, const std::vec
return 1;
}
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = -value;
effect.parameters[0] = -value;
} catch (std::invalid_argument const& ex) {
ERROR_MESSAGE("[SOH] Damage value must be a number.");
return 1;
@ -876,7 +873,7 @@ static bool HealHandler(std::shared_ptr<Ship::Console> Console, const std::vecto
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyHealth();
GameInteractionEffect::ModifyHealth effect;
try {
int value = std::stoi(args[1], nullptr, 10);
@ -885,7 +882,7 @@ static bool HealHandler(std::shared_ptr<Ship::Console> Console, const std::vecto
return 1;
}
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = value;
effect.parameters[0] = value;
} catch (std::invalid_argument const& ex) {
ERROR_MESSAGE("[SOH] Damage value must be a number.");
return 1;
@ -903,7 +900,7 @@ static bool HealHandler(std::shared_ptr<Ship::Console> Console, const std::vecto
static bool FillMagicHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args,
std::string* output) {
GameInteractionEffectBase* effect = new GameInteractionEffect::FillMagic();
GameInteractionEffect::FillMagic effect;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
@ -917,7 +914,7 @@ static bool FillMagicHandler(std::shared_ptr<Ship::Console> Console, const std::
static bool EmptyMagicHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args,
std::string* output) {
GameInteractionEffectBase* effect = new GameInteractionEffect::EmptyMagic();
GameInteractionEffect::EmptyMagic effect;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
@ -944,7 +941,7 @@ static bool NoZHandler(std::shared_ptr<Ship::Console> Console, const std::vector
return 1;
}
RemovableGameInteractionEffect* effect = new GameInteractionEffect::DisableZTargeting();
GameInteractionEffect::DisableZTargeting effect;
GameInteractionEffectQueryResult result =
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
@ -972,7 +969,7 @@ static bool OneHitKOHandler(std::shared_ptr<Ship::Console> Console, const std::v
return 1;
}
RemovableGameInteractionEffect* effect = new GameInteractionEffect::OneHitKO();
GameInteractionEffect::OneHitKO effect;
GameInteractionEffectQueryResult result =
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
@ -1000,7 +997,7 @@ static bool PacifistHandler(std::shared_ptr<Ship::Console> Console, const std::v
return 1;
}
RemovableGameInteractionEffect* effect = new GameInteractionEffect::PacifistMode();
GameInteractionEffect::PacifistMode effect;
GameInteractionEffectQueryResult result =
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
@ -1028,8 +1025,8 @@ static bool PaperLinkHandler(std::shared_ptr<Ship::Console> Console, const std::
return 1;
}
RemovableGameInteractionEffect* effect = new GameInteractionEffect::ModifyLinkSize();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = GI_LINK_SIZE_PAPER;
GameInteractionEffect::ModifyLinkSize effect;
effect.parameters[0] = GI_LINK_SIZE_PAPER;
GameInteractionEffectQueryResult result =
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
@ -1057,7 +1054,7 @@ static bool RainstormHandler(std::shared_ptr<Ship::Console> Console, const std::
return 1;
}
RemovableGameInteractionEffect* effect = new GameInteractionEffect::WeatherRainstorm();
GameInteractionEffect::WeatherRainstorm effect;
GameInteractionEffectQueryResult result =
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
@ -1085,7 +1082,7 @@ static bool ReverseControlsHandler(std::shared_ptr<Ship::Console> Console, const
return 1;
}
RemovableGameInteractionEffect* effect = new GameInteractionEffect::ReverseControls();
GameInteractionEffect::ReverseControls effect;
GameInteractionEffectQueryResult result =
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
@ -1105,10 +1102,10 @@ static bool UpdateRupeesHandler(std::shared_ptr<Ship::Console> Console, const st
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyRupees();
GameInteractionEffect::ModifyRupees effect;
try {
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = std::stoi(args[1], nullptr, 10);
effect.parameters[0] = std::stoi(args[1], nullptr, 10);
} catch (std::invalid_argument const& ex) {
ERROR_MESSAGE("[SOH] Rupee value must be a number.");
return 1;
@ -1130,10 +1127,10 @@ static bool SpeedModifierHandler(std::shared_ptr<Ship::Console> Console, const s
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyMovementSpeedMultiplier();
GameInteractionEffect::ModifyMovementSpeedMultiplier effect;
try {
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = std::stoi(args[1], nullptr, 10);
effect.parameters[0] = std::stoi(args[1], nullptr, 10);
} catch (std::invalid_argument const& ex) {
ERROR_MESSAGE("[SOH] Speed modifier value must be a number.");
return 1;
@ -1168,8 +1165,8 @@ static bool BootsHandler(std::shared_ptr<Ship::Console> Console, const std::vect
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::ForceEquipBoots();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = it->second;
GameInteractionEffect::ForceEquipBoots effect;
effect.parameters[0] = it->second;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
@ -1200,8 +1197,8 @@ static bool GiveShieldHandler(std::shared_ptr<Ship::Console> Console, const std:
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::GiveOrTakeShield();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = it->second;
GameInteractionEffect::GiveOrTakeShield effect;
effect.parameters[0] = it->second;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
@ -1226,8 +1223,8 @@ static bool TakeShieldHandler(std::shared_ptr<Ship::Console> Console, const std:
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::GiveOrTakeShield();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = it->second * -1;
GameInteractionEffect::GiveOrTakeShield effect;
effect.parameters[0] = it->second * -1;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
@ -1245,7 +1242,7 @@ static bool KnockbackHandler(std::shared_ptr<Ship::Console> Console, const std::
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
}
GameInteractionEffectBase* effect = new GameInteractionEffect::KnockbackPlayer();
GameInteractionEffect::KnockbackPlayer effect;
try {
int value = std::stoi(args[1], nullptr, 10);
@ -1254,7 +1251,7 @@ static bool KnockbackHandler(std::shared_ptr<Ship::Console> Console, const std::
return 1;
}
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = value;
effect.parameters[0] = value;
} catch (std::invalid_argument const& ex) {
ERROR_MESSAGE("[SOH] Knockback value must be a number.");
return 1;
@ -1272,7 +1269,7 @@ static bool KnockbackHandler(std::shared_ptr<Ship::Console> Console, const std::
static bool ElectrocuteHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args,
std::string* output) {
GameInteractionEffectBase* effect = new GameInteractionEffect::ElectrocutePlayer();
GameInteractionEffect::ElectrocutePlayer effect;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {
@ -1286,7 +1283,7 @@ static bool ElectrocuteHandler(std::shared_ptr<Ship::Console> Console, const std
static bool BurnHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args,
std::string* output) {
GameInteractionEffectBase* effect = new GameInteractionEffect::BurnPlayer();
GameInteractionEffect::BurnPlayer effect;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
if (result == GameInteractionEffectQueryResult::Possible) {

View file

@ -38,11 +38,9 @@ GameInteractionEffectQueryResult RemovableGameInteractionEffect::CanBeRemoved()
GameInteractionEffectQueryResult RemovableGameInteractionEffect::Remove() {
GameInteractionEffectQueryResult result = CanBeRemoved();
if (result != GameInteractionEffectQueryResult::Possible) {
return result;
if (result == GameInteractionEffectQueryResult::Possible) {
_Remove();
}
_Remove();
return result;
}

View file

@ -21,16 +21,16 @@ extern PlayState* gPlayState;
// MARK: - Effects
GameInteractionEffectQueryResult GameInteractor::CanApplyEffect(GameInteractionEffectBase* effect) {
return effect->CanBeApplied();
GameInteractionEffectQueryResult GameInteractor::CanApplyEffect(GameInteractionEffectBase& effect) {
return effect.CanBeApplied();
}
GameInteractionEffectQueryResult GameInteractor::ApplyEffect(GameInteractionEffectBase* effect) {
return effect->Apply();
GameInteractionEffectQueryResult GameInteractor::ApplyEffect(GameInteractionEffectBase& effect) {
return effect.Apply();
}
GameInteractionEffectQueryResult GameInteractor::RemoveEffect(RemovableGameInteractionEffect* effect) {
return effect->Remove();
GameInteractionEffectQueryResult GameInteractor::RemoveEffect(RemovableGameInteractionEffect& effect) {
return effect.Remove();
}
// MARK: - Helpers

View file

@ -220,9 +220,9 @@ class GameInteractor {
};
// Effects
static GameInteractionEffectQueryResult CanApplyEffect(GameInteractionEffectBase* effect);
static GameInteractionEffectQueryResult ApplyEffect(GameInteractionEffectBase* effect);
static GameInteractionEffectQueryResult RemoveEffect(RemovableGameInteractionEffect* effect);
static GameInteractionEffectQueryResult CanApplyEffect(GameInteractionEffectBase& effect);
static GameInteractionEffectQueryResult ApplyEffect(GameInteractionEffectBase& effect);
static GameInteractionEffectQueryResult RemoveEffect(RemovableGameInteractionEffect& effect);
// Game Hooks
HOOK_ID nextHookId = 1;

View file

@ -83,7 +83,8 @@ void CrowdControl::ProcessActiveEffects() {
if (effect->timeRemaining <= 0) {
it = activeEffects.erase(std::remove(activeEffects.begin(), activeEffects.end(), effect),
activeEffects.end());
GameInteractor::RemoveEffect(dynamic_cast<RemovableGameInteractionEffect*>(effect->giEffect));
GameInteractor::RemoveEffect(
*dynamic_cast<RemovableGameInteractionEffect*>(effect->giEffect.get()));
delete effect;
} else {
// If we have a success after previously being paused, tell CC to resume timer.
@ -140,7 +141,7 @@ CrowdControl::EffectResult CrowdControl::ExecuteEffect(Effect* effect) {
giResult =
GameInteractor::RawAction::SpawnActor(effect->spawnParams[0], effect->spawnParams[1], effect->viewerName);
} else {
giResult = GameInteractor::ApplyEffect(effect->giEffect);
giResult = GameInteractor::ApplyEffect(*effect->giEffect.get());
}
return TranslateGiEnum(giResult);
@ -149,7 +150,7 @@ CrowdControl::EffectResult CrowdControl::ExecuteEffect(Effect* effect) {
/// Checks if effect can be applied -- should not be used to check for spawn enemy effects.
CrowdControl::EffectResult CrowdControl::CanApplyEffect(Effect* effect) {
assert(effect->category != kEffectCatSpawnEnemy || effect->category != kEffectCatSpawnActor);
GameInteractionEffectQueryResult giResult = GameInteractor::CanApplyEffect(effect->giEffect);
GameInteractionEffectQueryResult giResult = GameInteractor::CanApplyEffect(*effect->giEffect.get());
return TranslateGiEnum(giResult);
}
@ -279,346 +280,382 @@ CrowdControl::Effect* CrowdControl::ParseMessage(nlohmann::json dataReceived) {
case kEffectTakeHalfDamage:
effect->category = kEffectCatDamageTaken;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ModifyDefenseModifier();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 2;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyDefenseModifier>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] = 2;
break;
case kEffectTakeDoubleDamage:
effect->category = kEffectCatDamageTaken;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ModifyDefenseModifier();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = -2;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyDefenseModifier>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] = -2;
break;
case kEffectOneHitKo:
effect->category = kEffectCatDamageTaken;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::OneHitKO();
effect->giEffect = std::make_unique<GameInteractionEffect::OneHitKO>();
break;
case kEffectInvincibility:
effect->category = kEffectCatDamageTaken;
effect->timeRemaining = 15000;
effect->giEffect = new GameInteractionEffect::PlayerInvincibility();
effect->giEffect = std::make_unique<GameInteractionEffect::PlayerInvincibility>();
break;
break;
case kEffectIncreaseSpeed:
effect->category = kEffectCatSpeed;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ModifyMovementSpeedMultiplier();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 2;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyMovementSpeedMultiplier>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] = 2;
break;
case kEffectDecreaseSpeed:
effect->category = kEffectCatSpeed;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ModifyMovementSpeedMultiplier();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = -2;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyMovementSpeedMultiplier>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] = -2;
break;
case kEffectLowGravity:
effect->category = kEffectCatGravity;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ModifyGravity();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_GRAVITY_LEVEL_LIGHT;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyGravity>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_GRAVITY_LEVEL_LIGHT;
break;
case kEffectHighGravity:
effect->category = kEffectCatGravity;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ModifyGravity();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_GRAVITY_LEVEL_HEAVY;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyGravity>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_GRAVITY_LEVEL_HEAVY;
break;
case kEffectForceIronBoots:
effect->category = kEffectCatBoots;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ForceEquipBoots();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = EQUIP_VALUE_BOOTS_IRON;
effect->giEffect = std::make_unique<GameInteractionEffect::ForceEquipBoots>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
EQUIP_VALUE_BOOTS_IRON;
break;
case kEffectForceHoverBoots:
effect->category = kEffectCatBoots;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ForceEquipBoots();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] =
effect->giEffect = std::make_unique<GameInteractionEffect::ForceEquipBoots>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
EQUIP_VALUE_BOOTS_HOVER;
break;
case kEffectSlipperyFloor:
effect->category = kEffectCatSlipperyFloor;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::SlipperyFloor();
effect->giEffect = std::make_unique<GameInteractionEffect::SlipperyFloor>();
break;
case kEffectNoLedgeGrabs:
effect->category = kEffectCatNoLedgeGrabs;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::DisableLedgeGrabs();
effect->giEffect = std::make_unique<GameInteractionEffect::DisableLedgeGrabs>();
break;
case kEffectRandomWind:
effect->category = kEffectCatRandomWind;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::RandomWind();
effect->giEffect = std::make_unique<GameInteractionEffect::RandomWind>();
break;
case kEffectRandomBonks:
effect->category = kEffectCatRandomBonks;
effect->timeRemaining = 60000;
effect->giEffect = new GameInteractionEffect::RandomBonks();
effect->giEffect = std::make_unique<GameInteractionEffect::RandomBonks>();
break;
// Hurt or Heal Link
case kEffectEmptyHeart:
effect->giEffect = new GameInteractionEffect::ModifyHealth();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyHealth>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter * -1;
break;
case kEffectFillHeart:
effect->giEffect = new GameInteractionEffect::ModifyHealth();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyHealth>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter;
break;
case kEffectKnockbackLinkWeak:
effect->giEffect = new GameInteractionEffect::KnockbackPlayer();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 1;
effect->giEffect = std::make_unique<GameInteractionEffect::KnockbackPlayer>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] = 1;
break;
case kEffectKnockbackLinkStrong:
effect->giEffect = new GameInteractionEffect::KnockbackPlayer();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 3;
effect->giEffect = std::make_unique<GameInteractionEffect::KnockbackPlayer>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] = 3;
break;
case kEffectKnockbackLinkMega:
effect->giEffect = new GameInteractionEffect::KnockbackPlayer();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 6;
effect->giEffect = std::make_unique<GameInteractionEffect::KnockbackPlayer>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] = 6;
break;
case kEffectBurnLink:
effect->giEffect = new GameInteractionEffect::BurnPlayer();
effect->giEffect = std::make_unique<GameInteractionEffect::BurnPlayer>();
break;
case kEffectFreezeLink:
effect->giEffect = new GameInteractionEffect::FreezePlayer();
effect->giEffect = std::make_unique<GameInteractionEffect::FreezePlayer>();
break;
case kEffectElectrocuteLink:
effect->giEffect = new GameInteractionEffect::ElectrocutePlayer();
effect->giEffect = std::make_unique<GameInteractionEffect::ElectrocutePlayer>();
break;
case kEffectKillLink:
effect->giEffect = new GameInteractionEffect::SetPlayerHealth();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 0;
effect->giEffect = std::make_unique<GameInteractionEffect::SetPlayerHealth>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] = 0;
break;
// Give Items and Consumables
case kEffectAddHeartContainer:
effect->giEffect = new GameInteractionEffect::ModifyHeartContainers();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 1;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyHeartContainers>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] = 1;
break;
case kEffectFillMagic:
effect->giEffect = new GameInteractionEffect::FillMagic();
effect->giEffect = std::make_unique<GameInteractionEffect::FillMagic>();
break;
case kEffectAddRupees:
effect->giEffect = new GameInteractionEffect::ModifyRupees();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyRupees>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter;
break;
case kEffectGiveDekuShield:
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = ITEM_SHIELD_DEKU;
effect->giEffect = std::make_unique<GameInteractionEffect::GiveOrTakeShield>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] = ITEM_SHIELD_DEKU;
break;
case kEffectGiveHylianShield:
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = ITEM_SHIELD_HYLIAN;
effect->giEffect = std::make_unique<GameInteractionEffect::GiveOrTakeShield>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
ITEM_SHIELD_HYLIAN;
break;
case kEffectRefillSticks:
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_STICK;
effect->giEffect = std::make_unique<GameInteractionEffect::AddOrTakeAmmo>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[1] = ITEM_STICK;
break;
case kEffectRefillNuts:
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_NUT;
effect->giEffect = std::make_unique<GameInteractionEffect::AddOrTakeAmmo>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[1] = ITEM_NUT;
break;
case kEffectRefillBombs:
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_BOMB;
effect->giEffect = std::make_unique<GameInteractionEffect::AddOrTakeAmmo>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[1] = ITEM_BOMB;
break;
case kEffectRefillSeeds:
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_SLINGSHOT;
effect->giEffect = std::make_unique<GameInteractionEffect::AddOrTakeAmmo>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[1] = ITEM_SLINGSHOT;
break;
case kEffectRefillArrows:
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_BOW;
effect->giEffect = std::make_unique<GameInteractionEffect::AddOrTakeAmmo>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[1] = ITEM_BOW;
break;
case kEffectRefillBombchus:
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_BOMBCHU;
effect->giEffect = std::make_unique<GameInteractionEffect::AddOrTakeAmmo>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[1] = ITEM_BOMBCHU;
break;
// Take Items and Consumables
case kEffectRemoveHeartContainer:
effect->giEffect = new GameInteractionEffect::ModifyHeartContainers();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = -1;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyHeartContainers>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] = -1;
break;
case kEffectEmptyMagic:
effect->giEffect = new GameInteractionEffect::EmptyMagic();
effect->giEffect = std::make_unique<GameInteractionEffect::EmptyMagic>();
break;
case kEffectRemoveRupees:
effect->giEffect = new GameInteractionEffect::ModifyRupees();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyRupees>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter * -1;
break;
case kEffectTakeDekuShield:
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = -ITEM_SHIELD_DEKU;
effect->giEffect = std::make_unique<GameInteractionEffect::GiveOrTakeShield>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
-ITEM_SHIELD_DEKU;
break;
case kEffectTakeHylianShield:
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = -ITEM_SHIELD_HYLIAN;
effect->giEffect = std::make_unique<GameInteractionEffect::GiveOrTakeShield>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
-ITEM_SHIELD_HYLIAN;
break;
case kEffectTakeSticks:
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_STICK;
effect->giEffect = std::make_unique<GameInteractionEffect::AddOrTakeAmmo>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter * -1;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[1] = ITEM_STICK;
break;
case kEffectTakeNuts:
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_NUT;
effect->giEffect = std::make_unique<GameInteractionEffect::AddOrTakeAmmo>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter * -1;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[1] = ITEM_NUT;
break;
case kEffectTakeBombs:
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_BOMB;
effect->giEffect = std::make_unique<GameInteractionEffect::AddOrTakeAmmo>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter * -1;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[1] = ITEM_BOMB;
break;
case kEffectTakeSeeds:
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_SLINGSHOT;
effect->giEffect = std::make_unique<GameInteractionEffect::AddOrTakeAmmo>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter * -1;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[1] = ITEM_SLINGSHOT;
break;
case kEffectTakeArrows:
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_BOW;
effect->giEffect = std::make_unique<GameInteractionEffect::AddOrTakeAmmo>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter * -1;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[1] = ITEM_BOW;
break;
case kEffectTakeBombchus:
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = receivedParameter * -1;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[1] = ITEM_BOMBCHU;
effect->giEffect = std::make_unique<GameInteractionEffect::AddOrTakeAmmo>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
receivedParameter * -1;
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[1] = ITEM_BOMBCHU;
break;
// Link Size Modifiers
case kEffectGiantLink:
effect->category = kEffectCatLinkSize;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_LINK_SIZE_GIANT;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyLinkSize>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_LINK_SIZE_GIANT;
break;
case kEffectMinishLink:
effect->category = kEffectCatLinkSize;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_LINK_SIZE_MINISH;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyLinkSize>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_LINK_SIZE_MINISH;
break;
case kEffectPaperLink:
effect->category = kEffectCatLinkSize;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_LINK_SIZE_PAPER;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyLinkSize>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_LINK_SIZE_PAPER;
break;
case kEffectSquishedLink:
effect->category = kEffectCatLinkSize;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_LINK_SIZE_SQUISHED;
effect->giEffect = std::make_unique<GameInteractionEffect::ModifyLinkSize>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_LINK_SIZE_SQUISHED;
break;
case kEffectInvisibleLink:
effect->category = kEffectCatLinkSize;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::InvisibleLink();
effect->giEffect = std::make_unique<GameInteractionEffect::InvisibleLink>();
break;
// Generic Effects
case kEffectRandomBombTimer:
effect->category = kEffectCatRandomBombFuseTimer;
effect->timeRemaining = 60000;
effect->giEffect = new GameInteractionEffect::RandomBombFuseTimer();
effect->giEffect = std::make_unique<GameInteractionEffect::RandomBombFuseTimer>();
break;
case kEffectSetTimeToDawn:
effect->giEffect = new GameInteractionEffect::SetTimeOfDay();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TIMEOFDAY_DAWN;
effect->giEffect = std::make_unique<GameInteractionEffect::SetTimeOfDay>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_TIMEOFDAY_DAWN;
break;
case kEffectSetTimeToDusk:
effect->giEffect = new GameInteractionEffect::SetTimeOfDay();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TIMEOFDAY_DUSK;
effect->giEffect = std::make_unique<GameInteractionEffect::SetTimeOfDay>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_TIMEOFDAY_DUSK;
break;
// Visual Effects
case kEffectNoUi:
effect->category = kEffectCatUi;
effect->timeRemaining = 60000;
effect->giEffect = new GameInteractionEffect::NoUI();
effect->giEffect = std::make_unique<GameInteractionEffect::NoUI>();
break;
case kEffectRainstorm:
effect->category = kEffectCatWeather;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::WeatherRainstorm();
effect->giEffect = std::make_unique<GameInteractionEffect::WeatherRainstorm>();
break;
case kEffectDebugMode:
effect->category = kEffectCatDebugMode;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::SetCollisionViewer();
effect->giEffect = std::make_unique<GameInteractionEffect::SetCollisionViewer>();
break;
case kEffectRandomCosmetics:
effect->giEffect = new GameInteractionEffect::RandomizeCosmetics();
effect->giEffect = std::make_unique<GameInteractionEffect::RandomizeCosmetics>();
break;
// Controls
case kEffectNoZButton:
effect->category = kEffectCatNoZ;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::DisableZTargeting();
effect->giEffect = std::make_unique<GameInteractionEffect::DisableZTargeting>();
break;
case kEffectReverseControls:
effect->category = kEffectCatReverseControls;
effect->timeRemaining = 60000;
effect->giEffect = new GameInteractionEffect::ReverseControls();
effect->giEffect = std::make_unique<GameInteractionEffect::ReverseControls>();
break;
case kEffectPacifistMode:
effect->category = kEffectCatPacifist;
effect->timeRemaining = 15000;
effect->giEffect = new GameInteractionEffect::PacifistMode();
effect->giEffect = std::make_unique<GameInteractionEffect::PacifistMode>();
break;
case kEffectPressRandomButtons:
effect->category = kEffectCatRandomButtons;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::PressRandomButton();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = 30;
effect->giEffect = std::make_unique<GameInteractionEffect::PressRandomButton>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] = 30;
break;
case kEffectClearCbuttons:
effect->giEffect = new GameInteractionEffect::ClearAssignedButtons();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_BUTTONS_CBUTTONS;
effect->giEffect = std::make_unique<GameInteractionEffect::ClearAssignedButtons>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_BUTTONS_CBUTTONS;
break;
case kEffectClearDpad:
effect->giEffect = new GameInteractionEffect::ClearAssignedButtons();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_BUTTONS_DPAD;
effect->giEffect = std::make_unique<GameInteractionEffect::ClearAssignedButtons>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] = GI_BUTTONS_DPAD;
break;
// Teleport Player
case kEffectTpLinksHouse:
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_LINKSHOUSE;
effect->giEffect = std::make_unique<GameInteractionEffect::TeleportPlayer>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_TP_DEST_LINKSHOUSE;
break;
case kEffectTpMinuet:
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_MINUET;
effect->giEffect = std::make_unique<GameInteractionEffect::TeleportPlayer>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_TP_DEST_MINUET;
break;
case kEffectTpBolero:
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_BOLERO;
effect->giEffect = std::make_unique<GameInteractionEffect::TeleportPlayer>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_TP_DEST_BOLERO;
break;
case kEffectTpSerenade:
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_SERENADE;
effect->giEffect = std::make_unique<GameInteractionEffect::TeleportPlayer>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_TP_DEST_SERENADE;
break;
case kEffectTpRequiem:
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_REQUIEM;
effect->giEffect = std::make_unique<GameInteractionEffect::TeleportPlayer>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_TP_DEST_REQUIEM;
break;
case kEffectTpNocturne:
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_NOCTURNE;
effect->giEffect = std::make_unique<GameInteractionEffect::TeleportPlayer>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_TP_DEST_NOCTURNE;
break;
case kEffectTpPrelude:
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect)->parameters[0] = GI_TP_DEST_PRELUDE;
effect->giEffect = std::make_unique<GameInteractionEffect::TeleportPlayer>();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect->giEffect.get())->parameters[0] =
GI_TP_DEST_PRELUDE;
break;
default:

View file

@ -54,7 +54,7 @@ class CrowdControl : public Network {
uint32_t spawnParams[2];
uint32_t category = 0;
long timeRemaining;
GameInteractionEffectBase* giEffect;
std::unique_ptr<GameInteractionEffectBase> giEffect;
std::string viewerName;
// Metadata used while executing (only for timed effects)