Skip to content

Commit a9a38ce

Browse files
authored
Merge pull request #117 from EverestAPI/cassette_friendly_strawberry_seeds
Cassette-friendly strawberry seeds
2 parents 44e4cbb + b610c12 commit a9a38ce

File tree

4 files changed

+153
-0
lines changed

4 files changed

+153
-0
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
module SpringCollab2020CassetteFriendlyStrawberry
2+
3+
using ..Ahorn, Maple
4+
5+
@mapdef Entity "SpringCollab2020/CassetteFriendlyStrawberry" CassetteFriendlyStrawberry(x::Integer, y::Integer, winged::Bool=false, moon::Bool=false,
6+
checkpointID::Integer=-1, order::Integer=-1, nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[])
7+
8+
const placements = Ahorn.PlacementDict(
9+
"Cassette-Friendly Strawberry (Spring Collab 2020)" => Ahorn.EntityPlacement(
10+
CassetteFriendlyStrawberry
11+
)
12+
)
13+
14+
# winged, has pips, moon
15+
sprites = Dict{Tuple{Bool, Bool, Bool}, String}(
16+
(false, false, false) => "collectables/strawberry/normal00",
17+
(true, false, false) => "collectables/strawberry/wings01",
18+
(false, true, false) => "collectables/ghostberry/idle00",
19+
(true, true, false) => "collectables/ghostberry/wings01",
20+
21+
(false, false, true) => "collectables/moonBerry/normal00",
22+
(true, false, true) => "collectables/moonBerry/ghost00",
23+
(false, true, true) => "collectables/moonBerry/ghost00",
24+
(true, true, true) => "collectables/moonBerry/ghost00"
25+
)
26+
27+
seedSprite = "collectables/strawberry/seed00"
28+
29+
Ahorn.nodeLimits(entity::CassetteFriendlyStrawberry) = 0, -1
30+
31+
function Ahorn.selection(entity::CassetteFriendlyStrawberry)
32+
x, y = Ahorn.position(entity)
33+
34+
nodes = get(entity.data, "nodes", ())
35+
moon = get(entity.data, "moon", false)
36+
winged = get(entity.data, "winged", false)
37+
hasPips = length(nodes) > 0
38+
39+
sprite = sprites[(winged, hasPips, moon)]
40+
41+
res = Ahorn.Rectangle[Ahorn.getSpriteRectangle(sprite, x, y)]
42+
43+
for node in nodes
44+
nx, ny = node
45+
46+
push!(res, Ahorn.getSpriteRectangle(seedSprite, nx, ny))
47+
end
48+
49+
return res
50+
end
51+
52+
function Ahorn.renderSelectedAbs(ctx::Ahorn.Cairo.CairoContext, entity::CassetteFriendlyStrawberry)
53+
x, y = Ahorn.position(entity)
54+
55+
for node in get(entity.data, "nodes", ())
56+
nx, ny = node
57+
58+
Ahorn.drawLines(ctx, Tuple{Number, Number}[(x, y), (nx, ny)], Ahorn.colors.selection_selected_fc)
59+
end
60+
end
61+
62+
function Ahorn.renderAbs(ctx::Ahorn.Cairo.CairoContext, entity::CassetteFriendlyStrawberry, room::Maple.Room)
63+
x, y = Ahorn.position(entity)
64+
65+
nodes = get(entity.data, "nodes", ())
66+
moon = get(entity.data, "moon", false)
67+
winged = get(entity.data, "winged", false)
68+
hasPips = length(nodes) > 0
69+
70+
sprite = sprites[(winged, hasPips, moon)]
71+
72+
for node in nodes
73+
nx, ny = node
74+
75+
Ahorn.drawSprite(ctx, seedSprite, nx, ny)
76+
end
77+
78+
Ahorn.drawSprite(ctx, sprite, x, y)
79+
end
80+
81+
end

