Skip to content

Commit ba2de3f

Browse files
committed
Resolved merge conflict
2 parents 1f5ad40 + 932a56a commit ba2de3f

File tree

8 files changed

+446
-0
lines changed

8 files changed

+446
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module SpringCollab2020BubbleReturnBerry
2+
3+
using ..Ahorn, Maple
4+
5+
@mapdef Entity "SpringCollab2020/returnBerry" ReturnBerry(x::Integer, y::Integer, order::Integer=-1, checkpointID::Integer=-1, winged::Bool=false)
6+
7+
const placements = Ahorn.PlacementDict(
8+
"Strawberry With Return (Spring Collab 2020)" => Ahorn.EntityPlacement(
9+
ReturnBerry
10+
)
11+
)
12+
13+
function getSpriteName(entity::ReturnBerry)
14+
winged = get(entity.data, "winged", false)
15+
16+
if winged
17+
return "collectables/strawberry/wings01"
18+
end
19+
20+
return "collectables/strawberry/normal00"
21+
end
22+
23+
function Ahorn.selection(entity::ReturnBerry)
24+
x, y = Ahorn.position(entity)
25+
26+
return Ahorn.getSpriteRectangle(getSpriteName(entity), x, y)
27+
end
28+
29+
function Ahorn.renderAbs(ctx::Ahorn.Cairo.CairoContext, entity::ReturnBerry, room::Maple.Room)
30+
x, y = Ahorn.position(entity)
31+
32+
Ahorn.drawSprite(ctx, getSpriteName(entity), x, y)
33+
end
34+
35+
end

Ahorn/entities/variableCrumble.jl

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
module SpringCollab2020VariableCrumbleBlock
2+
3+
using ..Ahorn, Maple
4+
5+
@mapdef Entity "SpringCollab2020/variableCrumbleBlock" VariableCrumbleBlock(x::Integer, y::Integer, width::Integer=Maple.defaultBlockWidth, texture::String="default", timer::Number=0.4)
6+
7+
const placements = Ahorn.PlacementDict(
8+
"Variable Crumble Blocks ($(uppercasefirst(texture))) (Spring Collab 2020)" => Ahorn.EntityPlacement(
9+
VariableCrumbleBlock,
10+
"rectangle",
11+
Dict{String, Any}(
12+
"texture" => texture
13+
)
14+
) for texture in Maple.crumble_block_textures
15+
)
16+
17+
Ahorn.editingOptions(entity::VariableCrumbleBlock) = Dict{String, Any}(
18+
"texture" => Maple.crumble_block_textures
19+
)
20+
21+
Ahorn.minimumSize(entity::VariableCrumbleBlock) = 8, 0
22+
Ahorn.resizable(entity::VariableCrumbleBlock) = true, false
23+
24+
function Ahorn.selection(entity::VariableCrumbleBlock)
25+
x, y = Ahorn.position(entity)
26+
width = Int(get(entity.data, "width", 8))
27+
28+
return Ahorn.Rectangle(x, y, width, 8)
29+
end
30+
31+
function Ahorn.render(ctx::Ahorn.Cairo.CairoContext, entity::VariableCrumbleBlock, room::Maple.Room)
32+
texture = get(entity.data, "texture", "default")
33+
texture = "objects/crumbleBlock/$texture"
34+
println(texture)
35+
36+
# Values need to be system specific integer
37+
x = Int(get(entity.data, "x", 0))
38+
y = Int(get(entity.data, "y", 0))
39+
40+
width = Int(get(entity.data, "width", 8))
41+
tilesWidth = div(width, 8)
42+
43+
Ahorn.Cairo.save(ctx)
44+
45+
Ahorn.rectangle(ctx, 0, 0, width, 8)
46+
Ahorn.clip(ctx)
47+
48+
for i in 0:ceil(Int, tilesWidth / 4)
49+
Ahorn.drawImage(ctx, texture, 32 * i, 0, 0, 0, 32, 8)
50+
end
51+
52+
Ahorn.restore(ctx)
53+
end
54+
55+
end

Ahorn/lang/en_gb.lang

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ placements.entities.SpringCollab2020/diagonalWingedStrawberry.tooltips.checkpoin
66
# Cave Wall
77
placements.entities.SpringCollab2020/caveWall.tooltips.tiletype=Changes the visual appearance of the wall.
88

