Skip to content

Commit bf0adbf

Browse files
Merge pull request #1107 from maddie480/finally-fix-999-mayhaps
2 parents 332161f + d0ce85a commit bf0adbf

2 files changed

Lines changed: 54 additions & 9 deletions

File tree

Celeste.Mod.mm/Mod/Entities/DialogCutscene.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections;
33

44
namespace Celeste.Mod.Entities {
5+
[Tracked]
56
public class DialogCutscene : CutsceneEntity {
67

78
private Player player;
@@ -45,5 +46,12 @@ public override void OnEnd(Level level) {
4546
}
4647
}
4748

49+
public static bool IsInProgress(string dialogID) {
50+
foreach (DialogCutscene dialogCutscene in Engine.Scene.Tracker.GetEntities<DialogCutscene>()) {
51+
if (dialogCutscene.dialogID == dialogID) return true;
52+
}
53+
return false;
54+
}
55+
4856
}
4957
}
Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,77 @@
1-
using Microsoft.Xna.Framework;
1+
using Microsoft.Xna.Framework;
2+
using Monocle;
23

34
namespace Celeste.Mod.Entities {
5+
[Tracked]
46
[CustomEntity("everest/dialogTrigger", "dialog/dialogtrigger", "cavern/dialogtrigger")]
57
public class DialogCutsceneTrigger : Trigger {
68

79
private string dialogEntry;
810
private bool triggered;
911
private EntityID id;
10-
private bool onlyOnce;
12+
private bool noRespawnAfterUse;
13+
private bool triggerOnlyOnce;
14+
private bool ignoreIntroState;
1115
private bool endLevel;
1216
private int deathCount;
1317

1418
public DialogCutsceneTrigger(EntityData data, Vector2 offset, EntityID entId)
1519
: base(data, offset) {
1620
dialogEntry = data.Attr("dialogId");
17-
onlyOnce = data.Bool("onlyOnce", true);
21+
noRespawnAfterUse = data.Bool("onlyOnce", true); // don't rename the EntityData name for backwards compat
22+
triggerOnlyOnce = data.Bool("triggerOnlyOnce", true);
23+
ignoreIntroState = data.Bool("ignoreIntroState", false);
1824
endLevel = data.Bool("endLevel", false);
1925
deathCount = data.Int("deathCount", -1);
2026
triggered = false;
2127
id = entId;
2228
}
2329

30+
// do not remove OnEnter! doing so will break maps that rely on third-party triggers to start dialog cutscenes.
31+
// vanilla naturally calls OnEnter and OnStay in the same frame when entering the trigger,
32+
// which would mean that we don't need the OnEnter method.
33+
// however, sj's "in filtration" uses a Trigger Trigger (CrystallineHelper) to start a dialog cutscene;
34+
// it only calls OnEnter and not OnStay, so removing OnEnter will make the dialog not appear and cause a tas desync!
2435
public override void OnEnter(Player player) {
25-
if (triggered || (Scene as Level).Session.GetFlag("DoNotLoad" + id) ||
26-
(deathCount >= 0 && SceneAs<Level>().Session.DeathsInCurrentLevel != deathCount)) {
36+
TriggerCutscene(player);
37+
}
38+
39+
public override void OnStay(Player player) {
40+
TriggerCutscene(player);
41+
}
42+
43+
public override void OnLeave(Player player) {
44+
if (!triggerOnlyOnce)
45+
triggered = false;
46+
}
2747

48+
private void TriggerCutscene(Player player) {
49+
if (Scene is not Level level)
50+
return;
51+
52+
if (triggered)
53+
return;
54+
55+
if (deathCount >= 0 && level.Session.DeathsInCurrentLevel != deathCount)
56+
return;
57+
58+
if (ignoreIntroState && ((patch_Player) player).IsIntroState)
59+
return;
60+
61+
// don't activate if the same dialog is already in progress
62+
if (DialogCutscene.IsInProgress(dialogEntry))
2863
return;
29-
}
3064

3165
triggered = true;
3266

3367
Scene.Add(new DialogCutscene(dialogEntry, player, endLevel));
3468

35-
if (onlyOnce)
36-
(Scene as Level).Session.SetFlag("DoNotLoad" + id, true); // Sets flag to not load
69+
if (noRespawnAfterUse) {
70+
// this flag is unused in vanilla and Everest, but mods may still make use of it,
71+
// so it remains here for backwards compatibility
72+
level.Session.SetFlag("DoNotLoad" + id, true);
73+
level.Session.DoNotLoad.Add(id);
74+
}
3775
}
38-
3976
}
4077
}

0 commit comments

Comments
 (0)