Skip to content

Commit f62ad24

Browse files
authored
Merge pull request #166 from EverestAPI/seeker_custom_colors
Seeker with custom particles and trail color
2 parents 4aab062 + 0c8af9e commit f62ad24

File tree

5 files changed

+235
-0
lines changed

5 files changed

+235
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
module SpringCollab2020SeekerCustomColors
2+
3+
using ..Ahorn, Maple
4+
5+
@mapdef Entity "SpringCollab2020/SeekerCustomColors" SeekerCustomColors(x::Integer, y::Integer, nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[],
6+
attackParticleColor1::String="99e550", attackParticleColor2::String="ddffbc", regenParticleColor1::String="cbdbfc", regenParticleColor2::String="575fd9", trailColor::String="99e550")
7+
8+
const placements = Ahorn.PlacementDict(
9+
"Seeker (Custom Colors) (Spring Collab 2020)" => Ahorn.EntityPlacement(
10+
SeekerCustomColors,
11+
"point",
12+
Dict{String, Any}(),
13+
function(entity)
14+
entity.data["nodes"] = [(Int(entity.data["x"]) + 32, Int(entity.data["y"]))]
15+
end
16+
)
17+
)
18+
19+
Ahorn.nodeLimits(entity::SeekerCustomColors) = 1, -1
20+
21+
function Ahorn.selection(entity::SeekerCustomColors)
22+
nodes = get(entity.data, "nodes", ())
23+
x, y = Ahorn.position(entity)
24+
25+
res = Ahorn.Rectangle[Ahorn.getSpriteRectangle(sprite, x, y)]
26+
27+
for node in nodes
28+
nx, ny = node
29+
30+
push!(res, Ahorn.getSpriteRectangle(sprite, nx, ny))
31+
end
32+
33+
return res
34+
end
35+
36+
sprite = "characters/monsters/predator73.png"
37+
38+
function Ahorn.renderSelectedAbs(ctx::Ahorn.Cairo.CairoContext, entity::SeekerCustomColors)
39+
px, py = Ahorn.position(entity)
40+
41+
for node in get(entity.data, "nodes", ())
42+
nx, ny = Int.(node)
43+
44+
Ahorn.drawArrow(ctx, px, py, nx, ny, Ahorn.colors.selection_selected_fc, headLength=6)
45+
Ahorn.drawSprite(ctx, sprite, nx, ny)
46+
47+
px, py = nx, ny
48+
end
49+
end
50+
51+
Ahorn.render(ctx::Ahorn.Cairo.CairoContext, entity::SeekerCustomColors, room::Maple.Room) = Ahorn.drawSprite(ctx, sprite, 0, 0)
52+
53+
end
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
module SpringCollab2020SeekerStatueCustomColors
2+
3+
using ..Ahorn, Maple
4+
5+
@mapdef Entity "SpringCollab2020/SeekerStatueCustomColors" SeekerStatueCustomColors(x::Integer, y::Integer, hatch::String="Distance", nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[],
6+
breakOutParticleColor1::String="643e73", breakOutParticleColor2::String="3e2854", attackParticleColor1::String="99e550", attackParticleColor2::String="ddffbc",
7+
regenParticleColor1::String="cbdbfc", regenParticleColor2::String="575fd9", trailColor::String="99e550")
8+
9+
const placements = Ahorn.PlacementDict(
10+
"Seeker Statue (Custom Colors) (Spring Collab 2020)" => Ahorn.EntityPlacement(
11+
SeekerStatueCustomColors,
12+
"point",
13+
Dict{String, Any}(),
14+
function(entity)
15+
entity.data["nodes"] = [(Int(entity.data["x"]) + 32, Int(entity.data["y"]))]
16+
end
17+
)
18+
)
19+
20+
Ahorn.nodeLimits(entity::SeekerStatueCustomColors) = 1, -1
21+
22+
Ahorn.editingOptions(entity::SeekerStatueCustomColors) = Dict{String, Any}(
23+
"hatch" => Maple.seeker_statue_hatches
24+
)
25+
26+
function Ahorn.selection(entity::SeekerStatueCustomColors)
27+
nodes = get(entity.data, "nodes", ())
28+
x, y = Ahorn.position(entity)
29+
30+
res = Ahorn.Rectangle[Ahorn.getSpriteRectangle(statueSprite, x, y)]
31+
32+
for node in nodes
33+
nx, ny = node
34+
35+
push!(res, Ahorn.getSpriteRectangle(monsterSprite, nx, ny))
36+
end
37+
38+
return res
39+
end
40+
41+
statueSprite = "decals/5-temple/statue_e.png"
42+
monsterSprite = "characters/monsters/predator73.png"
43+
44+
function Ahorn.renderSelectedAbs(ctx::Ahorn.Cairo.CairoContext, entity::SeekerStatueCustomColors)
45+
px, py = Ahorn.position(entity)
46+
47+
for node in get(entity.data, "nodes", ())
48+
nx, ny = Int.(node)
49+
50+
Ahorn.drawArrow(ctx, px, py, nx, ny, Ahorn.colors.selection_selected_fc, headLength=6)
51+
Ahorn.drawSprite(ctx, monsterSprite, nx, ny)
52+
53+
px, py = nx, ny
54+
end
55+
end
56+
57+
Ahorn.render(ctx::Ahorn.Cairo.CairoContext, entity::SeekerStatueCustomColors, room::Maple.Room) = Ahorn.drawSprite(ctx, statueSprite, 0, 0)
58+
59+
end

