mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-06-05 03:17:34 -04:00
Fix Crowd Control Wolfos despawning when scene switch 0 is set (#6591)
Crowd Control passed actor params 0 for EN_WF, so EnWf_Init treated switchFlag 0 and killed the actor when scene switch 0 was set. Match vanilla EnEncount1 Wolfos spawns: (0xFF << 8) | 0x00 Also prevent crowd control effects from triggering when link is not in controllable state
This commit is contained in:
@@ -259,9 +259,12 @@ void ElectrocutePlayer::_Apply() {
|
||||
|
||||
// MARK: - KnockbackPlayer
|
||||
GameInteractionEffectQueryResult KnockbackPlayer::CanBeApplied() {
|
||||
if (!GameInteractor::IsPlayerInControl()) {
|
||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||
}
|
||||
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
if (!GameInteractor::IsSaveLoaded(true) || GameInteractor::IsGameplayPaused() ||
|
||||
player->stateFlags2 & PLAYER_STATE2_CRAWLING) {
|
||||
if (player->stateFlags2 & PLAYER_STATE2_CRAWLING) {
|
||||
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
|
||||
} else {
|
||||
return GameInteractionEffectQueryResult::Possible;
|
||||
|
||||
@@ -51,15 +51,49 @@ bool GameInteractor::IsSaveLoaded(bool allowDbgSave) {
|
||||
}
|
||||
|
||||
bool GameInteractor::IsGameplayPaused() {
|
||||
if (gPlayState == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
if (player == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (Player_InBlockingCsMode(gPlayState, player) || gPlayState->pauseCtx.state != 0 ||
|
||||
gPlayState->msgCtx.msgMode != 0)
|
||||
? true
|
||||
: false;
|
||||
}
|
||||
|
||||
bool GameInteractor::IsPlayerInControl() {
|
||||
if (gPlayState == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
if (player == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gSaveContext.gameMode != GAMEMODE_NORMAL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!((gSaveContext.fileNum >= 0 && gSaveContext.fileNum <= 2) || gSaveContext.fileNum == 0xFF)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Player_InBlockingCsMode(gPlayState, player) || gPlayState->pauseCtx.state != 0 ||
|
||||
gPlayState->msgCtx.msgMode != 0 || player->unk_6AD == 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GameInteractor::CanSpawnActor() {
|
||||
return GameInteractor::IsSaveLoaded() && !GameInteractor::IsGameplayPaused();
|
||||
return GameInteractor::IsPlayerInControl();
|
||||
}
|
||||
|
||||
bool GameInteractor::CanAddOrTakeAmmo(int16_t amount, int16_t item) {
|
||||
|
||||
@@ -530,6 +530,7 @@ class GameInteractor {
|
||||
// Helpers
|
||||
static bool IsSaveLoaded(bool allowDbgSave = false);
|
||||
static bool IsGameplayPaused();
|
||||
static bool IsPlayerInControl();
|
||||
static bool CanSpawnActor();
|
||||
static bool CanAddOrTakeAmmo(int16_t amount, int16_t item);
|
||||
|
||||
|
||||
@@ -132,6 +132,10 @@ void CrowdControl::EmitMessage(uint32_t eventId, long timeRemaining, EffectResul
|
||||
}
|
||||
|
||||
CrowdControl::EffectResult CrowdControl::ExecuteEffect(Effect* effect) {
|
||||
if (!GameInteractor::IsPlayerInControl()) {
|
||||
return EffectResult::Retry;
|
||||
}
|
||||
|
||||
GameInteractionEffectQueryResult giResult;
|
||||
if (effect->category == kEffectCatSpawnEnemy) {
|
||||
giResult = GameInteractor::RawAction::SpawnEnemyWithOffset(effect->spawnParams[0], effect->spawnParams[1],
|
||||
@@ -149,6 +153,10 @@ CrowdControl::EffectResult CrowdControl::ExecuteEffect(Effect* effect) {
|
||||
/// Checks if effect can be applied -- should not be used to check for spawn enemy effects.
|
||||
CrowdControl::EffectResult CrowdControl::CanApplyEffect(Effect* effect) {
|
||||
assert(effect->category != kEffectCatSpawnEnemy || effect->category != kEffectCatSpawnActor);
|
||||
if (!GameInteractor::IsPlayerInControl()) {
|
||||
return EffectResult::Retry;
|
||||
}
|
||||
|
||||
GameInteractionEffectQueryResult giResult = GameInteractor::CanApplyEffect(*effect->giEffect.get());
|
||||
|
||||
return TranslateGiEnum(giResult);
|
||||
@@ -268,6 +276,9 @@ CrowdControl::Effect* CrowdControl::ParseMessage(nlohmann::json dataReceived) {
|
||||
break;
|
||||
case kEffectSpawnWolfos:
|
||||
effect->spawnParams[0] = ACTOR_EN_WF;
|
||||
// Match EnEncount1 wolfos spawner (0xFF00): high byte must be 0xFF so EnWf_Init does not treat
|
||||
// switchFlag 0; Flags_GetSwitch(play, 0) is true in many scenes and would instantly kill the actor.
|
||||
effect->spawnParams[1] = (0xFF << 8) | 0x00; // normal Wolfos; high byte 0xFF = no switch (vanilla encount)
|
||||
effect->category = kEffectCatSpawnEnemy;
|
||||
break;
|
||||
case kEffectSpawnWallmaster:
|
||||
|
||||
Reference in New Issue
Block a user