Skip to content

Commit 4aab062

Browse files
authored
Merge pull request #164 from EverestAPI/restore_light_sources_trigger
Remove Light Sources Trigger: Add option to re-enable light sources
2 parents 99332cd + 28a4b14 commit 4aab062

File tree

4 files changed

+100
-92
lines changed

4 files changed

+100
-92
lines changed

Ahorn/lang/en_gb.lang

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,6 @@ placements.triggers.SpringCollab2020/StrawberryCollectionField.tooltips.includeG
244244
# Negative Summit Checkpoint
245245
placements.entities.SpringCollab2020/NegativeSummitCheckpoint.tooltips.number=Changes the number on the checkpoint card. (Between -9 and 99 inclusive.)
246246

247+
# Remove Light Sources Trigger
248+
placements.triggers.SpringCollab2020/RemoveLightSourcesTrigger.tooltips.enableLightSources=If checked, this trigger will re-enable light sources instead of disabling them.
249+
placements.triggers.SpringCollab2020/RemoveLightSourcesTrigger.tooltips.fade=If checked, the lights will fade in or out.

Ahorn/triggers/removeLightSourcesTrigger.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
using ..Ahorn, Maple
44

5-
@mapdef Trigger "SpringCollab2020/RemoveLightSourcesTrigger" RemoveLightSourcesTrigger(x::Integer, y::Integer, width::Integer=Maple.defaultTriggerWidth, height::Integer=Maple.defaultTriggerHeight)
5+
@mapdef Trigger "SpringCollab2020/RemoveLightSourcesTrigger" RemoveLightSourcesTrigger(x::Integer, y::Integer, width::Integer=Maple.defaultTriggerWidth, height::Integer=Maple.defaultTriggerHeight,
6+
enableLightSources::Bool=false, fade::Bool=false)
67

