Skip to content

Commit dad0279

Browse files
committed
Cassette-Friendly Strawberries / Strawberry Seeds
1 parent 26ceb46 commit dad0279

File tree

4 files changed

+156
-0
lines changed

4 files changed

+156
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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+
fallback = "collectables/strawberry/normal00"
30+
31+
Ahorn.nodeLimits(entity::CassetteFriendlyStrawberry) = 0, -1
32+
33+
function Ahorn.selection(entity::CassetteFriendlyStrawberry)
34+
x, y = Ahorn.position(entity)
35+
36+
nodes = get(entity.data, "nodes", ())
37+
moon = get(entity.data, "moon", false)
38+
winged = get(entity.data, "winged", false) || entity.name == "memorialTextController"
39+
hasPips = length(nodes) > 0
40+
41+
sprite = sprites[(winged, hasPips, moon)]
42+
43+
res = Ahorn.Rectangle[Ahorn.getSpriteRectangle(sprite, x, y)]
44+
45+
for node in nodes
46+
nx, ny = node
47+
48+
push!(res, Ahorn.getSpriteRectangle(seedSprite, nx, ny))
49+
end
50+
51+
return res
52+
end
53+
54+
function Ahorn.renderSelectedAbs(ctx::Ahorn.Cairo.CairoContext, entity::CassetteFriendlyStrawberry)
55+
x, y = Ahorn.position(entity)
56+
57+
for node in get(entity.data, "nodes", ())
58+
nx, ny = node
59+
60+
Ahorn.drawLines(ctx, Tuple{Number, Number}[(x, y), (nx, ny)], Ahorn.colors.selection_selected_fc)
61+
end
62+
end
63+
64+
function Ahorn.renderAbs(ctx::Ahorn.Cairo.CairoContext, entity::CassetteFriendlyStrawberry, room::Maple.Room)
65+
x, y = Ahorn.position(entity)
66+
67+
nodes = get(entity.data, "nodes", ())
68+
moon = get(entity.data, "moon", false)
69+
winged = get(entity.data, "winged", false) || entity.name == "memorialTextController"
70+
hasPips = length(nodes) > 0
71+
72+
sprite = sprites[(winged, hasPips, moon)]
73+
74+
for node in nodes
75+
nx, ny = node
76+
77+
Ahorn.drawSprite(ctx, seedSprite, nx, ny)
78+
end
79+
80+
Ahorn.drawSprite(ctx, sprite, x, y)
81+
end
82+
83+
end

Ahorn/lang/en_gb.lang

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,9 @@ placements.entities.SpringCollab2020/MultiNodeMovingPlatform.tooltips.pauseTime=
136136
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
137137
placements.entities.SpringCollab2020/MultiNodeMovingPlatform.tooltips.texture=What texture to use for the platform.
138138
placements.entities.SpringCollab2020/MultiNodeMovingPlatform.tooltips.easing=Whether the platform movement should be eased (speedup/slowdown around each position).
139+
140+
# Cassette-Friendly Strawberry
141+
placements.entities.SpringCollab2020/CassetteFriendlyStrawberry.tooltips.winged=The strawberry attempts to vertically rise offscreen when the player dashes.
142+
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)
143+
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)
144+
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: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using Microsoft.Xna.Framework;
2+
using Monocle;
3+
using System;
4+
using System.Linq;
5+
using System.Reflection;
6+
7+
namespace Celeste.Mod.SpringCollab2020.Entities {
8+
/// <summary>
9+
/// Strawberry seeds that deal nicer with being hidden in cassette blocks.
10+
/// They appear when the cassette block disappears, and keep a normal hitbox.
11+
/// </summary>
12+
class CassetteFriendlyStrawberrySeed : StrawberrySeed {
13+
14+
bool isInCassetteBlock;
15+
16+
public CassetteFriendlyStrawberrySeed(Strawberry strawberry, Vector2 position, int index, bool ghost)
17+
: base(strawberry, position, index, ghost) { }
18+
19+
public override void Added(Scene scene) {
20+
if (scene.Entities.OfType<CassetteBlock>().Any(block => block.Collider.Bounds.Contains(Collider.Bounds))) {
21+
// our seed is entirely inside a cassette block: look for the static mover.
22+
foreach (Component component in this) {
23+
if (component is StaticMover mover) {
24+
Remove(mover);
25+
Depth = 11; // just below active cassette blocks
26+
isInCassetteBlock = true;
27+
break;
28+
}
29+
}
30+
}
31+
32+
base.Added(scene);
33+
}
34+
35+
public override void Update() {
36+
base.Update();
37+
38+
if (isInCassetteBlock && !Visible) {
39+
Depth = 11; // reset depth when losing the seed
40+
}
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)