Ahorn/lang/en_gb.lang

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,20 @@ placements.entities.SpringCollab2020/NegativeSummitCheckpoint.tooltips.number=Ch
247247
# Remove Light Sources Trigger
248248
placements.triggers.SpringCollab2020/RemoveLightSourcesTrigger.tooltips.enableLightSources=If checked, this trigger will re-enable light sources instead of disabling them.
249249
placements.triggers.SpringCollab2020/RemoveLightSourcesTrigger.tooltips.fade=If checked, the lights will fade in or out.
250+
251+
# Seeker (Custom Colors)
252+
placements.entities.SpringCollab2020/SeekerCustomColors.tooltips.attackParticleColor1=The first color of the particles the seeker emits when attacking.
253+
placements.entities.SpringCollab2020/SeekerCustomColors.tooltips.attackParticleColor2=The second color of the particles the seeker emits when attacking.
254+
placements.entities.SpringCollab2020/SeekerCustomColors.tooltips.regenParticleColor1=The first color of the particles the seeker emits when respawning.
255+
placements.entities.SpringCollab2020/SeekerCustomColors.tooltips.regenParticleColor2=The second color of the particles the seeker emits when respawning.
256+
placements.entities.SpringCollab2020/SeekerCustomColors.tooltips.trailColor=The color of the trail the seeker leaves behind it when "dashing".
257+
258+
# Seeker Statue (Custom Colors)
259+
placements.entities.SpringCollab2020/SeekerStatueCustomColors.tooltips.hatch=Determines whether the statue releases its seeker when the player is to the right of it, or when the player gets close enough.
260+
placements.entities.SpringCollab2020/SeekerStatueCustomColors.tooltips.breakOutParticleColor1=The first color of the particles the seeker emits when breaking out of the statue.
261+
placements.entities.SpringCollab2020/SeekerStatueCustomColors.tooltips.breakOutParticleColor2=The second color of the particles the seeker emits when breaking out of the statue.
262+
placements.entities.SpringCollab2020/SeekerStatueCustomColors.tooltips.attackParticleColor1=The first color of the particles the seeker emits when attacking.
263+
placements.entities.SpringCollab2020/SeekerStatueCustomColors.tooltips.attackParticleColor2=The second color of the particles the seeker emits when attacking.
264+
placements.entities.SpringCollab2020/SeekerStatueCustomColors.tooltips.regenParticleColor1=The first color of the particles the seeker emits when respawning.
265+
placements.entities.SpringCollab2020/SeekerStatueCustomColors.tooltips.regenParticleColor2=The second color of the particles the seeker emits when respawning.
266+
placements.entities.SpringCollab2020/SeekerStatueCustomColors.tooltips.trailColor=The color of the trail the seeker leaves behind it when "dashing".

