Skip to content

Commit b6941b7

Browse files
authored
Merge pull request #109 from EverestAPI/multi_node_moving_platforms
Multi-node moving platforms
2 parents bafe952 + e741bb6 commit b6941b7

File tree

3 files changed

+398
-1
lines changed

3 files changed

+398
-1
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
module SpringCollab2020MultiNodeMovingPlatform
2+
3+
using ..Ahorn, Maple
4+
5+
@pardef MultiNodeMovingPlatform(x::Integer, y::Integer, width::Integer=Maple.defaultBlockWidth, mode::String="Loop", texture::String="default", moveTime::Number=2.0, pauseTime::Number=0.0, easing::Bool=true) =
6+
Entity("SpringCollab2020/MultiNodeMovingPlatform", x=x, y=y, nodes=Tuple{Int, Int}[], width=width, mode=mode, texture=texture, moveTime=moveTime, pauseTime=pauseTime, easing=easing)
7+
8+
const placements = Ahorn.PlacementDict()
9+
10+
const modes = ["Loop", "LoopNoPause", "BackAndForth", "BackAndForthNoPause", "TeleportBack"]
11+
12+
for texture in Maple.wood_platform_textures
13+
placements["Platform (Moving, Multi-Node, $(uppercasefirst(texture))) (Spring Collab 2020)"] = Ahorn.EntityPlacement(
14+
MultiNodeMovingPlatform,
15+
"rectangle",
16+
Dict{String, Any}(
17+
"texture" => texture
18+
),
19+
function(entity)
20+
x, y = Int(entity.data["x"]), Int(entity.data["y"])
21+
width = Int(get(entity.data, "width", 8))
22+
entity.data["x"], entity.data["y"] = x + width, y
23+
entity.data["nodes"] = [(x, y)]
24+
end
25+
)
26+
end
27+
28+
Ahorn.editingOptions(entity::MultiNodeMovingPlatform) = Dict{String, Any}(
29+
"texture" => Maple.wood_platform_textures,
30+
"mode" => modes
31+
)
32+
33+
Ahorn.nodeLimits(entity::MultiNodeMovingPlatform) = 1, -1
34+
35+
Ahorn.resizable(entity::MultiNodeMovingPlatform) = true, false
36+
37+
Ahorn.minimumSize(entity::MultiNodeMovingPlatform) = 8, 0
38+
39+
function Ahorn.selection(entity::MultiNodeMovingPlatform)
40+
width = Int(get(entity.data, "width", 8))
41+
42+
nodes = get(entity.data, "nodes", ())
43+
startX, startY = Int(entity.data["x"]), Int(entity.data["y"])
44+
rectangles = Ahorn.Rectangle[Ahorn.Rectangle(startX, startY, width, 8)]
45+
46+
for node in nodes
47+
nodeX, nodeY = Int.(node)
48+
push!(rectangles, Ahorn.Rectangle(nodeX, nodeY, width, 8))
49+
end
50+
51+
return rectangles
52+
end
53+
54+
outerColor = (30, 14, 25) ./ 255
55+
innerColor = (10, 0, 6) ./ 255
56+
57+
function renderConnection(ctx::Ahorn.Cairo.CairoContext, x::Number, y::Number, nx::Number, ny::Number, width::Number)
58+
cx, cy = x + floor(Int, width / 2), y + 4
59+
cnx, cny = nx + floor(Int, width / 2), ny + 4
60+
61+
length = sqrt((x - nx)^2 + (y - ny)^2)
62+
theta = atan(cny - cy, cnx - cx)
63+
64+
Ahorn.Cairo.save(ctx)
65+
66+
Ahorn.translate(ctx, cx, cy)
67+
Ahorn.rotate(ctx, theta)
68+
69+
Ahorn.setSourceColor(ctx, outerColor)
70+
Ahorn.set_antialias(ctx, 1)
71+
Ahorn.set_line_width(ctx, 3);
72+
73+
Ahorn.move_to(ctx, 0, 0)
74+
Ahorn.line_to(ctx, length, 0)
75+
76+
Ahorn.stroke(ctx)
77+
78+
Ahorn.setSourceColor(ctx, innerColor)
79+
Ahorn.set_antialias(ctx, 1)
80+
Ahorn.set_line_width(ctx, 1);
81+
82+
Ahorn.move_to(ctx, 0, 0)
83+
Ahorn.line_to(ctx, length, 0)
84+
85+
Ahorn.stroke(ctx)
86+
87+
Ahorn.Cairo.restore(ctx)
88+
end
89+
90+
function renderPlatform(ctx::Ahorn.Cairo.CairoContext, texture::String, x::Number, y::Number, width::Number)
91+
tilesWidth = div(width, 8)
92+
93+
for i in 2:tilesWidth - 1
94+
Ahorn.drawImage(ctx, "objects/woodPlatform/$texture", x + 8 * (i - 1), y, 8, 0, 8, 8)
95+
end
96+
97+
Ahorn.drawImage(ctx, "objects/woodPlatform/$texture", x, y, 0, 0, 8, 8)
98+
Ahorn.drawImage(ctx, "objects/woodPlatform/$texture", x + tilesWidth * 8 - 8, y, 24, 0, 8, 8)
99+
Ahorn.drawImage(ctx, "objects/woodPlatform/$texture", x + floor(Int, width / 2) - 4, y, 16, 0, 8, 8)
100+
end
101+
102+
function Ahorn.renderAbs(ctx::Ahorn.Cairo.CairoContext, entity::MultiNodeMovingPlatform, room::Maple.Room)
103+
width = Int(get(entity.data, "width", 8))
104+
mode = get(entity.data, "mode", "Loop")
105+
106+
firstNodeX, firstNodeY = Int(entity.data["x"]), Int(entity.data["y"])
107+
previousNodeX, previousNodeY = firstNodeX, firstNodeY
108+
109+
texture = get(entity.data, "texture", "default")
110+
111+
nodes = get(entity.data, "nodes", ())
112+
for node in nodes
113+
nodeX, nodeY = Int.(node)
114+
renderConnection(ctx, previousNodeX, previousNodeY, nodeX, nodeY, width)
115+
previousNodeX, previousNodeY = nodeX, nodeY
116+
end
117+
118+
if mode == "Loop" || mode == "LoopNoPause"
119+
renderConnection(ctx, previousNodeX, previousNodeY, firstNodeX, firstNodeY, width)
120+
end
121+
122+
renderPlatform(ctx, texture, firstNodeX, firstNodeY, width)
123+
end
124+
125+
function Ahorn.renderSelectedAbs(ctx::Ahorn.Cairo.CairoContext, entity::MultiNodeMovingPlatform, room::Maple.Room)
126+
width = Int(get(entity.data, "width", 8))
127+
mode = get(entity.data, "mode", "Loop")
128+
129+
firstNodeX, firstNodeY = Int(entity.data["x"]), Int(entity.data["y"])
130+
previousNodeX, previousNodeY = firstNodeX, firstNodeY
131+
132+
texture = get(entity.data, "texture", "default")
133+
134+
nodes = get(entity.data, "nodes", ())
135+
for node in nodes
136+
nodeX, nodeY = Int.(node)
137+
renderPlatform(ctx, texture, nodeX, nodeY, width)
138+
Ahorn.drawArrow(ctx, previousNodeX + width / 2, previousNodeY, nodeX + width / 2, nodeY, Ahorn.colors.selection_selected_fc, headLength=6)
139+
previousNodeX, previousNodeY = nodeX, nodeY
140+
end
141+
142+
if mode == "Loop" || mode == "LoopNoPause"
143+
Ahorn.drawArrow(ctx, previousNodeX + width / 2, previousNodeY, firstNodeX + width / 2, firstNodeY, Ahorn.colors.selection_selected_fc, headLength=6)
144+
end
145+
end
146+
147+
end

