Skip to content

Commit 16a0d4f

Browse files
committed
Added graphics to Move Block Barriers
1 parent ba2de3f commit 16a0d4f

File tree

4 files changed

+273
-2
lines changed

4 files changed

+273
-2
lines changed

Ahorn/entities/moveBlockBarrier.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ function Ahorn.render(ctx::Ahorn.Cairo.CairoContext, entity::MoveBlockBarrier, r
2727
width = Int(get(entity.data, "width", 32))
2828
height = Int(get(entity.data, "height", 32))
2929

30-
# Slightly darker than seeker barriers, design unfinalized
31-
Ahorn.drawRectangle(ctx, 0, 0, width, height, (0.45, 0.45, 0.45, 0.8), (0.0, 0.0, 0.0, 0.0))
30+
Ahorn.drawRectangle(ctx, 0, 0, width, height, (0.45, 0.0, 0.45, 0.8), (0.0, 0.0, 0.0, 0.0))
3231
end
3332

3433
end

Entities/MoveBlockBarrier.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System;
2+
using System.Collections.Generic;
3+
using System.Reflection;
24
using Celeste.Mod.Entities;
35
using Microsoft.Xna.Framework;
46
using Monocle;
@@ -7,9 +9,34 @@ namespace Celeste.Mod.SpringCollab2020.Entities {
79
[CustomEntity("SpringCollab2020/moveBlockBarrier")]
810
[Tracked(false)]
911
public class MoveBlockBarrier : SeekerBarrier {
12+
13+
private static FieldInfo particlesInfo = typeof(SeekerBarrier).GetField("particles", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic);
14+
1015
public MoveBlockBarrier(EntityData data, Vector2 offset) : base(data, offset) {
1116
}
1217

18+
public override void Added(Scene scene) {
19+
base.Added(scene);
20+
scene.Tracker.GetEntity<SeekerBarrierRenderer>().Untrack(this);
21+
scene.Tracker.GetEntity<MoveBlockBarrierRenderer>().Track(this);
22+
}
23+
24+
public override void Removed(Scene scene) {
25+
base.Removed(scene);
26+
scene.Tracker.GetEntity<MoveBlockBarrierRenderer>().Untrack(this);
27+
}
28+
29+
public override void Render() {
30+
List<Vector2> particles = (List<Vector2>) particlesInfo.GetValue(this);
31+
Color color = Color.Pink * 0.5f;
32+
foreach (Vector2 particle in particles) {
33+
Draw.Pixel.Draw(Position + particle, Vector2.Zero, color);
34+
}
35+
if (Flashing) {
36+
Draw.Rect(base.Collider, Color.Pink * Flash * 0.5f);
37+
}
38+
}
39+
1340
public static void Load() {
1441
On.Celeste.MoveBlock.MoveCheck += MoveBlock_MoveCheck;
1542
On.Celeste.Platform.MoveHCollideSolids += Platform_MoveHCollideSolids;
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
using Microsoft.Xna.Framework;
2+
using Monocle;
3+
using System;
4+
using System.Collections.Generic;
5+
6+
namespace Celeste.Mod.SpringCollab2020.Entities {
7+
[Tracked(false)]
8+
public class MoveBlockBarrierRenderer : Entity {
9+
private class Edge {
10+
public MoveBlockBarrier Parent;
11+
12+
public bool Visible;
13+
14+
public Vector2 A;
15+
16+
public Vector2 B;
17+
18+
public Vector2 Min;
19+
20+
public Vector2 Max;
21+
22+
public Vector2 Normal;
23+
24+
public Vector2 Perpendicular;
25+
26+
public float[] Wave;
27+
28+
public float Length;
29+
30+
public Edge(MoveBlockBarrier parent, Vector2 a, Vector2 b) {
31+
Parent = parent;
32+
Visible = true;
33+
A = a;
34+
B = b;
35+
Min = new Vector2(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y));
36+
Max = new Vector2(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y));
37+
Normal = (b - a).SafeNormalize();
38+
Perpendicular = -Normal.Perpendicular();
39+
Length = (a - b).Length();
40+
}
41+
42+
public void UpdateWave(float time) {
43+
if (Wave == null || Wave.Length <= Length) {
44+
Wave = new float[(int) Length + 2];
45+
}
46+
for (int i = 0; i <= Length; i++) {
47+
Wave[i] = GetWaveAt(time, i, Length);
48+
}
49+
}
50+
51+
private float GetWaveAt(float offset, float along, float length) {
52+
if (along <= 1f || along >= length - 1f) {
53+
return 0f;
54+
}
55+
if (Parent.Solidify >= 1f) {
56+
return 0f;
57+
}
58+
float num = offset + along * 0.25f;
59+
float num2 = (float) (Math.Sin(num) * 2.0 + Math.Sin(num * 0.25f));
60+
return (1f + num2 * Ease.SineInOut(Calc.YoYo(along / length))) * (1f - Parent.Solidify);
61+
}
62+
63+
public bool InView(ref Rectangle view) {
64+
if (view.Left < Parent.X + Max.X && view.Right > Parent.X + Min.X && view.Top < Parent.Y + Max.Y) {
65+
return view.Bottom > Parent.Y + Min.Y;
66+
}
67+
return false;
68+
}
69+
}
70+
71+
private List<MoveBlockBarrier> list = new List<MoveBlockBarrier>();
72+
73+
private List<Edge> edges = new List<Edge>();
74+
75+
private VirtualMap<bool> tiles;
76+
77+
private Rectangle levelTileBounds;
78+
79+
private bool dirty;
80+
81+
public MoveBlockBarrierRenderer() {
82+
Tag = (Tags.Global | Tags.TransitionUpdate);
83+
Depth = 0;
84+
Add(new CustomBloom(OnRenderBloom));
85+
}
86+
87+
public static void Load() {
88+
On.Celeste.LevelLoader.LoadingThread += LevelLoader_LoadingThread;
89+
}
90+
91+
public static void Unload() {
92+
On.Celeste.LevelLoader.LoadingThread -= LevelLoader_LoadingThread;
93+
}
94+
95+
static void LevelLoader_LoadingThread(On.Celeste.LevelLoader.orig_LoadingThread orig, LevelLoader self) {
96+
self.Level.Add(new MoveBlockBarrierRenderer());
97+
orig(self);
98+
}
99+
100+
101+
public void Track(MoveBlockBarrier block) {
102+
list.Add(block);
103+
if (tiles == null) {
104+
levelTileBounds = (Scene as Level).TileBounds;
105+
tiles = new VirtualMap<bool>(levelTileBounds.Width, levelTileBounds.Height, emptyValue: false);
106+
}
107+
for (int i = (int) block.X / 8; i < block.Right / 8f; i++) {
108+
for (int j = (int) block.Y / 8; j < block.Bottom / 8f; j++) {
109+
tiles[i - levelTileBounds.X, j - levelTileBounds.Y] = true;
110+
}
111+
}
112+
dirty = true;
113+
}
114+
115+
public void Untrack(MoveBlockBarrier block) {
116+
list.Remove(block);
117+
if (list.Count <= 0) {
118+
tiles = null;
119+
} else {
120+
for (int i = (int) block.X / 8; i < block.Right / 8f; i++) {
121+
for (int j = (int) block.Y / 8; j < block.Bottom / 8f; j++) {
122+
tiles[i - levelTileBounds.X, j - levelTileBounds.Y] = false;
123+
}
124+
}
125+
}
126+
dirty = true;
127+
}
128+
129+
public override void Update() {
130+
if (dirty) {
131+
RebuildEdges();
132+
}
133+
UpdateEdges();
134+
}
135+
136+
public void UpdateEdges() {
137+
Camera camera = (Scene as Level).Camera;
138+
Rectangle view = new Rectangle((int) camera.Left - 4, (int) camera.Top - 4, (int) (camera.Right - camera.Left) + 8, (int) (camera.Bottom - camera.Top) + 8);
139+
for (int i = 0; i < edges.Count; i++) {
140+
if (edges[i].Visible) {
141+
if (Scene.OnInterval(0.25f, i * 0.01f) && !edges[i].InView(ref view)) {
142+
edges[i].Visible = false;
143+
}
144+
} else if (Scene.OnInterval(0.05f, i * 0.01f) && edges[i].InView(ref view)) {
145+
edges[i].Visible = true;
146+
}
147+
if (edges[i].Visible && (Scene.OnInterval(0.05f, i * 0.01f) || edges[i].Wave == null)) {
148+
edges[i].UpdateWave(Scene.TimeActive * 3f);
149+
}
150+
}
151+
}
152+
153+
private void RebuildEdges() {
154+
dirty = false;
155+
edges.Clear();
156+
if (list.Count > 0) {
157+
Level obj = Scene as Level;
158+
int left = obj.TileBounds.Left;
159+
int top = obj.TileBounds.Top;
160+
int right = obj.TileBounds.Right;
161+
int bottom = obj.TileBounds.Bottom;
162+
Point[] array = {
163+
new Point(0, -1),
164+
new Point(0, 1),
165+
new Point(-1, 0),
166+
new Point(1, 0)
167+
};
168+
foreach (MoveBlockBarrier item in list) {
169+
for (int i = (int) item.X / 8; i < item.Right / 8f; i++) {
170+
for (int j = (int) item.Y / 8; j < item.Bottom / 8f; j++) {
171+
Point[] array2 = array;
172+
for (int k = 0; k < array2.Length; k++) {
173+
Point point = array2[k];
174+
Point point2 = new Point(-point.Y, point.X);
175+
if (!Inside(i + point.X, j + point.Y) && (!Inside(i - point2.X, j - point2.Y) || Inside(i + point.X - point2.X, j + point.Y - point2.Y))) {
176+
Point point3 = new Point(i, j);
177+
Point point4 = new Point(i + point2.X, j + point2.Y);
178+
Vector2 value = new Vector2(4f) + new Vector2(point.X - point2.X, point.Y - point2.Y) * 4f;
179+
while (Inside(point4.X, point4.Y) && !Inside(point4.X + point.X, point4.Y + point.Y)) {
180+
point4.X += point2.X;
181+
point4.Y += point2.Y;
182+
}
183+
Vector2 a = new Vector2(point3.X, point3.Y) * 8f + value - item.Position;
184+
Vector2 b = new Vector2(point4.X, point4.Y) * 8f + value - item.Position;
185+
edges.Add(new Edge(item, a, b));
186+
}
187+
}
188+
}
189+
}
190+
}
191+
}
192+
}
193+
194+
private bool Inside(int tx, int ty) {
195+
return tiles[tx - levelTileBounds.X, ty - levelTileBounds.Y];
196+
}
197+
198+
private void OnRenderBloom() {
199+
Camera camera = (base.Scene as Level).Camera;
200+
new Rectangle((int) camera.Left, (int) camera.Top, (int) (camera.Right - camera.Left), (int) (camera.Bottom - camera.Top));
201+
foreach (MoveBlockBarrier item in list) {
202+
if (item.Visible) {
203+
Draw.Rect(item.X, item.Y, item.Width, item.Height, Color.Purple);
204+
}
205+
}
206+
foreach (Edge edge in edges) {
207+
if (edge.Visible) {
208+
Vector2 value = edge.Parent.Position + edge.A;
209+
Vector2 vector2 = edge.Parent.Position + edge.B;
210+
for (int i = 0; i <= edge.Length; i++) {
211+
Vector2 vector = value + edge.Normal * i;
212+
Draw.Line(vector, vector + edge.Perpendicular * edge.Wave[i], Color.Purple);
213+
}
214+
}
215+
}
216+
}
217+
218+
public override void Render() {
219+
if (list.Count > 0) {
220+
Color color = Color.Purple * 0.65f;
221+
Color value = Color.Purple * 0.75f;
222+
foreach (MoveBlockBarrier item in list) {
223+
if (item.Visible) {
224+
Draw.Rect(item.Collider, color);
225+
}
226+
}
227+
if (edges.Count > 0) {
228+
foreach (Edge edge in edges) {
229+
if (edge.Visible) {
230+
Vector2 value2 = edge.Parent.Position + edge.A;
231+
Vector2 vector2 = edge.Parent.Position + edge.B;
232+
Color.Lerp(value, Color.Purple, edge.Parent.Flash);
233+
for (int i = 0; i <= edge.Length; i++) {
234+
Vector2 vector = value2 + edge.Normal * i;
235+
Draw.Line(vector, vector + edge.Perpendicular * edge.Wave[i], color);
236+
}
237+
}
238+
}
239+
}
240+
}
241+
}
242+
}
243+
}

SpringCollab2020Module.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ public override void Load() {
1414
NoRefillField.Load();
1515
FloatierSpaceBlock.Load();
1616
MoveBlockBarrier.Load();
17+
MoveBlockBarrierRenderer.Load();
1718
RemoveLightSourcesTrigger.Load();
1819
}
1920

2021
public override void Unload() {
2122
NoRefillField.Unload();
2223
FloatierSpaceBlock.Unload();
2324
MoveBlockBarrier.Unload();
25+
MoveBlockBarrierRenderer.Unload();
2426
RemoveLightSourcesTrigger.Unload();
2527
}
2628
}

0 commit comments

Comments
 (0)