Ahorn/lang/en_gb.lang

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,9 @@ placements.entities.SpringCollab2020/MultiNodeMovingPlatform.tooltips.pauseTime=
156156
placements.entities.SpringCollab2020/MultiNodeMovingPlatform.tooltips.mode=Determines the way the platform will move between its nodes. For example, with 3 nodes A, B, C:\n- Loop: A > B > C > A\n- LoopNoPause: A > A (going through B and C)\n- BackAndForth: A > B > C > B > A\n- BackAndForthNoPause: A > C > A (going through B)\n- TeleportBack: A > B > C, then the platform teleports to A upon reaching C
157157
placements.entities.SpringCollab2020/MultiNodeMovingPlatform.tooltips.texture=What texture to use for the platform.
158158
placements.entities.SpringCollab2020/MultiNodeMovingPlatform.tooltips.easing=Whether the platform movement should be eased (speedup/slowdown around each position).
159+
160+
# Cassette-Friendly Strawberry
161+
placements.entities.SpringCollab2020/CassetteFriendlyStrawberry.tooltips.winged=The strawberry attempts to vertically rise offscreen when the player dashes.
162+
placements.entities.SpringCollab2020/CassetteFriendlyStrawberry.tooltips.checkpointID=Manually determine what checkpoint section strawberries are visually grouped up in, showing up on the start menu during gameplay and level select. Overrides Everest's automatic berry IDs. (Default= -1)
163+
placements.entities.SpringCollab2020/CassetteFriendlyStrawberry.tooltips.order=Manually determine what order strawberries are visually placed in on the start menu during gameplay and level select. Overrides Everest's automatic berry IDs. (Default= -1)
164+
placements.entities.SpringCollab2020/CassetteFriendlyStrawberry.tooltips.moon=Makes the strawberry render as a space berry.\nDoes not work with wings or nodes in the base game.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using Celeste.Mod.Entities;
2+
using Microsoft.Xna.Framework;
3+
using System.Collections.Generic;
4+
5+
namespace Celeste.Mod.SpringCollab2020.Entities {
6+
/// <summary>
7+
/// Just a strawberry with cassette-friendly strawberry seeds.
8+
/// </summary>
9+
[CustomEntity("SpringCollab2020/CassetteFriendlyStrawberry")]
10+
[RegisterStrawberry(true, false)]
11+
class CassetteFriendlyStrawberry : Strawberry {
12+
public CassetteFriendlyStrawberry(EntityData data, Vector2 offset, EntityID gid) : base(data, offset, gid) {
13+
bool isGhostBerry = SaveData.Instance.CheckStrawberry(ID);
14+
15+
// we just want to create cassette-friendly strawberry seeds to replace vanilla seeds.
16+
if (data.Nodes != null && data.Nodes.Length != 0) {
17+
Seeds = new List<StrawberrySeed>();
18+
for (int i = 0; i < data.Nodes.Length; i++) {
19+
Seeds.Add(new CassetteFriendlyStrawberrySeed(this, offset + data.Nodes[i], i, isGhostBerry));
20+
}
21+
}
22+
}
23+
}
24+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using Microsoft.Xna.Framework;
2+
using Monocle;
3+
using System.Linq;
4+
5+
namespace Celeste.Mod.SpringCollab2020.Entities {
6+
/// <summary>
7+
/// Strawberry seeds that deal nicer with being hidden in cassette blocks.
8+
/// - Their depth is adjusted to appear in front of disabled cassette blocks, but behind enabled ones.
9+
/// - They are not "attached", meaning they won't disappear when the cassette block disappears.
10+
/// </summary>
11+
class CassetteFriendlyStrawberrySeed : StrawberrySeed {
12+
13+
private bool isInCassetteBlock;
14+
15+
public CassetteFriendlyStrawberrySeed(Strawberry strawberry, Vector2 position, int index, bool ghost)
16+
: base(strawberry, position, index, ghost) { }
17+
18+
public override void Added(Scene scene) {
19+
if (scene.Entities.OfType<CassetteBlock>().Any(block => block.Collider.Bounds.Contains(Collider.Bounds))) {
20+
// our seed is entirely inside a cassette block: look for the static mover.
21+
foreach (Component component in this) {
22+
if (component is StaticMover mover) {
23+
Remove(mover); // get rid of behavior like "disappear with cassette block" or "get double-size hitbox"
24+
Depth = 11; // display just below active cassette blocks
25+
isInCassetteBlock = true;
26+
break;
27+
}
28+
}
29+
}
30+
31+
base.Added(scene);
32+
}
33+
34+
public override void Update() {
35+
base.Update();
36+
37+
if (isInCassetteBlock && !Visible) {
38+
Depth = 11; // reset depth when losing the seed
39+
}
40+
}
41+
}
42+
}

0 commit comments

Comments
 (0)