9+
# Variable Crumble Blocks
10+
11+
placements.entities.SpringCollab2020/variableCrumbleBlock.tooltips.texture=The texture of the blocks that are crumbling.2
12+
placements.entities.SpringCollab2020/variableCrumbleBlock.tooltips.timer=How long the blocks will shake for before falling.
13+
914
# Floatier Space Block
1015
placements.entities.SpringCollab2020/floatierSpaceBlock.tooltips.disableSpawnOffset=Whether or not the entity should spawn without the random offset.
1116
placements.entities.SpringCollab2020/floatierSpaceBlock.tooltips.floatinessMultiplier=A multiplier for how far the block sinks.
@@ -27,5 +32,8 @@ placements.triggers.SpringCollab2020/SmoothCameraOffsetTrigger.tooltips.offsetYT
2732
placements.triggers.SpringCollab2020/SmoothCameraOffsetTrigger.tooltips.positionMode=The fade direction.
2833
placements.triggers.SpringCollab2020/SmoothCameraOffsetTrigger.tooltips.onlyOnce=If checked, the trigger will be disabled when the player first leaves it.
2934

35+
# Remove Light Sources Trigger
36+
placements.triggers.SpringCollab2020/RemoveLightSourcesTrigger.tooltips.persistent=If checked, all light sources will stay disabled even after leaving the trigger.
37+
3038
# Dash Spring
3139
placements.entities.SpringCollab2020/dashSpring.tooltips.playerCanUse=Determines whether the player is able to interact with the spring.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module SpringCollab2020RemoveLightSources
2+
3+
using ..Ahorn, Maple
4+
5+
@mapdef Trigger "SpringCollab2020/RemoveLightSourcesTrigger" RemoveLightSourcesTrigger(x::Integer, y::Integer, width::Integer=Maple.defaultTriggerWidth, height::Integer=Maple.defaultTriggerHeight, persistent::Bool=true)
6+
7+
const placements = Ahorn.PlacementDict(
8+
"Remove Light Sources (Spring Collab 2020)" => Ahorn.EntityPlacement(
9+
RemoveLightSourcesTrigger,
10+
"rectangle",
11+
),
12+
)
13+
14+
end

Entities/BubbleReturnBerry.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using Celeste;
2+
using Celeste.Mod.Entities;
3+
using Microsoft.Xna.Framework;
4+
using Monocle;
5+
using System;
6+
using System.Collections;
7+
8+
namespace Celeste.Mod.SpringCollab2020.Entities {
9+
[CustomEntity("SpringCollab2020/returnBerry")]
10+
[RegisterStrawberry(true, false)]
11+
class BubbleReturnBerry : Strawberry {
12+
public BubbleReturnBerry(EntityData data, Vector2 position, EntityID gid) : base(data, position, gid) {
13+
Add(collider = new PlayerCollider(new Action<Player>(OnPlayer)));
14+
}
15+
16+
public new void OnPlayer(Player player) {
17+
Add(new Coroutine(Return(player), true));
18+
19+
Collidable = false;
20+
}
21+
22+
private IEnumerator Return(Player player) {
23+
yield return 0.3f;
24+
25+
if (!player.Dead) {
26+
Vector2 targetLocation = (Vector2) SceneAs<Level>().Session.RespawnPoint;
27+
28+
Audio.Play("event:/game/general/cassette_bubblereturn", SceneAs<Level>().Camera.Position + new Vector2(160f, 90f));
29+
player.StartCassetteFly(targetLocation, targetLocation);
30+
}
31+
}
32+
33+
private static PlayerCollider collider;
34+
}
35+
}

