mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-21 23:58:51 -05:00
CrowdControl V2: Effect Overhaul (#2433)
This commit is contained in:
parent
76e99ffe19
commit
866882e4c6
@ -141,6 +141,7 @@ list(FILTER soh__Enhancements EXCLUDE REGEX "soh/Enhancements/gfx.*")
|
|||||||
|
|
||||||
# handle crowd control removals
|
# handle crowd control removals
|
||||||
list(REMOVE_ITEM soh__Enhancements "soh/Enhancements/crowd-control/soh.cs")
|
list(REMOVE_ITEM soh__Enhancements "soh/Enhancements/crowd-control/soh.cs")
|
||||||
|
list(REMOVE_ITEM soh__Enhancements "soh/Enhancements/crowd-control/soh.ccpak")
|
||||||
if (!BUILD_CROWD_CONTROL)
|
if (!BUILD_CROWD_CONTROL)
|
||||||
list(FILTER soh__Enhancements EXCLUDE REGEX "soh/Enhancements/crowd-control/*")
|
list(FILTER soh__Enhancements EXCLUDE REGEX "soh/Enhancements/crowd-control/*")
|
||||||
endif()
|
endif()
|
||||||
|
@ -49,8 +49,6 @@ void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName);
|
|||||||
u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
|
u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyOrResetCustomGfxPatches(bool rainbowTick);
|
|
||||||
|
|
||||||
// Not to be confused with tabs, groups are 1:1 with the boxes shown in the UI, grouping them allows us to reset/randomize
|
// Not to be confused with tabs, groups are 1:1 with the boxes shown in the UI, grouping them allows us to reset/randomize
|
||||||
// every item in a group at once. If you are looking for tabs they are rendered manually in ImGui in `DrawCosmeticsEditor`
|
// every item in a group at once. If you are looking for tabs they are rendered manually in ImGui in `DrawCosmeticsEditor`
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -425,7 +423,7 @@ void CosmeticsUpdateTick(bool& open) {
|
|||||||
4. GFX Command Index: Index of the GFX command you want to replace, the instructions on finding this are in the giant comment block above the cosmeticOptions map
|
4. GFX Command Index: Index of the GFX command you want to replace, the instructions on finding this are in the giant comment block above the cosmeticOptions map
|
||||||
5. GFX Command: The GFX command you want to insert
|
5. GFX Command: The GFX command you want to insert
|
||||||
*/
|
*/
|
||||||
void ApplyOrResetCustomGfxPatches(bool manualChange = true) {
|
void ApplyOrResetCustomGfxPatches(bool manualChange) {
|
||||||
static CosmeticOption& linkGoronTunic = cosmeticOptions.at("Link_GoronTunic");
|
static CosmeticOption& linkGoronTunic = cosmeticOptions.at("Link_GoronTunic");
|
||||||
if (manualChange || CVarGetInteger(linkGoronTunic.rainbowCvar, 0)) {
|
if (manualChange || CVarGetInteger(linkGoronTunic.rainbowCvar, 0)) {
|
||||||
static Color_RGBA8 defaultColor = {linkGoronTunic.defaultColor.x, linkGoronTunic.defaultColor.y, linkGoronTunic.defaultColor.z, linkGoronTunic.defaultColor.w};
|
static Color_RGBA8 defaultColor = {linkGoronTunic.defaultColor.x, linkGoronTunic.defaultColor.y, linkGoronTunic.defaultColor.z, linkGoronTunic.defaultColor.w};
|
||||||
@ -1822,7 +1820,8 @@ void InitCosmeticsEditor() {
|
|||||||
|
|
||||||
void CosmeticsEditor_RandomizeAll() {
|
void CosmeticsEditor_RandomizeAll() {
|
||||||
for (auto& [id, cosmeticOption] : cosmeticOptions) {
|
for (auto& [id, cosmeticOption] : cosmeticOptions) {
|
||||||
if (!CVarGetInteger(cosmeticOption.lockedCvar, 0)) {
|
if (!CVarGetInteger(cosmeticOption.lockedCvar, 0) &&
|
||||||
|
(!cosmeticOption.advancedOption || CVarGetInteger("gCosmetics.AdvancedMode", 0))) {
|
||||||
RandomizeColor(cosmeticOption);
|
RandomizeColor(cosmeticOption);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,3 +27,4 @@ void InitCosmeticsEditor();//Init the menu itself
|
|||||||
ImVec4 GetRandomValue(int MaximumPossible);
|
ImVec4 GetRandomValue(int MaximumPossible);
|
||||||
void CosmeticsEditor_RandomizeAll();
|
void CosmeticsEditor_RandomizeAll();
|
||||||
void CosmeticsEditor_ResetAll();
|
void CosmeticsEditor_ResetAll();
|
||||||
|
void ApplyOrResetCustomGfxPatches(bool manualChange = true);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifdef ENABLE_CROWD_CONTROL
|
#ifdef ENABLE_CROWD_CONTROL
|
||||||
|
|
||||||
#include "CrowdControl.h"
|
#include "CrowdControl.h"
|
||||||
|
#include "CrowdControlTypes.h"
|
||||||
#include <libultraship/bridge.h>
|
#include <libultraship/bridge.h>
|
||||||
#include <Console.h>
|
#include <Console.h>
|
||||||
#include <ImGuiImpl.h>
|
#include <ImGuiImpl.h>
|
||||||
@ -17,65 +18,6 @@ extern "C" {
|
|||||||
extern PlayState* gPlayState;
|
extern PlayState* gPlayState;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EFFECT_HIGH_GRAVITY "high_gravity"
|
|
||||||
#define EFFECT_LOW_GRAVITY "low_gravity"
|
|
||||||
#define EFFECT_DAMAGE_MULTIPLIER "damage_multiplier"
|
|
||||||
#define EFFECT_DEFENSE_MULTIPLIER "defense_multiplier"
|
|
||||||
#define EFFECT_GIANT_LINK "giant_link"
|
|
||||||
#define EFFECT_MINISH_LINK "minish_link"
|
|
||||||
#define EFFECT_INVISIBLE_LINK "invisible"
|
|
||||||
#define EFFECT_PAPER_LINK "paper_link"
|
|
||||||
#define EFFECT_FREEZE "freeze"
|
|
||||||
#define EFFECT_DAMAGE "damage"
|
|
||||||
#define EFFECT_HEAL "heal"
|
|
||||||
#define EFFECT_KNOCKBACK "knockback"
|
|
||||||
#define EFFECT_ELECTROCUTE "electrocute"
|
|
||||||
#define EFFECT_BURN "burn"
|
|
||||||
#define EFFECT_KILL "kill"
|
|
||||||
#define EFFECT_HOVER_BOOTS "hover_boots"
|
|
||||||
#define EFFECT_IRON_BOOTS "iron_boots"
|
|
||||||
#define EFFECT_ADD_HEART_CONTAINER "add_heart_container"
|
|
||||||
#define EFFECT_REMOVE_HEART_CONTAINER "remove_heart_container"
|
|
||||||
#define EFFECT_NO_UI "no_ui"
|
|
||||||
#define EFFECT_FILL_MAGIC "fill_magic"
|
|
||||||
#define EFFECT_EMPTY_MAGIC "empty_magic"
|
|
||||||
#define EFFECT_OHKO "ohko"
|
|
||||||
#define EFFECT_PACIFIST "pacifist"
|
|
||||||
#define EFFECT_RAINSTORM "rainstorm"
|
|
||||||
#define EFFECT_REVERSE_CONTROLS "reverse"
|
|
||||||
#define EFFECT_ADD_RUPEES "add_rupees"
|
|
||||||
#define EFFECT_REMOVE_RUPEES "remove_rupees"
|
|
||||||
#define EFFECT_INCREASE_SPEED "increase_speed"
|
|
||||||
#define EFFECT_DECREASE_SPEED "decrease_speed"
|
|
||||||
#define EFFECT_NO_Z_TARGETING "no_z"
|
|
||||||
#define EFFECT_GIVE_DEKU_SHIELD "give_dekushield"
|
|
||||||
|
|
||||||
#define EFFECT_SPAWN_WALLMASTER "spawn_wallmaster"
|
|
||||||
#define EFFECT_SPAWN_ARWING "spawn_arwing"
|
|
||||||
#define EFFECT_SPAWN_DARK_LINK "spawn_darklink"
|
|
||||||
#define EFFECT_SPAWN_STALFOS "spawn_stalfos"
|
|
||||||
#define EFFECT_SPAWN_WOLFOS "spawn_wolfos"
|
|
||||||
#define EFFECT_SPAWN_FREEZARD "spawn_freezard"
|
|
||||||
#define EFFECT_SPAWN_KEESE "spawn_keese"
|
|
||||||
#define EFFECT_SPAWN_ICE_KEESE "spawn_icekeese"
|
|
||||||
#define EFFECT_SPAWN_FIRE_KEESE "spawn_firekeese"
|
|
||||||
#define EFFECT_SPAWN_TEKTITE "spawn_tektite"
|
|
||||||
#define EFFECT_SPAWN_LIKE_LIKE "spawn_likelike"
|
|
||||||
#define EFFECT_SPAWN_CUCCO_STORM "cucco_storm"
|
|
||||||
|
|
||||||
#define EFFECT_CAT_UI "ui"
|
|
||||||
#define EFFECT_CAT_GRAVITY "gravity"
|
|
||||||
#define EFFECT_CAT_LINK_SIZE "link_size"
|
|
||||||
#define EFFECT_CAT_PACIFIST "pacifist"
|
|
||||||
#define EFFECT_CAT_NO_Z "no_z"
|
|
||||||
#define EFFECT_CAT_WEATHER "weather"
|
|
||||||
#define EFFECT_CAT_REVERSE_CONTROLS "reverse_controls"
|
|
||||||
#define EFFECT_CAT_BOOTS "boots"
|
|
||||||
#define EFFECT_CAT_SPEED "speed"
|
|
||||||
#define EFFECT_CAT_DAMAGE_TAKEN "damage_taken"
|
|
||||||
#define EFFECT_CAT_SPAWN_ENEMY "spawn_enemy"
|
|
||||||
#define EFFECT_CAT_NONE "none"
|
|
||||||
|
|
||||||
void CrowdControl::Init() {
|
void CrowdControl::Init() {
|
||||||
SDLNet_Init();
|
SDLNet_Init();
|
||||||
}
|
}
|
||||||
@ -241,8 +183,6 @@ void CrowdControl::ProcessActiveEffects() {
|
|||||||
SPDLOG_TRACE("[CrowdControl] Ending Process thread...");
|
SPDLOG_TRACE("[CrowdControl] Ending Process thread...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Helpers
|
|
||||||
|
|
||||||
void CrowdControl::EmitMessage(TCPsocket socket, uint32_t eventId, long timeRemaining, EffectResult status) {
|
void CrowdControl::EmitMessage(TCPsocket socket, uint32_t eventId, long timeRemaining, EffectResult status) {
|
||||||
nlohmann::json payload;
|
nlohmann::json payload;
|
||||||
|
|
||||||
@ -255,208 +195,12 @@ void CrowdControl::EmitMessage(TCPsocket socket, uint32_t eventId, long timeRema
|
|||||||
SDLNet_TCP_Send(socket, jsonPayload.c_str(), jsonPayload.size() + 1);
|
SDLNet_TCP_Send(socket, jsonPayload.c_str(), jsonPayload.size() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) {
|
|
||||||
nlohmann::json dataReceived = nlohmann::json::parse(payload, nullptr, false);
|
|
||||||
if (dataReceived.is_discarded()) {
|
|
||||||
SPDLOG_ERROR("Error parsing JSON");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Effect* effect = new Effect();
|
|
||||||
effect->lastExecutionResult = EffectResult::Initiate;
|
|
||||||
effect->id = dataReceived["id"];
|
|
||||||
auto parameters = dataReceived["parameters"];
|
|
||||||
auto effectName = dataReceived["code"].get<std::string>();
|
|
||||||
|
|
||||||
if (parameters.size() > 0) {
|
|
||||||
effect->value[0] = dataReceived["parameters"][0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign GameInteractionEffect + values to CC effect.
|
|
||||||
// Categories are mostly used for checking for conflicting timed effects.
|
|
||||||
if (effectName == EFFECT_ADD_HEART_CONTAINER) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyHeartContainers();
|
|
||||||
effect->giEffect->parameter = 1;
|
|
||||||
} else if (effectName == EFFECT_REMOVE_HEART_CONTAINER) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyHeartContainers();
|
|
||||||
effect->giEffect->parameter = -1;
|
|
||||||
} else if (effectName == EFFECT_FILL_MAGIC) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::FillMagic();
|
|
||||||
} else if (effectName == EFFECT_EMPTY_MAGIC) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::EmptyMagic();
|
|
||||||
} else if (effectName == EFFECT_ADD_RUPEES) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyRupees();
|
|
||||||
} else if (effectName == EFFECT_REMOVE_RUPEES) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyRupees();
|
|
||||||
effect->paramMultiplier = -1;
|
|
||||||
} else if (effectName == EFFECT_NO_UI) {
|
|
||||||
effect->category = EFFECT_CAT_UI;
|
|
||||||
effect->timeRemaining = 60000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::NoUI();
|
|
||||||
} else if (effectName == EFFECT_HIGH_GRAVITY) {
|
|
||||||
effect->category = EFFECT_CAT_GRAVITY;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyGravity();
|
|
||||||
effect->giEffect->parameter = GI_GRAVITY_LEVEL_HEAVY;
|
|
||||||
} else if (effectName == EFFECT_LOW_GRAVITY) {
|
|
||||||
effect->category = EFFECT_CAT_GRAVITY;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyGravity();
|
|
||||||
effect->giEffect->parameter = GI_GRAVITY_LEVEL_LIGHT;
|
|
||||||
} else if (effectName == EFFECT_KILL) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::SetPlayerHealth();
|
|
||||||
effect->value[0] = 0;
|
|
||||||
} else if (effectName == EFFECT_FREEZE) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::FreezePlayer();
|
|
||||||
} else if (effectName == EFFECT_BURN) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::BurnPlayer();
|
|
||||||
} else if (effectName == EFFECT_ELECTROCUTE) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::ElectrocutePlayer();
|
|
||||||
} else if (effectName == EFFECT_KNOCKBACK) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::KnockbackPlayer();
|
|
||||||
} else if (effectName == EFFECT_HEAL) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyHealth();
|
|
||||||
} else if (effectName == EFFECT_DAMAGE) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyHealth();
|
|
||||||
effect->paramMultiplier = -1;
|
|
||||||
} else if (effectName == EFFECT_GIANT_LINK) {
|
|
||||||
effect->category = EFFECT_CAT_LINK_SIZE;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
|
||||||
effect->giEffect->parameter = GI_LINK_SIZE_GIANT;
|
|
||||||
} else if (effectName == EFFECT_MINISH_LINK) {
|
|
||||||
effect->category = EFFECT_CAT_LINK_SIZE;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
|
||||||
effect->giEffect->parameter = GI_LINK_SIZE_MINISH;
|
|
||||||
} else if (effectName == EFFECT_PAPER_LINK) {
|
|
||||||
effect->category = EFFECT_CAT_LINK_SIZE;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
|
||||||
effect->giEffect->parameter = GI_LINK_SIZE_PAPER;
|
|
||||||
} else if (effectName == EFFECT_INVISIBLE_LINK) {
|
|
||||||
effect->category = EFFECT_CAT_LINK_SIZE;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::InvisibleLink();
|
|
||||||
} else if (effectName == EFFECT_PACIFIST) {
|
|
||||||
effect->category = EFFECT_CAT_PACIFIST;
|
|
||||||
effect->timeRemaining = 15000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::PacifistMode();
|
|
||||||
} else if (effectName == EFFECT_NO_Z_TARGETING) {
|
|
||||||
effect->category = EFFECT_CAT_NO_Z;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::DisableZTargeting();
|
|
||||||
} else if (effectName == EFFECT_RAINSTORM) {
|
|
||||||
effect->category = EFFECT_CAT_WEATHER;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::WeatherRainstorm();
|
|
||||||
} else if (effectName == EFFECT_REVERSE_CONTROLS) {
|
|
||||||
effect->category = EFFECT_CAT_REVERSE_CONTROLS;
|
|
||||||
effect->timeRemaining = 60000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::ReverseControls();
|
|
||||||
} else if (effectName == EFFECT_IRON_BOOTS) {
|
|
||||||
effect->category = EFFECT_CAT_BOOTS;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::ForceEquipBoots();
|
|
||||||
effect->giEffect->parameter = PLAYER_BOOTS_IRON;
|
|
||||||
} else if (effectName == EFFECT_HOVER_BOOTS) {
|
|
||||||
effect->category = EFFECT_CAT_BOOTS;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::ForceEquipBoots();
|
|
||||||
effect->giEffect->parameter = PLAYER_BOOTS_HOVER;;
|
|
||||||
} else if (effectName == EFFECT_GIVE_DEKU_SHIELD) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::GiveDekuShield();
|
|
||||||
} else if (effectName == EFFECT_INCREASE_SPEED) {
|
|
||||||
effect->category = EFFECT_CAT_SPEED;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyRunSpeedModifier();
|
|
||||||
effect->giEffect->parameter = 2;
|
|
||||||
} else if (effectName == EFFECT_DECREASE_SPEED) {
|
|
||||||
effect->category = EFFECT_CAT_SPEED;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyRunSpeedModifier();
|
|
||||||
effect->giEffect->parameter = -2;
|
|
||||||
} else if (effectName == EFFECT_OHKO) {
|
|
||||||
effect->category = EFFECT_CAT_DAMAGE_TAKEN;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::OneHitKO();
|
|
||||||
} else if (effectName == EFFECT_DAMAGE_MULTIPLIER) {
|
|
||||||
effect->category = EFFECT_CAT_DAMAGE_TAKEN;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyDefenseModifier();
|
|
||||||
effect->paramMultiplier = -1;
|
|
||||||
} else if (effectName == EFFECT_DEFENSE_MULTIPLIER) {
|
|
||||||
effect->category = EFFECT_CAT_DAMAGE_TAKEN;
|
|
||||||
effect->timeRemaining = 30000;
|
|
||||||
effect->giEffect = new GameInteractionEffect::ModifyDefenseModifier();
|
|
||||||
} else if (effectName == EFFECT_SPAWN_CUCCO_STORM) {
|
|
||||||
effect->giEffect = new GameInteractionEffect::SpawnCuccoStorm();
|
|
||||||
} else if (effectName == EFFECT_SPAWN_WALLMASTER) {
|
|
||||||
effect->value[0] = ACTOR_EN_WALLMAS;
|
|
||||||
effect->category = EFFECT_CAT_SPAWN_ENEMY;
|
|
||||||
} else if (effectName == EFFECT_SPAWN_ARWING) {
|
|
||||||
effect->value[0] = ACTOR_EN_CLEAR_TAG;
|
|
||||||
// Parameter for no cutscene Arwing
|
|
||||||
effect->value[1] = 1;
|
|
||||||
effect->category = EFFECT_CAT_SPAWN_ENEMY;
|
|
||||||
} else if (effectName == EFFECT_SPAWN_DARK_LINK) {
|
|
||||||
effect->value[0] = ACTOR_EN_TORCH2;
|
|
||||||
effect->category = EFFECT_CAT_SPAWN_ENEMY;
|
|
||||||
} else if (effectName == EFFECT_SPAWN_STALFOS) {
|
|
||||||
effect->value[0] = ACTOR_EN_TEST;
|
|
||||||
// Parameter for gravity-obeying Stalfos
|
|
||||||
effect->value[1] = 2;
|
|
||||||
effect->category = EFFECT_CAT_SPAWN_ENEMY;
|
|
||||||
} else if (effectName == EFFECT_SPAWN_WOLFOS) {
|
|
||||||
effect->value[0] = ACTOR_EN_WF;
|
|
||||||
effect->category = EFFECT_CAT_SPAWN_ENEMY;
|
|
||||||
} else if (effectName == EFFECT_SPAWN_FREEZARD) {
|
|
||||||
effect->value[0] = ACTOR_EN_FZ;
|
|
||||||
effect->category = EFFECT_CAT_SPAWN_ENEMY;
|
|
||||||
} else if (effectName == EFFECT_SPAWN_KEESE) {
|
|
||||||
effect->value[0] = ACTOR_EN_FIREFLY;
|
|
||||||
// Parameter for normal keese
|
|
||||||
effect->value[1] = 2;
|
|
||||||
effect->category = EFFECT_CAT_SPAWN_ENEMY;
|
|
||||||
} else if (effectName == EFFECT_SPAWN_ICE_KEESE) {
|
|
||||||
effect->value[0] = ACTOR_EN_FIREFLY;
|
|
||||||
// Parameter for ice keese
|
|
||||||
effect->value[1] = 4;
|
|
||||||
effect->category = EFFECT_CAT_SPAWN_ENEMY;
|
|
||||||
} else if (effectName == EFFECT_SPAWN_FIRE_KEESE) {
|
|
||||||
effect->value[0] = ACTOR_EN_FIREFLY;
|
|
||||||
// Parameter for fire keese
|
|
||||||
effect->value[1] = 1;
|
|
||||||
effect->category = EFFECT_CAT_SPAWN_ENEMY;
|
|
||||||
} else if (effectName == EFFECT_SPAWN_TEKTITE) {
|
|
||||||
effect->value[0] = ACTOR_EN_TITE;
|
|
||||||
effect->category = EFFECT_CAT_SPAWN_ENEMY;
|
|
||||||
} else if (effectName == EFFECT_SPAWN_LIKE_LIKE) {
|
|
||||||
effect->value[0] = ACTOR_EN_RR;
|
|
||||||
effect->category = EFFECT_CAT_SPAWN_ENEMY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no value is specifically set, default to using whatever CC sends us.
|
|
||||||
// Values are used for various things depending on the effect, but they
|
|
||||||
// usually represent the "amount" of an effect. Amount of hearts healed,
|
|
||||||
// strength of knockback, etc.
|
|
||||||
if (effect->giEffect != NULL) {
|
|
||||||
if (!effect->giEffect->parameter && effect->value[0]) {
|
|
||||||
effect->giEffect->parameter = effect->value[0] * effect->paramMultiplier;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (effect->category == "") {
|
|
||||||
effect->category = EFFECT_CAT_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return effect;
|
|
||||||
}
|
|
||||||
|
|
||||||
CrowdControl::EffectResult CrowdControl::ExecuteEffect(Effect* effect) {
|
CrowdControl::EffectResult CrowdControl::ExecuteEffect(Effect* effect) {
|
||||||
GameInteractionEffectQueryResult giResult;
|
GameInteractionEffectQueryResult giResult;
|
||||||
if (effect->category == EFFECT_CAT_SPAWN_ENEMY) {
|
if (effect->category == kEffectCatSpawnEnemy) {
|
||||||
giResult = GameInteractor::RawAction::SpawnEnemyWithOffset(effect->value[0], effect->value[1]);
|
giResult = GameInteractor::RawAction::SpawnEnemyWithOffset(effect->spawnParams[0], effect->spawnParams[1]);
|
||||||
|
} else if (effect->category == kEffectCatSpawnActor) {
|
||||||
|
giResult = GameInteractor::RawAction::SpawnActor(effect->spawnParams[0], effect->spawnParams[1]);
|
||||||
} else {
|
} else {
|
||||||
giResult = GameInteractor::ApplyEffect(effect->giEffect);
|
giResult = GameInteractor::ApplyEffect(effect->giEffect);
|
||||||
}
|
}
|
||||||
@ -466,7 +210,7 @@ CrowdControl::EffectResult CrowdControl::ExecuteEffect(Effect* effect) {
|
|||||||
|
|
||||||
/// Checks if effect can be applied -- should not be used to check for spawn enemy effects.
|
/// Checks if effect can be applied -- should not be used to check for spawn enemy effects.
|
||||||
CrowdControl::EffectResult CrowdControl::CanApplyEffect(Effect* effect) {
|
CrowdControl::EffectResult CrowdControl::CanApplyEffect(Effect* effect) {
|
||||||
assert(effect->category != EFFECT_CAT_SPAWN_ENEMY);
|
assert(effect->category != kEffectCatSpawnEnemy || effect->category != kEffectCatSpawnActor);
|
||||||
GameInteractionEffectQueryResult giResult = GameInteractor::CanApplyEffect(effect->giEffect);
|
GameInteractionEffectQueryResult giResult = GameInteractor::CanApplyEffect(effect->giEffect);
|
||||||
|
|
||||||
return TranslateGiEnum(giResult);
|
return TranslateGiEnum(giResult);
|
||||||
@ -486,4 +230,598 @@ CrowdControl::EffectResult CrowdControl::TranslateGiEnum(GameInteractionEffectQu
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) {
|
||||||
|
nlohmann::json dataReceived = nlohmann::json::parse(payload, nullptr, false);
|
||||||
|
if (dataReceived.is_discarded()) {
|
||||||
|
SPDLOG_ERROR("Error parsing JSON");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Effect* effect = new Effect();
|
||||||
|
effect->lastExecutionResult = EffectResult::Initiate;
|
||||||
|
effect->id = dataReceived["id"];
|
||||||
|
auto parameters = dataReceived["parameters"];
|
||||||
|
uint32_t receivedParameter = 0;
|
||||||
|
auto effectName = dataReceived["code"].get<std::string>();
|
||||||
|
|
||||||
|
if (parameters.size() > 0) {
|
||||||
|
receivedParameter = dataReceived["parameters"][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign GameInteractionEffect + values to CC effect.
|
||||||
|
// Categories are mostly used for checking for conflicting timed effects.
|
||||||
|
switch (effectStringToEnum[effectName]) {
|
||||||
|
|
||||||
|
// Spawn Enemies and Objects
|
||||||
|
case kEffectSpawnCuccoStorm:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_NIW;
|
||||||
|
effect->category = kEffectCatSpawnActor;
|
||||||
|
break;
|
||||||
|
case kEffectSpawnLitBomb:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_BOM;
|
||||||
|
effect->category = kEffectCatSpawnActor;
|
||||||
|
break;
|
||||||
|
case kEffectSpawnExplosion:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_BOM;
|
||||||
|
effect->spawnParams[1] = 1;
|
||||||
|
effect->category = kEffectCatSpawnActor;
|
||||||
|
break;
|
||||||
|
case kEffectSpawnArwing:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_CLEAR_TAG;
|
||||||
|
// Parameter for no cutscene Arwing
|
||||||
|
effect->spawnParams[1] = 1;
|
||||||
|
effect->category = kEffectCatSpawnEnemy;
|
||||||
|
break;
|
||||||
|
case kEffectSpawnDarklink:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_TORCH2;
|
||||||
|
effect->category = kEffectCatSpawnEnemy;
|
||||||
|
break;
|
||||||
|
case kEffectSpawnIronKnuckle:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_IK;
|
||||||
|
// Parameter for black standing Iron Knuckle
|
||||||
|
effect->spawnParams[1] = 2;
|
||||||
|
effect->category = kEffectCatSpawnEnemy;
|
||||||
|
break;
|
||||||
|
case kEffectSpawnStalfos:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_TEST;
|
||||||
|
// Parameter for gravity-obeying Stalfos
|
||||||
|
effect->spawnParams[1] = 2;
|
||||||
|
effect->category = kEffectCatSpawnEnemy;
|
||||||
|
break;
|
||||||
|
case kEffectSpawnFreezard:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_FZ;
|
||||||
|
effect->category = kEffectCatSpawnEnemy;
|
||||||
|
break;
|
||||||
|
case kEffectSpawnLikeLike:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_RR;
|
||||||
|
effect->category = kEffectCatSpawnEnemy;
|
||||||
|
break;
|
||||||
|
case kEffectSpawnGibdo:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_RD;
|
||||||
|
// Parameter for Gibdo
|
||||||
|
effect->spawnParams[1] = 32766;
|
||||||
|
effect->category = kEffectCatSpawnEnemy;
|
||||||
|
break;
|
||||||
|
case kEffectSpawnKeese:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_FIREFLY;
|
||||||
|
// Parameter for normal keese
|
||||||
|
effect->spawnParams[1] = 2;
|
||||||
|
effect->category = kEffectCatSpawnEnemy;
|
||||||
|
break;
|
||||||
|
case kEffectSpawnIceKeese:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_FIREFLY;
|
||||||
|
// Parameter for ice keese
|
||||||
|
effect->spawnParams[1] = 4;
|
||||||
|
effect->category = kEffectCatSpawnEnemy;
|
||||||
|
break;
|
||||||
|
case kEffectSpawnFireKeese:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_FIREFLY;
|
||||||
|
// Parameter for fire keese
|
||||||
|
effect->spawnParams[1] = 1;
|
||||||
|
effect->category = kEffectCatSpawnEnemy;
|
||||||
|
break;
|
||||||
|
case kEffectSpawnWolfos:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_WF;
|
||||||
|
effect->category = kEffectCatSpawnEnemy;
|
||||||
|
break;
|
||||||
|
case kEffectSpawnWallmaster:
|
||||||
|
effect->spawnParams[0] = ACTOR_EN_WALLMAS;
|
||||||
|
effect->category = kEffectCatSpawnEnemy;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Link Modifiers
|
||||||
|
case kEffectTakeHalfDamage:
|
||||||
|
effect->category = kEffectCatDamageTaken;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyDefenseModifier();
|
||||||
|
effect->giEffect->parameters[0] = 2;
|
||||||
|
break;
|
||||||
|
case kEffectTakeDoubleDamage:
|
||||||
|
effect->category = kEffectCatDamageTaken;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyDefenseModifier();
|
||||||
|
effect->giEffect->parameters[0] = -2;
|
||||||
|
break;
|
||||||
|
case kEffectOneHitKo:
|
||||||
|
effect->category = kEffectCatOhko;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::OneHitKO();
|
||||||
|
break;
|
||||||
|
case kEffectInvincibility:
|
||||||
|
effect->category = kEffectCatInvincible;
|
||||||
|
effect->timeRemaining = 15000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::PlayerInvincibility();
|
||||||
|
break;
|
||||||
|
break;
|
||||||
|
case kEffectIncreaseSpeed:
|
||||||
|
effect->category = kEffectCatSpeed;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyRunSpeedModifier();
|
||||||
|
effect->giEffect->parameters[0] = 2;
|
||||||
|
break;
|
||||||
|
case kEffectDecreaseSpeed:
|
||||||
|
effect->category = kEffectCatSpeed;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyRunSpeedModifier();
|
||||||
|
effect->giEffect->parameters[0] = -2;
|
||||||
|
break;
|
||||||
|
case kEffectLowGravity:
|
||||||
|
effect->category = kEffectCatGravity;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyGravity();
|
||||||
|
effect->giEffect->parameters[0] = GI_GRAVITY_LEVEL_LIGHT;
|
||||||
|
break;
|
||||||
|
case kEffectHighGravity:
|
||||||
|
effect->category = kEffectCatGravity;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyGravity();
|
||||||
|
effect->giEffect->parameters[0] = GI_GRAVITY_LEVEL_HEAVY;
|
||||||
|
break;
|
||||||
|
case kEffectForceIronBoots:
|
||||||
|
effect->category = kEffectCatBoots;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::ForceEquipBoots();
|
||||||
|
effect->giEffect->parameters[0] = PLAYER_BOOTS_IRON;
|
||||||
|
break;
|
||||||
|
case kEffectForceHoverBoots:
|
||||||
|
effect->category = kEffectCatBoots;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::ForceEquipBoots();
|
||||||
|
effect->giEffect->parameters[0] = PLAYER_BOOTS_HOVER;
|
||||||
|
break;
|
||||||
|
case kEffectSlipperyFloor:
|
||||||
|
effect->category = kEffectCatSlipperyFloor;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::SlipperyFloor();
|
||||||
|
break;
|
||||||
|
case kEffectNoLedgeGrabs:
|
||||||
|
effect->category = kEffectCatNoLedgeGrabs;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::DisableLedgeGrabs();
|
||||||
|
break;
|
||||||
|
case kEffectRandomWind:
|
||||||
|
effect->category = kEffectCatRandomWind;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::RandomWind();
|
||||||
|
break;
|
||||||
|
case kEffectRandomBonks:
|
||||||
|
effect->category = kEffectCatRandomBonks;
|
||||||
|
effect->timeRemaining = 60000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::RandomBonks();
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Hurt or Heal Link
|
||||||
|
case kEffectEmptyHeart:
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyHealth();
|
||||||
|
effect->giEffect->parameters[0] = receivedParameter * -1;
|
||||||
|
break;
|
||||||
|
case kEffectFillHeart:
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyHealth();
|
||||||
|
break;
|
||||||
|
case kEffectKnockbackLinkWeak:
|
||||||
|
effect->giEffect = new GameInteractionEffect::KnockbackPlayer();
|
||||||
|
effect->giEffect->parameters[0] = 1;
|
||||||
|
break;
|
||||||
|
case kEffectKnockbackLinkStrong:
|
||||||
|
effect->giEffect = new GameInteractionEffect::KnockbackPlayer();
|
||||||
|
effect->giEffect->parameters[0] = 3;
|
||||||
|
break;
|
||||||
|
case kEffectKnockbackLinkMega:
|
||||||
|
effect->giEffect = new GameInteractionEffect::KnockbackPlayer();
|
||||||
|
effect->giEffect->parameters[0] = 6;
|
||||||
|
break;
|
||||||
|
case kEffectBurnLink:
|
||||||
|
effect->giEffect = new GameInteractionEffect::BurnPlayer();
|
||||||
|
break;
|
||||||
|
case kEffectFreezeLink:
|
||||||
|
effect->giEffect = new GameInteractionEffect::FreezePlayer();
|
||||||
|
break;
|
||||||
|
case kEffectElectrocuteLink:
|
||||||
|
effect->giEffect = new GameInteractionEffect::ElectrocutePlayer();
|
||||||
|
break;
|
||||||
|
case kEffectKillLink:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetPlayerHealth();
|
||||||
|
effect->giEffect->parameters[0] = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Give Items and Consumables
|
||||||
|
case kEffectAddHeartContainer:
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyHeartContainers();
|
||||||
|
effect->giEffect->parameters[0] = 1;
|
||||||
|
break;
|
||||||
|
case kEffectFillMagic:
|
||||||
|
effect->giEffect = new GameInteractionEffect::FillMagic();
|
||||||
|
break;
|
||||||
|
case kEffectAddRupees:
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyRupees();
|
||||||
|
break;
|
||||||
|
case kEffectGiveDekuShield:
|
||||||
|
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
|
||||||
|
effect->giEffect->parameters[0] = ITEM_SHIELD_DEKU;
|
||||||
|
break;
|
||||||
|
case kEffectGiveHylianShield:
|
||||||
|
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
|
||||||
|
effect->giEffect->parameters[0] = ITEM_SHIELD_HYLIAN;
|
||||||
|
break;
|
||||||
|
case kEffectRefillSticks:
|
||||||
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
|
effect->giEffect->parameters[1] = ITEM_STICK;
|
||||||
|
break;
|
||||||
|
case kEffectRefillNuts:
|
||||||
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
|
effect->giEffect->parameters[1] = ITEM_NUT;
|
||||||
|
break;
|
||||||
|
case kEffectRefillBombs:
|
||||||
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
|
effect->giEffect->parameters[1] = ITEM_BOMB;
|
||||||
|
break;
|
||||||
|
case kEffectRefillSeeds:
|
||||||
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
|
effect->giEffect->parameters[1] = ITEM_SLINGSHOT;
|
||||||
|
break;
|
||||||
|
case kEffectRefillArrows:
|
||||||
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
|
effect->giEffect->parameters[1] = ITEM_BOW;
|
||||||
|
break;
|
||||||
|
case kEffectRefillBombchus:
|
||||||
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
|
effect->giEffect->parameters[1] = ITEM_BOMBCHU;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Take Items and Consumables
|
||||||
|
case kEffectRemoveHeartContainer:
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyHeartContainers();
|
||||||
|
effect->giEffect->parameters[0] = -1;
|
||||||
|
break;
|
||||||
|
case kEffectEmptyMagic:
|
||||||
|
effect->giEffect = new GameInteractionEffect::EmptyMagic();
|
||||||
|
break;
|
||||||
|
case kEffectRemoveRupees:
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyRupees();
|
||||||
|
effect->giEffect->parameters[0] = receivedParameter * -1;
|
||||||
|
break;
|
||||||
|
case kEffectTakeDekuShield:
|
||||||
|
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
|
||||||
|
effect->giEffect->parameters[0] = -ITEM_SHIELD_DEKU;
|
||||||
|
break;
|
||||||
|
case kEffectTakeHylianShield:
|
||||||
|
effect->giEffect = new GameInteractionEffect::GiveOrTakeShield();
|
||||||
|
effect->giEffect->parameters[0] = -ITEM_SHIELD_HYLIAN;
|
||||||
|
break;
|
||||||
|
case kEffectTakeSticks:
|
||||||
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
|
effect->giEffect->parameters[0] = receivedParameter * -1;
|
||||||
|
effect->giEffect->parameters[1] = ITEM_STICK;
|
||||||
|
break;
|
||||||
|
case kEffectTakeNuts:
|
||||||
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
|
effect->giEffect->parameters[0] = receivedParameter * -1;
|
||||||
|
effect->giEffect->parameters[1] = ITEM_NUT;
|
||||||
|
break;
|
||||||
|
case kEffectTakeBombs:
|
||||||
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
|
effect->giEffect->parameters[0] = receivedParameter * -1;
|
||||||
|
effect->giEffect->parameters[1] = ITEM_BOMB;
|
||||||
|
break;
|
||||||
|
case kEffectTakeSeeds:
|
||||||
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
|
effect->giEffect->parameters[0] = receivedParameter * -1;
|
||||||
|
effect->giEffect->parameters[1] = ITEM_SLINGSHOT;
|
||||||
|
break;
|
||||||
|
case kEffectTakeArrows:
|
||||||
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
|
effect->giEffect->parameters[0] = receivedParameter * -1;
|
||||||
|
effect->giEffect->parameters[1] = ITEM_BOW;
|
||||||
|
break;
|
||||||
|
case kEffectTakeBombchus:
|
||||||
|
effect->giEffect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
|
effect->giEffect->parameters[0] = receivedParameter * -1;
|
||||||
|
effect->giEffect->parameters[1] = ITEM_BOMBCHU;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Link Size Modifiers
|
||||||
|
case kEffectGiantLink:
|
||||||
|
effect->category = kEffectCatLinkSize;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
||||||
|
effect->giEffect->parameters[0] = GI_LINK_SIZE_GIANT;
|
||||||
|
break;
|
||||||
|
case kEffectMinishLink:
|
||||||
|
effect->category = kEffectCatLinkSize;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
||||||
|
effect->giEffect->parameters[0] = GI_LINK_SIZE_MINISH;
|
||||||
|
break;
|
||||||
|
case kEffectPaperLink:
|
||||||
|
effect->category = kEffectCatLinkSize;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
||||||
|
effect->giEffect->parameters[0] = GI_LINK_SIZE_PAPER;
|
||||||
|
break;
|
||||||
|
case kEffectSquishedLink:
|
||||||
|
effect->category = kEffectCatLinkSize;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::ModifyLinkSize();
|
||||||
|
effect->giEffect->parameters[0] = GI_LINK_SIZE_SQUISHED;
|
||||||
|
break;
|
||||||
|
case kEffectInvisibleLink:
|
||||||
|
effect->category = kEffectCatLinkSize;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::InvisibleLink();
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Generic Effects
|
||||||
|
case kEffectRandomBombTimer:
|
||||||
|
effect->category = kEffectCatRandomBombFuseTimer;
|
||||||
|
effect->timeRemaining = 60000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::RandomBombFuseTimer();
|
||||||
|
break;
|
||||||
|
case kEffectSetTimeToDawn:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetTimeOfDay();
|
||||||
|
effect->giEffect->parameters[0] = GI_TIMEOFDAY_DAWN;
|
||||||
|
break;
|
||||||
|
case kEffectSetTimeToDusk:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetTimeOfDay();
|
||||||
|
effect->giEffect->parameters[0] = GI_TIMEOFDAY_DUSK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Visual Effects
|
||||||
|
case kEffectNoUi:
|
||||||
|
effect->category = kEffectCatUi;
|
||||||
|
effect->timeRemaining = 60000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::NoUI();
|
||||||
|
break;
|
||||||
|
case kEffectRainstorm:
|
||||||
|
effect->category = kEffectCatWeather;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::WeatherRainstorm();
|
||||||
|
break;
|
||||||
|
case kEffectDebugMode:
|
||||||
|
effect->category = kEffectCatDebugMode;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCollisionViewer();
|
||||||
|
break;
|
||||||
|
case kEffectRandomCosmetics:
|
||||||
|
effect->giEffect = new GameInteractionEffect::RandomizeCosmetics();
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Controls
|
||||||
|
case kEffectNoZButton:
|
||||||
|
effect->category = kEffectCatNoZ;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::DisableZTargeting();
|
||||||
|
break;
|
||||||
|
case kEffectReverseControls:
|
||||||
|
effect->category = kEffectCatReverseControls;
|
||||||
|
effect->timeRemaining = 60000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::ReverseControls();
|
||||||
|
break;
|
||||||
|
case kEffectPacifistMode:
|
||||||
|
effect->category = kEffectCatPacifist;
|
||||||
|
effect->timeRemaining = 15000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::PacifistMode();
|
||||||
|
break;
|
||||||
|
case kEffectPressRandomButtons:
|
||||||
|
effect->category = kEffectCatRandomButtons;
|
||||||
|
effect->timeRemaining = 30000;
|
||||||
|
effect->giEffect = new GameInteractionEffect::PressRandomButton();
|
||||||
|
effect->giEffect->parameters[0] = 30;
|
||||||
|
break;
|
||||||
|
case kEffectClearCbuttons:
|
||||||
|
effect->giEffect = new GameInteractionEffect::ClearAssignedButtons();
|
||||||
|
effect->giEffect->parameters[0] = GI_BUTTONS_CBUTTONS;
|
||||||
|
break;
|
||||||
|
case kEffectClearDpad:
|
||||||
|
effect->giEffect = new GameInteractionEffect::ClearAssignedButtons();
|
||||||
|
effect->giEffect->parameters[0] = GI_BUTTONS_DPAD;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Teleport Player
|
||||||
|
case kEffectTpLinksHouse:
|
||||||
|
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
||||||
|
effect->giEffect->parameters[0] = GI_TP_DEST_LINKSHOUSE;
|
||||||
|
break;
|
||||||
|
case kEffectTpMinuet:
|
||||||
|
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
||||||
|
effect->giEffect->parameters[0] = GI_TP_DEST_MINUET;
|
||||||
|
break;
|
||||||
|
case kEffectTpBolero:
|
||||||
|
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
||||||
|
effect->giEffect->parameters[0] = GI_TP_DEST_BOLERO;
|
||||||
|
break;
|
||||||
|
case kEffectTpSerenade:
|
||||||
|
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
||||||
|
effect->giEffect->parameters[0] = GI_TP_DEST_SERENADE;
|
||||||
|
break;
|
||||||
|
case kEffectTpRequiem:
|
||||||
|
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
||||||
|
effect->giEffect->parameters[0] = GI_TP_DEST_REQUIEM;
|
||||||
|
break;
|
||||||
|
case kEffectTpNocturne:
|
||||||
|
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
||||||
|
effect->giEffect->parameters[0] = GI_TP_DEST_NOCTURNE;
|
||||||
|
break;
|
||||||
|
case kEffectTpPrelude:
|
||||||
|
effect->giEffect = new GameInteractionEffect::TeleportPlayer();
|
||||||
|
effect->giEffect->parameters[0] = GI_TP_DEST_PRELUDE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Tunic Color (Bidding War)
|
||||||
|
case kEffectTunicRed:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_RED;
|
||||||
|
break;
|
||||||
|
case kEffectTunicGreen:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_GREEN;
|
||||||
|
break;
|
||||||
|
case kEffectTunicBlue:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_BLUE;
|
||||||
|
break;
|
||||||
|
case kEffectTunicOrange:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_ORANGE;
|
||||||
|
break;
|
||||||
|
case kEffectTunicYellow:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_YELLOW;
|
||||||
|
break;
|
||||||
|
case kEffectTunicPurple:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_PURPLE;
|
||||||
|
break;
|
||||||
|
case kEffectTunicPink:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_PINK;
|
||||||
|
break;
|
||||||
|
case kEffectTunicBrown:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_BROWN;
|
||||||
|
break;
|
||||||
|
case kEffectTunicBlack:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_TUNICS;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_BLACK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Navi Color (Bidding War)
|
||||||
|
case kEffectNaviRed:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_RED;
|
||||||
|
break;
|
||||||
|
case kEffectNaviGreen:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_GREEN;
|
||||||
|
break;
|
||||||
|
case kEffectNaviBlue:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_BLUE;
|
||||||
|
break;
|
||||||
|
case kEffectNaviOrange:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_ORANGE;
|
||||||
|
break;
|
||||||
|
case kEffectNaviYellow:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_YELLOW;
|
||||||
|
break;
|
||||||
|
case kEffectNaviPurple:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_PURPLE;
|
||||||
|
break;
|
||||||
|
case kEffectNaviPink:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_PINK;
|
||||||
|
break;
|
||||||
|
case kEffectNaviBrown:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_BROWN;
|
||||||
|
break;
|
||||||
|
case kEffectNaviBlack:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_NAVI;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_BLACK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Link's Hair Color (Bidding War)
|
||||||
|
case kEffectHairRed:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_RED;
|
||||||
|
break;
|
||||||
|
case kEffectHairGreen:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_GREEN;
|
||||||
|
break;
|
||||||
|
case kEffectHairBlue:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_BLUE;
|
||||||
|
break;
|
||||||
|
case kEffectHairOrange:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_ORANGE;
|
||||||
|
break;
|
||||||
|
case kEffectHairYellow:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_YELLOW;
|
||||||
|
break;
|
||||||
|
case kEffectHairPurple:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_PURPLE;
|
||||||
|
break;
|
||||||
|
case kEffectHairPink:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_PINK;
|
||||||
|
break;
|
||||||
|
case kEffectHairBrown:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_BROWN;
|
||||||
|
break;
|
||||||
|
case kEffectHairBlack:
|
||||||
|
effect->giEffect = new GameInteractionEffect::SetCosmeticsColor();
|
||||||
|
effect->giEffect->parameters[0] = GI_COSMETICS_HAIR;
|
||||||
|
effect->giEffect->parameters[1] = GI_COLOR_BLACK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no value is specifically set, default to using whatever CC sends us.
|
||||||
|
// Values are used for various things depending on the effect, but they
|
||||||
|
// usually represent the "amount" of an effect. Amount of hearts healed,
|
||||||
|
// strength of knockback, etc.
|
||||||
|
if (effect->giEffect != NULL) {
|
||||||
|
if (!effect->giEffect->parameters[0]) {
|
||||||
|
effect->giEffect->parameters[0] = receivedParameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return effect;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -63,11 +63,10 @@ class CrowdControl {
|
|||||||
|
|
||||||
typedef struct Effect {
|
typedef struct Effect {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint32_t value[2];
|
uint32_t spawnParams[2];
|
||||||
std::string category;
|
uint32_t category = 0;
|
||||||
long timeRemaining;
|
long timeRemaining;
|
||||||
GameInteractionEffectBase *giEffect;
|
GameInteractionEffectBase *giEffect;
|
||||||
int32_t paramMultiplier = 1;
|
|
||||||
|
|
||||||
// Metadata used while executing (only for timed effects)
|
// Metadata used while executing (only for timed effects)
|
||||||
bool isPaused;
|
bool isPaused;
|
||||||
|
310
soh/soh/Enhancements/crowd-control/CrowdControlTypes.h
Normal file
310
soh/soh/Enhancements/crowd-control/CrowdControlTypes.h
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
enum CCStringEnumValues {
|
||||||
|
|
||||||
|
// Spawn Enemies and Objects
|
||||||
|
kEffectSpawnCuccoStorm,
|
||||||
|
kEffectSpawnLitBomb,
|
||||||
|
kEffectSpawnExplosion,
|
||||||
|
kEffectSpawnArwing,
|
||||||
|
kEffectSpawnDarklink,
|
||||||
|
kEffectSpawnIronKnuckle,
|
||||||
|
kEffectSpawnStalfos,
|
||||||
|
kEffectSpawnFreezard,
|
||||||
|
kEffectSpawnLikeLike,
|
||||||
|
kEffectSpawnGibdo,
|
||||||
|
kEffectSpawnKeese,
|
||||||
|
kEffectSpawnIceKeese,
|
||||||
|
kEffectSpawnFireKeese,
|
||||||
|
kEffectSpawnWolfos,
|
||||||
|
kEffectSpawnWallmaster,
|
||||||
|
|
||||||
|
// Link Modifiers
|
||||||
|
kEffectTakeHalfDamage,
|
||||||
|
kEffectTakeDoubleDamage,
|
||||||
|
kEffectOneHitKo,
|
||||||
|
kEffectInvincibility,
|
||||||
|
kEffectIncreaseSpeed,
|
||||||
|
kEffectDecreaseSpeed,
|
||||||
|
kEffectLowGravity,
|
||||||
|
kEffectHighGravity,
|
||||||
|
kEffectForceIronBoots,
|
||||||
|
kEffectForceHoverBoots,
|
||||||
|
kEffectSlipperyFloor,
|
||||||
|
kEffectNoLedgeGrabs,
|
||||||
|
kEffectRandomWind,
|
||||||
|
kEffectRandomBonks,
|
||||||
|
|
||||||
|
// Hurt or Heal Link
|
||||||
|
kEffectEmptyHeart,
|
||||||
|
kEffectFillHeart,
|
||||||
|
kEffectKnockbackLinkWeak,
|
||||||
|
kEffectKnockbackLinkStrong,
|
||||||
|
kEffectKnockbackLinkMega,
|
||||||
|
kEffectBurnLink,
|
||||||
|
kEffectFreezeLink,
|
||||||
|
kEffectElectrocuteLink,
|
||||||
|
kEffectKillLink,
|
||||||
|
|
||||||
|
// Give Items and Consumables
|
||||||
|
kEffectAddHeartContainer,
|
||||||
|
kEffectFillMagic,
|
||||||
|
kEffectAddRupees,
|
||||||
|
kEffectGiveDekuShield,
|
||||||
|
kEffectGiveHylianShield,
|
||||||
|
kEffectRefillSticks,
|
||||||
|
kEffectRefillNuts,
|
||||||
|
kEffectRefillBombs,
|
||||||
|
kEffectRefillSeeds,
|
||||||
|
kEffectRefillArrows,
|
||||||
|
kEffectRefillBombchus,
|
||||||
|
|
||||||
|
// Take Items and Consumables
|
||||||
|
kEffectRemoveHeartContainer,
|
||||||
|
kEffectEmptyMagic,
|
||||||
|
kEffectRemoveRupees,
|
||||||
|
kEffectTakeDekuShield,
|
||||||
|
kEffectTakeHylianShield,
|
||||||
|
kEffectTakeSticks,
|
||||||
|
kEffectTakeNuts,
|
||||||
|
kEffectTakeBombs,
|
||||||
|
kEffectTakeSeeds,
|
||||||
|
kEffectTakeArrows,
|
||||||
|
kEffectTakeBombchus,
|
||||||
|
|
||||||
|
// Link Size Modifiers
|
||||||
|
kEffectGiantLink,
|
||||||
|
kEffectMinishLink,
|
||||||
|
kEffectPaperLink,
|
||||||
|
kEffectSquishedLink,
|
||||||
|
kEffectInvisibleLink,
|
||||||
|
|
||||||
|
// Generic kEffects
|
||||||
|
kEffectRandomBombTimer,
|
||||||
|
kEffectSetTimeToDawn,
|
||||||
|
kEffectSetTimeToDusk,
|
||||||
|
|
||||||
|
// Visual kEffects
|
||||||
|
kEffectNoUi,
|
||||||
|
kEffectRainstorm,
|
||||||
|
kEffectDebugMode,
|
||||||
|
kEffectRandomCosmetics,
|
||||||
|
|
||||||
|
// Controls
|
||||||
|
kEffectNoZButton,
|
||||||
|
kEffectReverseControls,
|
||||||
|
kEffectPacifistMode,
|
||||||
|
kEffectPressRandomButtons,
|
||||||
|
kEffectClearCbuttons,
|
||||||
|
kEffectClearDpad,
|
||||||
|
|
||||||
|
// Teleport Player
|
||||||
|
kEffectTpLinksHouse,
|
||||||
|
kEffectTpMinuet,
|
||||||
|
kEffectTpBolero,
|
||||||
|
kEffectTpSerenade,
|
||||||
|
kEffectTpRequiem,
|
||||||
|
kEffectTpNocturne,
|
||||||
|
kEffectTpPrelude,
|
||||||
|
|
||||||
|
// Tunic Color (Bidding War)
|
||||||
|
kEffectTunicRed,
|
||||||
|
kEffectTunicGreen,
|
||||||
|
kEffectTunicBlue,
|
||||||
|
kEffectTunicOrange,
|
||||||
|
kEffectTunicYellow,
|
||||||
|
kEffectTunicPurple,
|
||||||
|
kEffectTunicPink,
|
||||||
|
kEffectTunicBrown,
|
||||||
|
kEffectTunicBlack,
|
||||||
|
|
||||||
|
// Navi Color (Bidding War)
|
||||||
|
kEffectNaviRed,
|
||||||
|
kEffectNaviGreen,
|
||||||
|
kEffectNaviBlue,
|
||||||
|
kEffectNaviOrange,
|
||||||
|
kEffectNaviYellow,
|
||||||
|
kEffectNaviPurple,
|
||||||
|
kEffectNaviPink,
|
||||||
|
kEffectNaviBrown,
|
||||||
|
kEffectNaviBlack,
|
||||||
|
|
||||||
|
// Link's Hair Color (Bidding War)
|
||||||
|
kEffectHairRed,
|
||||||
|
kEffectHairGreen,
|
||||||
|
kEffectHairBlue,
|
||||||
|
kEffectHairOrange,
|
||||||
|
kEffectHairYellow,
|
||||||
|
kEffectHairPurple,
|
||||||
|
kEffectHairPink,
|
||||||
|
kEffectHairBrown,
|
||||||
|
kEffectHairBlack,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CCCatEnumValues {
|
||||||
|
kEffectCatNone,
|
||||||
|
kEffectCatGravity,
|
||||||
|
kEffectCatLinkSize,
|
||||||
|
kEffectCatRandomBombFuseTimer,
|
||||||
|
kEffectCatPacifist,
|
||||||
|
kEffectCatNoZ,
|
||||||
|
kEffectCatRandomButtons,
|
||||||
|
kEffectCatUi,
|
||||||
|
kEffectCatWeather,
|
||||||
|
kEffectCatDebugMode,
|
||||||
|
kEffectCatNoLedgeGrabs,
|
||||||
|
kEffectCatRandomWind,
|
||||||
|
kEffectCatRandomBonks,
|
||||||
|
kEffectCatReverseControls,
|
||||||
|
kEffectCatBoots,
|
||||||
|
kEffectCatSlipperyFloor,
|
||||||
|
kEffectCatSpeed,
|
||||||
|
kEffectCatDamageTaken,
|
||||||
|
kEffectCatOhko,
|
||||||
|
kEffectCatInvincible,
|
||||||
|
kEffectCatSpawnEnemy,
|
||||||
|
kEffectCatSpawnActor
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<std::string, CCStringEnumValues> effectStringToEnum = {
|
||||||
|
|
||||||
|
// Spawn Enemies and Objects
|
||||||
|
{ "spawn_cucco_storm", kEffectSpawnCuccoStorm },
|
||||||
|
{ "spawn_lit_bomb", kEffectSpawnLitBomb },
|
||||||
|
{ "spawn_explosion", kEffectSpawnExplosion },
|
||||||
|
{ "spawn_arwing", kEffectSpawnArwing },
|
||||||
|
{ "spawn_darklink", kEffectSpawnDarklink },
|
||||||
|
{ "spawn_iron_knuckle", kEffectSpawnIronKnuckle },
|
||||||
|
{ "spawn_stalfos", kEffectSpawnStalfos },
|
||||||
|
{ "spawn_freezard", kEffectSpawnFreezard },
|
||||||
|
{ "spawn_like_like", kEffectSpawnLikeLike },
|
||||||
|
{ "spawn_gibdo", kEffectSpawnGibdo },
|
||||||
|
{ "spawn_keese", kEffectSpawnKeese },
|
||||||
|
{ "spawn_ice_keese", kEffectSpawnIceKeese },
|
||||||
|
{ "spawn_fire_keese", kEffectSpawnFireKeese },
|
||||||
|
{ "spawn_wolfos", kEffectSpawnWolfos },
|
||||||
|
{ "spawn_wallmaster", kEffectSpawnWallmaster },
|
||||||
|
|
||||||
|
// Link Modifiers
|
||||||
|
{ "take_half_damage", kEffectTakeHalfDamage },
|
||||||
|
{ "take_double_damage", kEffectTakeDoubleDamage },
|
||||||
|
{ "one_hit_ko", kEffectOneHitKo },
|
||||||
|
{ "invincibility", kEffectInvincibility },
|
||||||
|
{ "increase_speed", kEffectIncreaseSpeed },
|
||||||
|
{ "decrease_speed", kEffectDecreaseSpeed },
|
||||||
|
{ "low_gravity", kEffectLowGravity },
|
||||||
|
{ "high_gravity", kEffectHighGravity },
|
||||||
|
{ "force_iron_boots", kEffectForceIronBoots },
|
||||||
|
{ "force_hover_boots", kEffectForceHoverBoots },
|
||||||
|
{ "slippery_floor", kEffectSlipperyFloor },
|
||||||
|
{ "no_ledge_grabs", kEffectNoLedgeGrabs },
|
||||||
|
{ "random_wind", kEffectRandomWind },
|
||||||
|
{ "random_bonks", kEffectRandomBonks },
|
||||||
|
|
||||||
|
// Hurt or Heal Link
|
||||||
|
{ "empty_heart", kEffectEmptyHeart },
|
||||||
|
{ "fill_heart", kEffectFillHeart },
|
||||||
|
{ "knockback_link_weak", kEffectKnockbackLinkWeak },
|
||||||
|
{ "knockback_link_strong", kEffectKnockbackLinkStrong },
|
||||||
|
{ "knockback_link_mega", kEffectKnockbackLinkMega },
|
||||||
|
{ "burn_link", kEffectBurnLink },
|
||||||
|
{ "freeze_link", kEffectFreezeLink },
|
||||||
|
{ "electrocute_link", kEffectElectrocuteLink },
|
||||||
|
{ "kill_link", kEffectKillLink },
|
||||||
|
|
||||||
|
// Give Items and Consumables
|
||||||
|
{ "add_heart_container", kEffectAddHeartContainer },
|
||||||
|
{ "fill_magic", kEffectFillMagic },
|
||||||
|
{ "add_rupees", kEffectAddRupees },
|
||||||
|
{ "give_deku_shield", kEffectGiveDekuShield },
|
||||||
|
{ "give_hylian_shield", kEffectGiveHylianShield },
|
||||||
|
{ "refill_sticks", kEffectRefillSticks },
|
||||||
|
{ "refill_nuts", kEffectRefillNuts },
|
||||||
|
{ "refill_bombs", kEffectRefillBombs },
|
||||||
|
{ "refill_seeds", kEffectRefillSeeds },
|
||||||
|
{ "refill_arrows", kEffectRefillArrows },
|
||||||
|
{ "refill_bombchus", kEffectRefillBombchus },
|
||||||
|
|
||||||
|
// Take Items and Consumables
|
||||||
|
{ "remove_heart_container", kEffectRemoveHeartContainer },
|
||||||
|
{ "empty_magic", kEffectEmptyMagic },
|
||||||
|
{ "remove_rupees", kEffectRemoveRupees },
|
||||||
|
{ "take_deku_shield", kEffectTakeDekuShield },
|
||||||
|
{ "take_hylian_shield", kEffectTakeHylianShield },
|
||||||
|
{ "take_sticks", kEffectTakeSticks },
|
||||||
|
{ "take_nuts", kEffectTakeNuts },
|
||||||
|
{ "take_bombs", kEffectTakeBombs },
|
||||||
|
{ "take_seeds", kEffectTakeSeeds },
|
||||||
|
{ "take_arrows", kEffectTakeArrows },
|
||||||
|
{ "take_bombchus", kEffectTakeBombchus },
|
||||||
|
|
||||||
|
// Link Size Modifiers
|
||||||
|
{ "giant_link", kEffectGiantLink },
|
||||||
|
{ "minish_link", kEffectMinishLink },
|
||||||
|
{ "paper_link", kEffectPaperLink },
|
||||||
|
{ "squished_link", kEffectSquishedLink },
|
||||||
|
{ "invisible_link", kEffectInvisibleLink },
|
||||||
|
|
||||||
|
// Generic kEffects
|
||||||
|
{ "random_bomb_timer", kEffectRandomBombTimer },
|
||||||
|
{ "set_time_to_dawn", kEffectSetTimeToDawn },
|
||||||
|
{ "set_time_to_dusk", kEffectSetTimeToDusk },
|
||||||
|
|
||||||
|
// Visual kEffects
|
||||||
|
{ "no_ui", kEffectNoUi },
|
||||||
|
{ "rainstorm", kEffectRainstorm },
|
||||||
|
{ "debug_mode", kEffectDebugMode },
|
||||||
|
{ "random_cosmetics", kEffectRandomCosmetics },
|
||||||
|
|
||||||
|
// Controls
|
||||||
|
{ "no_z_button", kEffectNoZButton },
|
||||||
|
{ "reverse_controls", kEffectReverseControls },
|
||||||
|
{ "pacifist_mode", kEffectPacifistMode },
|
||||||
|
{ "press_random_buttons", kEffectPressRandomButtons },
|
||||||
|
{ "clear_cbuttons", kEffectClearCbuttons },
|
||||||
|
{ "clear_dpad", kEffectClearDpad },
|
||||||
|
|
||||||
|
// Teleport Player
|
||||||
|
{ "tp_links_house", kEffectTpLinksHouse },
|
||||||
|
{ "tp_minuet", kEffectTpMinuet },
|
||||||
|
{ "tp_bolero", kEffectTpBolero },
|
||||||
|
{ "tp_serenade", kEffectTpSerenade },
|
||||||
|
{ "tp_requiem", kEffectTpRequiem },
|
||||||
|
{ "tp_nocturne", kEffectTpNocturne },
|
||||||
|
{ "tp_prelude", kEffectTpPrelude },
|
||||||
|
|
||||||
|
// Tunic Color (Bidding War)
|
||||||
|
{ "tunic_red", kEffectTunicRed },
|
||||||
|
{ "tunic_green", kEffectTunicGreen },
|
||||||
|
{ "tunic_blue", kEffectTunicBlue },
|
||||||
|
{ "tunic_orange", kEffectTunicOrange },
|
||||||
|
{ "tunic_yellow", kEffectTunicYellow },
|
||||||
|
{ "tunic_purple", kEffectTunicPurple },
|
||||||
|
{ "tunic_pink", kEffectTunicPink },
|
||||||
|
{ "tunic_brown", kEffectTunicBrown },
|
||||||
|
{ "tunic_black", kEffectTunicBlack },
|
||||||
|
|
||||||
|
// Navi Color (Bidding War)
|
||||||
|
{ "navi_red", kEffectNaviRed },
|
||||||
|
{ "navi_green", kEffectNaviGreen },
|
||||||
|
{ "navi_blue", kEffectNaviBlue },
|
||||||
|
{ "navi_orange", kEffectNaviOrange },
|
||||||
|
{ "navi_yellow", kEffectNaviYellow },
|
||||||
|
{ "navi_purple", kEffectNaviPurple },
|
||||||
|
{ "navi_pink", kEffectNaviPink },
|
||||||
|
{ "navi_brown", kEffectNaviBrown },
|
||||||
|
{ "navi_black", kEffectNaviBlack },
|
||||||
|
|
||||||
|
// Link's Hair Color (Bidding War)
|
||||||
|
{ "hair_red", kEffectHairRed },
|
||||||
|
{ "hair_green", kEffectHairGreen },
|
||||||
|
{ "hair_blue", kEffectHairBlue },
|
||||||
|
{ "hair_orange", kEffectHairOrange },
|
||||||
|
{ "hair_yellow", kEffectHairYellow },
|
||||||
|
{ "hair_purple", kEffectHairPurple },
|
||||||
|
{ "hair_pink", kEffectHairPink },
|
||||||
|
{ "hair_brown", kEffectHairBrown },
|
||||||
|
{ "hair_black", kEffectHairBlack },
|
||||||
|
};
|
BIN
soh/soh/Enhancements/crowd-control/soh.ccpak
Normal file
BIN
soh/soh/Enhancements/crowd-control/soh.ccpak
Normal file
Binary file not shown.
@ -15,76 +15,193 @@ public class SoH : SimpleTCPPack
|
|||||||
|
|
||||||
public override Game Game { get; } = new Game(90, "Ship of Harkinian", "SoH", "PC", ConnectorType.SimpleTCPConnector);
|
public override Game Game { get; } = new Game(90, "Ship of Harkinian", "SoH", "PC", ConnectorType.SimpleTCPConnector);
|
||||||
|
|
||||||
private Dictionary<string, string> _enemyType = new Dictionary<string, string>()
|
public override List<Effect> Effects => new List<Effect>
|
||||||
{
|
{
|
||||||
{"wallmaster", ("Wallmaster")},
|
|
||||||
{"arwing", ("Arwing")},
|
|
||||||
{"darklink", ("Dark Link")},
|
|
||||||
{"stalfos", ("Stalfos")},
|
|
||||||
{"wolfos", ("Wolfos")},
|
|
||||||
{"freezard", ("Freezard")},
|
|
||||||
{"keese", ("Keese")},
|
|
||||||
{"icekeese", ("Ice Keese")},
|
|
||||||
{"firekeese", ("Fire Keese")},
|
|
||||||
{"tektite", ("Tektite")},
|
|
||||||
{"likelike", ("Like-Like")}
|
|
||||||
};
|
|
||||||
|
|
||||||
public override List<Effect> Effects
|
// Spawn Enemies and Objects
|
||||||
{
|
new Effect("Spawn Enemies/Objects", "spawn_stuff", ItemKind.Folder),
|
||||||
get
|
|
||||||
{
|
|
||||||
List<Effect> effects = new List<Effect>
|
|
||||||
{
|
|
||||||
new Effect("Add Heart Container", "add_heart_container"),
|
|
||||||
new Effect("Remove Heart Container", "remove_heart_container"),
|
|
||||||
new Effect("Damage Multiplier", "damage_multiplier", new[] { "damdefmulti" }) { Duration = 30 },
|
|
||||||
new Effect("Defense Multiplier", "defense_multiplier", new[] { "damdefmulti" }) { Duration = 30 },
|
|
||||||
new Effect("Freeze Link", "freeze"),
|
|
||||||
new Effect("Giant Lonk", "giant_link") { Duration = 30 },
|
|
||||||
new Effect("Empty Heart", "damage", new[] { "health20" }),
|
|
||||||
new Effect("Fill Heart", "heal", new[] { "health20" }),
|
|
||||||
new Effect("Kill Player", "kill"),
|
|
||||||
new Effect("High Gravity", "high_gravity") { Duration = 30 },
|
|
||||||
new Effect("Hover Boots", "hover_boots") { Duration = 30 },
|
|
||||||
new Effect("Invisible Link", "invisible") { Duration = 30 },
|
|
||||||
new Effect("No UI", "no_ui") { Duration = 60 },
|
|
||||||
new Effect("Low Gravity", "low_gravity") { Duration = 30 },
|
|
||||||
new Effect("Fill Magic", "fill_magic"),
|
|
||||||
new Effect("Empty Magic", "empty_magic"),
|
|
||||||
new Effect("Minish Link", "minish_link") { Duration = 30 },
|
|
||||||
new Effect("No Z Button", "no_z") { Duration = 30 },
|
|
||||||
new Effect("One-Hit KO", "ohko") { Duration = 30 },
|
|
||||||
new Effect("Pacifist", "pacifist") { Duration = 15 },
|
|
||||||
new Effect("Paper Link", "paper_link") { Duration = 30 },
|
|
||||||
new Effect("Rainstorm", "rainstorm") { Duration = 30 },
|
|
||||||
new Effect("Reverse Controls", "reverse") { Duration = 60 },
|
|
||||||
new Effect("Give Rupees", "add_rupees", new[] { "rupees999" }),
|
|
||||||
new Effect("Take Rupees", "remove_rupees", new[] { "rupees999" }),
|
|
||||||
new Effect("Increase Speed", "increase_speed") { Duration = 30 },
|
|
||||||
new Effect("Decrease Speed", "decrease_speed") { Duration = 30 },
|
|
||||||
new Effect("Cucco Swarm", "cucco_storm"),
|
|
||||||
new Effect("Knockback Link", "knockback", new[] { "knockbackstrength" }),
|
|
||||||
new Effect("Burn Link", "burn"),
|
|
||||||
new Effect("Electrocute Link", "electrocute"),
|
|
||||||
new Effect("Iron Boots", "iron_boots") { Duration = 30 },
|
|
||||||
new Effect("Give Deku Shield", "give_dekushield"),
|
|
||||||
new Effect("Spawn Enemy", "spawn_enemy", ItemKind.Folder),
|
|
||||||
};
|
|
||||||
|
|
||||||
effects.AddRange(_enemyType.Select(t => new Effect($"Spawn {t.Value}", $"spawn_{t.Key}", "spawn_enemy")));
|
|
||||||
|
|
||||||
return effects;
|
new Effect ("Cucco Storm", "spawn_cucco_storm", "spawn_stuff"),
|
||||||
}
|
new Effect ("Lit Bomb", "spawn_lit_bomb", "spawn_stuff"),
|
||||||
}
|
new Effect ("Explosion", "spawn_explosion", "spawn_stuff"),
|
||||||
|
new Effect ("Arwing", "spawn_arwing", "spawn_stuff"),
|
||||||
|
new Effect ("Dark Link", "spawn_darklink", "spawn_stuff"),
|
||||||
|
new Effect ("Iron Knuckle", "spawn_iron_knuckle", "spawn_stuff"),
|
||||||
|
new Effect ("Stalfos", "spawn_stalfos", "spawn_stuff"),
|
||||||
|
new Effect ("Freezard", "spawn_freezard", "spawn_stuff"),
|
||||||
|
new Effect ("Like-Like", "spawn_like_like", "spawn_stuff"),
|
||||||
|
new Effect ("Gibdo", "spawn_gibdo", "spawn_stuff"),
|
||||||
|
new Effect ("Flock of Keese (5x)", "spawn_keese", "spawn_stuff"),
|
||||||
|
new Effect ("Ice Keese", "spawn_ice_keese", "spawn_stuff"),
|
||||||
|
new Effect ("Fire Keese", "spawn_fire_keese", "spawn_stuff"),
|
||||||
|
new Effect ("Wolfos", "spawn_wolfos", "spawn_stuff"),
|
||||||
|
new Effect ("Wallmaster", "spawn_wallmaster", "spawn_stuff"),
|
||||||
|
|
||||||
|
|
||||||
|
// Link Modifiers
|
||||||
|
new Effect("Link Modifiers", "link_modifiers", ItemKind.Folder),
|
||||||
|
|
||||||
|
new Effect("Take Half Damage", "take_half_damage", "link_modifiers") { Duration = 30 },
|
||||||
|
new Effect("Take Double Damage", "take_double_damage", "link_modifiers") { Duration = 30 },
|
||||||
|
new Effect("One-Hit KO", "one_hit_ko", "link_modifiers") { Duration = 30 },
|
||||||
|
new Effect("Invincibility", "invincibility", "link_modifiers") { Duration = 15 },
|
||||||
|
new Effect("Increase Speed", "increase_speed", "link_modifiers") { Duration = 30 },
|
||||||
|
new Effect("Decrease Speed", "decrease_speed", "link_modifiers") { Duration = 30 },
|
||||||
|
new Effect("Low Gravity", "low_gravity", "link_modifiers") { Duration = 30 },
|
||||||
|
new Effect("High Gravity", "high_gravity", "link_modifiers") { Duration = 30 },
|
||||||
|
new Effect("Force Iron Boots", "force_iron_boots", "link_modifiers") { Duration = 30 },
|
||||||
|
new Effect("Force Hover Boots", "force_hover_boots", "link_modifiers") { Duration = 30 },
|
||||||
|
new Effect("Slippery Floor", "slippery_floor", "link_modifiers") { Duration = 30 },
|
||||||
|
new Effect("Disable Ledge Grabs", "no_ledge_grabs", "link_modifiers") { Duration = 30 },
|
||||||
|
new Effect("Random Wind", "random_wind", "link_modifiers") { Duration = 30 },
|
||||||
|
new Effect("Random Bonks When Rolling", "random_bonks", "link_modifiers") { Duration = 60 },
|
||||||
|
|
||||||
|
|
||||||
|
// Hurt or Heal Link
|
||||||
|
new Effect("Hurt/Heal Link", "hurtheal_link", ItemKind.Folder),
|
||||||
|
|
||||||
|
new Effect("Empty Heart", "empty_heart", new[] { "health20" }, "hurtheal_link"),
|
||||||
|
new Effect("Fill Heart", "fill_heart", new[] { "health20" }, "hurtheal_link"),
|
||||||
|
new Effect("Knockback Link (Weak)", "knockback_link_weak", "hurtheal_link"),
|
||||||
|
new Effect("Knockback Link (Strong)", "knockback_link_strong", "hurtheal_link"),
|
||||||
|
new Effect("Knockback Link (Mega)", "knockback_link_mega", "hurtheal_link"),
|
||||||
|
new Effect("Burn Link", "burn_link", "hurtheal_link"),
|
||||||
|
new Effect("Freeze Link", "freeze_link", "hurtheal_link"),
|
||||||
|
new Effect("Electrocute Link", "electrocute_link", "hurtheal_link"),
|
||||||
|
new Effect("Kill Link", "kill_link", "hurtheal_link"),
|
||||||
|
|
||||||
|
|
||||||
|
// Give Items and Consumables
|
||||||
|
new Effect("Give Items/Consumables", "give_item", ItemKind.Folder),
|
||||||
|
|
||||||
|
new Effect("Add Heart Container", "add_heart_container", "give_item"),
|
||||||
|
new Effect("Fill Magic", "fill_magic", "give_item"),
|
||||||
|
new Effect("Give Rupees", "add_rupees", new[] { "rupees999" }, "give_item"),
|
||||||
|
new Effect("Give Deku Shield", "give_deku_shield", "give_item"),
|
||||||
|
new Effect("Give Hylian Shield", "give_hylian_shield", "give_item"),
|
||||||
|
new Effect("Refill Deku Sticks", "refill_sticks", new[] { "ammo30" }, "give_item"),
|
||||||
|
new Effect("Refill Deku Nuts", "refill_nuts", new[] { "ammo30" }, "give_item"),
|
||||||
|
new Effect("Refill Bombs", "refill_bombs", new[] { "ammo30" }, "give_item"),
|
||||||
|
new Effect("Refill Slingshot Seeds", "refill_seeds", new[] { "ammo30" }, "give_item"),
|
||||||
|
new Effect("Refill Arrows", "refill_arrows", new[] { "ammo30" }, "give_item"),
|
||||||
|
new Effect("Refill Bombchus", "refill_bombchus", new[] { "ammo30" }, "give_item"),
|
||||||
|
|
||||||
|
|
||||||
|
// Take Items and Consumables
|
||||||
|
new Effect("Take Items/Consumables", "take_item", ItemKind.Folder),
|
||||||
|
|
||||||
|
new Effect("Remove Heart Container", "remove_heart_container", "take_item"),
|
||||||
|
new Effect("Empty Magic", "empty_magic", "take_item"),
|
||||||
|
new Effect("Take Rupees", "remove_rupees", new[] { "rupees999" }, "take_item"),
|
||||||
|
new Effect("Take Deku Shield", "take_deku_shield", "take_item"),
|
||||||
|
new Effect("Take Hylian Shield", "take_hylian_shield", "take_item"),
|
||||||
|
new Effect("Take Deku Sticks", "take_sticks", new[] { "ammo30" }, "take_item"),
|
||||||
|
new Effect("Take Deku Nuts", "take_nuts", new[] { "ammo30" }, "take_item"),
|
||||||
|
new Effect("Take Bombs", "take_bombs", new[] { "ammo30" }, "take_item"),
|
||||||
|
new Effect("Take Slingshot Seeds", "take_seeds", new[] { "ammo30" }, "take_item"),
|
||||||
|
new Effect("Take Arrows", "take_arrows", new[] { "ammo30" }, "take_item"),
|
||||||
|
new Effect("Take Bombchus", "take_bombchus", new[] { "ammo30" }, "take_item"),
|
||||||
|
|
||||||
|
|
||||||
|
// Link Size Modifiers
|
||||||
|
new Effect("Change Link's Size", "link_size", ItemKind.Folder),
|
||||||
|
|
||||||
|
new Effect("Giant Lonk", "giant_link", "link_size") { Duration = 30 },
|
||||||
|
new Effect("Minish Link", "minish_link", "link_size") { Duration = 30 },
|
||||||
|
new Effect("Paper Link", "paper_link", "link_size") { Duration = 30 },
|
||||||
|
new Effect("Squished Link", "squished_link", "link_size") { Duration = 30 },
|
||||||
|
new Effect("Invisible Link", "invisible_link", "link_size") { Duration = 30 },
|
||||||
|
|
||||||
|
|
||||||
|
// Generic Effects
|
||||||
|
new Effect("Generic Effects", "generic_effects", ItemKind.Folder),
|
||||||
|
|
||||||
|
new Effect("Random Bomb Fuse Timer", "random_bomb_timer", "generic_effects") { Duration = 60 },
|
||||||
|
new Effect("Set Time to Dawn", "set_time_to_dawn", "generic_effects"),
|
||||||
|
new Effect("Set Time to Dusk", "set_time_to_dusk", "generic_effects"),
|
||||||
|
|
||||||
|
|
||||||
|
// Visual Effects
|
||||||
|
new Effect("Visual Effects", "visual_effects", ItemKind.Folder),
|
||||||
|
|
||||||
|
new Effect("No UI", "no_ui", "visual_effects") { Duration = 60 },
|
||||||
|
new Effect("Rainstorm", "rainstorm", "visual_effects") { Duration = 30 },
|
||||||
|
new Effect("Debug Mode", "debug_mode", "visual_effects") { Duration = 30 },
|
||||||
|
new Effect("Randomize Cosmetics", "random_cosmetics", "visual_effects") { Duration = 30 },
|
||||||
|
|
||||||
|
|
||||||
|
// Controls
|
||||||
|
new Effect("Controls", "controls", ItemKind.Folder),
|
||||||
|
|
||||||
|
new Effect("No Z Button", "no_z_button", "controls") { Duration = 30 },
|
||||||
|
new Effect("Reverse Controls", "reverse_controls", "controls") { Duration = 60 },
|
||||||
|
new Effect("Pacifist Mode", "pacifist_mode", "controls") { Duration = 15 },
|
||||||
|
new Effect("Press Random Buttons", "press_random_buttons", "controls") { Duration = 30 },
|
||||||
|
new Effect("Clear C-Buttons", "clear_cbuttons", "controls"),
|
||||||
|
new Effect("Clear D-pad", "clear_dpad", "controls"),
|
||||||
|
|
||||||
|
|
||||||
|
// Teleport Player
|
||||||
|
new Effect("Teleport Player", "teleport", ItemKind.Folder),
|
||||||
|
|
||||||
|
new Effect("Link's House", "tp_links_house", "teleport"),
|
||||||
|
new Effect("Minuet Destination", "tp_minuet", "teleport"),
|
||||||
|
new Effect("Bolero Destination", "tp_bolero", "teleport"),
|
||||||
|
new Effect("Serenade Destination", "tp_serenade", "teleport"),
|
||||||
|
new Effect("Requiem Destination", "tp_requiem", "teleport"),
|
||||||
|
new Effect("Nocturne Destination", "tp_nocturne", "teleport"),
|
||||||
|
new Effect("Prelude Destination", "tp_prelude", "teleport"),
|
||||||
|
|
||||||
|
|
||||||
|
// Tunic Color (Bidding War)
|
||||||
|
new Effect("Tunic Color", "color_tunic", ItemKind.BidWar),
|
||||||
|
|
||||||
|
new Effect("Red", "tunic_red", ItemKind.BidWarValue, "color_tunic"),
|
||||||
|
new Effect("Green", "tunic_green", ItemKind.BidWarValue, "color_tunic"),
|
||||||
|
new Effect("Blue", "tunic_blue", ItemKind.BidWarValue, "color_tunic"),
|
||||||
|
new Effect("Orange", "tunic_orange", ItemKind.BidWarValue, "color_tunic"),
|
||||||
|
new Effect("Yellow", "tunic_yellow", ItemKind.BidWarValue, "color_tunic"),
|
||||||
|
new Effect("Purple", "tunic_purple", ItemKind.BidWarValue, "color_tunic"),
|
||||||
|
new Effect("Pink", "tunic_pink", ItemKind.BidWarValue, "color_tunic"),
|
||||||
|
new Effect("Brown", "tunic_brown", ItemKind.BidWarValue, "color_tunic"),
|
||||||
|
new Effect("Black", "tunic_black", ItemKind.BidWarValue, "color_tunic"),
|
||||||
|
|
||||||
|
|
||||||
|
// Navi Color (Bidding War)
|
||||||
|
new Effect("Navi Color", "color_navi", ItemKind.BidWar),
|
||||||
|
|
||||||
|
new Effect("Red", "navi_red", ItemKind.BidWarValue, "color_navi"),
|
||||||
|
new Effect("Green", "navi_green", ItemKind.BidWarValue, "color_navi"),
|
||||||
|
new Effect("Blue", "navi_blue", ItemKind.BidWarValue, "color_navi"),
|
||||||
|
new Effect("Orange", "navi_orange", ItemKind.BidWarValue, "color_navi"),
|
||||||
|
new Effect("Yellow", "navi_yellow", ItemKind.BidWarValue, "color_navi"),
|
||||||
|
new Effect("Purple", "navi_purple", ItemKind.BidWarValue, "color_navi"),
|
||||||
|
new Effect("Pink", "navi_pink", ItemKind.BidWarValue, "color_navi"),
|
||||||
|
new Effect("Brown", "navi_brown", ItemKind.BidWarValue, "color_navi"),
|
||||||
|
new Effect("Black", "navi_black", ItemKind.BidWarValue, "color_navi"),
|
||||||
|
|
||||||
|
|
||||||
|
// Link's Hair Color (Bidding War)
|
||||||
|
new Effect("Link's Hair Color", "color_hair", ItemKind.BidWar),
|
||||||
|
|
||||||
|
new Effect("Red", "hair_red", ItemKind.BidWarValue, "color_hair"),
|
||||||
|
new Effect("Green", "hair_green", ItemKind.BidWarValue, "color_hair"),
|
||||||
|
new Effect("Blue", "hair_blue", ItemKind.BidWarValue, "color_hair"),
|
||||||
|
new Effect("Orange", "hair_orange", ItemKind.BidWarValue, "color_hair"),
|
||||||
|
new Effect("Yellow", "hair_yellow", ItemKind.BidWarValue, "color_hair"),
|
||||||
|
new Effect("Purple", "hair_purple", ItemKind.BidWarValue, "color_hair"),
|
||||||
|
new Effect("Pink", "hair_pink", ItemKind.BidWarValue, "color_hair"),
|
||||||
|
new Effect("Brown", "hair_brown", ItemKind.BidWarValue, "color_hair"),
|
||||||
|
new Effect("Black", "hair_black", ItemKind.BidWarValue, "color_hair"),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
//Slider ranges need to be defined
|
//Slider ranges need to be defined
|
||||||
public override List<ItemType> ItemTypes => new List<ItemType>
|
public override List<ItemType> ItemTypes => new List<ItemType>
|
||||||
{
|
{
|
||||||
new ItemType("Rupees", "rupees999", ItemType.Subtype.Slider, "{\"min\":1,\"max\":999}"),
|
new ItemType("Rupees", "rupees999", ItemType.Subtype.Slider, "{\"min\":1,\"max\":999}"),
|
||||||
new ItemType("Health", "health20", ItemType.Subtype.Slider, "{\"min\":1,\"max\":20}"),
|
new ItemType("Health", "health20", ItemType.Subtype.Slider, "{\"min\":1,\"max\":20}"),
|
||||||
new ItemType("Damage/Defense Multiplier", "damdefmulti", ItemType.Subtype.Slider, "{\"min\":1,\"max\":10}"),
|
new ItemType("Ammo", "ammo30", ItemType.Subtype.Slider, "{\"min\":1,\"max\":30}"),
|
||||||
new ItemType("Knockback Strength", "knockbackstrength", ItemType.Subtype.Slider, "{\"min\":1,\"max\":3}")
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -82,21 +82,9 @@ static bool ActorSpawnHandler(std::shared_ptr<Ship::Console> Console, const std:
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GiveDekuShieldHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>&) {
|
|
||||||
GameInteractionEffectBase* effect = new GameInteractionEffect::GiveDekuShield();
|
|
||||||
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
|
||||||
if (result == GameInteractionEffectQueryResult::Possible) {
|
|
||||||
SohImGui::GetConsole()->SendInfoMessage("[SOH] Gave Deku Shield.");
|
|
||||||
return CMD_SUCCESS;
|
|
||||||
} else {
|
|
||||||
SohImGui::GetConsole()->SendInfoMessage("[SOH] Command failed: Could not give Deku Shield.");
|
|
||||||
return CMD_FAILED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool KillPlayerHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>&) {
|
static bool KillPlayerHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>&) {
|
||||||
GameInteractionEffectBase* effect = new GameInteractionEffect::SetPlayerHealth();
|
GameInteractionEffectBase* effect = new GameInteractionEffect::SetPlayerHealth();
|
||||||
effect->parameter = 0;
|
effect->parameters[0] = 0;
|
||||||
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
||||||
if (result == GameInteractionEffectQueryResult::Possible) {
|
if (result == GameInteractionEffectQueryResult::Possible) {
|
||||||
SohImGui::GetConsole()->SendInfoMessage("[SOH] You've met with a terrible fate, haven't you?");
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] You've met with a terrible fate, haven't you?");
|
||||||
@ -127,7 +115,7 @@ static bool SetPlayerHealthHandler(std::shared_ptr<Ship::Console> Console, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
GameInteractionEffectBase* effect = new GameInteractionEffect::SetPlayerHealth();
|
GameInteractionEffectBase* effect = new GameInteractionEffect::SetPlayerHealth();
|
||||||
effect->parameter = health;
|
effect->parameters[0] = health;
|
||||||
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
||||||
if (result == GameInteractionEffectQueryResult::Possible) {
|
if (result == GameInteractionEffectQueryResult::Possible) {
|
||||||
SohImGui::GetConsole()->SendInfoMessage("[SOH] Player health updated to %d", health);
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Player health updated to %d", health);
|
||||||
@ -210,48 +198,90 @@ static bool ResetHandler(std::shared_ptr<Ship::Console> Console, std::vector<std
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
const static std::map<std::string, uint16_t> ammoItems{
|
const static std::map<std::string, uint16_t> ammoItems{
|
||||||
{ "sticks", ITEM_STICK }, { "deku_sticks", ITEM_STICK },
|
{ "sticks", ITEM_STICK }, { "nuts", ITEM_NUT },
|
||||||
{ "nuts", ITEM_NUT }, { "deku_nuts", ITEM_NUT },
|
{ "bombs", ITEM_BOMB }, { "seeds", ITEM_SLINGSHOT },
|
||||||
{ "bombs", ITEM_BOMB }, { "arrows", ITEM_BOW },
|
{ "arrows", ITEM_BOW }, { "bombchus", ITEM_BOMBCHU },
|
||||||
{ "bombchus", ITEM_BOMBCHU }, { "chus", ITEM_BOMBCHU },
|
{ "beans", ITEM_BEAN }
|
||||||
{ "beans", ITEM_BEAN },
|
|
||||||
{ "seeds", ITEM_SLINGSHOT }, { "deku_seeds", ITEM_SLINGSHOT },
|
|
||||||
{ "magic_beans", ITEM_BEAN },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool AmmoHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args) {
|
static bool AddAmmoHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args) {
|
||||||
if (args.size() != 3) {
|
if (args.size() != 3) {
|
||||||
SohImGui::GetConsole()->SendErrorMessage("[SOH] Unexpected arguments passed");
|
SohImGui::GetConsole()->SendErrorMessage("[SOH] Unexpected arguments passed");
|
||||||
return CMD_FAILED;
|
return CMD_FAILED;
|
||||||
}
|
}
|
||||||
|
int amount;
|
||||||
int count;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
count = std::stoi(args[2]);
|
amount = std::stoi(args[2]);
|
||||||
} catch (std::invalid_argument const& ex) {
|
} catch (std::invalid_argument const& ex) {
|
||||||
SohImGui::GetConsole()->SendErrorMessage("Ammo count must be an integer");
|
SohImGui::GetConsole()->SendErrorMessage("Ammo count must be an integer");
|
||||||
return CMD_FAILED;
|
return CMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count < 0) {
|
if (amount < 0) {
|
||||||
SohImGui::GetConsole()->SendErrorMessage("Ammo count must be positive");
|
SohImGui::GetConsole()->SendErrorMessage("Ammo count must be positive");
|
||||||
return CMD_FAILED;
|
return CMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& it = ammoItems.find(args[1]);
|
const auto& it = ammoItems.find(args[1]);
|
||||||
|
|
||||||
if (it == ammoItems.end()) {
|
if (it == ammoItems.end()) {
|
||||||
SohImGui::GetConsole()->SendErrorMessage("Invalid item passed");
|
SohImGui::GetConsole()->SendErrorMessage("Invalid ammo type. Options are 'sticks', 'nuts', 'bombs', 'seeds', 'arrows', 'bombchus' and 'beans'");
|
||||||
return CMD_FAILED;
|
return CMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// I dont think you can do OOB with just this
|
GameInteractionEffectBase* effect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
AMMO(it->second) = count;
|
effect->parameters[0] = amount;
|
||||||
|
effect->parameters[1] = it->second;
|
||||||
|
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
||||||
|
|
||||||
//To use a change by uncomment this
|
if (result == GameInteractionEffectQueryResult::Possible) {
|
||||||
//Inventory_ChangeAmmo(it->second, count);
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Added ammo.");
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
} else {
|
||||||
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Command failed: Could not add ammo.");
|
||||||
|
return CMD_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool TakeAmmoHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args) {
|
||||||
|
if (args.size() != 3) {
|
||||||
|
SohImGui::GetConsole()->SendErrorMessage("[SOH] Unexpected arguments passed");
|
||||||
|
return CMD_FAILED;
|
||||||
|
}
|
||||||
|
int amount;
|
||||||
|
|
||||||
|
try {
|
||||||
|
amount = std::stoi(args[2]);
|
||||||
|
} catch (std::invalid_argument const& ex) {
|
||||||
|
SohImGui::GetConsole()->SendErrorMessage("Ammo count must be an integer");
|
||||||
|
return CMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amount < 0) {
|
||||||
|
SohImGui::GetConsole()->SendErrorMessage("Ammo count must be positive");
|
||||||
|
return CMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& it = ammoItems.find(args[1]);
|
||||||
|
if (it == ammoItems.end()) {
|
||||||
|
SohImGui::GetConsole()->SendErrorMessage(
|
||||||
|
"Invalid ammo type. Options are 'sticks', 'nuts', 'bombs', 'seeds', 'arrows', 'bombchus' and 'beans'");
|
||||||
|
return CMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameInteractionEffectBase* effect = new GameInteractionEffect::AddOrTakeAmmo();
|
||||||
|
effect->parameters[0] = -amount;
|
||||||
|
effect->parameters[1] = it->second;
|
||||||
|
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
||||||
|
|
||||||
|
if (result == GameInteractionEffectQueryResult::Possible) {
|
||||||
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Took ammo.");
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
} else {
|
||||||
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Command failed: Could not take ammo.");
|
||||||
|
return CMD_FAILED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const static std::map<std::string, uint16_t> bottleItems{
|
const static std::map<std::string, uint16_t> bottleItems{
|
||||||
@ -561,7 +591,7 @@ static bool GiantLinkHandler(std::shared_ptr<Ship::Console> Console, const std::
|
|||||||
}
|
}
|
||||||
|
|
||||||
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyLinkSize();
|
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyLinkSize();
|
||||||
effect->parameter = GI_LINK_SIZE_GIANT;
|
effect->parameters[0] = GI_LINK_SIZE_GIANT;
|
||||||
GameInteractionEffectQueryResult result =
|
GameInteractionEffectQueryResult result =
|
||||||
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
|
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
|
||||||
if (result == GameInteractionEffectQueryResult::Possible) {
|
if (result == GameInteractionEffectQueryResult::Possible) {
|
||||||
@ -589,7 +619,7 @@ static bool MinishLinkHandler(std::shared_ptr<Ship::Console> Console, const std:
|
|||||||
}
|
}
|
||||||
|
|
||||||
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyLinkSize();
|
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyLinkSize();
|
||||||
effect->parameter = GI_LINK_SIZE_MINISH;
|
effect->parameters[0] = GI_LINK_SIZE_MINISH;
|
||||||
GameInteractionEffectQueryResult result =
|
GameInteractionEffectQueryResult result =
|
||||||
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
|
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
|
||||||
if (result == GameInteractionEffectQueryResult::Possible) {
|
if (result == GameInteractionEffectQueryResult::Possible) {
|
||||||
@ -622,7 +652,7 @@ static bool AddHeartContainerHandler(std::shared_ptr<Ship::Console> Console, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyHeartContainers();
|
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyHeartContainers();
|
||||||
effect->parameter = hearts;
|
effect->parameters[0] = hearts;
|
||||||
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
||||||
if (result == GameInteractionEffectQueryResult::Possible) {
|
if (result == GameInteractionEffectQueryResult::Possible) {
|
||||||
SohImGui::GetConsole()->SendInfoMessage("[SOH] Added %d heart containers", hearts);
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Added %d heart containers", hearts);
|
||||||
@ -653,7 +683,7 @@ static bool RemoveHeartContainerHandler(std::shared_ptr<Ship::Console> Console,
|
|||||||
}
|
}
|
||||||
|
|
||||||
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyHeartContainers();
|
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyHeartContainers();
|
||||||
effect->parameter = -hearts;
|
effect->parameters[0] = -hearts;
|
||||||
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
||||||
if (result == GameInteractionEffectQueryResult::Possible) {
|
if (result == GameInteractionEffectQueryResult::Possible) {
|
||||||
SohImGui::GetConsole()->SendInfoMessage("[SOH] Removed %d heart containers", hearts);
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Removed %d heart containers", hearts);
|
||||||
@ -673,7 +703,7 @@ static bool GravityHandler(std::shared_ptr<Ship::Console> Console, const std::ve
|
|||||||
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyGravity();
|
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyGravity();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
effect->parameter = Ship::Math::clamp(std::stoi(args[1], nullptr, 10), GI_GRAVITY_LEVEL_LIGHT, GI_GRAVITY_LEVEL_HEAVY);
|
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) {
|
} catch (std::invalid_argument const& ex) {
|
||||||
SohImGui::GetConsole()->SendErrorMessage("[SOH] Gravity value must be a number.");
|
SohImGui::GetConsole()->SendErrorMessage("[SOH] Gravity value must be a number.");
|
||||||
return CMD_FAILED;
|
return CMD_FAILED;
|
||||||
@ -738,7 +768,7 @@ static bool DefenseModifierHandler(std::shared_ptr<Ship::Console> Console, const
|
|||||||
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyDefenseModifier();
|
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyDefenseModifier();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
effect->parameter = std::stoi(args[1], nullptr, 10);
|
effect->parameters[0] = std::stoi(args[1], nullptr, 10);
|
||||||
} catch (std::invalid_argument const& ex) {
|
} catch (std::invalid_argument const& ex) {
|
||||||
SohImGui::GetConsole()->SendErrorMessage("[SOH] Defense modifier value must be a number.");
|
SohImGui::GetConsole()->SendErrorMessage("[SOH] Defense modifier value must be a number.");
|
||||||
return CMD_FAILED;
|
return CMD_FAILED;
|
||||||
@ -746,7 +776,7 @@ static bool DefenseModifierHandler(std::shared_ptr<Ship::Console> Console, const
|
|||||||
|
|
||||||
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
||||||
if (result == GameInteractionEffectQueryResult::Possible) {
|
if (result == GameInteractionEffectQueryResult::Possible) {
|
||||||
SohImGui::GetConsole()->SendInfoMessage("[SOH] Defense modifier set to %d", effect->parameter);
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Defense modifier set to %d", effect->parameters[0]);
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
SohImGui::GetConsole()->SendInfoMessage("[SOH] Command failed: Could not set defense modifier.");
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Command failed: Could not set defense modifier.");
|
||||||
@ -768,7 +798,7 @@ static bool DamageHandler(std::shared_ptr<Ship::Console> Console, const std::vec
|
|||||||
return CMD_FAILED;
|
return CMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
effect->parameter = -value;
|
effect->parameters[0] = -value;
|
||||||
} catch (std::invalid_argument const& ex) {
|
} catch (std::invalid_argument const& ex) {
|
||||||
SohImGui::GetConsole()->SendErrorMessage("[SOH] Damage value must be a number.");
|
SohImGui::GetConsole()->SendErrorMessage("[SOH] Damage value must be a number.");
|
||||||
return CMD_FAILED;
|
return CMD_FAILED;
|
||||||
@ -798,7 +828,7 @@ static bool HealHandler(std::shared_ptr<Ship::Console> Console, const std::vecto
|
|||||||
return CMD_FAILED;
|
return CMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
effect->parameter = value;
|
effect->parameters[0] = value;
|
||||||
} catch (std::invalid_argument const& ex) {
|
} catch (std::invalid_argument const& ex) {
|
||||||
SohImGui::GetConsole()->SendErrorMessage("[SOH] Damage value must be a number.");
|
SohImGui::GetConsole()->SendErrorMessage("[SOH] Damage value must be a number.");
|
||||||
return CMD_FAILED;
|
return CMD_FAILED;
|
||||||
@ -939,7 +969,7 @@ static bool PaperLinkHandler(std::shared_ptr<Ship::Console> Console, const std::
|
|||||||
}
|
}
|
||||||
|
|
||||||
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyLinkSize();
|
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyLinkSize();
|
||||||
effect->parameter = GI_LINK_SIZE_PAPER;
|
effect->parameters[0] = GI_LINK_SIZE_PAPER;
|
||||||
GameInteractionEffectQueryResult result =
|
GameInteractionEffectQueryResult result =
|
||||||
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
|
state ? GameInteractor::ApplyEffect(effect) : GameInteractor::RemoveEffect(effect);
|
||||||
|
|
||||||
@ -1018,7 +1048,7 @@ static bool UpdateRupeesHandler(std::shared_ptr<Ship::Console> Console, const st
|
|||||||
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyRupees();
|
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyRupees();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
effect->parameter = std::stoi(args[1], nullptr, 10);
|
effect->parameters[0] = std::stoi(args[1], nullptr, 10);
|
||||||
} catch (std::invalid_argument const& ex) {
|
} catch (std::invalid_argument const& ex) {
|
||||||
SohImGui::GetConsole()->SendErrorMessage("[SOH] Rupee value must be a number.");
|
SohImGui::GetConsole()->SendErrorMessage("[SOH] Rupee value must be a number.");
|
||||||
return CMD_FAILED;
|
return CMD_FAILED;
|
||||||
@ -1042,7 +1072,7 @@ static bool SpeedModifierHandler(std::shared_ptr<Ship::Console> Console, const s
|
|||||||
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyRunSpeedModifier();
|
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyRunSpeedModifier();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
effect->parameter = std::stoi(args[1], nullptr, 10);
|
effect->parameters[0] = std::stoi(args[1], nullptr, 10);
|
||||||
} catch (std::invalid_argument const& ex) {
|
} catch (std::invalid_argument const& ex) {
|
||||||
SohImGui::GetConsole()->SendErrorMessage("[SOH] Speed modifier value must be a number.");
|
SohImGui::GetConsole()->SendErrorMessage("[SOH] Speed modifier value must be a number.");
|
||||||
return CMD_FAILED;
|
return CMD_FAILED;
|
||||||
@ -1077,11 +1107,11 @@ static bool BootsHandler(std::shared_ptr<Ship::Console> Console, const std::vect
|
|||||||
}
|
}
|
||||||
|
|
||||||
GameInteractionEffectBase* effect = new GameInteractionEffect::ForceEquipBoots();
|
GameInteractionEffectBase* effect = new GameInteractionEffect::ForceEquipBoots();
|
||||||
effect->parameter = it->second;
|
effect->parameters[0] = it->second;
|
||||||
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
||||||
|
|
||||||
if (result == GameInteractionEffectQueryResult::Possible) {
|
if (result == GameInteractionEffectQueryResult::Possible) {
|
||||||
SohImGui::GetConsole()->SendInfoMessage("[SOH] Boots updated");
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Boots updated.");
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
SohImGui::GetConsole()->SendInfoMessage("[SOH] Command failed: Could not update boots.");
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Command failed: Could not update boots.");
|
||||||
@ -1089,6 +1119,62 @@ static bool BootsHandler(std::shared_ptr<Ship::Console> Console, const std::vect
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const static std::map<std::string, uint16_t> shields {
|
||||||
|
{ "deku", ITEM_SHIELD_DEKU },
|
||||||
|
{ "hylian", ITEM_SHIELD_HYLIAN },
|
||||||
|
{ "mirror", ITEM_SHIELD_MIRROR },
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool GiveShieldHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args) {
|
||||||
|
if (args.size() != 2) {
|
||||||
|
SohImGui::GetConsole()->SendErrorMessage("[SOH] Unexpected arguments passed");
|
||||||
|
return CMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& it = shields.find(args[1]);
|
||||||
|
if (it == shields.end()) {
|
||||||
|
SohImGui::GetConsole()->SendErrorMessage("Invalid shield type. Options are 'deku', 'hylian' and 'mirror'");
|
||||||
|
return CMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameInteractionEffectBase* effect = new GameInteractionEffect::GiveOrTakeShield();
|
||||||
|
effect->parameters[0] = it->second;
|
||||||
|
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
||||||
|
|
||||||
|
if (result == GameInteractionEffectQueryResult::Possible) {
|
||||||
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Gave shield.");
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
} else {
|
||||||
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Command failed: Could not give shield.");
|
||||||
|
return CMD_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool TakeShieldHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args) {
|
||||||
|
if (args.size() != 2) {
|
||||||
|
SohImGui::GetConsole()->SendErrorMessage("[SOH] Unexpected arguments passed");
|
||||||
|
return CMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& it = shields.find(args[1]);
|
||||||
|
if (it == shields.end()) {
|
||||||
|
SohImGui::GetConsole()->SendErrorMessage("Invalid shield type. Options are 'deku', 'hylian' and 'mirror'");
|
||||||
|
return CMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameInteractionEffectBase* effect = new GameInteractionEffect::GiveOrTakeShield();
|
||||||
|
effect->parameters[0] = it->second * -1;
|
||||||
|
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
||||||
|
|
||||||
|
if (result == GameInteractionEffectQueryResult::Possible) {
|
||||||
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Took shield.");
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
} else {
|
||||||
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Command failed: Could not take shield.");
|
||||||
|
return CMD_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool KnockbackHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args) {
|
static bool KnockbackHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args) {
|
||||||
if (args.size() != 2) {
|
if (args.size() != 2) {
|
||||||
SohImGui::GetConsole()->SendErrorMessage("[SOH] Unexpected arguments passed");
|
SohImGui::GetConsole()->SendErrorMessage("[SOH] Unexpected arguments passed");
|
||||||
@ -1103,7 +1189,7 @@ static bool KnockbackHandler(std::shared_ptr<Ship::Console> Console, const std::
|
|||||||
return CMD_FAILED;
|
return CMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
effect->parameter = value;
|
effect->parameters[0] = value;
|
||||||
} catch (std::invalid_argument const& ex) {
|
} catch (std::invalid_argument const& ex) {
|
||||||
SohImGui::GetConsole()->SendErrorMessage("[SOH] Knockback value must be a number.");
|
SohImGui::GetConsole()->SendErrorMessage("[SOH] Knockback value must be a number.");
|
||||||
return CMD_FAILED;
|
return CMD_FAILED;
|
||||||
@ -1146,8 +1232,7 @@ static bool BurnHandler(std::shared_ptr<Ship::Console> Console, const std::vecto
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool CuccoStormHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args) {
|
static bool CuccoStormHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args) {
|
||||||
GameInteractionEffectBase* effect = new GameInteractionEffect::SpawnCuccoStorm();
|
GameInteractionEffectQueryResult result = GameInteractor::RawAction::SpawnActor(ACTOR_EN_NIW, 0);
|
||||||
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
|
|
||||||
|
|
||||||
if (result == GameInteractionEffectQueryResult::Possible) {
|
if (result == GameInteractionEffectQueryResult::Possible) {
|
||||||
SohImGui::GetConsole()->SendInfoMessage("[SOH] Spawned cucco storm");
|
SohImGui::GetConsole()->SendInfoMessage("[SOH] Spawned cucco storm");
|
||||||
@ -1344,8 +1429,6 @@ void DebugConsole_Init(void) {
|
|||||||
{ "Item ID", Ship::ArgumentType::NUMBER }
|
{ "Item ID", Ship::ArgumentType::NUMBER }
|
||||||
}});
|
}});
|
||||||
|
|
||||||
CMD_REGISTER("givedekushield", { GiveDekuShieldHandler, "Gives a deku shield and equips it when Link is a child with no shield equiped." });
|
|
||||||
|
|
||||||
CMD_REGISTER("spawn", { ActorSpawnHandler, "Spawn an actor.", { { "actor_id", Ship::ArgumentType::NUMBER },
|
CMD_REGISTER("spawn", { ActorSpawnHandler, "Spawn an actor.", { { "actor_id", Ship::ArgumentType::NUMBER },
|
||||||
{ "data", Ship::ArgumentType::NUMBER },
|
{ "data", Ship::ArgumentType::NUMBER },
|
||||||
{ "x", Ship::ArgumentType::PLAYER_POS, true },
|
{ "x", Ship::ArgumentType::PLAYER_POS, true },
|
||||||
@ -1371,8 +1454,13 @@ void DebugConsole_Init(void) {
|
|||||||
{ "varName", Ship::ArgumentType::TEXT }
|
{ "varName", Ship::ArgumentType::TEXT }
|
||||||
}});
|
}});
|
||||||
|
|
||||||
CMD_REGISTER("ammo", { AmmoHandler, "Changes ammo of an item.", {
|
CMD_REGISTER("addammo", { AddAmmoHandler, "Adds ammo of an item.", {
|
||||||
{ "item", Ship::ArgumentType::TEXT },
|
{ "sticks|nuts|bombs|seeds|arrows|bombchus|beans", Ship::ArgumentType::TEXT },
|
||||||
|
{ "count", Ship::ArgumentType::NUMBER }
|
||||||
|
}});
|
||||||
|
|
||||||
|
CMD_REGISTER("takeammo", { TakeAmmoHandler, "Removes ammo of an item.", {
|
||||||
|
{ "sticks|nuts|bombs|seeds|arrows|bombchus|beans", Ship::ArgumentType::TEXT },
|
||||||
{ "count", Ship::ArgumentType::NUMBER }
|
{ "count", Ship::ArgumentType::NUMBER }
|
||||||
}});
|
}});
|
||||||
|
|
||||||
@ -1464,7 +1552,15 @@ void DebugConsole_Init(void) {
|
|||||||
}});
|
}});
|
||||||
|
|
||||||
CMD_REGISTER("boots", { BootsHandler, "Activates boots.", {
|
CMD_REGISTER("boots", { BootsHandler, "Activates boots.", {
|
||||||
{ "type", Ship::ArgumentType::TEXT },
|
{ "kokiri|iron|hover", Ship::ArgumentType::TEXT },
|
||||||
|
}});
|
||||||
|
|
||||||
|
CMD_REGISTER("giveshield", { GiveShieldHandler, "Gives a shield and equips it when Link is the right age for it.", {
|
||||||
|
{ "deku|hylian|mirror", Ship::ArgumentType::TEXT },
|
||||||
|
}});
|
||||||
|
|
||||||
|
CMD_REGISTER("takeshield", { TakeShieldHandler, "Takes a shield and unequips it if Link is wearing it.", {
|
||||||
|
{ "deku|hylian|mirror", Ship::ArgumentType::TEXT },
|
||||||
}});
|
}});
|
||||||
|
|
||||||
CMD_REGISTER("knockback", { KnockbackHandler, "Knocks Link back.", {
|
CMD_REGISTER("knockback", { KnockbackHandler, "Knocks Link back.", {
|
||||||
|
@ -52,8 +52,8 @@ namespace GameInteractionEffect {
|
|||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else if (
|
} else if (
|
||||||
(parameter > 0 && (gSaveContext.healthCapacity + (parameter * 0x10) > 0x140)) ||
|
(parameters[0] > 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) > 0x140)) ||
|
||||||
(parameter < 0 && (gSaveContext.healthCapacity + (parameter * 0x10) < 0x10))
|
(parameters[0] < 0 && (gSaveContext.healthCapacity + (parameters[0] * 0x10) < 0x10))
|
||||||
) {
|
) {
|
||||||
return GameInteractionEffectQueryResult::NotPossible;
|
return GameInteractionEffectQueryResult::NotPossible;
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ namespace GameInteractionEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ModifyHeartContainers::_Apply() {
|
void ModifyHeartContainers::_Apply() {
|
||||||
GameInteractor::RawAction::AddOrRemoveHealthContainers(parameter);
|
GameInteractor::RawAction::AddOrRemoveHealthContainers(parameters[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - FillMagic
|
// MARK: - FillMagic
|
||||||
@ -98,8 +98,8 @@ namespace GameInteractionEffect {
|
|||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else if (
|
} else if (
|
||||||
(parameter < 0 && gSaveContext.rupees <= 0) ||
|
(parameters[0] < 0 && gSaveContext.rupees <= 0) ||
|
||||||
(parameter > 0 && gSaveContext.rupees >= CUR_CAPACITY(UPG_WALLET))
|
(parameters[0] > 0 && gSaveContext.rupees >= CUR_CAPACITY(UPG_WALLET))
|
||||||
) {
|
) {
|
||||||
return GameInteractionEffectQueryResult::NotPossible;
|
return GameInteractionEffectQueryResult::NotPossible;
|
||||||
} else {
|
} else {
|
||||||
@ -107,7 +107,7 @@ namespace GameInteractionEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ModifyRupees::_Apply() {
|
void ModifyRupees::_Apply() {
|
||||||
Rupees_ChangeBy(parameter);
|
Rupees_ChangeBy(parameters[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - NoUI
|
// MARK: - NoUI
|
||||||
@ -134,7 +134,7 @@ namespace GameInteractionEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ModifyGravity::_Apply() {
|
void ModifyGravity::_Apply() {
|
||||||
GameInteractor::State::GravityLevel = (GIGravityLevel)parameter;
|
GameInteractor::State::GravityLevel = (GIGravityLevel)parameters[0];
|
||||||
}
|
}
|
||||||
void ModifyGravity::_Remove() {
|
void ModifyGravity::_Remove() {
|
||||||
GameInteractor::State::GravityLevel = GI_GRAVITY_LEVEL_NORMAL;
|
GameInteractor::State::GravityLevel = GI_GRAVITY_LEVEL_NORMAL;
|
||||||
@ -145,8 +145,8 @@ namespace GameInteractionEffect {
|
|||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else if (
|
} else if (
|
||||||
(parameter > 0 && gSaveContext.health == gSaveContext.healthCapacity)
|
(parameters[0] > 0 && gSaveContext.health == gSaveContext.healthCapacity)
|
||||||
|| (parameter < 0 && (gSaveContext.health + (16 * parameter) <= 0))
|
|| (parameters[0] < 0 && (gSaveContext.health + (16 * parameters[0]) <= 0))
|
||||||
) {
|
) {
|
||||||
return GameInteractionEffectQueryResult::NotPossible;
|
return GameInteractionEffectQueryResult::NotPossible;
|
||||||
}
|
}
|
||||||
@ -154,7 +154,7 @@ namespace GameInteractionEffect {
|
|||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
}
|
}
|
||||||
void ModifyHealth::_Apply() {
|
void ModifyHealth::_Apply() {
|
||||||
GameInteractor::RawAction::HealOrDamagePlayer(parameter);
|
GameInteractor::RawAction::HealOrDamagePlayer(parameters[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - SetPlayerHealth
|
// MARK: - SetPlayerHealth
|
||||||
@ -167,7 +167,7 @@ namespace GameInteractionEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void SetPlayerHealth::_Apply() {
|
void SetPlayerHealth::_Apply() {
|
||||||
GameInteractor::RawAction::SetPlayerHealth(parameter);
|
GameInteractor::RawAction::SetPlayerHealth(parameters[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - FreezePlayer
|
// MARK: - FreezePlayer
|
||||||
@ -218,7 +218,7 @@ namespace GameInteractionEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void KnockbackPlayer::_Apply() {
|
void KnockbackPlayer::_Apply() {
|
||||||
GameInteractor::RawAction::KnockbackPlayer(parameter);
|
GameInteractor::RawAction::KnockbackPlayer(parameters[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - ModifyLinkSize
|
// MARK: - ModifyLinkSize
|
||||||
@ -230,7 +230,7 @@ namespace GameInteractionEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ModifyLinkSize::_Apply() {
|
void ModifyLinkSize::_Apply() {
|
||||||
GameInteractor::State::LinkSize = (GILinkSize)parameter;
|
GameInteractor::State::LinkSize = (GILinkSize)parameters[0];
|
||||||
}
|
}
|
||||||
void ModifyLinkSize::_Remove() {
|
void ModifyLinkSize::_Remove() {
|
||||||
GameInteractor::State::LinkSize = GI_LINK_SIZE_RESET;
|
GameInteractor::State::LinkSize = GI_LINK_SIZE_RESET;
|
||||||
@ -320,7 +320,7 @@ namespace GameInteractionEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ForceEquipBoots::_Apply() {
|
void ForceEquipBoots::_Apply() {
|
||||||
GameInteractor::RawAction::ForceEquipBoots(parameter);
|
GameInteractor::RawAction::ForceEquipBoots(parameters[0]);
|
||||||
}
|
}
|
||||||
void ForceEquipBoots::_Remove() {
|
void ForceEquipBoots::_Remove() {
|
||||||
GameInteractor::RawAction::ForceEquipBoots(PLAYER_BOOTS_KOKIRI);
|
GameInteractor::RawAction::ForceEquipBoots(PLAYER_BOOTS_KOKIRI);
|
||||||
@ -335,7 +335,7 @@ namespace GameInteractionEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ModifyRunSpeedModifier::_Apply() {
|
void ModifyRunSpeedModifier::_Apply() {
|
||||||
GameInteractor::State::RunSpeedModifier = parameter;
|
GameInteractor::State::RunSpeedModifier = parameters[0];
|
||||||
}
|
}
|
||||||
void ModifyRunSpeedModifier::_Remove() {
|
void ModifyRunSpeedModifier::_Remove() {
|
||||||
GameInteractor::State::RunSpeedModifier = 0;
|
GameInteractor::State::RunSpeedModifier = 0;
|
||||||
@ -356,7 +356,7 @@ namespace GameInteractionEffect {
|
|||||||
GameInteractor::State::OneHitKOActive = 0;
|
GameInteractor::State::OneHitKOActive = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - IncreaseDamageTaken
|
// MARK: - ModifyDefenseModifier
|
||||||
GameInteractionEffectQueryResult ModifyDefenseModifier::CanBeApplied() {
|
GameInteractionEffectQueryResult ModifyDefenseModifier::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
@ -365,35 +365,229 @@ namespace GameInteractionEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void ModifyDefenseModifier::_Apply() {
|
void ModifyDefenseModifier::_Apply() {
|
||||||
GameInteractor::State::DefenseModifier = parameter;
|
GameInteractor::State::DefenseModifier = parameters[0];
|
||||||
}
|
}
|
||||||
void ModifyDefenseModifier::_Remove() {
|
void ModifyDefenseModifier::_Remove() {
|
||||||
GameInteractor::State::DefenseModifier = 0;
|
GameInteractor::State::DefenseModifier = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - GiveDekuShield
|
// MARK: - GiveOrTakeShield
|
||||||
GameInteractionEffectQueryResult GiveDekuShield::CanBeApplied() {
|
GameInteractionEffectQueryResult GiveOrTakeShield::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded()) {
|
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else if ((Item_CheckObtainability(ITEM_SHIELD_DEKU) != ITEM_NONE)) {
|
} else if ((parameters[0] > 0 && ((gBitFlags[parameters[0] - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_SHIELD]) &
|
||||||
|
gSaveContext.inventory.equipment)) ||
|
||||||
|
(parameters[0] < 0 && !((gBitFlags[(parameters[0] * -1) - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_SHIELD]) &
|
||||||
|
gSaveContext.inventory.equipment))) {
|
||||||
return GameInteractionEffectQueryResult::NotPossible;
|
return GameInteractionEffectQueryResult::NotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void GiveDekuShield::_Apply() {
|
void GiveOrTakeShield::_Apply() {
|
||||||
GameInteractor::RawAction::GiveDekuShield();
|
GameInteractor::RawAction::GiveOrTakeShield(parameters[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - SpawnCuccoStorm
|
// MARK: - TeleportPlayer
|
||||||
GameInteractionEffectQueryResult SpawnCuccoStorm::CanBeApplied() {
|
GameInteractionEffectQueryResult TeleportPlayer::CanBeApplied() {
|
||||||
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
if (!GameInteractor::IsSaveLoaded() || GameInteractor::IsGameplayPaused()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else {
|
} else {
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void SpawnCuccoStorm::_Apply() {
|
void TeleportPlayer::_Apply() {
|
||||||
GameInteractor::RawAction::SpawnCuccoStorm();
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,9 @@ public:
|
|||||||
virtual GameInteractionEffectQueryResult CanBeRemoved();
|
virtual GameInteractionEffectQueryResult CanBeRemoved();
|
||||||
GameInteractionEffectQueryResult Apply();
|
GameInteractionEffectQueryResult Apply();
|
||||||
GameInteractionEffectQueryResult Remove();
|
GameInteractionEffectQueryResult Remove();
|
||||||
int32_t parameter;
|
int32_t parameters[2];
|
||||||
protected:
|
|
||||||
|
protected:
|
||||||
virtual void _Apply() = 0;
|
virtual void _Apply() = 0;
|
||||||
virtual void _Remove() {};
|
virtual void _Remove() {};
|
||||||
};
|
};
|
||||||
@ -147,15 +148,92 @@ namespace GameInteractionEffect {
|
|||||||
void _Remove() override;
|
void _Remove() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GiveDekuShield: public GameInteractionEffectBase {
|
class GiveOrTakeShield: public GameInteractionEffectBase {
|
||||||
GameInteractionEffectQueryResult CanBeApplied() override;
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
void _Apply() override;
|
void _Apply() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SpawnCuccoStorm: public GameInteractionEffectBase {
|
class TeleportPlayer: public GameInteractionEffectBase {
|
||||||
GameInteractionEffectQueryResult CanBeApplied() override;
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
void _Apply() override;
|
void _Apply() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ClearAssignedButtons: public GameInteractionEffectBase {
|
||||||
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
|
void _Apply() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SetTimeOfDay: public GameInteractionEffectBase {
|
||||||
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
|
void _Apply() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SetCollisionViewer: public GameInteractionEffectBase {
|
||||||
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
|
void _Apply() override;
|
||||||
|
void _Remove() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SetCosmeticsColor: public GameInteractionEffectBase {
|
||||||
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
|
void _Apply() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RandomizeCosmetics: public GameInteractionEffectBase {
|
||||||
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
|
void _Apply() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PressButton: public GameInteractionEffectBase {
|
||||||
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
|
void _Apply() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PressRandomButton: public GameInteractionEffectBase {
|
||||||
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
|
void _Apply() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AddOrTakeAmmo: public GameInteractionEffectBase {
|
||||||
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
|
void _Apply() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RandomBombFuseTimer: public GameInteractionEffectBase {
|
||||||
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
|
void _Apply() override;
|
||||||
|
void _Remove() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DisableLedgeGrabs: public GameInteractionEffectBase {
|
||||||
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
|
void _Apply() override;
|
||||||
|
void _Remove() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RandomWind: public GameInteractionEffectBase {
|
||||||
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
|
void _Apply() override;
|
||||||
|
void _Remove() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RandomBonks: public GameInteractionEffectBase {
|
||||||
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
|
void _Apply() override;
|
||||||
|
void _Remove() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PlayerInvincibility: public GameInteractionEffectBase {
|
||||||
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
|
void _Apply() override;
|
||||||
|
void _Remove() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SlipperyFloor: public GameInteractionEffectBase {
|
||||||
|
GameInteractionEffectQueryResult CanBeApplied() override;
|
||||||
|
void _Apply() override;
|
||||||
|
void _Remove() override;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
@ -50,6 +50,48 @@ bool GameInteractor::IsGameplayPaused() {
|
|||||||
return (Player_InBlockingCsMode(gPlayState, player) || gPlayState->pauseCtx.state != 0 || gPlayState->msgCtx.msgMode != 0) ? true : false;
|
return (Player_InBlockingCsMode(gPlayState, player) || gPlayState->pauseCtx.state != 0 || gPlayState->msgCtx.msgMode != 0) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GameInteractor::CanSpawnEnemy() {
|
bool GameInteractor::CanSpawnActor() {
|
||||||
return GameInteractor::IsSaveLoaded() && !GameInteractor::IsGameplayPaused();
|
return GameInteractor::IsSaveLoaded() && !GameInteractor::IsGameplayPaused();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GameInteractor::CanAddOrTakeAmmo(int16_t amount, int16_t item) {
|
||||||
|
int16_t upgradeToCheck = 0;
|
||||||
|
|
||||||
|
switch (item) {
|
||||||
|
case ITEM_STICK:
|
||||||
|
upgradeToCheck = UPG_STICKS;
|
||||||
|
break;
|
||||||
|
case ITEM_NUT:
|
||||||
|
upgradeToCheck = UPG_NUTS;
|
||||||
|
break;
|
||||||
|
case ITEM_BOW:
|
||||||
|
upgradeToCheck = UPG_QUIVER;
|
||||||
|
break;
|
||||||
|
case ITEM_SLINGSHOT:
|
||||||
|
upgradeToCheck = UPG_BULLET_BAG;
|
||||||
|
break;
|
||||||
|
case ITEM_BOMB:
|
||||||
|
upgradeToCheck = UPG_BOMB_BAG;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amount < 0 && AMMO(item) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item != ITEM_BOMBCHU && item != ITEM_BEAN) {
|
||||||
|
if ((CUR_CAPACITY(upgradeToCheck) == 0) || (amount > 0 && AMMO(item) == CUR_CAPACITY(upgradeToCheck))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// Seperate checks for beans and bombchus because they don't have capacity upgrades
|
||||||
|
if (INV_CONTENT(item) != item ||
|
||||||
|
(amount > 0 && ((item == ITEM_BOMBCHU && AMMO(item) == 50) || (item == ITEM_BEAN && AMMO(item) == 10)))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -11,6 +11,7 @@ typedef enum {
|
|||||||
/* 0x01 */ GI_LINK_SIZE_GIANT,
|
/* 0x01 */ GI_LINK_SIZE_GIANT,
|
||||||
/* 0x02 */ GI_LINK_SIZE_MINISH,
|
/* 0x02 */ GI_LINK_SIZE_MINISH,
|
||||||
/* 0x03 */ GI_LINK_SIZE_PAPER,
|
/* 0x03 */ GI_LINK_SIZE_PAPER,
|
||||||
|
/* 0x03 */ GI_LINK_SIZE_SQUISHED,
|
||||||
/* 0x04 */ GI_LINK_SIZE_RESET
|
/* 0x04 */ GI_LINK_SIZE_RESET
|
||||||
} GILinkSize;
|
} GILinkSize;
|
||||||
|
|
||||||
@ -20,6 +21,46 @@ typedef enum {
|
|||||||
/* 0x02 */ GI_GRAVITY_LEVEL_HEAVY,
|
/* 0x02 */ GI_GRAVITY_LEVEL_HEAVY,
|
||||||
} GIGravityLevel;
|
} GIGravityLevel;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0x00 */ GI_BUTTONS_CBUTTONS,
|
||||||
|
/* 0x01 */ GI_BUTTONS_DPAD,
|
||||||
|
} GIButtonSet;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* */ GI_TIMEOFDAY_DAWN = 32768,
|
||||||
|
/* */ GI_TIMEOFDAY_NOON = 49152,
|
||||||
|
/* */ GI_TIMEOFDAY_DUSK = 0,
|
||||||
|
/* */ GI_TIMEOFDAY_MIDNIGHT = 16384,
|
||||||
|
} GITimeOfDay;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0x00 */ GI_COSMETICS_TUNICS,
|
||||||
|
/* 0x01 */ GI_COSMETICS_NAVI,
|
||||||
|
/* 0x02 */ GI_COSMETICS_HAIR,
|
||||||
|
} GICosmeticCategories;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0x00 */ GI_COLOR_RED,
|
||||||
|
/* 0x01 */ GI_COLOR_GREEN,
|
||||||
|
/* 0x02 */ GI_COLOR_BLUE,
|
||||||
|
/* 0x03 */ GI_COLOR_ORANGE,
|
||||||
|
/* 0x04 */ GI_COLOR_YELLOW,
|
||||||
|
/* 0x05 */ GI_COLOR_PURPLE,
|
||||||
|
/* 0x06 */ GI_COLOR_PINK,
|
||||||
|
/* 0x07 */ GI_COLOR_BROWN,
|
||||||
|
/* 0x08 */ GI_COLOR_BLACK,
|
||||||
|
} GIColors;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* */ GI_TP_DEST_LINKSHOUSE = 187,
|
||||||
|
/* */ GI_TP_DEST_MINUET = 1536,
|
||||||
|
/* */ GI_TP_DEST_BOLERO = 1270,
|
||||||
|
/* */ GI_TP_DEST_SERENADE = 1540,
|
||||||
|
/* */ GI_TP_DEST_REQUIEM = 497,
|
||||||
|
/* */ GI_TP_DEST_NOCTURNE = 1384,
|
||||||
|
/* */ GI_TP_DEST_PRELUDE = 1524,
|
||||||
|
} GITeleportDestinations;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -34,6 +75,13 @@ uint8_t GameInteractor_ReverseControlsActive();
|
|||||||
int32_t GameInteractor_DefenseModifier();
|
int32_t GameInteractor_DefenseModifier();
|
||||||
int32_t GameInteractor_RunSpeedModifier();
|
int32_t GameInteractor_RunSpeedModifier();
|
||||||
GIGravityLevel GameInteractor_GravityLevel();
|
GIGravityLevel GameInteractor_GravityLevel();
|
||||||
|
uint32_t GameInteractor_GetEmulatedButtons();
|
||||||
|
void GameInteractor_SetEmulatedButtons(uint32_t buttons);
|
||||||
|
uint8_t GameInteractor_GetRandomBombFuseTimerActive();
|
||||||
|
uint8_t GameInteractor_GetDisableLedgeGrabsActive();
|
||||||
|
uint8_t GameInteractor_GetRandomWindActive();
|
||||||
|
uint8_t GameInteractor_GetRandomBonksActive();
|
||||||
|
uint8_t GameInteractor_GetSlipperyFloorActive();
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -66,6 +114,13 @@ public:
|
|||||||
static int32_t DefenseModifier;
|
static int32_t DefenseModifier;
|
||||||
static int32_t RunSpeedModifier;
|
static int32_t RunSpeedModifier;
|
||||||
static GIGravityLevel GravityLevel;
|
static GIGravityLevel GravityLevel;
|
||||||
|
static uint32_t EmulatedButtons;
|
||||||
|
static uint8_t RandomBombFuseTimerActive;
|
||||||
|
static uint8_t DisableLedgeGrabsActive;
|
||||||
|
static uint8_t RandomWindActive;
|
||||||
|
static uint8_t RandomWindSecondsSinceLastDirectionChange;
|
||||||
|
static uint8_t RandomBonksActive;
|
||||||
|
static uint8_t SlipperyFloorActive;
|
||||||
|
|
||||||
static void SetPacifistMode(bool active);
|
static void SetPacifistMode(bool active);
|
||||||
};
|
};
|
||||||
@ -116,7 +171,8 @@ public:
|
|||||||
// Helpers
|
// Helpers
|
||||||
static bool IsSaveLoaded();
|
static bool IsSaveLoaded();
|
||||||
static bool IsGameplayPaused();
|
static bool IsGameplayPaused();
|
||||||
static bool CanSpawnEnemy();
|
static bool CanSpawnActor();
|
||||||
|
static bool CanAddOrTakeAmmo(int16_t amount, int16_t item);
|
||||||
|
|
||||||
class RawAction {
|
class RawAction {
|
||||||
public:
|
public:
|
||||||
@ -131,11 +187,22 @@ public:
|
|||||||
static void BurnPlayer();
|
static void BurnPlayer();
|
||||||
static void ElectrocutePlayer();
|
static void ElectrocutePlayer();
|
||||||
static void KnockbackPlayer(float strength);
|
static void KnockbackPlayer(float strength);
|
||||||
static void GiveDekuShield();
|
static void GiveOrTakeShield(int32_t shield);
|
||||||
static void SpawnCuccoStorm();
|
|
||||||
static void ForceInterfaceUpdate();
|
static void ForceInterfaceUpdate();
|
||||||
|
static void TeleportPlayer(int32_t nextEntrance);
|
||||||
|
static void ClearAssignedButtons(uint8_t buttonSet);
|
||||||
|
static void SetTimeOfDay(uint32_t time);
|
||||||
|
static void SetCollisionViewer(bool active);
|
||||||
|
static void SetCosmeticsColor(uint8_t cosmeticCategory, uint8_t colorValue);
|
||||||
|
static void RandomizeCosmeticsColors(bool excludeBiddingWarColors);
|
||||||
|
static void EmulateButtonPress(int32_t button);
|
||||||
|
static void AddOrTakeAmmo(int16_t amount, int16_t item);
|
||||||
|
static void EmulateRandomButtonPress(uint32_t chancePercentage = 100);
|
||||||
|
static void SetRandomWind(bool active);
|
||||||
|
static void SetPlayerInvincibility(bool active);
|
||||||
|
|
||||||
static GameInteractionEffectQueryResult SpawnEnemyWithOffset(uint32_t enemyId, int32_t enemyParams);
|
static GameInteractionEffectQueryResult SpawnEnemyWithOffset(uint32_t enemyId, int32_t enemyParams);
|
||||||
|
static GameInteractionEffectQueryResult SpawnActor(uint32_t actorId, int32_t actorParams);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#include "GameInteractor.h"
|
#include "GameInteractor.h"
|
||||||
#include <libultraship/bridge.h>
|
#include <libultraship/bridge.h>
|
||||||
|
#include "soh/Enhancements/cosmetics/CosmeticsEditor.h"
|
||||||
|
#include "soh/Enhancements/randomizer/3drando/random.hpp"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "variables.h"
|
#include "variables.h"
|
||||||
@ -9,6 +12,7 @@ extern PlayState* gPlayState;
|
|||||||
}
|
}
|
||||||
|
|
||||||
#include "overlays/actors/ovl_En_Niw/z_en_niw.h"
|
#include "overlays/actors/ovl_En_Niw/z_en_niw.h"
|
||||||
|
#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
|
||||||
|
|
||||||
void GameInteractor::RawAction::AddOrRemoveHealthContainers(int16_t amount) {
|
void GameInteractor::RawAction::AddOrRemoveHealthContainers(int16_t amount) {
|
||||||
gSaveContext.healthCapacity += amount * 0x10;
|
gSaveContext.healthCapacity += amount * 0x10;
|
||||||
@ -120,21 +124,53 @@ void GameInteractor::RawAction::KnockbackPlayer(float strength) {
|
|||||||
func_8002F71C(gPlayState, &player->actor, strength * 5, player->actor.world.rot.y + 0x8000, strength * 5);
|
func_8002F71C(gPlayState, &player->actor, strength * 5, player->actor.world.rot.y + 0x8000, strength * 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameInteractor::RawAction::GiveDekuShield() {
|
void GameInteractor::RawAction::GiveOrTakeShield(int32_t shield) {
|
||||||
// Give Deku Shield to the player, and automatically equip it when they're child and have no shield currently equiped.
|
// When taking a shield, make sure it is unequipped as well.
|
||||||
Player* player = GET_PLAYER(gPlayState);
|
// When giving a shield and the player isn't wearing one yet,
|
||||||
Item_Give(gPlayState, ITEM_SHIELD_DEKU);
|
// equip said shield when the player's current age can equip it.
|
||||||
if (LINK_IS_CHILD && player->currentShield == PLAYER_SHIELD_NONE) {
|
// 'shield' being a negative number means taking that shield.
|
||||||
player->currentShield = PLAYER_SHIELD_DEKU;
|
|
||||||
Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_DEKU);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameInteractor::RawAction::SpawnCuccoStorm() {
|
|
||||||
Player* player = GET_PLAYER(gPlayState);
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
EnNiw* cucco = (EnNiw*)Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_NIW, player->actor.world.pos.x,
|
int8_t shieldToCheck = PLAYER_SHIELD_NONE;
|
||||||
player->actor.world.pos.y + 2200, player->actor.world.pos.z, 0, 0, 0, 0, 0);
|
|
||||||
cucco->actionFunc = func_80AB70A0_nocutscene;
|
if (shield < 0) {
|
||||||
|
shield = shield * -1;
|
||||||
|
|
||||||
|
switch (shield) {
|
||||||
|
case ITEM_SHIELD_DEKU:
|
||||||
|
shieldToCheck = PLAYER_SHIELD_DEKU;
|
||||||
|
break;
|
||||||
|
case ITEM_SHIELD_HYLIAN:
|
||||||
|
shieldToCheck = PLAYER_SHIELD_HYLIAN;
|
||||||
|
break;
|
||||||
|
case ITEM_SHIELD_MIRROR:
|
||||||
|
shieldToCheck = PLAYER_SHIELD_MIRROR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
gSaveContext.inventory.equipment &= ~(gBitFlags[shield - ITEM_SHIELD_DEKU] << gEquipShifts[EQUIP_SHIELD]);
|
||||||
|
|
||||||
|
if (player->currentShield == shieldToCheck) {
|
||||||
|
player->currentShield = PLAYER_SHIELD_NONE;
|
||||||
|
Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_NONE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Item_Give(gPlayState, shield);
|
||||||
|
if (player->currentShield == PLAYER_SHIELD_NONE) {
|
||||||
|
if (LINK_IS_CHILD && shield == ITEM_SHIELD_DEKU) {
|
||||||
|
player->currentShield = PLAYER_SHIELD_DEKU;
|
||||||
|
Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_DEKU);
|
||||||
|
} else if (LINK_IS_ADULT && shield == ITEM_SHIELD_MIRROR) {
|
||||||
|
player->currentShield = PLAYER_SHIELD_MIRROR;
|
||||||
|
Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_MIRROR);
|
||||||
|
} else if (shield == ITEM_SHIELD_HYLIAN) {
|
||||||
|
player->currentShield = PLAYER_SHIELD_HYLIAN;
|
||||||
|
Inventory_ChangeEquipment(EQUIP_SHIELD, PLAYER_SHIELD_HYLIAN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameInteractor::RawAction::ForceInterfaceUpdate() {
|
void GameInteractor::RawAction::ForceInterfaceUpdate() {
|
||||||
@ -142,58 +178,348 @@ void GameInteractor::RawAction::ForceInterfaceUpdate() {
|
|||||||
Interface_Update(gPlayState);
|
Interface_Update(gPlayState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameInteractor::RawAction::TeleportPlayer(int32_t nextEntrance) {
|
||||||
|
Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||||
|
gPlayState->nextEntranceIndex = nextEntrance;
|
||||||
|
gPlayState->sceneLoadFlag = 0x14;
|
||||||
|
gPlayState->fadeTransition = 2;
|
||||||
|
gSaveContext.nextTransitionType = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameInteractor::RawAction::ClearAssignedButtons(uint8_t buttonSet) {
|
||||||
|
switch (buttonSet) {
|
||||||
|
case GI_BUTTONS_CBUTTONS:
|
||||||
|
gSaveContext.equips.buttonItems[1] = gSaveContext.equips.buttonItems[2] =
|
||||||
|
gSaveContext.equips.buttonItems[3] = ITEM_NONE;
|
||||||
|
break;
|
||||||
|
case GI_BUTTONS_DPAD:
|
||||||
|
gSaveContext.equips.buttonItems[4] = gSaveContext.equips.buttonItems[5] =
|
||||||
|
gSaveContext.equips.buttonItems[6] = gSaveContext.equips.buttonItems[7] = ITEM_NONE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameInteractor::RawAction::SetTimeOfDay(uint32_t time) {
|
||||||
|
if (time > 0xFFFF) {
|
||||||
|
gSaveContext.dayTime = 0xFFFF;
|
||||||
|
} else {
|
||||||
|
gSaveContext.dayTime = time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameInteractor::RawAction::SetCollisionViewer(bool active) {
|
||||||
|
CVarSetInteger("gColViewerEnabled", active);
|
||||||
|
CVarSetInteger("gColViewerDecal", active);
|
||||||
|
|
||||||
|
if (active) {
|
||||||
|
CVarSetInteger("gColViewerScene", 2);
|
||||||
|
CVarSetInteger("gColViewerBgActors", 2);
|
||||||
|
CVarSetInteger("gColViewerColCheck", 2);
|
||||||
|
CVarSetInteger("gColViewerWaterbox", 2);
|
||||||
|
} else {
|
||||||
|
CVarSetInteger("gColViewerScene", 0);
|
||||||
|
CVarSetInteger("gColViewerBgActors", 0);
|
||||||
|
CVarSetInteger("gColViewerColCheck", 0);
|
||||||
|
CVarSetInteger("gColViewerWaterbox", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameInteractor::RawAction::SetCosmeticsColor(uint8_t cosmeticCategory, uint8_t colorValue) {
|
||||||
|
Color_RGBA8 newColor;
|
||||||
|
newColor.r = 255;
|
||||||
|
newColor.g = 255;
|
||||||
|
newColor.b = 255;
|
||||||
|
newColor.a = 255;
|
||||||
|
|
||||||
|
switch (colorValue) {
|
||||||
|
case GI_COLOR_RED:
|
||||||
|
newColor.r = 200;
|
||||||
|
newColor.g = 30;
|
||||||
|
newColor.b = 30;
|
||||||
|
break;
|
||||||
|
case GI_COLOR_GREEN:
|
||||||
|
newColor.r = 50;
|
||||||
|
newColor.g = 200;
|
||||||
|
newColor.b = 50;
|
||||||
|
break;
|
||||||
|
case GI_COLOR_BLUE:
|
||||||
|
newColor.r = 50;
|
||||||
|
newColor.g = 50;
|
||||||
|
newColor.b = 200;
|
||||||
|
break;
|
||||||
|
case GI_COLOR_ORANGE:
|
||||||
|
newColor.r = 200;
|
||||||
|
newColor.g = 120;
|
||||||
|
newColor.b = 0;
|
||||||
|
break;
|
||||||
|
case GI_COLOR_YELLOW:
|
||||||
|
newColor.r = 234;
|
||||||
|
newColor.g = 240;
|
||||||
|
newColor.b = 33;
|
||||||
|
break;
|
||||||
|
case GI_COLOR_PURPLE:
|
||||||
|
newColor.r = 144;
|
||||||
|
newColor.g = 13;
|
||||||
|
newColor.b = 178;
|
||||||
|
break;
|
||||||
|
case GI_COLOR_PINK:
|
||||||
|
newColor.r = 215;
|
||||||
|
newColor.g = 93;
|
||||||
|
newColor.b = 246;
|
||||||
|
break;
|
||||||
|
case GI_COLOR_BROWN:
|
||||||
|
newColor.r = 108;
|
||||||
|
newColor.g = 72;
|
||||||
|
newColor.b = 15;
|
||||||
|
break;
|
||||||
|
case GI_COLOR_BLACK:
|
||||||
|
newColor.r = 0;
|
||||||
|
newColor.g = 0;
|
||||||
|
newColor.b = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cosmeticCategory) {
|
||||||
|
case GI_COSMETICS_TUNICS:
|
||||||
|
CVarSetColor("gCosmetics.Link_KokiriTunic.Value", newColor);
|
||||||
|
CVarSetInteger("gCosmetics.Link_KokiriTunic.Changed", 1);
|
||||||
|
CVarSetColor("gCosmetics.Link_GoronTunic.Value", newColor);
|
||||||
|
CVarSetInteger("gCosmetics.Link_GoronTunic.Changed", 1);
|
||||||
|
CVarSetColor("gCosmetics.Link_ZoraTunic.Value", newColor);
|
||||||
|
CVarSetInteger("gCosmetics.Link_ZoraTunic.Changed", 1);
|
||||||
|
break;
|
||||||
|
case GI_COSMETICS_NAVI:
|
||||||
|
CVarSetColor("gCosmetics.Navi_EnemyPrimary.Value", newColor);
|
||||||
|
CVarSetInteger("gCosmetics.Navi_EnemyPrimary.Changed", 1);
|
||||||
|
CVarSetColor("gCosmetics.Navi_EnemySecondary.Value", newColor);
|
||||||
|
CVarSetInteger("gCosmetics.Navi_EnemySecondary.Changed", 1);
|
||||||
|
CVarSetColor("gCosmetics.Navi_IdlePrimary.Value", newColor);
|
||||||
|
CVarSetInteger("gCosmetics.Navi_IdlePrimary.Changed", 1);
|
||||||
|
CVarSetColor("gCosmetics.Navi_IdleSecondary.Value", newColor);
|
||||||
|
CVarSetInteger("gCosmetics.Navi_IdleSecondary.Changed", 1);
|
||||||
|
CVarSetColor("gCosmetics.Navi_NPCPrimary.Value", newColor);
|
||||||
|
CVarSetInteger("gCosmetics.Navi_NPCPrimary.Changed", 1);
|
||||||
|
CVarSetColor("gCosmetics.Navi_NPCSecondary.Value", newColor);
|
||||||
|
CVarSetInteger("gCosmetics.Navi_NPCSecondary.Changed", 1);
|
||||||
|
CVarSetColor("gCosmetics.Navi_PropsPrimary.Value", newColor);
|
||||||
|
CVarSetInteger("gCosmetics.Navi_PropsPrimary.Changed", 1);
|
||||||
|
CVarSetColor("gCosmetics.Navi_PropsSecondary.Value", newColor);
|
||||||
|
CVarSetInteger("gCosmetics.Navi_PropsSecondary.Changed", 1);
|
||||||
|
break;
|
||||||
|
case GI_COSMETICS_HAIR:
|
||||||
|
CVarSetColor("gCosmetics.Link_Hair.Value", newColor);
|
||||||
|
CVarSetInteger("gCosmetics.Link_Hair.Changed", 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
SohImGui::RequestCvarSaveOnNextTick();
|
||||||
|
ApplyOrResetCustomGfxPatches();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameInteractor::RawAction::RandomizeCosmeticsColors(bool excludeBiddingWarColors) {
|
||||||
|
const char* cvarsToLock[12] = {
|
||||||
|
"gCosmetics.Link_KokiriTunic.Locked",
|
||||||
|
"gCosmetics.Link_GoronTunic.Locked",
|
||||||
|
"gCosmetics.Link_ZoraTunic.Locked",
|
||||||
|
"gCosmetics.Navi_EnemyPrimary.Locked",
|
||||||
|
"gCosmetics.Navi_EnemySecondary.Locked",
|
||||||
|
"gCosmetics.Navi_IdlePrimary.Locked",
|
||||||
|
"gCosmetics.Navi_IdleSecondary.Locked",
|
||||||
|
"gCosmetics.Navi_NPCPrimary.Locked",
|
||||||
|
"gCosmetics.Navi_NPCSecondary.Locked",
|
||||||
|
"gCosmetics.Navi_PropsPrimary.Locked",
|
||||||
|
"gCosmetics.Navi_PropsSecondary.Locked",
|
||||||
|
"gCosmetics.Link_Hair.Locked"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (excludeBiddingWarColors) {
|
||||||
|
for (uint8_t i = 0; i < 12; i++) {
|
||||||
|
CVarSetInteger(cvarsToLock[i], 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CosmeticsEditor_RandomizeAll();
|
||||||
|
|
||||||
|
if (excludeBiddingWarColors) {
|
||||||
|
for (uint8_t i = 0; i < 12; i++) {
|
||||||
|
CVarSetInteger(cvarsToLock[i], 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameInteractor::RawAction::EmulateButtonPress(int32_t button) {
|
||||||
|
GameInteractor::State::EmulatedButtons |= button;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameInteractor::RawAction::EmulateRandomButtonPress(uint32_t chancePercentage) {
|
||||||
|
uint32_t emulatedButton;
|
||||||
|
uint32_t randomNumber = rand();
|
||||||
|
uint32_t possibleButtons[14] = { BTN_CRIGHT, BTN_CLEFT, BTN_CDOWN, BTN_CUP, BTN_R, BTN_L, BTN_DRIGHT,
|
||||||
|
BTN_DLEFT, BTN_DDOWN, BTN_DUP, BTN_START, BTN_Z, BTN_B, BTN_A };
|
||||||
|
|
||||||
|
emulatedButton = possibleButtons[randomNumber % 14];
|
||||||
|
|
||||||
|
if (randomNumber % 100 < chancePercentage) {
|
||||||
|
GameInteractor::State::EmulatedButtons |= emulatedButton;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameInteractor::RawAction::AddOrTakeAmmo(int16_t amount, int16_t item) {
|
||||||
|
Inventory_ChangeAmmo(item, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameInteractor::RawAction::SetRandomWind(bool active) {
|
||||||
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
|
if (active) {
|
||||||
|
GameInteractor::State::RandomWindActive = 1;
|
||||||
|
if (GameInteractor::State::RandomWindSecondsSinceLastDirectionChange == 0) {
|
||||||
|
player->windDirection = (rand() % 49152) - 32767;
|
||||||
|
GameInteractor::State::RandomWindSecondsSinceLastDirectionChange = 5;
|
||||||
|
} else {
|
||||||
|
GameInteractor::State::RandomWindSecondsSinceLastDirectionChange--;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GameInteractor::State::RandomWindActive = 0;
|
||||||
|
GameInteractor::State::RandomWindSecondsSinceLastDirectionChange = 0;
|
||||||
|
player->windSpeed = 0.0f;
|
||||||
|
player->windDirection = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameInteractor::RawAction::SetPlayerInvincibility(bool active) {
|
||||||
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
|
if (active) {
|
||||||
|
player->invincibilityTimer = 1000;
|
||||||
|
} else {
|
||||||
|
player->invincibilityTimer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnEnemyWithOffset(uint32_t enemyId, int32_t enemyParams) {
|
GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnEnemyWithOffset(uint32_t enemyId, int32_t enemyParams) {
|
||||||
|
|
||||||
if (!GameInteractor::CanSpawnEnemy()) {
|
if (!GameInteractor::CanSpawnActor()) {
|
||||||
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t sceneNum = gPlayState->sceneNum;
|
||||||
|
int16_t roomNum = gPlayState->roomCtx.curRoom.num;
|
||||||
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
|
|
||||||
|
// Disallow enemy spawns in the painting Poe rooms in Forest Temple.
|
||||||
|
// Killing a spawned enemy before the Poe can softlock the rooms entirely.
|
||||||
|
if (sceneNum == SCENE_BMORI1 && (roomNum == 12 || roomNum == 13 || roomNum == 16)) {
|
||||||
|
return GameInteractionEffectQueryResult::NotPossible;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only one Dark Link may exist at a time.
|
||||||
|
if (enemyId == ACTOR_EN_TORCH2) {
|
||||||
|
Actor* nearbyEnTest = Actor_FindNearby(gPlayState, &player->actor, ACTOR_EN_TORCH2, ACTORCAT_ENEMY, 8000.0f);
|
||||||
|
if (nearbyEnTest != NULL) {
|
||||||
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enemyId == ACTOR_EN_CLEAR_TAG) {
|
||||||
|
// Don't allow Arwings in certain areas because they cause issues.
|
||||||
|
// Locations: King dodongo room, Morpha room, Twinrova room, Ganondorf room, Fishing pond, Ganon's room
|
||||||
|
// TODO: Swap this to disabling the option in CC options menu instead.
|
||||||
|
if (sceneNum == SCENE_DDAN_BOSS || sceneNum == SCENE_MIZUSIN_BS || sceneNum == SCENE_JYASINBOSS ||
|
||||||
|
sceneNum == SCENE_GANON_BOSS || sceneNum == SCENE_TURIBORI || sceneNum == SCENE_GANON_DEMO) {
|
||||||
|
return GameInteractionEffectQueryResult::NotPossible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate point in random angle with a radius.
|
||||||
|
float angle = Random(0, 2 * M_PI);
|
||||||
|
float radius = 150;
|
||||||
|
float posXOffset = radius * cos(angle);
|
||||||
|
float posZOffset = radius * sin(angle);
|
||||||
|
|
||||||
|
// Raycast to the ground from randomly generated point.
|
||||||
|
CollisionPoly poly;
|
||||||
|
Vec3f pos;
|
||||||
|
f32 raycastResult;
|
||||||
|
|
||||||
|
pos.x = player->actor.world.pos.x + posXOffset;
|
||||||
|
pos.y = player->actor.world.pos.y + 50;
|
||||||
|
pos.z = player->actor.world.pos.z + posZOffset;
|
||||||
|
raycastResult = BgCheck_AnyRaycastFloor1(&gPlayState->colCtx, &poly, &pos);
|
||||||
|
|
||||||
|
// If ground is found below actor, move actor to that height.
|
||||||
|
// If not it's likely out of bounds, so make it temporarily not possible and try again later.
|
||||||
|
if (raycastResult > BGCHECK_Y_MIN) {
|
||||||
|
pos.y = raycastResult;
|
||||||
|
} else {
|
||||||
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Offset flying enemies off the ground
|
||||||
|
if (enemyId == ACTOR_EN_CLEAR_TAG || enemyId == ACTOR_EN_FIREFLY) {
|
||||||
|
pos.y += 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enemyId == ACTOR_EN_FIREFLY && enemyParams == 2) {
|
||||||
|
// Spawn Flock of Keese (5x)
|
||||||
|
for (uint8_t i = 0; i < 5; i++) {
|
||||||
|
pos.x += 10;
|
||||||
|
pos.y += 10;
|
||||||
|
pos.z += 10;
|
||||||
|
if (Actor_Spawn(&gPlayState->actorCtx, gPlayState, enemyId, pos.x, pos.y, pos.z, 0, 0, 0, enemyParams, 0) == NULL) {
|
||||||
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
} else {
|
||||||
|
if (Actor_Spawn(&gPlayState->actorCtx, gPlayState, enemyId, pos.x, pos.y, pos.z, 0, 0, 0, enemyParams, 0) != NULL) {
|
||||||
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameInteractionEffectQueryResult GameInteractor::RawAction::SpawnActor(uint32_t actorId, int32_t actorParams) {
|
||||||
|
|
||||||
|
if (!GameInteractor::CanSpawnActor()) {
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
}
|
}
|
||||||
|
|
||||||
Player* player = GET_PLAYER(gPlayState);
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
|
|
||||||
float posXOffset = 0;
|
if (actorId == ACTOR_EN_NIW) {
|
||||||
float posYOffset = 0;
|
// Spawn Cucco and make it angry
|
||||||
float posZOffset = 0;
|
EnNiw* cucco = (EnNiw*)Actor_Spawn(&gPlayState->actorCtx, gPlayState, actorId, player->actor.world.pos.x,
|
||||||
|
player->actor.world.pos.y + 2200, player->actor.world.pos.z, 0, 0, 0, actorParams, 0);
|
||||||
if (enemyId == ACTOR_EN_WALLMAS) {
|
if (cucco == NULL) {
|
||||||
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
} else if (enemyId == ACTOR_EN_CLEAR_TAG) {
|
|
||||||
// Don't allow Arwings in certain areas because they cause issues.
|
|
||||||
// Locations: King dodongo room, Morpha room, Twinrova room, Ganondorf room, Fishing pond, Ganon's room
|
|
||||||
// TODO: Swap this to disabling the option in CC options menu instead.
|
|
||||||
if (gPlayState->sceneNum == SCENE_DDAN_BOSS || gPlayState->sceneNum == SCENE_MIZUSIN_BS ||
|
|
||||||
gPlayState->sceneNum == SCENE_JYASINBOSS || gPlayState->sceneNum == SCENE_GANON_BOSS ||
|
|
||||||
gPlayState->sceneNum == SCENE_TURIBORI || gPlayState->sceneNum == SCENE_GANON_DEMO) {
|
|
||||||
return GameInteractionEffectQueryResult::NotPossible;
|
|
||||||
}
|
}
|
||||||
posYOffset = 100;
|
|
||||||
} else if (enemyId == ACTOR_EN_TORCH2) {
|
|
||||||
posXOffset = 75;
|
|
||||||
posYOffset = 50;
|
|
||||||
} else if (enemyId == ACTOR_EN_TEST) {
|
|
||||||
posXOffset = 75;
|
|
||||||
posYOffset = 50;
|
|
||||||
} else if (enemyId == ACTOR_EN_WF) {
|
|
||||||
posXOffset = 75;
|
|
||||||
posYOffset = 50;
|
|
||||||
} else if (enemyId == ACTOR_EN_FZ) {
|
|
||||||
posXOffset = 75;
|
|
||||||
posYOffset = 50;
|
|
||||||
} else if (enemyId == ACTOR_EN_FIREFLY) {
|
|
||||||
posXOffset = 75;
|
|
||||||
posYOffset = 50;
|
|
||||||
} else if (enemyId == ACTOR_EN_TITE) {
|
|
||||||
posXOffset = 75;
|
|
||||||
posYOffset = 50;
|
|
||||||
} else if (enemyId == ACTOR_EN_RR) {
|
|
||||||
posXOffset = 75;
|
|
||||||
posYOffset = 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Actor_Spawn(&gPlayState->actorCtx, gPlayState, enemyId, player->actor.world.pos.x + posXOffset,
|
cucco->actionFunc = func_80AB70A0_nocutscene;
|
||||||
player->actor.world.pos.y + posYOffset, player->actor.world.pos.z + posZOffset, 0, 0, 0,
|
|
||||||
enemyParams, 0) != NULL) {
|
|
||||||
return GameInteractionEffectQueryResult::Possible;
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
} else if (actorId == ACTOR_EN_BOM) {
|
||||||
|
// Spawn a bomb, make it explode instantly when params is set to 1 to emulate spawning an explosion
|
||||||
|
EnBom* bomb = (EnBom*)Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_BOM, player->actor.world.pos.x,
|
||||||
|
player->actor.world.pos.y + 30, player->actor.world.pos.z, 0, 0, 0, BOMB_BODY, true);
|
||||||
|
|
||||||
|
if (bomb == NULL) {
|
||||||
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make bomb explode immediately
|
||||||
|
if (actorParams == 1) {
|
||||||
|
bomb->timer = 2;
|
||||||
|
}
|
||||||
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
} else {
|
||||||
|
// Generic spawn an actor at Link's position
|
||||||
|
if (Actor_Spawn(&gPlayState->actorCtx, gPlayState, actorId, player->actor.world.pos.x,
|
||||||
|
player->actor.world.pos.y, player->actor.world.pos.z, 0, 0, 0, actorParams, 0) != NULL) {
|
||||||
|
return GameInteractionEffectQueryResult::Possible;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,13 @@ bool GameInteractor::State::ReverseControlsActive = 0;
|
|||||||
int32_t GameInteractor::State::DefenseModifier = 0;
|
int32_t GameInteractor::State::DefenseModifier = 0;
|
||||||
int32_t GameInteractor::State::RunSpeedModifier = 0;
|
int32_t GameInteractor::State::RunSpeedModifier = 0;
|
||||||
GIGravityLevel GameInteractor::State::GravityLevel = GI_GRAVITY_LEVEL_NORMAL;
|
GIGravityLevel GameInteractor::State::GravityLevel = GI_GRAVITY_LEVEL_NORMAL;
|
||||||
|
uint32_t GameInteractor::State::EmulatedButtons = 0;
|
||||||
|
uint8_t GameInteractor::State::RandomBombFuseTimerActive = 0;
|
||||||
|
uint8_t GameInteractor::State::DisableLedgeGrabsActive = 0;
|
||||||
|
uint8_t GameInteractor::State::RandomWindActive = 0;
|
||||||
|
uint8_t GameInteractor::State::RandomWindSecondsSinceLastDirectionChange = 0;
|
||||||
|
uint8_t GameInteractor::State::RandomBonksActive = 0;
|
||||||
|
uint8_t GameInteractor::State::SlipperyFloorActive = 0;
|
||||||
|
|
||||||
void GameInteractor::State::SetPacifistMode(bool active) {
|
void GameInteractor::State::SetPacifistMode(bool active) {
|
||||||
PacifistModeActive = active;
|
PacifistModeActive = active;
|
||||||
@ -79,3 +86,38 @@ int32_t GameInteractor_RunSpeedModifier() {
|
|||||||
GIGravityLevel GameInteractor_GravityLevel() {
|
GIGravityLevel GameInteractor_GravityLevel() {
|
||||||
return GameInteractor::State::GravityLevel;
|
return GameInteractor::State::GravityLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - GameInteractor::State::GetEmulatedButtons
|
||||||
|
uint32_t GameInteractor_GetEmulatedButtons() {
|
||||||
|
return GameInteractor::State::EmulatedButtons;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - GameInteractor::State::SetEmulatedButtons
|
||||||
|
void GameInteractor_SetEmulatedButtons(uint32_t buttons) {
|
||||||
|
GameInteractor::State::EmulatedButtons = buttons;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - GameInteractor::State::GetRandomBombFuseTimerActive
|
||||||
|
uint8_t GameInteractor_GetRandomBombFuseTimerActive() {
|
||||||
|
return GameInteractor::State::RandomBombFuseTimerActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - GameInteractor::State::GetDisableLedgeGrabsActive
|
||||||
|
uint8_t GameInteractor_GetDisableLedgeGrabsActive() {
|
||||||
|
return GameInteractor::State::DisableLedgeGrabsActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - GameInteractor::State::GetRandomWindActive
|
||||||
|
uint8_t GameInteractor_GetRandomWindActive() {
|
||||||
|
return GameInteractor::State::RandomWindActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - GameInteractor::State::GetRandomBonksActive
|
||||||
|
uint8_t GameInteractor_GetRandomBonksActive() {
|
||||||
|
return GameInteractor::State::RandomBonksActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - GameInteractor::State::GetSlipperyFloorActive
|
||||||
|
uint8_t GameInteractor_GetSlipperyFloorActive() {
|
||||||
|
return GameInteractor::State::SlipperyFloorActive;
|
||||||
|
}
|
||||||
|
@ -233,6 +233,12 @@ void PadMgr_ProcessInputs(PadMgr* padMgr) {
|
|||||||
input->cur.button &= ~(BTN_Z);
|
input->cur.button &= ~(BTN_Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t emulatedButtons = GameInteractor_GetEmulatedButtons();
|
||||||
|
if (emulatedButtons) {
|
||||||
|
input->cur.button |= emulatedButtons;
|
||||||
|
GameInteractor_SetEmulatedButtons(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (GameInteractor_ReverseControlsActive()) {
|
if (GameInteractor_ReverseControlsActive()) {
|
||||||
if (input->cur.stick_x == -128) {
|
if (input->cur.stick_x == -128) {
|
||||||
input->cur.stick_x = 127;
|
input->cur.stick_x = 127;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "z_en_bom.h"
|
#include "z_en_bom.h"
|
||||||
#include "overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.h"
|
#include "overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.h"
|
||||||
#include "objects/gameplay_keep/gameplay_keep.h"
|
#include "objects/gameplay_keep/gameplay_keep.h"
|
||||||
|
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||||
|
|
||||||
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
|
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
|
||||||
|
|
||||||
@ -96,7 +97,16 @@ void EnBom_Init(Actor* thisx, PlayState* play) {
|
|||||||
thisx->colChkInfo.mass = 200;
|
thisx->colChkInfo.mass = 200;
|
||||||
thisx->colChkInfo.cylRadius = 5;
|
thisx->colChkInfo.cylRadius = 5;
|
||||||
thisx->colChkInfo.cylHeight = 10;
|
thisx->colChkInfo.cylHeight = 10;
|
||||||
this->timer = 70;
|
if (!GameInteractor_GetRandomBombFuseTimerActive()) {
|
||||||
|
this->timer = 70;
|
||||||
|
} else {
|
||||||
|
// Set random fuse timer with a minimum of 10. Do the sound and scale immediately,
|
||||||
|
// otherwise the bomb is invisible until the timer hits the "normal" amount.
|
||||||
|
uint32_t randomTimer = (rand() % 150) + 10;
|
||||||
|
this->timer = randomTimer;
|
||||||
|
Audio_PlayActorSound2(thisx, NA_SE_PL_TAKE_OUT_SHIELD);
|
||||||
|
Actor_SetScale(thisx, 0.01f);
|
||||||
|
}
|
||||||
this->flashSpeedScale = 7;
|
this->flashSpeedScale = 7;
|
||||||
Collider_InitCylinder(play, &this->bombCollider);
|
Collider_InitCylinder(play, &this->bombCollider);
|
||||||
Collider_InitJntSph(play, &this->explosionCollider);
|
Collider_InitJntSph(play, &this->explosionCollider);
|
||||||
@ -244,7 +254,8 @@ void EnBom_Update(Actor* thisx, PlayState* play2) {
|
|||||||
this->timer--;
|
this->timer--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->timer == 67) {
|
// With random bomb fuse timer, sound effect and scaling is already done on init.
|
||||||
|
if (this->timer == 67 && !GameInteractor_GetRandomBombFuseTimerActive()) {
|
||||||
Audio_PlayActorSound2(thisx, NA_SE_PL_TAKE_OUT_SHIELD);
|
Audio_PlayActorSound2(thisx, NA_SE_PL_TAKE_OUT_SHIELD);
|
||||||
Actor_SetScale(thisx, 0.01f);
|
Actor_SetScale(thisx, 0.01f);
|
||||||
}
|
}
|
||||||
|
@ -230,12 +230,14 @@ void func_80A74398(Actor* thisx, PlayState* play) {
|
|||||||
Effect_Add(play, &this->blureIdx, EFFECT_BLURE1, 0, 0, &blureInit);
|
Effect_Add(play, &this->blureIdx, EFFECT_BLURE1, 0, 0, &blureInit);
|
||||||
func_80A74714(this);
|
func_80A74714(this);
|
||||||
|
|
||||||
|
uint8_t enemyRandoCCActive = CVarGetInteger("gRandomizedEnemies", 0) || CVarGetInteger("gCrowdControl", 0);
|
||||||
|
|
||||||
if (this->switchFlags != 0xFF) {
|
if (this->switchFlags != 0xFF) {
|
||||||
// In vanilla gameplay, Iron Knuckles are despawned based on specific flags in specific scenarios.
|
// In vanilla gameplay, Iron Knuckles are despawned based on specific flags in specific scenarios.
|
||||||
// In Enemy Randomizer, this made the Iron Knuckles despawn when the same flag was set by other objects.
|
// In Enemy Randomizer and Crowd Control, this made the Iron Knuckles despawn when the same flag was set by other objects.
|
||||||
// Instead, rely on the "Clear enemy room" flag when in Enemy Randomizer for Iron Knuckles that aren't Nabooru.
|
// Instead, rely on the "Clear enemy room" flag when in Enemy Randomizer for Iron Knuckles that aren't Nabooru.
|
||||||
if ((Flags_GetSwitch(play, this->switchFlags) && !CVarGetInteger("gRandomizedEnemies", 0)) ||
|
if ((Flags_GetSwitch(play, this->switchFlags) && !enemyRandoCCActive) ||
|
||||||
(thisx->params != 0 && Flags_GetClear(play, play->roomCtx.curRoom.num) && CVarGetInteger("gRandomizedEnemies", 0))) {
|
(thisx->params != 0 && Flags_GetClear(play, play->roomCtx.curRoom.num) && enemyRandoCCActive)) {
|
||||||
Actor_Kill(thisx);
|
Actor_Kill(thisx);
|
||||||
}
|
}
|
||||||
} else if (thisx->params != 0 && Flags_GetClear(play, play->roomCtx.curRoom.num)) {
|
} else if (thisx->params != 0 && Flags_GetClear(play, play->roomCtx.curRoom.num)) {
|
||||||
@ -656,9 +658,9 @@ void func_80A75A38(EnIk* this, PlayState* play) {
|
|||||||
}
|
}
|
||||||
if (this->unk_2F9 == 0) {
|
if (this->unk_2F9 == 0) {
|
||||||
Item_DropCollectibleRandom(play, &this->actor, &this->actor.world.pos, 0xB0);
|
Item_DropCollectibleRandom(play, &this->actor, &this->actor.world.pos, 0xB0);
|
||||||
// Don't set flag when Iron Knuckle is spawned by Enemy Rando.
|
// Don't set flag when Enemy Rando or CrowdControl are on.
|
||||||
// Instead Iron Knuckles rely on the "clear room" flag when Enemy Rando is on.
|
// Instead Iron Knuckles rely on the "clear room" flag.
|
||||||
if (this->switchFlags != 0xFF && !CVarGetInteger("gRandomizedEnemies",0)) {
|
if (this->switchFlags != 0xFF && !CVarGetInteger("gRandomizedEnemies", 0) && !CVarGetInteger("gCrowdControl", 0)) {
|
||||||
Flags_SetSwitch(play, this->switchFlags);
|
Flags_SetSwitch(play, this->switchFlags);
|
||||||
}
|
}
|
||||||
Actor_Kill(&this->actor);
|
Actor_Kill(&this->actor);
|
||||||
@ -1481,8 +1483,8 @@ void EnIk_Init(Actor* thisx, PlayState* play) {
|
|||||||
func_80A780D0(this, play);
|
func_80A780D0(this, play);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Immediately trigger Iron Knuckle for enemy randomizer
|
// Immediately trigger Iron Knuckle for Enemy Rando and Crowd Control
|
||||||
if (CVarGetInteger("gRandomizedEnemies", 0) && (thisx->params == 2 || thisx->params == 3)) {
|
if ((CVarGetInteger("gRandomizedEnemies", 0) || CVarGetInteger("gCrowdControl", 0)) && (thisx->params == 2 || thisx->params == 3)) {
|
||||||
this->skelAnime.playSpeed = 1.0f;
|
this->skelAnime.playSpeed = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,8 +251,8 @@ void func_80AE2744(EnRd* this, PlayState* play) {
|
|||||||
// Add a height check to redeads/gibdos freeze when Enemy Randomizer is on.
|
// Add a height check to redeads/gibdos freeze when Enemy Randomizer is on.
|
||||||
// Without the height check, redeads/gibdos can freeze the player from insane distances in
|
// Without the height check, redeads/gibdos can freeze the player from insane distances in
|
||||||
// vertical rooms (like the first room in Deku Tree), making these rooms nearly unplayable.
|
// vertical rooms (like the first room in Deku Tree), making these rooms nearly unplayable.
|
||||||
s8 enemyRando = CVarGetInteger("gRandomizedEnemies", 0);
|
s8 enemyRandoCCActive = CVarGetInteger("gRandomizedEnemies", 0) || CVarGetInteger("gCrowdControl", 0);
|
||||||
if (!enemyRando || (enemyRando && this->actor.yDistToPlayer <= 100.0f && this->actor.yDistToPlayer >= -100.0f)) {
|
if (!enemyRandoCCActive || (enemyRandoCCActive && this->actor.yDistToPlayer <= 100.0f && this->actor.yDistToPlayer >= -100.0f)) {
|
||||||
if ((this->actor.params != 2) && (this->unk_305 == 0)) {
|
if ((this->actor.params != 2) && (this->unk_305 == 0)) {
|
||||||
func_80AE37BC(this);
|
func_80AE37BC(this);
|
||||||
} else {
|
} else {
|
||||||
@ -663,8 +663,9 @@ void func_80AE3C98(EnRd* this, PlayState* play) {
|
|||||||
|
|
||||||
if (SkelAnime_Update(&this->skelAnime)) {
|
if (SkelAnime_Update(&this->skelAnime)) {
|
||||||
if (this->unk_30C == 0) {
|
if (this->unk_30C == 0) {
|
||||||
|
s8 enemyRandoCCActive = CVarGetInteger("gRandomizedEnemies", 0) || CVarGetInteger("gCrowdControl", 0);
|
||||||
// Don't set this flag in Enemy Rando as it can overlap with other objects using the same flag.
|
// Don't set this flag in Enemy Rando as it can overlap with other objects using the same flag.
|
||||||
if (!Flags_GetSwitch(play, this->unk_312 & 0x7F) && !CVarGetInteger("gRandomizedEnemies", 0)) {
|
if (!Flags_GetSwitch(play, this->unk_312 & 0x7F) && !enemyRandoCCActive) {
|
||||||
Flags_SetSwitch(play, this->unk_312 & 0x7F);
|
Flags_SetSwitch(play, this->unk_312 & 0x7F);
|
||||||
}
|
}
|
||||||
if (this->unk_314 != 0) {
|
if (this->unk_314 != 0) {
|
||||||
|
@ -8559,7 +8559,8 @@ void func_8084411C(Player* this, PlayState* play) {
|
|||||||
func_80843E14(this, NA_SE_VO_LI_FALL_L);
|
func_80843E14(this, NA_SE_VO_LI_FALL_L);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((this->actor.bgCheckFlags & 0x200) && !(this->stateFlags2 & PLAYER_STATE2_19) &&
|
if (!GameInteractor_GetDisableLedgeGrabsActive() && (this->actor.bgCheckFlags & 0x200) &&
|
||||||
|
!(this->stateFlags2 & PLAYER_STATE2_19) &&
|
||||||
!(this->stateFlags1 & (PLAYER_STATE1_11 | PLAYER_STATE1_27)) && (this->linearVelocity > 0.0f)) {
|
!(this->stateFlags1 & (PLAYER_STATE1_11 | PLAYER_STATE1_27)) && (this->linearVelocity > 0.0f)) {
|
||||||
if ((this->wallHeight >= 150.0f) && (this->unk_84B[this->unk_846] == 0)) {
|
if ((this->wallHeight >= 150.0f) && (this->unk_84B[this->unk_846] == 0)) {
|
||||||
func_8083EC18(this, play, D_808535F0);
|
func_8083EC18(this, play, D_808535F0);
|
||||||
@ -8655,8 +8656,10 @@ void func_80844708(Player* this, PlayState* play) {
|
|||||||
func_8083A060(this, play);
|
func_8083A060(this, play);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
f32 rand = Rand_ZeroOne();
|
||||||
|
uint8_t randomBonk = (rand <= .05) && GameInteractor_GetRandomBonksActive();
|
||||||
if (this->linearVelocity >= 7.0f) {
|
if (this->linearVelocity >= 7.0f) {
|
||||||
if (((this->actor.bgCheckFlags & 0x200) && (D_8085360C < 0x2000)) ||
|
if (randomBonk || ((this->actor.bgCheckFlags & 0x200) && (D_8085360C < 0x2000)) ||
|
||||||
((this->cylinder.base.ocFlags1 & OC1_HIT) &&
|
((this->cylinder.base.ocFlags1 & OC1_HIT) &&
|
||||||
(cylinderOc = this->cylinder.base.oc,
|
(cylinderOc = this->cylinder.base.oc,
|
||||||
((cylinderOc->id == ACTOR_EN_WOOD02) &&
|
((cylinderOc->id == ACTOR_EN_WOOD02) &&
|
||||||
@ -10665,7 +10668,7 @@ void Player_UpdateCommon(Player* this, PlayState* play, Input* input) {
|
|||||||
|
|
||||||
if (!(this->skelAnime.moveFlags & 0x80)) {
|
if (!(this->skelAnime.moveFlags & 0x80)) {
|
||||||
if (((this->actor.bgCheckFlags & 1) && (D_808535E4 == 5) && (this->currentBoots != PLAYER_BOOTS_IRON)) ||
|
if (((this->actor.bgCheckFlags & 1) && (D_808535E4 == 5) && (this->currentBoots != PLAYER_BOOTS_IRON)) ||
|
||||||
((this->currentBoots == PLAYER_BOOTS_HOVER) &&
|
((this->currentBoots == PLAYER_BOOTS_HOVER || GameInteractor_GetSlipperyFloorActive()) &&
|
||||||
!(this->stateFlags1 & (PLAYER_STATE1_27 | PLAYER_STATE1_29)))) {
|
!(this->stateFlags1 & (PLAYER_STATE1_27 | PLAYER_STATE1_29)))) {
|
||||||
f32 sp70 = this->linearVelocity;
|
f32 sp70 = this->linearVelocity;
|
||||||
s16 sp6E = this->currentYaw;
|
s16 sp6E = this->currentYaw;
|
||||||
@ -11003,42 +11006,67 @@ void Player_Update(Actor* thisx, PlayState* play) {
|
|||||||
MREG(54) = this->actor.world.pos.z;
|
MREG(54) = this->actor.world.pos.z;
|
||||||
MREG(55) = this->actor.world.rot.y;
|
MREG(55) = this->actor.world.rot.y;
|
||||||
|
|
||||||
switch (GameInteractor_GetLinkSize()) {
|
// Make Link normal size when going through doors and crawlspaces and when climbing ladders.
|
||||||
case GI_LINK_SIZE_RESET:
|
// Otherwise Link can glitch out, being in unloaded rooms or falling OoB.
|
||||||
this->actor.scale.x = 0.01f;
|
if (this->stateFlags1 & PLAYER_STATE1_21 || this->stateFlags1 & PLAYER_STATE1_29 ||
|
||||||
this->actor.scale.y = 0.01f;
|
this->stateFlags2 & PLAYER_STATE2_CRAWLING) {
|
||||||
this->actor.scale.z = 0.01f;
|
this->actor.scale.x = 0.01f;
|
||||||
GameInteractor_SetLinkSize(GI_LINK_SIZE_NORMAL);
|
this->actor.scale.y = 0.01f;
|
||||||
break;
|
this->actor.scale.z = 0.01f;
|
||||||
case GI_LINK_SIZE_GIANT:
|
} else {
|
||||||
this->actor.scale.x = 0.02f;
|
switch (GameInteractor_GetLinkSize()) {
|
||||||
this->actor.scale.y = 0.02f;
|
case GI_LINK_SIZE_RESET:
|
||||||
this->actor.scale.z = 0.02f;
|
this->actor.scale.x = 0.01f;
|
||||||
break;
|
this->actor.scale.y = 0.01f;
|
||||||
case GI_LINK_SIZE_MINISH:
|
this->actor.scale.z = 0.01f;
|
||||||
this->actor.scale.x = 0.001f;
|
GameInteractor_SetLinkSize(GI_LINK_SIZE_NORMAL);
|
||||||
this->actor.scale.y = 0.001f;
|
break;
|
||||||
this->actor.scale.z = 0.001f;
|
case GI_LINK_SIZE_GIANT:
|
||||||
break;
|
this->actor.scale.x = 0.02f;
|
||||||
case GI_LINK_SIZE_PAPER:
|
this->actor.scale.y = 0.02f;
|
||||||
this->actor.scale.x = 0.001f;
|
this->actor.scale.z = 0.02f;
|
||||||
this->actor.scale.y = 0.01f;
|
break;
|
||||||
this->actor.scale.z = 0.01f;
|
case GI_LINK_SIZE_MINISH:
|
||||||
break;
|
this->actor.scale.x = 0.001f;
|
||||||
case GI_LINK_SIZE_NORMAL:
|
this->actor.scale.y = 0.001f;
|
||||||
default:
|
this->actor.scale.z = 0.001f;
|
||||||
break;
|
break;
|
||||||
|
case GI_LINK_SIZE_PAPER:
|
||||||
|
this->actor.scale.x = 0.001f;
|
||||||
|
this->actor.scale.y = 0.01f;
|
||||||
|
this->actor.scale.z = 0.01f;
|
||||||
|
break;
|
||||||
|
case GI_LINK_SIZE_SQUISHED:
|
||||||
|
this->actor.scale.x = 0.015f;
|
||||||
|
this->actor.scale.y = 0.001f;
|
||||||
|
this->actor.scale.z = 0.015f;
|
||||||
|
break;
|
||||||
|
case GI_LINK_SIZE_NORMAL:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (GameInteractor_GravityLevel()) {
|
// Don't apply gravity when Link is in water, otherwise
|
||||||
case GI_GRAVITY_LEVEL_HEAVY:
|
// it makes him sink instead of float.
|
||||||
this->actor.gravity = -4.0f;
|
if (!(this->stateFlags1 & PLAYER_STATE1_27)) {
|
||||||
break;
|
switch (GameInteractor_GravityLevel()) {
|
||||||
case GI_GRAVITY_LEVEL_LIGHT:
|
case GI_GRAVITY_LEVEL_HEAVY:
|
||||||
this->actor.gravity = -0.3f;
|
this->actor.gravity = -4.0f;
|
||||||
break;
|
break;
|
||||||
default:
|
case GI_GRAVITY_LEVEL_LIGHT:
|
||||||
break;
|
this->actor.gravity = -0.3f;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GameInteractor_GetRandomWindActive()) {
|
||||||
|
Player* player = GET_PLAYER(play);
|
||||||
|
player->windSpeed = 3.0f;
|
||||||
|
// Play fan sound (too annoying)
|
||||||
|
//func_8002F974(&player->actor, NA_SE_EV_WIND_TRAP - SFX_FLAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
GameInteractor_ExecuteOnPlayerUpdate();
|
GameInteractor_ExecuteOnPlayerUpdate();
|
||||||
|
Loading…
Reference in New Issue
Block a user