Skip to content

Commit 53bcb47

Browse files
committed
amending this later
1 parent d774b0a commit 53bcb47

6 files changed

+193
-25
lines changed

Entities/FlagTouchSwitch.cs

+42-24
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace Celeste.Mod.MaxHelpingHand.Entities {
2020
/// - inactiveColor / activeColor / finishColor: custom colors for the touch switch.
2121
/// </summary>
2222
[CustomEntity("MaxHelpingHand/FlagTouchSwitch")]
23-
[Tracked]
23+
[Tracked(inherited: true)]
2424
public class FlagTouchSwitch : Entity {
2525
private static FieldInfo seekerPushRadius = typeof(Seeker).GetField("pushRadius", BindingFlags.NonPublic | BindingFlags.Instance);
2626
private static FieldInfo seekerPhysicsHitbox = typeof(Seeker).GetField("physicsHitbox", BindingFlags.NonPublic | BindingFlags.Instance);
@@ -90,7 +90,7 @@ private static void turnOnTouchSwitchesCollidingWith(Entity self) {
9090

9191
private MTexture border = GFX.Game["objects/touchswitch/container"];
9292

93-
private Sprite icon;
93+
protected Sprite icon;
9494

9595
private int[] frames;
9696
private bool persistent;
@@ -119,6 +119,8 @@ private static void turnOnTouchSwitchesCollidingWith(Entity self) {
119119

120120
private Level level => (Level) Scene;
121121

122+
protected virtual Vector2 IconPosition => Vector2.Zero;
123+
122124
public FlagTouchSwitch(EntityData data, Vector2 offset)
123125
: base(data.Position + offset) {
124126

@@ -152,13 +154,7 @@ public FlagTouchSwitch(EntityData data, Vector2 offset)
152154
Color = finishColor
153155
};
154156

155-
// set up collision
156-
Collider = new Hitbox(16f, 16f, -8f, -8f);
157-
if (data.Bool("playerCanActivate", defaultValue: true)) {
158-
Add(new PlayerCollider(onPlayer, null, new Hitbox(30f, 30f, -15f, -15f)));
159-
}
160-
Add(new HoldableCollider(onHoldable, new Hitbox(20f, 20f, -10f, -10f)));
161-
Add(new SeekerCollider(onSeeker, new Hitbox(24f, 24f, -12f, -12f)));
157+
setUpCollision(data);
162158

163159
// set up the icon
164160
string iconAttribute = data.Attr("icon", "vanilla");
@@ -175,16 +171,27 @@ public FlagTouchSwitch(EntityData data, Vector2 offset)
175171
icon.Play("spin");
176172
icon.Color = inactiveColor;
177173
icon.CenterOrigin();
174+
icon.Position = IconPosition;
178175

179176
Add(bloom = new BloomPoint(0f, 16f));
180177
bloom.Alpha = 0f;
178+
bloom.Position = IconPosition;
181179

182180
Add(wiggler = Wiggler.Create(0.5f, 4f, v => {
183181
pulse = Vector2.One * (1f + v * 0.25f);
184182
}));
185183

186-
Add(new VertexLight(Color.White, 0.8f, 16, 32));
187-
Add(touchSfx = new SoundSource());
184+
Add(new VertexLight(Color.White, 0.8f, 16, 32) { Position = IconPosition });
185+
Add(touchSfx = new SoundSource { Position = IconPosition });
186+
}
187+
188+
protected virtual void setUpCollision(EntityData data) {
189+
Collider = new Hitbox(16f, 16f, -8f, -8f);
190+
if (data.Bool("playerCanActivate", defaultValue: true)) {
191+
Add(new PlayerCollider(onPlayer, null, new Hitbox(30f, 30f, -15f, -15f)));
192+
}
193+
Add(new HoldableCollider(onHoldable, new Hitbox(20f, 20f, -10f, -10f)));
194+
Add(new SeekerCollider(onSeeker, new Hitbox(24f, 24f, -12f, -12f)));
188195
}
189196

190197
public override void Added(Scene scene) {
@@ -224,15 +231,15 @@ public override void Awake(Scene scene) {
224231
new DynData<TouchSwitch>(touchSwitch).Get<string>("flag") == flag).ToList();
225232
}
226233

227-
private void onPlayer(Player player) {
234+
protected void onPlayer(Player player) {
228235
TurnOn();
229236
}
230237

231-
private void onHoldable(Holdable h) {
238+
protected void onHoldable(Holdable h) {
232239
TurnOn();
233240
}
234241

235-
private void onSeeker(Seeker seeker) {
242+
protected void onSeeker(Seeker seeker) {
236243
if (SceneAs<Level>().InsideCamera(Position, 10f)) {
237244
TurnOn();
238245
}
@@ -249,31 +256,38 @@ public void TurnOn() {
249256
wiggler.Start();
250257
for (int i = 0; i < 32; i++) {
251258
float num = Calc.Random.NextFloat((float) Math.PI * 2f);
252-
level.Particles.Emit(TouchSwitch.P_FireWhite, Position + Calc.AngleToVector(num, 6f), num);
259+
level.Particles.Emit(TouchSwitch.P_FireWhite, Position + IconPosition + Calc.AngleToVector(num, 6f), num);
253260
}
254261
});
255262
icon.Rate = 4f;
256263

257264
HandleCollectedFlagTouchSwitch(flag, inverted, persistent, level, id, allTouchSwitchesInRoom, allMovingFlagTouchSwitchesInRoom, () => doEffect(() => {
258265
SoundEmitter.Play(completeSoundFromScene);
259-
Add(new SoundSource(completeSoundFromSwitch));
266+
Add(new SoundSource(completeSoundFromSwitch) { Position = IconPosition });
260267
}));
261268
}
262269
}
263270

264271
// returns true if the entire group was completed.
265-
internal static bool HandleCollectedFlagTouchSwitch(string flag, bool inverted, bool persistent, Level level, int id,
266-
List<FlagTouchSwitch> allTouchSwitchesInRoom, List<TouchSwitch> allMovingFlagTouchSwitchesInRoom, Action onFinished) {
272+
internal static bool HandleCollectedFlagTouchSwitch(
273+
string flag,
274+
bool inverted,
275+
bool persistent,
276+
Level level,
277+
int id,
278+
List<FlagTouchSwitch> allTouchSwitchesInRoom,
279+
List<TouchSwitch> allMovingFlagTouchSwitchesInRoom,
280+
Action onFinished) {
267281

268282
if (persistent) {
269283
// this switch is persistent. save its activation in the session.
270284
level.Session.SetFlag(flag + "_switch" + id, true);
271285
}
272286

273287
if (MaxHelpingHandMapDataProcessor.FlagTouchSwitches[level.Session.Area.SID][(int) level.Session.Area.Mode][new KeyValuePair<string, bool>(flag, inverted)]
274-
.All(touchSwitchID => touchSwitchID.Level == level.Session.Level || level.Session.GetFlag(flag + "_switch" + touchSwitchID.ID))
275-
&& allTouchSwitchesInRoom.All(touchSwitch => touchSwitch.Activated || touchSwitch.isHidden())
276-
&& allMovingFlagTouchSwitchesInRoom.All(touchSwitch => touchSwitch.Switch.Activated || MovingFlagTouchSwitch.IsHidden(touchSwitch))) {
288+
.All(touchSwitchID => touchSwitchID.Level == level.Session.Level || level.Session.GetFlag(flag + "_switch" + touchSwitchID.ID))
289+
&& allTouchSwitchesInRoom.All(touchSwitch => touchSwitch.Activated || touchSwitch.isHidden())
290+
&& allMovingFlagTouchSwitchesInRoom.All(touchSwitch => touchSwitch.Switch.Activated || MovingFlagTouchSwitch.IsHidden(touchSwitch))) {
277291

278292
// all switches in the room are enabled or hidden, and all session flags for switches outside the room are enabled.
279293
// so, the group is complete.
@@ -366,10 +380,10 @@ public override void Update() {
366380
icon.Rate = 0.1f;
367381
wiggler.Start();
368382
icon.Play("idle");
369-
level.Displacement.AddBurst(Position, 0.6f, 4f, 28f, 0.2f);
383+
level.Displacement.AddBurst(Position + IconPosition, 0.6f, 4f, 28f, 0.2f);
370384
}
371385
} else if (Scene.OnInterval(0.03f) && smoke) {
372-
Vector2 position = Position + new Vector2(0f, 1f) + Calc.AngleToVector(Calc.Random.NextAngle(), 5f);
386+
Vector2 position = Position + IconPosition + new Vector2(0f, 1f) + Calc.AngleToVector(Calc.Random.NextAngle(), 5f);
373387
level.ParticlesBG.Emit(P_RecoloredFire, position);
374388
}
375389

@@ -395,9 +409,13 @@ public override void Update() {
395409
}
396410

397411
public override void Render() {
412+
renderBorder();
413+
base.Render();
414+
}
415+
416+
protected virtual void renderBorder() {
398417
border.DrawCentered(Position + new Vector2(0f, -1f), Color.Black);
399418
border.DrawCentered(Position, icon.Color, pulse);
400-
base.Render();
401419
}
402420

403421
private void doEffect(Action effect) {

Entities/FlagTouchSwitchWall.cs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Celeste.Mod.Entities;
2+
using Microsoft.Xna.Framework;
3+
using Monocle;
4+
5+
namespace Celeste.Mod.MaxHelpingHand.Entities {
6+
[CustomEntity("MaxHelpingHand/FlagTouchSwitchWall")]
7+
public class FlagTouchSwitchWall : FlagTouchSwitch {
8+
protected override Vector2 IconPosition => new Vector2(Width / 2, Height / 2);
9+
10+
public FlagTouchSwitchWall(EntityData data, Vector2 offset) : base(data, offset) {
11+
}
12+
13+
protected override void setUpCollision(EntityData data) {
14+
Collider = new Hitbox(data.Width, data.Height);
15+
16+
if (data.Bool("playerCanActivate", defaultValue: true)) {
17+
Add(new PlayerCollider(onPlayer, null, new Hitbox(data.Width, data.Height)));
18+
}
19+
20+
Add(new HoldableCollider(onHoldable, new Hitbox(data.Width, data.Height)));
21+
Add(new SeekerCollider(onSeeker, new Hitbox(data.Width, data.Height)));
22+
}
23+
24+
protected override void renderBorder() {
25+
Draw.HollowRect(X - 1, Y - 1, Width + 2, Height + 2, new Color(icon.Color.R, icon.Color.G, icon.Color.B, (int) (0.7f * 255)));
26+
Draw.Rect(X + 1, Y + 1, Width - 2, Height - 2, Color.Lerp(icon.Color, Calc.HexToColor("0a0a0a"), 0.5f) * 0.3f);
27+
}
28+
}
29+
}

Loenn/entities/flagTouchSwitch.lua

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
local drawableSprite = require("structs.drawable_sprite")
2-
local utils = require("utils")
32

43
local touchSwitch = {}
54

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
local drawableSprite = require("structs.drawable_sprite")
2+
local drawableRectangle = require("structs.drawable_rectangle")
3+
4+
local touchSwitch = {}
5+
6+
touchSwitch.name = "MaxHelpingHand/FlagTouchSwitchWall"
7+
touchSwitch.depth = 2000
8+
touchSwitch.minimumSize = {8, 8}
9+
touchSwitch.placements = {
10+
{
11+
name = "touch_switch",
12+
data = {
13+
width = 16,
14+
height = 16,
15+
flag = "flag_touch_switch",
16+
icon = "vanilla",
17+
animationLength = 6,
18+
persistent = false,
19+
inactiveColor = "5FCDE4",
20+
activeColor = "FFFFFF",
21+
finishColor = "F141DF",
22+
smoke = true,
23+
inverted = false,
24+
allowDisable = false,
25+
playerCanActivate = true,
26+
hitSound = "event:/game/general/touchswitch_any",
27+
completeSoundFromSwitch = "event:/game/general/touchswitch_last_cutoff",
28+
completeSoundFromScene = "event:/game/general/touchswitch_last_oneshot",
29+
hideIfFlag = ""
30+
}
31+
}
32+
}
33+
34+
function touchSwitch.fieldOrder(entity)
35+
local fieldOrder = {"x", "y", "width", "height", "inactiveColor", "activeColor", "finishColor", "hitSound", "completeSoundFromSwitch", "completeSoundFromScene"}
36+
37+
-- only include animationLength to fieldOrder if the field exists, otherwise it will appear as nil in the entity properties window
38+
if entity.animationLength ~= nil then
39+
table.insert(fieldOrder, "animationLength")
40+
end
41+
42+
return fieldOrder
43+
end
44+
45+
touchSwitch.fieldInformation = {
46+
inactiveColor = {
47+
fieldType = "color"
48+
},
49+
activeColor = {
50+
fieldType = "color"
51+
},
52+
finishColor = {
53+
fieldType = "color"
54+
},
55+
icon = {
56+
options = { "vanilla", "tall", "triangle", "circle", "diamond", "double", "heart", "square", "wide", "winged", "cross", "drop", "hourglass", "split", "star", "triple" }
57+
},
58+
animationLength = {
59+
fieldType = "integer"
60+
}
61+
}
62+
63+
function touchSwitch.sprite(room, entity)
64+
local containerSprite = drawableRectangle.fromRectangle('bordered', entity.x, entity.y, entity.width, entity.height, {0.0, 0.0, 0.0, 0.3}, {1.0, 1.0, 1.0, 0.5})
65+
66+
local iconResource = "objects/touchswitch/icon00"
67+
if entity.icon ~= "vanilla" then
68+
iconResource = "objects/MaxHelpingHand/flagTouchSwitch/" .. entity.icon .."/icon00"
69+
end
70+
71+
local iconSprite = drawableSprite.fromTexture(iconResource, entity)
72+
iconSprite:setPosition(entity.x + entity.width / 2, entity.y + entity.height / 2)
73+
74+
return {containerSprite, iconSprite}
75+
end
76+
77+
return touchSwitch

Loenn/lang/en_gb.lang

+20
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,26 @@ entities.MaxHelpingHand/FlagTouchSwitch.attributes.name.completeSoundFromScene=C
237237
entities.MaxHelpingHand/FlagTouchSwitch.attributes.description.hideIfFlag=If a session flag is specified here, turning it on will make the touch switch disappear, and will make other touch switches in the room ignore it for the group's completion.
238238
entities.MaxHelpingHand/FlagTouchSwitch.attributes.description.animationLength=The length of the provided spinning animation, in frames.
239239

240+
# Flag Touch Switch Wall
241+
entities.MaxHelpingHand/FlagTouchSwitchWall.placements.name.touch_switch=Flag Touch Switch Wall
242+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.flag=The session flag this touch switch sets. Give the same to multiple touch switches and switch gates to group them.
243+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.icon=The name of the icon for the touch switch (relative to objects/MaxHelpingHand/flagTouchSwitch), or "vanilla" for the default one.
244+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.persistent=If enabled, the touch switch will stay active when the player dies or changes rooms.\nThis touch switch will also set a flag when it is enabled: [flagName]_switch[entityID]
245+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.inactiveColor=The switch color when not triggered yet.
246+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.activeColor=The switch color when triggered, but the group is not complete yet.
247+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.finishColor=The switch color when the group is complete.
248+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.smoke=Whether the touch switch emits smoke when the group is complete.
249+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.inverted=Whether the touch switch should turn off the flag instead of turning it on. The option should match on all touch switches of the group.
250+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.allowDisable=Whether the touch switch can be disabled once the group is complete, if the flag change is reverted. Does not work with non-persistent flag switch gates.
251+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.playerCanActivate=Whether the player can activate the touch switch. If not, only throwables can activate it.
252+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.hitSound=The sound played when the switch is hit by the player.
253+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.completeSoundFromSwitch=The sound emitted by the latest switch collected when the group is complete.
254+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.completeSoundFromScene=A global sound emitted when the group is complete. As opposed to "Complete Sound (Switch)", this sound isn't emitted by a particular switch.
255+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.name.completeSoundFromSwitch=Complete Sound (Switch)
256+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.name.completeSoundFromScene=Complete Sound (Global)
257+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.hideIfFlag=If a session flag is specified here, turning it on will make the touch switch disappear, and will make other touch switches in the room ignore it for the group's completion.
258+
entities.MaxHelpingHand/FlagTouchSwitchWall.attributes.description.animationLength=The length of the provided spinning animation, in frames.
259+
240260
# Floaty Space Block with Attached Sideways Jumpthru support
241261
entities.MaxHelpingHand/FloatySpaceBlockWithAttachedSidewaysJumpthruSupport.placements.name.floaty_space_block=Floaty Space Block (supporting Sideways Jump Throughs)
242262
entities.MaxHelpingHand/FloatySpaceBlockWithAttachedSidewaysJumpthruSupport.attributes.description.tiletype=Determines the visual appearance of the wall.

Module/MaxHelpingHandMapDataProcessor.cs

+25
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,34 @@ public class MaxHelpingHandMapDataProcessor : EverestMapDataProcessor {
7474
{
7575
"entity:MaxHelpingHand/MovingFlagTouchSwitch", flagTouchSwitchHandler
7676
},
77+
{
78+
"entity:MaxHelpingHand/FlagTouchSwitchWall", flagTouchSwitchHandler
79+
},
80+
{
81+
"entity:ChroniaHelper/FlagTouchSwitch", flagTouchSwitch => {
82+
// Take over Chronia Helper flag touch switches, after UnderDragon reached out to merge those back into Helping Hand
83+
if (flagTouchSwitch.Attr("switch") == "touchSwitch") {
84+
Logger.Log(LogLevel.Verbose, "MaxHelpingHand/MapDataProcessor", $"area {AreaKey.SID} / mode {AreaKey.Mode} / room {levelName} has a ChroniaHelper/FlagTouchSwitch, turning it into a MaxHelpingHand/FlagTouchSwitch");
85+
flagTouchSwitch.Name = "MaxHelpingHand/FlagTouchSwitch";
86+
flagTouchSwitch.SetAttr("x", flagTouchSwitch.AttrInt("x") + flagTouchSwitch.AttrInt("width") / 2);
87+
flagTouchSwitch.SetAttr("y", flagTouchSwitch.AttrInt("y") + flagTouchSwitch.AttrInt("height") / 2);
88+
} else {
89+
Logger.Log(LogLevel.Verbose, "MaxHelpingHand/MapDataProcessor", $"area {AreaKey.SID} / mode {AreaKey.Mode} / room {levelName} has a ChroniaHelper/FlagTouchSwitch, turning it into a MaxHelpingHand/FlagTouchSwitchWall");
90+
flagTouchSwitch.Name = "MaxHelpingHand/FlagTouchSwitchWall";
91+
}
92+
flagTouchSwitchHandler(flagTouchSwitch);
93+
}
94+
},
7795
{
7896
"entity:MaxHelpingHand/FlagSwitchGate", flagSwitchGateHandler
7997
},
98+
{
99+
"entity:ChroniaHelper/FlagSwitchGate", flagSwitchGate => {
100+
Logger.Log(LogLevel.Verbose, "MaxHelpingHand/MapDataProcessor", $"area {AreaKey.SID} / mode {AreaKey.Mode} / room {levelName} has a ChroniaHelper/FlagSwitchGate, turning it into a MaxHelpingHand/FlagSwitchGate");
101+
flagSwitchGate.Name = "MaxHelpingHand/FlagSwitchGate";
102+
flagSwitchGateHandler(flagSwitchGate);
103+
}
104+
},
80105
{
81106
"entity:CommunalHelper/MaxHelpingHand/DreamFlagSwitchGate", flagSwitchGateHandler
82107
},

0 commit comments

Comments
 (0)