Entities/SeekerCustomColors.cs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using Celeste.Mod.Entities;
2+
using Microsoft.Xna.Framework;
3+
using Monocle;
4+
using MonoMod.Utils;
5+
6+
namespace Celeste.Mod.SpringCollab2020.Entities {
7+
[CustomEntity("SpringCollab2020/SeekerCustomColors")]
8+
[TrackedAs(typeof(Seeker))]
9+
class SeekerCustomColors : Seeker {
10+
private static ParticleType basePAttack;
11+
private static ParticleType basePHitWall;
12+
private static ParticleType basePStomp;
13+
private static ParticleType basePRegen;
14+
private static Color baseTrailColor;
15+
16+
private ParticleType pAttack; // blinks between 99e550 and ddffbc
17+
private ParticleType pHitWall; // blinks between 99e550 and ddffbc (same as Attack)
18+
private ParticleType pStomp; // copies pAttack
19+
private ParticleType pRegen; // blinks between cbdbfc and 575fd9
20+
private Color trailColor;
21+
22+
private DynData<Seeker> self;
23+
24+
public SeekerCustomColors(EntityData data, Vector2 offset) : base(data, offset) {
25+
if (basePAttack == null) {
26+
basePAttack = P_Attack;
27+
basePHitWall = P_HitWall;
28+
basePStomp = P_Stomp;
29+
basePRegen = P_Regen;
30+
baseTrailColor = TrailColor;
31+
}
32+
33+
pAttack = new ParticleType(P_Attack) {
34+
Color = Calc.HexToColor(data.Attr("attackParticleColor1")),
35+
Color2 = Calc.HexToColor(data.Attr("attackParticleColor2"))
36+
};
37+
pHitWall = new ParticleType(P_HitWall) {
38+
Color = Calc.HexToColor(data.Attr("attackParticleColor1")),
39+
Color2 = Calc.HexToColor(data.Attr("attackParticleColor2"))
40+
};
41+
pStomp = new ParticleType(P_Stomp) {
42+
Color = Calc.HexToColor(data.Attr("attackParticleColor1")),
43+
Color2 = Calc.HexToColor(data.Attr("attackParticleColor2"))
44+
};
45+
pRegen = new ParticleType(P_Regen) {
46+
Color = Calc.HexToColor(data.Attr("regenParticleColor1")),
47+
Color2 = Calc.HexToColor(data.Attr("regenParticleColor2"))
48+
};
49+
trailColor = Calc.HexToColor(data.Attr("trailColor"));
50+
51+
self = new DynData<Seeker>(this);
52+
}
53+
54+
public override void Update() {
55+
P_Attack = pAttack;
56+
P_HitWall = pHitWall;
57+
P_Stomp = pStomp;
58+
P_Regen = pRegen;
59+
self["TrailColor"] = trailColor;
60+
61+
base.Update();
62+
63+
P_Attack = basePAttack;
64+
P_HitWall = basePHitWall;
65+
P_Stomp = basePStomp;
66+
P_Regen = basePRegen;
67+
self["TrailColor"] = baseTrailColor;
68+
}
69+
}
70+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using Celeste.Mod.Entities;
2+
using Microsoft.Xna.Framework;
3+
using Monocle;
4+
using MonoMod.Utils;
5+
6+
namespace Celeste.Mod.SpringCollab2020.Entities {
7+
[CustomEntity("SpringCollab2020/SeekerStatueCustomColors")]
8+
class SeekerStatueCustomColors : SeekerStatue {
9+
private static ParticleType basePBreakOut;
10+
private ParticleType pBreakOut; // chooses between 643e73 and 3e2854
11+
12+
public SeekerStatueCustomColors(EntityData data, Vector2 offset) : base(data, offset) {
13+
if (basePBreakOut == null) {
14+
basePBreakOut = Seeker.P_BreakOut;
15+
}
16+
17+
pBreakOut = new ParticleType(Seeker.P_BreakOut) {
18+
Color = Calc.HexToColor(data.Attr("breakOutParticleColor1")),
19+
Color2 = Calc.HexToColor(data.Attr("breakOutParticleColor2"))
20+
};
21+
22+
new DynData<SeekerStatue>(this).Get<Sprite>("sprite").OnLastFrame = anim => {
23+
if (anim == "hatch") {
24+
Scene.Add(new SeekerCustomColors(data, offset) { Light = { Alpha = 0f } });
25+
RemoveSelf();
26+
}
27+
};
28+
}
29+
30+
public override void Update() {
31+
Seeker.P_BreakOut = pBreakOut;
32+
base.Update();
33+
Seeker.P_BreakOut = basePBreakOut;
34+
}
35+
}
36+
}

0 commit comments

Comments
 (0)