mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-22 14:23:44 -07:00
Rework ActorViewer to use hooks
This commit is contained in:
parent
f2298c6a8e
commit
f71aa90c5f
6 changed files with 144 additions and 201 deletions
|
@ -7,6 +7,7 @@
|
||||||
#include "soh/Enhancements/nametag.h"
|
#include "soh/Enhancements/nametag.h"
|
||||||
#include "soh/ShipInit.hpp"
|
#include "soh/ShipInit.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -45,13 +46,6 @@ typedef struct {
|
||||||
Vec3s rot;
|
Vec3s rot;
|
||||||
} ActorInfo;
|
} ActorInfo;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
LIST,
|
|
||||||
TARGET,
|
|
||||||
HELD,
|
|
||||||
INTERACT,
|
|
||||||
} RetrievalMethod;
|
|
||||||
|
|
||||||
std::array<const char*, 12> acMapping = {
|
std::array<const char*, 12> acMapping = {
|
||||||
"Switch", "Background (Prop type 1)",
|
"Switch", "Background (Prop type 1)",
|
||||||
"Player", "Bomb",
|
"Player", "Bomb",
|
||||||
|
@ -873,88 +867,14 @@ void ActorViewer_AddTagForAllActors() {
|
||||||
|
|
||||||
void ActorViewerWindow::DrawElement() {
|
void ActorViewerWindow::DrawElement() {
|
||||||
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
|
||||||
static Actor* display;
|
|
||||||
static Actor empty{};
|
|
||||||
static Actor* fetch = NULL;
|
|
||||||
static ActorInfo newActor = { 0, 0, { 0, 0, 0 }, { 0, 0, 0 } };
|
static ActorInfo newActor = { 0, 0, { 0, 0, 0 }, { 0, 0, 0 } };
|
||||||
static bool needs_reset = false;
|
|
||||||
static ImU16 one = 1;
|
static ImU16 one = 1;
|
||||||
static int actor;
|
|
||||||
static int category = 0;
|
|
||||||
static RetrievalMethod rm;
|
|
||||||
static std::string filler = "Please select";
|
static std::string filler = "Please select";
|
||||||
static std::vector<Actor*> list;
|
|
||||||
static u16 lastSceneId = 0;
|
|
||||||
static std::string searchString = "";
|
static std::string searchString = "";
|
||||||
static s16 currentSelectedInDropdown;
|
static s16 currentSelectedInDropdown = -1;
|
||||||
static std::vector<u16> actors;
|
static std::vector<u16> actorSearchResults;
|
||||||
|
|
||||||
if (gPlayState != nullptr) {
|
if (gPlayState != nullptr) {
|
||||||
needs_reset = lastSceneId != gPlayState->sceneNum;
|
|
||||||
if (needs_reset) {
|
|
||||||
display = ∅
|
|
||||||
fetch = nullptr;
|
|
||||||
actor = category = 0;
|
|
||||||
filler = "Please Select";
|
|
||||||
list.clear();
|
|
||||||
needs_reset = false;
|
|
||||||
searchString = "";
|
|
||||||
currentSelectedInDropdown = -1;
|
|
||||||
actors.clear();
|
|
||||||
}
|
|
||||||
lastSceneId = gPlayState->sceneNum;
|
|
||||||
|
|
||||||
if (ImGui::BeginChild("options", ImVec2(0, 0), ImGuiChildFlags_Border | ImGuiChildFlags_AutoResizeY)) {
|
|
||||||
bool toggled = false;
|
|
||||||
bool optionChange = false;
|
|
||||||
|
|
||||||
ImGui::SeparatorText("Options");
|
|
||||||
|
|
||||||
toggled = UIWidgets::CVarCheckbox("Actor Name Tags", CVAR_ACTOR_NAME_TAGS("Enabled"),
|
|
||||||
{ { .tooltip = "Adds \"name tags\" above actors for identification" } });
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
|
|
||||||
UIWidgets::Button("Display Items", { { .tooltip = "Click to add display items on the name tags" } });
|
|
||||||
|
|
||||||
if (ImGui::BeginPopupContextItem(nullptr, ImGuiPopupFlags_MouseButtonLeft | ImGuiPopupFlags_NoReopen)) {
|
|
||||||
optionChange |= UIWidgets::CVarCheckbox("ID", CVAR_ACTOR_NAME_TAGS("DisplayID"));
|
|
||||||
optionChange |= UIWidgets::CVarCheckbox("Description", CVAR_ACTOR_NAME_TAGS("DisplayDescription"));
|
|
||||||
optionChange |= UIWidgets::CVarCheckbox("Category", CVAR_ACTOR_NAME_TAGS("DisplayCategory"));
|
|
||||||
optionChange |= UIWidgets::CVarCheckbox("Params", CVAR_ACTOR_NAME_TAGS("DisplayParams"));
|
|
||||||
|
|
||||||
ImGui::EndPopup();
|
|
||||||
}
|
|
||||||
|
|
||||||
optionChange |= UIWidgets::CVarCheckbox(
|
|
||||||
"Name tags with Z-Buffer", CVAR_ACTOR_NAME_TAGS("WithZBuffer"),
|
|
||||||
{ { .tooltip = "Allow name tags to be obstructed when behind geometry and actors" } });
|
|
||||||
|
|
||||||
if (toggled || optionChange) {
|
|
||||||
bool tagsEnabled = CVarGetInteger(CVAR_ACTOR_NAME_TAGS("Enabled"), 0);
|
|
||||||
bool noOptionsEnabled = !CVarGetInteger(CVAR_ACTOR_NAME_TAGS("DisplayID"), 0) &&
|
|
||||||
!CVarGetInteger(CVAR_ACTOR_NAME_TAGS("DisplayDescription"), 0) &&
|
|
||||||
!CVarGetInteger(CVAR_ACTOR_NAME_TAGS("DisplayCategory"), 0) &&
|
|
||||||
!CVarGetInteger(CVAR_ACTOR_NAME_TAGS("DisplayParams"), 0);
|
|
||||||
|
|
||||||
// Save the user an extra click and prevent adding "empty" tags by enabling,
|
|
||||||
// disabling, or setting an option based on what changed
|
|
||||||
if (tagsEnabled && noOptionsEnabled) {
|
|
||||||
if (toggled) {
|
|
||||||
CVarSetInteger(CVAR_ACTOR_NAME_TAGS("DisplayID"), 1);
|
|
||||||
} else {
|
|
||||||
CVarSetInteger(CVAR_ACTOR_NAME_TAGS("Enabled"), 0);
|
|
||||||
}
|
|
||||||
} else if (optionChange && !tagsEnabled && !noOptionsEnabled) {
|
|
||||||
CVarSetInteger(CVAR_ACTOR_NAME_TAGS("Enabled"), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
NameTag_RemoveAllByTag(DEBUG_ACTOR_NAMETAG_TAG);
|
|
||||||
ActorViewer_AddTagForAllActors();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndChild();
|
|
||||||
|
|
||||||
PushStyleCombobox(THEME_COLOR);
|
PushStyleCombobox(THEME_COLOR);
|
||||||
if (ImGui::BeginCombo("Actor Type", acMapping[category])) {
|
if (ImGui::BeginCombo("Actor Type", acMapping[category])) {
|
||||||
for (int i = 0; i < acMapping.size(); i++) {
|
for (int i = 0; i < acMapping.size(); i++) {
|
||||||
|
@ -967,21 +887,19 @@ void ActorViewerWindow::DrawElement() {
|
||||||
ImGui::EndCombo();
|
ImGui::EndCombo();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::BeginCombo("Actor", filler.c_str())) {
|
if (display == nullptr) {
|
||||||
if (gPlayState != nullptr && lastSceneId != gPlayState->sceneNum) {
|
filler = "Please select";
|
||||||
PopulateActorDropdown(category, list);
|
|
||||||
lastSceneId = gPlayState->sceneNum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginCombo("Actor", filler.c_str())) {
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
std::string label = std::to_string(i) + ": " + ActorDB::Instance->RetrieveEntry(list[i]->id).name;
|
std::string label = std::to_string(i) + ": " + ActorDB::Instance->RetrieveEntry(list[i]->id).name;
|
||||||
std::string description = GetActorDescription(list[i]->id);
|
std::string description = GetActorDescription(list[i]->id);
|
||||||
if (description != "")
|
if (description != "")
|
||||||
label += " (" + description + ")";
|
label += " (" + description + ")";
|
||||||
|
|
||||||
if (ImGui::Selectable(label.c_str())) {
|
if (ImGui::Selectable(label.c_str(), list[i] == display)) {
|
||||||
rm = LIST;
|
|
||||||
display = list[i];
|
display = list[i];
|
||||||
actor = i;
|
|
||||||
filler = label;
|
filler = label;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -992,6 +910,7 @@ void ActorViewerWindow::DrawElement() {
|
||||||
|
|
||||||
PushStyleHeader(THEME_COLOR);
|
PushStyleHeader(THEME_COLOR);
|
||||||
if (ImGui::TreeNode("Selected Actor")) {
|
if (ImGui::TreeNode("Selected Actor")) {
|
||||||
|
if (display != nullptr) {
|
||||||
DrawGroupWithBorder(
|
DrawGroupWithBorder(
|
||||||
[&]() {
|
[&]() {
|
||||||
ImGui::Text("Name: %s", ActorDB::Instance->RetrieveEntry(display->id).name.c_str());
|
ImGui::Text("Name: %s", ActorDB::Instance->RetrieveEntry(display->id).name.c_str());
|
||||||
|
@ -1054,61 +973,42 @@ void ActorViewerWindow::DrawElement() {
|
||||||
},
|
},
|
||||||
"bgCheckFlags");
|
"bgCheckFlags");
|
||||||
|
|
||||||
if (Button("Refresh", ButtonOptions().Color(THEME_COLOR))) {
|
|
||||||
PopulateActorDropdown(category, list);
|
|
||||||
switch (rm) {
|
|
||||||
case INTERACT:
|
|
||||||
case HELD:
|
|
||||||
case TARGET:
|
|
||||||
display = fetch;
|
|
||||||
break;
|
|
||||||
case LIST:
|
|
||||||
display = list[actor];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Button("Go to Actor", ButtonOptions().Color(THEME_COLOR))) {
|
if (Button("Go to Actor", ButtonOptions().Color(THEME_COLOR))) {
|
||||||
Player* player = GET_PLAYER(gPlayState);
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
Math_Vec3f_Copy(&player->actor.world.pos, &display->world.pos);
|
Math_Vec3f_Copy(&player->actor.world.pos, &display->world.pos);
|
||||||
Math_Vec3f_Copy(&player->actor.home.pos, &player->actor.world.pos);
|
Math_Vec3f_Copy(&player->actor.home.pos, &player->actor.world.pos);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ImGui::Text("Select an actor to display information.");
|
||||||
|
}
|
||||||
|
|
||||||
if (Button("Fetch from Target",
|
if (Button("Fetch from Target",
|
||||||
ButtonOptions()
|
ButtonOptions()
|
||||||
.Color(THEME_COLOR)
|
.Color(THEME_COLOR)
|
||||||
.Tooltip("Grabs actor with target arrow above it. You might need C-Up for enemies"))) {
|
.Tooltip("Grabs actor with target arrow above it. You might need C-Up for enemies"))) {
|
||||||
Player* player = GET_PLAYER(gPlayState);
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
fetch = player->talkActor;
|
if (player->talkActor != NULL) {
|
||||||
if (fetch != NULL) {
|
display = player->talkActor;
|
||||||
display = fetch;
|
category = display->category;
|
||||||
category = fetch->category;
|
|
||||||
PopulateActorDropdown(category, list);
|
PopulateActorDropdown(category, list);
|
||||||
rm = TARGET;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Button("Fetch from Held",
|
if (Button("Fetch from Held",
|
||||||
ButtonOptions().Color(THEME_COLOR).Tooltip("Grabs actor that Link is holding"))) {
|
ButtonOptions().Color(THEME_COLOR).Tooltip("Grabs actor that Link is holding"))) {
|
||||||
Player* player = GET_PLAYER(gPlayState);
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
fetch = player->heldActor;
|
if (player->heldActor != NULL) {
|
||||||
if (fetch != NULL) {
|
display = player->heldActor;
|
||||||
display = fetch;
|
category = display->category;
|
||||||
category = fetch->category;
|
|
||||||
PopulateActorDropdown(category, list);
|
PopulateActorDropdown(category, list);
|
||||||
rm = HELD;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Button("Fetch from Interaction",
|
if (Button("Fetch from Interaction",
|
||||||
ButtonOptions().Color(THEME_COLOR).Tooltip("Grabs actor from \"interaction range\""))) {
|
ButtonOptions().Color(THEME_COLOR).Tooltip("Grabs actor from \"interaction range\""))) {
|
||||||
Player* player = GET_PLAYER(gPlayState);
|
Player* player = GET_PLAYER(gPlayState);
|
||||||
fetch = player->interactRangeActor;
|
if (player->interactRangeActor != NULL) {
|
||||||
if (fetch != NULL) {
|
display = player->interactRangeActor;
|
||||||
display = fetch;
|
category = display->category;
|
||||||
category = fetch->category;
|
|
||||||
PopulateActorDropdown(category, list);
|
PopulateActorDropdown(category, list);
|
||||||
rm = INTERACT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1119,21 +1019,22 @@ void ActorViewerWindow::DrawElement() {
|
||||||
// ImGui::PushItemWidth(ImGui::GetFontSize() * 10);
|
// ImGui::PushItemWidth(ImGui::GetFontSize() * 10);
|
||||||
|
|
||||||
if (InputString("Search Actor", &searchString, InputOptions().Color(THEME_COLOR))) {
|
if (InputString("Search Actor", &searchString, InputOptions().Color(THEME_COLOR))) {
|
||||||
actors = GetActorsWithDescriptionContainingString(searchString);
|
actorSearchResults = GetActorsWithDescriptionContainingString(searchString);
|
||||||
currentSelectedInDropdown = -1;
|
currentSelectedInDropdown = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SohUtils::IsStringEmpty(searchString) && !actors.empty()) {
|
if (!SohUtils::IsStringEmpty(searchString) && !actorSearchResults.empty()) {
|
||||||
std::string preview = currentSelectedInDropdown == -1
|
std::string preview =
|
||||||
|
currentSelectedInDropdown == -1
|
||||||
? "Please Select"
|
? "Please Select"
|
||||||
: ActorDB::Instance->RetrieveEntry(actors[currentSelectedInDropdown]).desc;
|
: ActorDB::Instance->RetrieveEntry(actorSearchResults[currentSelectedInDropdown]).desc;
|
||||||
PushStyleCombobox(THEME_COLOR);
|
PushStyleCombobox(THEME_COLOR);
|
||||||
if (ImGui::BeginCombo("Results", preview.c_str())) {
|
if (ImGui::BeginCombo("Results", preview.c_str())) {
|
||||||
for (u8 i = 0; i < actors.size(); i++) {
|
for (u8 i = 0; i < actorSearchResults.size(); i++) {
|
||||||
if (ImGui::Selectable(ActorDB::Instance->RetrieveEntry(actors[i]).desc.c_str(),
|
if (ImGui::Selectable(ActorDB::Instance->RetrieveEntry(actorSearchResults[i]).desc.c_str(),
|
||||||
i == currentSelectedInDropdown)) {
|
i == currentSelectedInDropdown)) {
|
||||||
currentSelectedInDropdown = i;
|
currentSelectedInDropdown = i;
|
||||||
newActor.id = actors[i];
|
newActor.id = actorSearchResults[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndCombo();
|
ImGui::EndCombo();
|
||||||
|
@ -1237,20 +1138,38 @@ void ActorViewerWindow::DrawElement() {
|
||||||
PopStyleHeader();
|
PopStyleHeader();
|
||||||
} else {
|
} else {
|
||||||
ImGui::Text("Global Context needed for actor info!");
|
ImGui::Text("Global Context needed for actor info!");
|
||||||
if (needs_reset) {
|
|
||||||
fetch = nullptr;
|
|
||||||
actor = category = 0;
|
|
||||||
filler = "Please Select";
|
|
||||||
list.clear();
|
|
||||||
needs_reset = false;
|
|
||||||
searchString = "";
|
|
||||||
currentSelectedInDropdown = -1;
|
|
||||||
actors.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActorViewerWindow::InitElement() {
|
||||||
|
ResetData();
|
||||||
|
|
||||||
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorSpawn>([this](void* refActor) {
|
||||||
|
Actor* actor = static_cast<Actor*>(refActor);
|
||||||
|
|
||||||
|
// Reload actor list if the new actor belongs to the selected category
|
||||||
|
if (category == actor->category) {
|
||||||
|
PopulateActorDropdown(actor->category, list);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorDestroy>([this](void* refActor) {
|
||||||
|
Actor* actor = static_cast<Actor*>(refActor);
|
||||||
|
|
||||||
|
// If the actor belongs to the selected category, we need to manually remove it, as it has not been removed from
|
||||||
|
// the global actor array yet
|
||||||
|
if (category == actor->category) {
|
||||||
|
list.erase(std::remove(list.begin(), list.end(), actor), list.end());
|
||||||
|
}
|
||||||
|
if (display == actor) {
|
||||||
|
display = nullptr;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([this](int16_t sceneNum) { ResetData(); });
|
||||||
|
}
|
||||||
|
|
||||||
void ActorViewer_RegisterNameTagHooks() {
|
void ActorViewer_RegisterNameTagHooks() {
|
||||||
COND_HOOK(OnActorInit, CVAR_ACTOR_NAME_TAGS_ENABLED,
|
COND_HOOK(OnActorInit, CVAR_ACTOR_NAME_TAGS_ENABLED,
|
||||||
[](void* actor) { ActorViewer_AddTagForActor(static_cast<Actor*>(actor)); });
|
[](void* actor) { ActorViewer_AddTagForActor(static_cast<Actor*>(actor)); });
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
#include <libultraship/libultraship.h>
|
#include <libultraship/libultraship.h>
|
||||||
|
|
||||||
|
#include "z64actor.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class ActorViewerWindow final : public Ship::GuiWindow {
|
class ActorViewerWindow final : public Ship::GuiWindow {
|
||||||
public:
|
public:
|
||||||
using GuiWindow::GuiWindow;
|
using GuiWindow::GuiWindow;
|
||||||
|
@ -9,4 +13,11 @@ class ActorViewerWindow final : public Ship::GuiWindow {
|
||||||
void DrawElement() override;
|
void DrawElement() override;
|
||||||
void InitElement() override{};
|
void InitElement() override{};
|
||||||
void UpdateElement() override{};
|
void UpdateElement() override{};
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ResetData();
|
||||||
|
|
||||||
|
Actor* display = nullptr;
|
||||||
|
int category = ACTORCAT_SWITCH;
|
||||||
|
std::vector<Actor*> list;
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,6 +27,7 @@ DEFINE_HOOK(OnOcarinaSongAction, ());
|
||||||
DEFINE_HOOK(OnCuccoOrChickenHatch, ());
|
DEFINE_HOOK(OnCuccoOrChickenHatch, ());
|
||||||
DEFINE_HOOK(OnShopSlotChange, (uint8_t cursorIndex, int16_t price));
|
DEFINE_HOOK(OnShopSlotChange, (uint8_t cursorIndex, int16_t price));
|
||||||
DEFINE_HOOK(OnActorInit, (void* actor));
|
DEFINE_HOOK(OnActorInit, (void* actor));
|
||||||
|
DEFINE_HOOK(OnActorSpawn, (void* actor));
|
||||||
DEFINE_HOOK(OnActorUpdate, (void* actor));
|
DEFINE_HOOK(OnActorUpdate, (void* actor));
|
||||||
DEFINE_HOOK(OnActorKill, (void* actor));
|
DEFINE_HOOK(OnActorKill, (void* actor));
|
||||||
DEFINE_HOOK(OnActorDestroy, (void* actor));
|
DEFINE_HOOK(OnActorDestroy, (void* actor));
|
||||||
|
|
|
@ -108,6 +108,13 @@ void GameInteractor_ExecuteOnActorInit(void* actor) {
|
||||||
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnActorInit>(actor);
|
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnActorInit>(actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameInteractor_ExecuteOnActorSpawn(void* actor) {
|
||||||
|
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnActorSpawn>(actor);
|
||||||
|
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnActorSpawn>(((Actor*)actor)->id, actor);
|
||||||
|
GameInteractor::Instance->ExecuteHooksForPtr<GameInteractor::OnActorSpawn>((uintptr_t)actor, actor);
|
||||||
|
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnActorSpawn>(actor);
|
||||||
|
}
|
||||||
|
|
||||||
void GameInteractor_ExecuteOnActorUpdate(void* actor) {
|
void GameInteractor_ExecuteOnActorUpdate(void* actor) {
|
||||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnActorUpdate>(actor);
|
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnActorUpdate>(actor);
|
||||||
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnActorUpdate>(((Actor*)actor)->id, actor);
|
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnActorUpdate>(((Actor*)actor)->id, actor);
|
||||||
|
|
|
@ -29,6 +29,7 @@ void GameInteractor_ExecuteOnSetDoAction(uint16_t action);
|
||||||
void GameInteractor_ExecuteOnOcarinaSongAction();
|
void GameInteractor_ExecuteOnOcarinaSongAction();
|
||||||
void GameInteractor_ExecuteOnCuccoOrChickenHatch();
|
void GameInteractor_ExecuteOnCuccoOrChickenHatch();
|
||||||
void GameInteractor_ExecuteOnActorInit(void* actor);
|
void GameInteractor_ExecuteOnActorInit(void* actor);
|
||||||
|
void GameInteractor_ExecuteOnActorSpawn(void* actor);
|
||||||
void GameInteractor_ExecuteOnActorUpdate(void* actor);
|
void GameInteractor_ExecuteOnActorUpdate(void* actor);
|
||||||
void GameInteractor_ExecuteOnActorKill(void* actor);
|
void GameInteractor_ExecuteOnActorKill(void* actor);
|
||||||
void GameInteractor_ExecuteOnActorDestroy(void* actor);
|
void GameInteractor_ExecuteOnActorDestroy(void* actor);
|
||||||
|
|
|
@ -3401,6 +3401,8 @@ Actor* Actor_Spawn(ActorContext* actorCtx, PlayState* play, s16 actorId, f32 pos
|
||||||
Actor_Init(actor, play);
|
Actor_Init(actor, play);
|
||||||
gSegments[6] = temp;
|
gSegments[6] = temp;
|
||||||
|
|
||||||
|
GameInteractor_ExecuteOnActorSpawn(actor);
|
||||||
|
|
||||||
return actor;
|
return actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3474,6 +3476,8 @@ Actor* Actor_Delete(ActorContext* actorCtx, Actor* actor, PlayState* play) {
|
||||||
Actor* newHead;
|
Actor* newHead;
|
||||||
ActorDBEntry* dbEntry;
|
ActorDBEntry* dbEntry;
|
||||||
|
|
||||||
|
GameInteractor_ExecuteOnActorDelete(actor);
|
||||||
|
|
||||||
player = GET_PLAYER(play);
|
player = GET_PLAYER(play);
|
||||||
|
|
||||||
// Execute before actor memory is freed
|
// Execute before actor memory is freed
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue