Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 113 additions & 1 deletion OFFHarmonyPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,10 @@ static bool Prefix()
[HarmonyPatch(typeof(FPGAudioManager), "ChangeBGM")]
class MusicPatch
{
static bool Prefix(ScriptedAudioClip sound)
static bool Prefix(ScriptedAudioClip sound, ref bool savePositionOfCurrentlyPlayingTrack)
{
if (OFFMainPlugin.DontSaveBGMProgress.Value)
savePositionOfCurrentlyPlayingTrack = false;
ReplaceSound.Replace(sound, "Music");

// Continue with the rest of the function
Expand Down Expand Up @@ -156,4 +158,114 @@ static bool Prefix(ScriptedAudioClip sound)
return true;
}
}

// Changes speed-change-based tracks back to behaving that way as in the original French version of OFF, and also undo some remake changes
[HarmonyPatch(typeof(FPGCmdPlayMusic), "Activate")]
class PitchShiftPatch_Events
{
static bool Prefix(FPGCmdPlayMusic __instance)
{
if (OFFMainPlugin.QueenPostFightOriginal.Value && __instance.bgmTrack == OFFMusicTracks.Stille)
return false;
if (OFFMainPlugin.RestoreEnochPrefightSlowdown.Value &&
__instance.bgmTrack == OFFMusicTracks.ORostoDeUmAssassinoCansado)
{
__instance.scriptedAudio.pitch = 0.7f;
return true;
}
if (!OFFMainPlugin.RestoreOriginalSpeedChanges.Value)
return true;
float pitch;
(__instance.bgmTrack, pitch) = OFFMainPlugin.ConvertSpeed(__instance.bgmTrack);
if (pitch != 0f)
__instance.scriptedAudio.pitch = pitch;
return true;
}
}

[HarmonyPatch(typeof(FPGGameState), "PlaySystemBGM")]
class PitchShiftPatch_System
{
static bool Prefix(FPGGameState __instance, FPGSystemBGM.SystemBGMType type, bool savePositionOfCurrentlyPlayingTrack)
{
FPGSystemBGM fPGSystemBGM = null;
foreach (FPGAudioOverride audioOverride in __instance.audioOverrides)
{
if (audioOverride.type == type)
{
fPGSystemBGM = new FPGSystemBGM();
fPGSystemBGM.bgmTrack = audioOverride.track;
}
}
if (fPGSystemBGM == null)
{
foreach (FPGSystemBGM systemBGM in FPGOverworldMode.instance.globalDatabase.systemBGMs)
{
if (systemBGM.systemBGMType == type)
{
fPGSystemBGM = systemBGM;
}
}
}
float pitch = 0f;
if (OFFMainPlugin.RestoreOriginalSpeedChanges.Value)
(fPGSystemBGM.bgmTrack, pitch) = OFFMainPlugin.ConvertSpeed(fPGSystemBGM.bgmTrack);
if (pitch != 0f)
fPGSystemBGM.scriptedAudioClip.pitch = pitch;
fPGSystemBGM.scriptedAudioClip.clip = FPGOverworldMode.instance.audioManager.musicMap.GetBGM(fPGSystemBGM.bgmTrack);
FPGOverworldMode.instance.audioManager.ChangeBGM(fPGSystemBGM.scriptedAudioClip, loop: true, savePositionOfCurrentlyPlayingTrack);
return false;
}
}

[HarmonyPatch(typeof(FPGOverworldMode), "StartMusic")]
class PitchShiftPatch_OverworldMode
{
static bool Prefix(FPGOverworldMode __instance, bool isBackFromBattle, OFFMapComponent ___m_mapComp)
{
float pitch = 0f;
OFFMusicTracks track;
if (!__instance.gameState.playerState.isInBoat && isBackFromBattle &&
___m_mapComp.bgmTrackBackFromBattle != (OFFMusicTracks)(-1))
{
if (OFFMainPlugin.RestoreOriginalSpeedChanges.Value)
(track, pitch) = OFFMainPlugin.ConvertSpeed(___m_mapComp.bgmTrackBackFromBattle);
else
track = ___m_mapComp.bgmTrackBackFromBattle;
___m_mapComp.backgroundMusic.clip = __instance.audioManager.musicMap.GetBGM(track);
if (pitch != 0f)
___m_mapComp.backgroundMusic.pitch = pitch;
__instance.audioManager.ChangeBGM(___m_mapComp.backgroundMusic, loop: true);
}
else if (!__instance.gameState.playerState.isInBoat)
{
if (OFFMainPlugin.RestoreOriginalSpeedChanges.Value)
(track, pitch) = OFFMainPlugin.ConvertSpeed(___m_mapComp.bgmTrack);
else
track = ___m_mapComp.bgmTrack;
___m_mapComp.backgroundMusic.clip = __instance.audioManager.musicMap.GetBGM(track);
if (pitch != 0f)
___m_mapComp.backgroundMusic.pitch = pitch;
__instance.audioManager.ChangeBGM(___m_mapComp.backgroundMusic, loop: true);
}
else
{
__instance.gameState.PlaySystemBGM(FPGSystemBGM.SystemBGMType.Boat);
}

return false;
}
}