78
const placements = Ahorn.PlacementDict(
89
"Remove Light Sources (Spring Collab 2020)" => Ahorn.EntityPlacement(

SpringCollab2020Session.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,7 @@ public class MultiRoomStrawberrySeedInfo {
1515
public List<MultiRoomStrawberrySeedInfo> CollectedMultiRoomStrawberrySeeds { get; set; } = new List<MultiRoomStrawberrySeedInfo>();
1616

1717
public bool MadelineIsSilhouette { get; set; } = false;
18+
19+
public bool LightSourcesDisabled { get; set; } = false;
1820
}
1921
}

Triggers/RemoveLightSourcesTrigger.cs

Lines changed: 93 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,117 @@
11
using Celeste.Mod.Entities;
22
using Monocle;
33
using Microsoft.Xna.Framework;
4-
using System.Reflection;
5-
4+
using System.Collections.Generic;
5+
using System;
6+
67
namespace Celeste.Mod.SpringCollab2020.Triggers {
78
[CustomEntity("SpringCollab2020/RemoveLightSourcesTrigger")]
89
[Tracked]
9-
class RemoveLightSourcesTrigger : Trigger {
10-
11-
private static FieldInfo LightsField;
12-
13-
private static FieldInfo BloomField;
14-
15-
private static FieldInfo LightField;
16-
17-
private static bool HooksEnabled = false;
18-
19-
public RemoveLightSourcesTrigger(EntityData data, Vector2 offset) : base(data, offset) { }
10+
class RemoveLightSourcesTrigger : Trigger {
11+
12+
private static float alphaFade = 1f;
2013

2114
public static void Load() {
22-
Everest.Events.Level.OnLoadLevel += LevelLoadHandler;
23-
Everest.Events.Level.OnExit += OnExitHandler;
24-
25-
LightsField = typeof(LightingRenderer).GetField("lights", BindingFlags.NonPublic | BindingFlags.Instance);
26-
BloomField = typeof(Payphone).GetField("bloom", BindingFlags.NonPublic | BindingFlags.Instance);
27-
LightField = typeof(Payphone).GetField("light", BindingFlags.NonPublic | BindingFlags.Instance);
28-
}
29-
15+
On.Celeste.LightingRenderer.BeforeRender += LightHook;
16+
On.Celeste.BloomRenderer.Apply += BloomRendererHook;
17+
On.Celeste.Level.LoadLevel += OnLoadLevel;
18+
On.Celeste.Level.Update += OnLevelUpdate;
19+
}
20+
3021
public static void Unload() {
31-
Everest.Events.Level.OnLoadLevel -= LevelLoadHandler;
32-
Everest.Events.Level.OnExit -= OnExitHandler;
33-
}
34-
35-
private static void PayphoneHook(On.Celeste.Payphone.orig_Update orig, Payphone self) {
36-
orig(self);
37-
38-
VertexLight tempLight = (VertexLight) LightField.GetValue(self);
39-
BloomPoint tempBloom = (BloomPoint) BloomField.GetValue(self);
40-
tempBloom.Visible = tempLight.Visible = !tempLight.Visible;
41-
42-
BloomField.SetValue(self, tempBloom);
43-
LightField.SetValue(self, tempLight);
44-
}
45-
46-
private static void LevelLoadHandler(Level loadedLevel, Player.IntroTypes playerIntro, bool isFromLoader) {
47-
if (loadedLevel.Session.GetFlag("lightsDisabled"))
48-
DisableLightRender();
49-
else
50-
EnableLightRender();
51-
}
52-
53-
private static void OnExitHandler(Level exitLevel, LevelExit exit, LevelExit.Mode mode, Session session, HiresSnow snow) {
54-
EnableLightRender();
22+
On.Celeste.LightingRenderer.BeforeRender -= LightHook;
23+
On.Celeste.BloomRenderer.Apply -= BloomRendererHook;
24+
On.Celeste.Level.LoadLevel -= OnLoadLevel;
25+
On.Celeste.Level.Update -= OnLevelUpdate;
26+
}
27+
28+
private static void OnLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) {
29+
orig(self, playerIntro, isFromLoader);
30+
31+
if (playerIntro != Player.IntroTypes.Transition) {
32+
// do not fade and set the alpha right away when spawning into the level.
33+
alphaFade = SpringCollab2020Module.Instance.Session.LightSourcesDisabled ? 0f : 1f;
34+
}
35+
}
36+
37+
private static void OnLevelUpdate(On.Celeste.Level.orig_Update orig, Level self) {
38+
orig(self);
39+
40+
if (!self.Paused) {
41+
// progressively fade in or out.
42+
alphaFade = Calc.Approach(alphaFade, SpringCollab2020Module.Instance.Session.LightSourcesDisabled ? 0f : 1f, Engine.DeltaTime * 3f);
43+
}
5544
}
5645

5746
private static void BloomRendererHook(On.Celeste.BloomRenderer.orig_Apply orig, BloomRenderer self, VirtualRenderTarget target, Scene scene) {
58-
foreach (BloomPoint component in scene.Tracker.GetComponents<BloomPoint>().ToArray()) {
59-
if (!(component.Entity is Payphone))
60-
component.Visible = false;
47+
if (alphaFade < 1f) {
48+
// multiply all alphas by alphaFade, and back up original values.
49+
List<BloomPoint> affectedBloomPoints = new List<BloomPoint>();
50+
List<float> originalAlpha = new List<float>();
51+
foreach (BloomPoint bloomPoint in scene.Tracker.GetComponents<BloomPoint>().ToArray()) {
52+
if (bloomPoint.Visible && !(bloomPoint.Entity is Payphone)) {
53+
affectedBloomPoints.Add(bloomPoint);
54+
originalAlpha.Add(bloomPoint.Alpha);
55+
bloomPoint.Alpha *= alphaFade;
56+
}
57+
}
58+
59+
// render the bloom.
60+
orig(self, target, scene);
61+
62+
// restore original alphas.
63+
int index = 0;
64+
foreach (BloomPoint bloomPoint in affectedBloomPoints) {
65+
bloomPoint.Alpha = originalAlpha[index++];
66+
}
67+
} else {
68+
// alpha multiplier is 1: nothing to modify, go on with vanilla.
69+
orig(self, target, scene);
6170
}
62-
63-
orig(self, target, scene);
6471
}
6572

6673
private static void LightHook(On.Celeste.LightingRenderer.orig_BeforeRender orig, LightingRenderer self, Scene scene) {
67-
foreach (VertexLight component in scene.Tracker.GetComponents<VertexLight>().ToArray()) {
68-
if (!component.Spotlight)
69-
component.RemoveSelf();
74+
if (alphaFade < 1f) {
75+
// multiply all alphas by alphaFade, and back up original values.
76+
List<VertexLight> affectedVertexLights = new List<VertexLight>();
77+
List<float> originalAlpha = new List<float>();
78+
foreach (VertexLight vertexLight in scene.Tracker.GetComponents<VertexLight>().ToArray()) {
79+
if (vertexLight.Visible && !vertexLight.Spotlight) {
80+
affectedVertexLights.Add(vertexLight);
81+
originalAlpha.Add(vertexLight.Alpha);
82+
vertexLight.Alpha *= alphaFade;
83+
}
84+
}
85+
86+
// render the lighting.
87+
orig(self, scene);
88+
89+
// restore original alphas.
90+
int index = 0;
91+
foreach (VertexLight vertexLight in affectedVertexLights) {
92+
vertexLight.Alpha = originalAlpha[index++];
93+
}
94+
} else {
95+
// alpha multiplier is 1: nothing to modify, go on with vanilla.
96+
orig(self, scene);
7097
}
71-
72-
LightsField.SetValue(self, new VertexLight[64]);
73-
orig(self, scene);
74-
}
75-
76-
private static void TransitionHook(On.Celeste.Level.orig_TransitionTo orig, Level transitionLevel, LevelData next, Vector2 direction) {
77-
transitionLevel.Tracker.GetComponents<VertexLight>().ForEach(light => {
78-
if (!((VertexLight)light).Spotlight)
79-
light.RemoveSelf();
80-
});
81-
82-
orig(transitionLevel, next, direction);
83-
}
84-
85-
private static void EnableLightRender() {
86-
if (!HooksEnabled)
87-
return;
88-
89-
On.Celeste.LightingRenderer.BeforeRender -= LightHook;
90-
On.Celeste.BloomRenderer.Apply -= BloomRendererHook;
91-
On.Celeste.Level.TransitionTo -= TransitionHook;
92-
On.Celeste.Payphone.Update -= PayphoneHook;
93-
HooksEnabled = false;
94-
}
95-
96-
private static void DisableLightRender() {
97-
if (HooksEnabled)
98-
return;
99-
100-
On.Celeste.LightingRenderer.BeforeRender += LightHook;
101-
On.Celeste.BloomRenderer.Apply += BloomRendererHook;
102-
On.Celeste.Level.TransitionTo += TransitionHook;
103-
On.Celeste.Payphone.Update += PayphoneHook;
104-
HooksEnabled = true;
98+
}
99+
100+
private bool enableLightSources;
101+
private bool fade;
102+
103+
public RemoveLightSourcesTrigger(EntityData data, Vector2 offset) : base(data, offset) {
104+
enableLightSources = data.Bool("enableLightSources", false);
105+
fade = data.Bool("fade", false);
105106
}
106107

107108
public override void OnEnter(Player player) {
108109
base.OnEnter(player);
109-
110-
if (SceneAs<Level>().Session.GetFlag("lightsDisabled") == false) {
111-
SceneAs<Level>().Session.SetFlag("lightsDisabled", true);
112-
DisableLightRender();
110+
SpringCollab2020Module.Instance.Session.LightSourcesDisabled = !enableLightSources;
111+
112+
if (!fade) {
113+
// don't fade; set the fade to its final value right away.
114+
alphaFade = SpringCollab2020Module.Instance.Session.LightSourcesDisabled ? 0f : 1f;
113115
}
114116
}
115117
}

0 commit comments

Comments
 (0)