Entities/VariableCrumbleBlock.cs

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
using Celeste.Mod.Entities;
2+
using Microsoft.Xna.Framework;
3+
using Monocle;
4+
using System;
5+
using System.Collections;
6+
using System.Collections.Generic;
7+
8+
namespace Celeste.Mod.SpringCollab2020.Entities {
9+
[CustomEntity("SpringCollab2020/variableCrumbleBlock")]
10+
public class VariableCrumblePlatform : Solid {
11+
public static ParticleType P_Crumble = CrumblePlatform.P_Crumble;
12+
13+
private List<Image> images;
14+
15+
private List<Image> outline;
16+
17+
private List<Coroutine> falls;
18+
19+
private List<int> fallOrder;
20+
21+
private ShakerList shaker;
22+
23+
private LightOcclude occluder;
24+
25+
private Coroutine outlineFader;
26+
27+
public float crumbleTime = 0.4f;
28+
29+
public string OverrideTexture;
30+
31+
public VariableCrumblePlatform(Vector2 position, float width, float timer)
32+
: base(position, width, 8f, false) {
33+
EnableAssistModeChecks = false;
34+
crumbleTime = timer;
35+
}
36+
37+
public VariableCrumblePlatform(EntityData data, Vector2 offset)
38+
: this(data.Position + offset, (float) data.Width, data.Float("timer", 0.4f)) {
39+
}
40+
41+
public override void Added(Scene scene) {
42+
AreaData areaData = AreaData.Get(scene);
43+
string crumbleBlock = areaData.CrumbleBlock;
44+
if (OverrideTexture != null) {
45+
areaData.CrumbleBlock = OverrideTexture;
46+
}
47+
base.Added(scene);
48+
MTexture mTexture = GFX.Game["objects/crumbleBlock/outline"];
49+
outline = new List<Image>();
50+
if (base.Width <= 8f) {
51+
Image image = new Image(mTexture.GetSubtexture(24, 0, 8, 8));
52+
image.Color = Color.White * 0f;
53+
Add(image);
54+
outline.Add(image);
55+
} else {
56+
for (int i = 0; (float) i < base.Width; i += 8) {
57+
int num = (i != 0) ? ((i > 0 && (float) i < base.Width - 8f) ? 1 : 2) : 0;
58+
Image image2 = new Image(mTexture.GetSubtexture(num * 8, 0, 8, 8));
59+
image2.Position = new Vector2(i, 0f);
60+
image2.Color = Color.White * 0f;
61+
Add(image2);
62+
outline.Add(image2);
63+
}
64+
}
65+
Add(outlineFader = new Coroutine());
66+
outlineFader.RemoveOnComplete = false;
67+
images = new List<Image>();
68+
falls = new List<Coroutine>();
69+
fallOrder = new List<int>();
70+
MTexture mTexture2 = GFX.Game["objects/crumbleBlock/" + AreaData.Get(scene).CrumbleBlock];
71+
for (int j = 0; (float) j < base.Width; j += 8) {
72+
int num2 = (int) ((Math.Abs(base.X) + (float) j) / 8f) % 4;
73+
Image image3 = new Image(mTexture2.GetSubtexture(num2 * 8, 0, 8, 8));
74+
image3.Position = new Vector2(4 + j, 4f);
75+
image3.CenterOrigin();
76+
Add(image3);
77+
images.Add(image3);
78+
Coroutine coroutine = new Coroutine();
79+
coroutine.RemoveOnComplete = false;
80+
falls.Add(coroutine);
81+
Add(coroutine);
82+
fallOrder.Add(j / 8);
83+
}
84+
fallOrder.Shuffle();
85+
Add(new Coroutine(Sequence()));
86+
Add(shaker = new ShakerList(images.Count, false, delegate (Vector2[] v) {
87+
for (int k = 0; k < images.Count; k++) {
88+
images[k].Position = new Vector2(4 + k * 8, 4f) + v[k];
89+
}
90+
}));
91+
Add(occluder = new LightOcclude(0.2f));
92+
areaData.CrumbleBlock = crumbleBlock;
93+
}
94+
95+
private IEnumerator Sequence() {
96+
while (true) {
97+
Player player = GetPlayerOnTop();
98+
bool onTop;
99+
if (player != null) {
100+
onTop = true;
101+
Input.Rumble(RumbleStrength.Medium, RumbleLength.Medium);
102+
} else {
103+
player = GetPlayerClimbing();
104+
if (player == null) {
105+
yield return null;
106+
continue;
107+
}
108+
onTop = false;
109+
Input.Rumble(RumbleStrength.Medium, RumbleLength.Medium);
110+
}
111+
Audio.Play("event:/game/general/platform_disintegrate", Center);
112+
shaker.ShakeFor(onTop ? crumbleTime + 0.4f : crumbleTime + 0.8f, removeOnFinish: false);
113+
foreach (Image img2 in images) {
114+
SceneAs<Level>().Particles.Emit(P_Crumble, 2, Position + img2.Position + new Vector2(0f, 2f), Vector2.One * 3f);
115+
}
116+
for (int l = 0; l < (onTop ? 1 : 3); l++) {
117+
yield return 0.2f;
118+
foreach (Image img in images) {
119+
SceneAs<Level>().Particles.Emit(P_Crumble, 2, Position + img.Position + new Vector2(0f, 2f), Vector2.One * 3f);
120+
}
121+
}
122+
float timer = crumbleTime;
123+
if (onTop) {
124+
while (timer > 0f && GetPlayerOnTop() != null) {
125+
yield return null;
126+
timer -= Engine.DeltaTime;
127+
}
128+
} else {
129+
while (timer > 0f) {
130+
yield return null;
131+
timer -= Engine.DeltaTime;
132+
}
133+
}
134+
outlineFader.Replace(OutlineFade(1f));
135+
occluder.Visible = false;
136+
Collidable = false;
137+
float delay = 0.05f;
138+
for (int m = 0; m < 4; m++) {
139+
for (int i = 0; i < images.Count; i++) {
140+
if (i % 4 - m == 0) {
141+
falls[i].Replace(TileOut(images[fallOrder[i]], delay * (float) m));
142+
}
143+
}
144+
}
145+
yield return 2f;
146+
while (CollideCheck<Actor>() || CollideCheck<Solid>()) {
147+
yield return null;
148+
}
149+
outlineFader.Replace(OutlineFade(0f));
150+
occluder.Visible = true;
151+
Collidable = true;
152+
for (int k = 0; k < 4; k++) {
153+
for (int j = 0; j < images.Count; j++) {
154+
if (j % 4 - k == 0) {
155+
falls[j].Replace(TileIn(j, images[fallOrder[j]], 0.05f * (float) k));
156+
}
157+
}
158+
}
159+
}
160+
}
161+
162+
private IEnumerator OutlineFade(float to) {
163+
float from = 1f - to;
164+
for (float t = 0f; t < 1f; t += Engine.DeltaTime * 2f) {
165+
Color color = Color.White * (from + (to - from) * Ease.CubeInOut(t));
166+
foreach (Image img in outline) {
167+
img.Color = color;
168+
}
169+
yield return null;
170+
}
171+
}
172+
173+
private IEnumerator TileOut(Image img, float delay) {
174+
img.Color = Color.Gray;
175+
yield return delay;
176+
float distance = (img.X * 7f % 3f + 1f) * 12f;
177+
Vector2 from = img.Position;
178+
for (float time = 0f; time < 1f; time += Engine.DeltaTime / 0.4f) {
179+
yield return null;
180+
img.Position = from + Vector2.UnitY * Ease.CubeIn(time) * distance;
181+
img.Color = Color.Gray * (1f - time);
182+
img.Scale = Vector2.One * (1f - time * 0.5f);
183+
}
184+
img.Visible = false;
185+
}
186+
187+
private IEnumerator TileIn(int index, Image img, float delay) {
188+
yield return delay;
189+
Audio.Play("event:/game/general/platform_return", Center);
190+
img.Visible = true;
191+
img.Color = Color.White;
192+
img.Position = new Vector2(index * 8 + 4, 4f);
193+
for (float time = 0f; time < 1f; time += Engine.DeltaTime / 0.25f) {
194+
yield return null;
195+
img.Scale = Vector2.One * (1f + Ease.BounceOut(1f - time) * 0.2f);
196+
}
197+
img.Scale = Vector2.One;
198+
}
199+
}
200+
}

SpringCollab2020Module.cs

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

1920
public override void Unload() {
2021
NoRefillField.Unload();
2122
FloatierSpaceBlock.Unload();
2223
MoveBlockBarrier.Unload();
24+
RemoveLightSourcesTrigger.Unload();
2325
}
2426
}
2527
}

0 commit comments

Comments
 (0)