Ahorn/lang/en_gb.lang

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,11 @@ placements.entities.SpringCollab2020/CustomBirdTutorial.tooltips.controls=The co
128128

129129
# Custom Bird Tutorial Trigger
130130
placements.triggers.SpringCollab2020/CustomBirdTutorialTrigger.tooltips.birdId=The ID of the bird this trigger is controlling.
131-
placements.triggers.SpringCollab2020/CustomBirdTutorialTrigger.tooltips.showTutorial=If checked, the trigger will make the bird show the tutorial bubble. If unchecked, the trigger will make the bird fly away.
131+
placements.triggers.SpringCollab2020/CustomBirdTutorialTrigger.tooltips.showTutorial=If checked, the trigger will make the bird show the tutorial bubble. If unchecked, the trigger will make the bird fly away.
132+
133+
# Multi-Node Moving Platform
134+
placements.entities.SpringCollab2020/MultiNodeMovingPlatform.tooltips.moveTime=The time the platform takes to move between two successive positions. Default is 2 seconds.
135+
placements.entities.SpringCollab2020/MultiNodeMovingPlatform.tooltips.pauseTime=The time the platform stops at each position. Default is 0 seconds.
136+
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
137+
placements.entities.SpringCollab2020/MultiNodeMovingPlatform.tooltips.texture=What texture to use for the platform.
138+
placements.entities.SpringCollab2020/MultiNodeMovingPlatform.tooltips.easing=Whether the platform movement should be eased (speedup/slowdown around each position).

0 commit comments

Comments
 (0)