// boss death animations don't cut out the music
[HarmonyPatch(typeof(BATBattleAnimator), "FadeOutMusic")]
class BossDeathNoPause
{
static bool Prefix(BATBattleAnimator __instance)
{
if (OFFMainPlugin.BossDeathDontStopBGM.Value)
return false;
return true;
}
}
}
63 changes: 63 additions & 0 deletions OFFMainPlugin.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using BepInEx;
using BepInEx.Configuration;
using System.Collections.Generic;
using BepInEx.Logging;
using FangamerRPG;
using HarmonyLib;

namespace OFFRestored;
Expand All @@ -21,6 +23,11 @@ public class OFFMainPlugin : BaseUnityPlugin
public static ConfigEntry<bool> ReplaceMusic;
public static ConfigEntry<bool> DedanLoopFix;
public static ConfigEntry<bool> DisableCreditsLoop;
public static ConfigEntry<bool> RestoreEnochPrefightSlowdown;
public static ConfigEntry<bool> RestoreOriginalSpeedChanges;
public static ConfigEntry<bool> QueenPostFightOriginal;
public static ConfigEntry<bool> BossDeathDontStopBGM;
public static ConfigEntry<bool> DontSaveBGMProgress;

// SFX config
public static ConfigEntry<bool> ReplaceSFX;
Expand Down Expand Up @@ -97,6 +104,41 @@ private void SetConfig()
true,
"If true, The credits music will not loop."
);
// Queen post-fight restoration
QueenPostFightOriginal = Config.Bind(
"Music",
"QueenPostFightOriginal",
true,
"If true, The Woman of Your Dreams (or its counterpart) will be restored in the cutscene after Queen is defeated, instead of playing 50% speed Silence (or its counterpart)."
);
// Enoch pre-fight music slowed down
RestoreEnochPrefightSlowdown = Config.Bind(
"Music",
"RestoreEnochPrefightSlowdown",
true,
"If true, Enoch's battle theme will be slowed down in the prefight cutscene, like in the original game."
);
// bosses don't stop music during their death animations
BossDeathDontStopBGM = Config.Bind(
"Music",
"BossDeathDontStopBGM",
false,
"If true, battle music will not pause during boss defeat animations. This also means Tender Sugar won't restart after winning."
);
// pitch-shifted music behaves like in French version
RestoreOriginalSpeedChanges = Config.Bind(
"Music",
"RestoreOriginalSpeedChanges",
true,
"If true, tracks that were originally just sped-up or slowed-down of other tracks in the original French version will be restored to that form, making them transition as they did originally before the English fan translation."
);
// bgm progress doesn't save
DontSaveBGMProgress = Config.Bind(
"Music",
"DontSaveBGMProgress",
false,
"If true, disables the remake's new feature where overworld music continues from where it left off after battles instead of starting over from the beginning of the track (this doesn't change the behavior when battle music and overworld music are the same)"
);

// Replace SFX
ReplaceSFX = Config.Bind(
Expand All @@ -113,4 +155,25 @@ private void SetConfig()
"If true, removes the sound that plays at the start of an ally's turn in battle."
);
}

public static (OFFMusicTracks, float) ConvertSpeed(OFFMusicTracks track) => track switch
{
OFFMusicTracks.BrainPlagueSlowRewind => (OFFMusicTracks.BrainPlagueRewind, 0.6f),
OFFMusicTracks.TheRaceOfAThousandAntsOhno => (OFFMusicTracks.TheRaceOfAThousandAnts, 0.8f),
OFFMusicTracks.TheRaceofAThousandAntsSafe => (OFFMusicTracks.TheRaceOfAThousandAnts, 0.5f),
OFFMusicTracks.Stille => (OFFMusicTracks.Silence, 0.5f),
OFFMusicTracks.Shhhhhh => (OFFMusicTracks.Silencio, 1.5f),
OFFMusicTracks.TheWallsAreListeningCliff => (OFFMusicTracks.TheWallsAreListening, 0.6f),
OFFMusicTracks.ClockworkLostGripOfTime => (OFFMusicTracks.Clockwork, 0.6f),
OFFMusicTracks.EndlessHallwayStuck => (OFFMusicTracks.EndlessHallway, 0.5f),
OFFMusicTracks.FourteenFakeResidents => (OFFMusicTracks.FourteenResidents, 0.8f),
OFFMusicTracks.FourteenResidentsOFFTitle => (OFFMusicTracks.FourteenResidents, 0.5f),
OFFMusicTracks.BurnedBodiesOut => (OFFMusicTracks.BurnedBodies, 0.8f),
OFFMusicTracks.BurnedBodiesThe => (OFFMusicTracks.BurnedBodies, 0.7f),
OFFMusicTracks.BurnedBodiesChimney => (OFFMusicTracks.BurnedBodies, 0.6f),
OFFMusicTracks.BurnedBodiesSweetTooth => (OFFMusicTracks.BurnedBodies, 0.5f),
OFFMusicTracks.YesterdayWasEvenBetter => (OFFMusicTracks.YesterdayWasBetter, 0.8f),
OFFMusicTracks.TodayIsWorstSweet => (OFFMusicTracks.TodayIsWorst, 0.8f),
_ => (track, 0f)
};
}