Skip to content

Commit 2c43b12

Browse files
committed
Reapply "Merge pull request #999 from SnipUndercover/dialog-cutscene-changes"
This reverts commit 62ef4d0.
1 parent 62ef4d0 commit 2c43b12

1 file changed

Lines changed: 46 additions & 9 deletions

File tree

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 some dialog is already in progress
62+
if (level.Tracker.GetEntity<Textbox>() is not null)
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)