ShadowTag (7.0.1) (#2825)

* Add Checkbox in Extra Modes
Spawn Code in mods.cpp
Category Change for Clear Room Exclusion
Kill Actor if Mode is Disabled

* Fix non door scene changes and adds a delay to avoid misfiring or not firing on quick room changes like falling to B1 in Tree and Lost Woods loading triggers.

* Requested Updates
This commit is contained in:
Caladius 2023-05-28 18:46:18 -04:00 committed by GitHub
parent 3ab547c69d
commit edc5e8f7d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 6 deletions

View File

@ -336,6 +336,31 @@ void RegisterRupeeDash() {
});
}
void RegisterShadowTag() {
static bool shouldSpawn = false;
static uint16_t delayTimer = 60;
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerUpdate>([]() {
if (!CVarGetInteger("gShadowTag", 0)) {
return;
}
if (shouldSpawn && (delayTimer <= 0)) {
Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_WALLMAS, 0, 0, 0, 0, 0, 0, 3, false);
shouldSpawn = false;
} else {
delayTimer--;
}
});
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneSpawnActors>([]() {
shouldSpawn = true;
delayTimer = 60;
});
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) {
shouldSpawn = true;
delayTimer = 60;
});
}
struct DayTimeGoldSkulltulas {
uint16_t scene;
uint16_t room;
@ -533,6 +558,7 @@ void InitMods() {
RegisterAutoSave();
RegisterDaytimeGoldSkultullas();
RegisterRupeeDash();
RegisterShadowTag();
RegisterHyperBosses();
RegisterHyperEnemies();
RegisterBonkDamage();

View File

@ -981,6 +981,14 @@ namespace GameMenuBar {
UIWidgets::Tooltip("Interval between Rupee reduction in Rupee Dash Mode");
}
UIWidgets::Spacer(0);
UIWidgets::PaddedEnhancementCheckbox("Shadow Tag Mode", "gShadowTag", true, false);
if (CVarGetInteger("gShadowTag", 0)) {
UIWidgets::Tooltip("A wallmaster follows Link everywhere, don't get caught!");
}
ImGui::EndMenu();
}

View File

@ -130,6 +130,10 @@ void EnWallmas_Init(Actor* thisx, PlayState* play) {
this->switchFlag = (u8)(thisx->params >> 0x8);
thisx->params = thisx->params & 0xFF;
if (this->actor.params == WMT_SHADOWTAG) {
Actor_ChangeCategory(play, &play->actorCtx, this, ACTORCAT_NPC);
}
if (thisx->params == WMT_FLAG) {
if (Flags_GetSwitch(play, this->switchFlag) != 0) {
Actor_Kill(thisx);
@ -273,7 +277,7 @@ void EnWallmas_ProximityOrSwitchInit(EnWallmas* this) {
this->timer = 0;
this->actor.draw = NULL;
this->actor.flags &= ~ACTOR_FLAG_0;
if (this->actor.params == WMT_PROXIMITY) {
if (this->actor.params == WMT_PROXIMITY || this->actor.params == WMT_SHADOWTAG) {
this->actionFunc = EnWallmas_WaitForProximity;
} else {
this->actionFunc = EnWallmas_WaitForSwitchFlag;
@ -307,7 +311,12 @@ void EnWallmas_WaitToDrop(EnWallmas* this, PlayState* play) {
this->timer--;
}
if ((player->stateFlags1 & 0x100000) || (player->stateFlags1 & 0x8000000) || !(player->actor.bgCheckFlags & 1) ||
if (this->actor.params == WMT_SHADOWTAG) {
if ((player->stateFlags1 & 0x100000) || (player->stateFlags1 & 0x8000000) || !(player->actor.bgCheckFlags & 1)) {
Audio_StopSfxById(NA_SE_EN_FALL_AIM);
this->timer = 0x82;
}
} else if ((player->stateFlags1 & 0x100000) || (player->stateFlags1 & 0x8000000) || !(player->actor.bgCheckFlags & 1) ||
((this->actor.params == 1) && (320.0f < Math_Vec3f_DistXZ(&this->actor.home.pos, playerPos)))) {
Audio_StopSfxById(NA_SE_EN_FALL_AIM);
this->timer = 0x82;
@ -390,6 +399,11 @@ void EnWallmas_ReturnToCeiling(EnWallmas* this, PlayState* play) {
EnWallmas_ProximityOrSwitchInit(this);
}
}
if (this->actor.params == WMT_SHADOWTAG) {
if (!CVarGetInteger("gShadowTag", 0)) {
Actor_Kill(&this->actor);
}
}
}
void EnWallmas_TakeDamage(EnWallmas* this, PlayState* play) {
@ -419,6 +433,13 @@ void EnWallmas_Die(EnWallmas* this, PlayState* play) {
Item_DropCollectibleRandom(play, &this->actor, &this->actor.world.pos, 0xC0);
Actor_Kill(&this->actor);
}
if (this->actor.params == WMT_SHADOWTAG) {
if (!CVarGetInteger("gShadowTag", 0)) {
Actor_Kill(&this->actor);
} else {
EnWallmas_Init(this, play);
}
}
this->actor.scale.z = this->actor.scale.x;
this->actor.scale.y = this->actor.scale.x;
}
@ -478,7 +499,8 @@ void EnWallmas_TakePlayer(EnWallmas* this, PlayState* play) {
void EnWallmas_WaitForProximity(EnWallmas* this, PlayState* play) {
Player* player = GET_PLAYER(play);
if (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < 200.0f) {
if (this->actor.params == WMT_SHADOWTAG ||
Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < 200.0f) {
EnWallmas_TimerInit(this, play);
}
}

View File

@ -7,7 +7,8 @@
typedef enum {
/* 0x00 */ WMT_TIMER,
/* 0x01 */ WMT_PROXIMITY,
/* 0x02 */ WMT_FLAG
/* 0x02 */ WMT_FLAG,
/* 0x03 */ WMT_SHADOWTAG
} WallmasType;
struct EnWallmas;