forked from Mirrors/openclonk
Add MovingBrick editorprops and graph movement
parent
5e2c39da28
commit
fb400456ce
|
@ -1,19 +1,44 @@
|
|||
/*--
|
||||
Moving Bricks
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
local size; // Length of the brick.
|
||||
|
||||
// Constants
|
||||
local MovementType = { // enum
|
||||
None = nil,
|
||||
Horizontal = 1,
|
||||
Vertical = 2,
|
||||
Graph = 3
|
||||
};
|
||||
local EdgeSpeed_Infinite = -1;
|
||||
local EdgeAdvancement = { // enum: How to select the next edge when advancing on the graph
|
||||
Random = nil,
|
||||
Clockwise = 1,
|
||||
Counterclockwise = 2
|
||||
};
|
||||
|
||||
// Movement properties (for editor)
|
||||
local movement;
|
||||
local movement_speed = 100;
|
||||
// Movement on graph
|
||||
local current_edge_index, current_vertex_index, target_vertex_index;
|
||||
local vertex_wait_time;
|
||||
local last_vx, last_vy, target_pos_x, target_pos_y;
|
||||
|
||||
|
||||
protected func Initialize()
|
||||
{
|
||||
// No movement by default
|
||||
movement = { Type=MovementType.None };
|
||||
// Size defaults to four.
|
||||
SetSize(4);
|
||||
|
||||
// Allow for dynamically changing speeds.
|
||||
ActMap = { Prototype = this.Prototype.ActMap };
|
||||
ActMap.Moving = { Prototype = ActMap.Moving };
|
||||
movement_speed = ActMap.Moving.Speed;
|
||||
|
||||
// Set floating action.
|
||||
SetAction("Moving");
|
||||
|
@ -36,21 +61,35 @@ public func SetSize(int to_size)
|
|||
|
||||
public func SetMoveSpeed(int speed)
|
||||
{
|
||||
ActMap.Moving.Speed = Max(0, speed);
|
||||
movement_speed = ActMap.Moving.Speed = Max(0, speed);
|
||||
return;
|
||||
}
|
||||
|
||||
public func ClearMovement()
|
||||
{
|
||||
RemoveEffect("MoveHorizontal", this);
|
||||
RemoveEffect("MoveVertical", this);
|
||||
RemoveEffect("MoveOnGraph", this);
|
||||
movement = { Type=MovementType.None };
|
||||
current_edge_index = current_vertex_index = -1;
|
||||
SetComDir(COMD_None);
|
||||
SetXDir(); SetYDir();
|
||||
return true;
|
||||
}
|
||||
|
||||
/*-- Horizontal movement --*/
|
||||
|
||||
public func MoveHorizontal(int left, int right, int speed)
|
||||
{
|
||||
RemoveEffect("MoveHorizontal", this); RemoveEffect("MoveVertical", this);
|
||||
ClearMovement();
|
||||
var effect = AddEffect("MoveHorizontal", this, 100, 1, this);
|
||||
effect.Left = left;
|
||||
effect.Right = right;
|
||||
if (speed != nil)
|
||||
SetMoveSpeed(10 * speed);
|
||||
if (GetComDir() != COMD_Right) SetComDir(COMD_Left);
|
||||
// Props for editor display of movement range
|
||||
movement = { Type = MovementType.Horizontal, Graph = [{X=left, Y=GetY()}, {X=right, Y=GetY()}] };
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -71,13 +110,15 @@ private func FxMoveHorizontalTimer(object target, proplist effect)
|
|||
|
||||
public func MoveVertical(int top, int bottom, int speed)
|
||||
{
|
||||
RemoveEffect("MoveHorizontal", this); RemoveEffect("MoveVertical", this);
|
||||
ClearMovement();
|
||||
var effect = AddEffect("MoveVertical", this, 100, 1, this);
|
||||
effect.Top = top;
|
||||
effect.Bottom = bottom;
|
||||
if (speed != nil)
|
||||
SetMoveSpeed(10 * speed);
|
||||
if (GetComDir() != COMD_Down) SetComDir(COMD_Up);
|
||||
// Props for editor display of movement range
|
||||
movement = { Type=MovementType.Vertical, Graph = [{X=GetX(), Y=top}, {X=GetX(), Y=bottom}] };
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -89,18 +130,140 @@ private func FxMoveVerticalTimer(object target, proplist effect)
|
|||
|
||||
if (target->GetY() < effect.Top + 7)
|
||||
if (target->GetComDir() == COMD_Up)
|
||||
SetComDir(COMD_Down);
|
||||
SetComDir(COMD_Down);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*-- Movement on graph --*/
|
||||
|
||||
public func MoveOnGraph(proplist graph)
|
||||
{
|
||||
ClearMovement();
|
||||
movement = { Type = MovementType.Graph, Graph = graph };
|
||||
OnGraphUpdate(movement.Graph);
|
||||
var effect = AddEffect("MoveOnGraph", this, 100, 1, this);
|
||||
return;
|
||||
}
|
||||
|
||||
private func FxMoveOnGraphTimer(object target, proplist effect)
|
||||
{
|
||||
// Vertex wait time?
|
||||
if (vertex_wait_time)
|
||||
{
|
||||
if (!--vertex_wait_time)
|
||||
{
|
||||
OnVertexReached(current_vertex_index, true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Check if the target vertex has been reached
|
||||
var dx = target_pos_x - GetX();
|
||||
var dy = target_pos_y - GetY();
|
||||
if (dx * last_vx + dy * last_vy <= 0)
|
||||
{
|
||||
OnVertexReached(target_vertex_index);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
private func StartEdgeMovement(int edge_index, int edge_direction)
|
||||
{
|
||||
// Initiate movement towards target vertex
|
||||
//Log("%v Start edge movement %v (%v)", this, edge_index, edge_direction);
|
||||
current_edge_index = edge_index;
|
||||
current_vertex_index = -1;
|
||||
var edge = movement.Graph.Edges[edge_index];
|
||||
target_vertex_index = edge.Vertices[edge_direction];
|
||||
var target_vertex = movement.Graph.Vertices[target_vertex_index];
|
||||
target_pos_x = target_vertex.X;
|
||||
target_pos_y = target_vertex.Y;
|
||||
var speed = edge.Speed ?? movement_speed;
|
||||
if (speed == EdgeSpeed_Infinite)
|
||||
{
|
||||
SetPosition(target_pos_x, target_pos_y);
|
||||
speed = 100; // For trigger
|
||||
}
|
||||
else
|
||||
{
|
||||
var dx = target_pos_x - GetX();
|
||||
var dy = target_pos_y - GetY();
|
||||
var d = Max(1, Distance(dx, dy));
|
||||
SetXDir((last_vx = speed * dx / d), 100);
|
||||
SetYDir((last_vy = speed * dy / d), 100);
|
||||
ActMap.Moving.Speed = Max(0, speed);
|
||||
}
|
||||
}
|
||||
|
||||
private func OnVertexReached(int vertex_index, bool after_wait)
|
||||
{
|
||||
//Log("Vertex reached %v (%v)", vertex_index, after_wait);
|
||||
// Safety
|
||||
if (vertex_index < 0 || vertex_index >= GetLength(movement.Graph.Vertices))
|
||||
{
|
||||
vertex_index = 0;
|
||||
}
|
||||
// Called when a vertex has been reached. Perform vertex action & continue movement
|
||||
current_vertex_index = vertex_index;
|
||||
target_vertex_index = -1;
|
||||
var vertex = movement.Graph.Vertices[vertex_index];
|
||||
if (!after_wait)
|
||||
{
|
||||
// Stop for now (befure UserAction because UserAction may do movement)
|
||||
SetXDir(); SetYDir();
|
||||
// Vertex action
|
||||
if (vertex.ArrivalAction)
|
||||
{
|
||||
UserAction->EvaluateAction(vertex.ArrivalAction, this);
|
||||
}
|
||||
// Vertex wait time? Finish for now; function Will be called again later.
|
||||
if (vertex.WaitTime)
|
||||
{
|
||||
vertex_wait_time = vertex.WaitTime;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Find next vertex to continue to
|
||||
var vertex = movement.Graph.Vertices[vertex_index];
|
||||
var n_edges = GetLength(vertex._edges);
|
||||
if (!n_edges) return; // Stuck on an unconnected vertex
|
||||
// First figure out where we came from
|
||||
var last_edge_index = -1; // index in vertex._edges array
|
||||
if (current_edge_index >= 0)
|
||||
{
|
||||
last_edge_index = GetIndexOf(vertex._edges, movement.Graph.Edges[current_edge_index]);
|
||||
}
|
||||
// Advance in specified order
|
||||
var advancement = vertex.Advancement;
|
||||
var next_edge_index = 0; // index in vertex._edges array
|
||||
if (advancement == EdgeAdvancement.Random)
|
||||
{
|
||||
var exclude_current = (last_edge_index >= 0 && n_edges > 1);
|
||||
next_edge_index = Random(n_edges - exclude_current);
|
||||
if (next_edge_index == last_edge_index) next_edge_index += exclude_current;
|
||||
}
|
||||
else if (advancement == EdgeAdvancement.Clockwise)
|
||||
{
|
||||
next_edge_index = (last_edge_index + 1) % n_edges;
|
||||
}
|
||||
else if (advancement == EdgeAdvancement.Counterclockwise)
|
||||
{
|
||||
next_edge_index = last_edge_index - 1;
|
||||
if (next_edge_index < 0) next_edge_index = n_edges - 1;
|
||||
}
|
||||
var next_edge = vertex._edges[next_edge_index];
|
||||
StartEdgeMovement(next_edge._index, next_edge.Vertices[0] == current_vertex_index);
|
||||
}
|
||||
|
||||
|
||||
/* Scenario saving */
|
||||
|
||||
func SaveScenarioObject(props)
|
||||
{
|
||||
if (!inherited(props, ...)) return false;
|
||||
if (size != 4) props->AddCall("Size", this, "SetSize", size);
|
||||
if (ActMap.Moving.Speed != GetID().ActMap.Moving.Speed) props->AddCall("MoveSpeed", this, "SetMoveSpeed", ActMap.Moving.Speed);
|
||||
if (movement_speed != GetID().ActMap.Moving.Speed) props->AddCall("MoveSpeed", this, "SetMoveSpeed", movement_speed);
|
||||
if (GetComDir() == COMD_None) props->Remove("ComDir");
|
||||
return true;
|
||||
}
|
||||
|
@ -117,6 +280,215 @@ func FxMoveVerticalSaveScen(obj, fx, props)
|
|||
return true;
|
||||
}
|
||||
|
||||
func FxMoveGraphSaveScen(obj, fx, props)
|
||||
{
|
||||
props->AddCall("Move", obj, "MoveOnGraph", obj.movement_graph);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Editor */
|
||||
|
||||
public func SetMoveType(new_movement)
|
||||
{
|
||||
var movement_type = new_movement.Type;
|
||||
// Set movement in editor: Set default graphs
|
||||
if (movement_type == MovementType.Horizontal)
|
||||
{
|
||||
MoveHorizontal(Max(GetX()-50, 10), Min(GetX()+50, LandscapeWidth()-10));
|
||||
}
|
||||
else if (movement_type == MovementType.Vertical)
|
||||
{
|
||||
MoveVertical(Max(GetY()-50, 10), Min(GetY()+50, LandscapeHeight()-10));
|
||||
}
|
||||
else if (movement_type == MovementType.Graph)
|
||||
{
|
||||
var x = BoundBy(GetX(), 30, LandscapeWidth()-30), y = BoundBy(GetY(), 50, LandscapeHeight()-50);
|
||||
MoveOnGraph({ Vertices=[{X=x, Y=y}, {X=x-20, Y=y-40}, {X=x+20, Y=y-40}, {X=x, Y=y+40}], Edges=[{Vertices=[0, 1]}, {Vertices=[0, 2]}, {Vertices=[0, 3]}] });
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearMovement();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public func Definition(def)
|
||||
{
|
||||
if (!def.EditorProps) def.EditorProps = {};
|
||||
def.EditorProps.movement_speed = { Name="$Speed$", EditorHelp="$SpeedHelp$", Type="int", Min=5, Set="SetMoveSpeed" };
|
||||
def.EditorProps.movement = { Name="$Movement$", EditorHelp="$MovementHelp$", Type="enum", Set="SetMoveType", OptionKey="Type", ValueKey="Graph", Options=[
|
||||
{ Name="$NoMovement$", EditorHelp="$NoMovementHelp$", Value={Type=MovementType.None} },
|
||||
{ Name="$Horizontal$", EditorHelp="$HorizontalHelp$", Value={Type=MovementType.Horizontal}, Delegate={ Type="polyline", VerticalFix=true, StructureFix=true, OnUpdate="OnHorizontalGraphUpdate", Relative=false, Color=0xff2010 } },
|
||||
{ Name="$Vertical$", EditorHelp="$VerticalHelp$", Value={Type=MovementType.Vertical}, Delegate={ Type="polyline", HorizontalFix=true, StructureFix=true, OnUpdate="OnVerticalGraphUpdate", Relative=false, Color=0x20ff10 } },
|
||||
{ Name="$Graph$", EditorHelp="$GraphHelp$", Value={Type=MovementType.Graph}, Delegate={ Type="graph", OnUpdate="OnGraphUpdate", Relative=false, Color=0xef8000,
|
||||
EdgeDelegate = { Name="$Edge$", EditorHelp="$EdgeHelp$", EditorProps={
|
||||
Speed = { Name="$Speed$", EditorHelp="$EdgeSpeedHelp$", Type="enum", Options=[
|
||||
{Name="$Default$", EditorHelp="$DefaultHelp$"},
|
||||
{Name="$Instant$", EditorHelp="$InstantSpeedHelp$", Value=EdgeSpeed_Infinite },
|
||||
{Name="$CustomSpeed$", EditorHelp="$CustomSpeedHelp$", Type=C4V_Int, Delegate={Type="int", Min=5} }
|
||||
] },
|
||||
} },
|
||||
VertexDelegate = { Name="$Vertex$", EditorHelp="$VertexHelp$", EditorProps={
|
||||
ArrivalAction = new UserAction.Prop { Name="$ArrivalAction$", EditorHelp="$ArrivalActionHelp$" },
|
||||
WaitTime = {Name="$VertexWaitTime$", EditorHelp="$VertexWaitTimeHelp$", Type="int", Min=0},
|
||||
Advancement = { Name="$Advancement$", EditorHelp="$AdvancementHelp$", Type="enum", Options=[
|
||||
{ Name="$Random$", EditorHelp="$RandomAdvancementHelp$", Value=EdgeAdvancement.Random },
|
||||
{ Name="$Clockwise$", EditorHelp="$CWAdvancementHelp$", Value=EdgeAdvancement.Clockwise },
|
||||
{ Name="$Counterclockwise$", EditorHelp="$CCWAdvancementHelp$", Value=EdgeAdvancement.Counterclockwise }
|
||||
] }
|
||||
} },
|
||||
} },
|
||||
]};
|
||||
// TODO: Button to flip direction
|
||||
}
|
||||
|
||||
public func EditCursorMoved(int old_x, int old_y, bool movement_finished)
|
||||
{
|
||||
// Move horizontal/vertical graph elements
|
||||
if (movement.Type == MovementType.Horizontal)
|
||||
{
|
||||
movement.Graph = [{X=movement.Graph[0].X, Y=GetY()}, {X=movement.Graph[1].X, Y=GetY()}];
|
||||
}
|
||||
else if (movement.Type == MovementType.Vertical)
|
||||
{
|
||||
movement.Graph = [{Y=movement.Graph[0].Y, X=GetX()}, {Y=movement.Graph[1].Y, X=GetX()}];
|
||||
}
|
||||
else if (movement.Type == MovementType.Graph)
|
||||
{
|
||||
// Snap to nearest edge if mouse is let go
|
||||
if (movement_finished)
|
||||
{
|
||||
SetPositionToNearestEdge();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stop movment during drag (will be reactivated in SetPositionToNearestEdge)
|
||||
ActMap.Moving.Speed = 0;
|
||||
}
|
||||
}
|
||||
// return true to signal engine to update shapes
|
||||
return true;
|
||||
}
|
||||
|
||||
private func OnHorizontalGraphUpdate(array vertices)
|
||||
{
|
||||
var fx = GetEffect("MoveHorizontal", this);
|
||||
if (fx)
|
||||
{
|
||||
fx.Left = Min(vertices[0].X, vertices[1].X);
|
||||
fx.Right = Max(vertices[0].X, vertices[1].X);
|
||||
}
|
||||
}
|
||||
|
||||
private func OnVerticalGraphUpdate(array vertices)
|
||||
{
|
||||
var fx = GetEffect("MoveVertical", this);
|
||||
if (fx)
|
||||
{
|
||||
fx.Top = Min(vertices[0].Y, vertices[1].Y);
|
||||
fx.Bottom = Max(vertices[0].Y, vertices[1].Y);
|
||||
}
|
||||
}
|
||||
|
||||
private func OnGraphUpdate(proplist graph)
|
||||
{
|
||||
// Graph update
|
||||
// Update vertex indices
|
||||
var vertex, ivertex = 0, n, edge, iedge = 0;
|
||||
for (vertex in graph.Vertices)
|
||||
{
|
||||
vertex._index = ivertex++;
|
||||
}
|
||||
for (edge in graph.Edges)
|
||||
{
|
||||
edge._index = iedge++;
|
||||
}
|
||||
// Update all connectivities
|
||||
for (vertex in graph.Vertices)
|
||||
{
|
||||
// Order connected edges by angle
|
||||
n = 0;
|
||||
vertex._edges = [];
|
||||
for (var edge in graph.Edges)
|
||||
{
|
||||
var evtxidx = GetIndexOf(edge.Vertices, vertex._index);
|
||||
if (evtxidx > -1)
|
||||
{
|
||||
var connected_vertex = graph.Vertices[edge.Vertices[1 - evtxidx]];
|
||||
vertex._edges[n++] = edge;
|
||||
edge._angle = Angle(vertex.X, vertex.Y, connected_vertex.X, connected_vertex.Y);
|
||||
}
|
||||
}
|
||||
// Order them by angle to allow clockwise/counter-clockwise graph traversal
|
||||
SortArrayByProperty(vertex._edges, "_angle");
|
||||
}
|
||||
// Reset position to closest edge
|
||||
SetPositionToNearestEdge();
|
||||
// Done
|
||||
return true;
|
||||
}
|
||||
|
||||
private func SetPositionToNearestEdge()
|
||||
{
|
||||
// First check if we're close to a current vertex
|
||||
var x = GetX(), y = GetY();
|
||||
//Log("x=%d, y=%d", x, y);
|
||||
if (current_vertex_index >= 0 && current_vertex_index < GetLength(movement.Graph.Vertices))
|
||||
{
|
||||
var current_vertex = movement.Graph.Vertices[current_vertex_index];
|
||||
if (Distance(current_vertex.X, current_vertex.Y, x, y) < 8)
|
||||
{
|
||||
// no reset necessery. But do restart edge movement if e.g. stuck on an unconnected vertex that just got connected.
|
||||
if (!vertex_wait_time) OnVertexReached(current_vertex_index, true);
|
||||
}
|
||||
}
|
||||
current_vertex_index = target_vertex_index = -1;
|
||||
vertex_wait_time = 0;
|
||||
// Reset position to closest edge
|
||||
var best_distance, edge_index = 0, best_edge;
|
||||
var proj_x, proj_y, edge_direction;
|
||||
for (var edge in movement.Graph.Edges)
|
||||
{
|
||||
var v0 = movement.Graph.Vertices[edge.Vertices[0]], v1 = movement.Graph.Vertices[edge.Vertices[1]];
|
||||
var dx0 = x - v0.X, dy0 = y - v0.Y;
|
||||
var dx1 = v1.X - v0.X, dy1 = v1.Y - v0.Y;
|
||||
var d = dx1*dx1 + dy1*dy1;
|
||||
// Perpendicular distance
|
||||
var dp = Abs(dx0 * dy1 - dx1 * dy0);
|
||||
// Penalty if outside edge along the edge axis
|
||||
var da = dx0 * dx1 + dy0 * dy1;
|
||||
// Total distance (multiplied by d1 length)
|
||||
var distance = dp + Max(-da) + Max(da - d);
|
||||
//Log("%d (%v, %v) dist = %d", edge_index, {X=v0.X, Y=v0.Y, idx=v0._index}, {X=v1.X, Y=v1.Y, idx=v1._index}, distance);
|
||||
//Log("dx0=%d, dx1=%d, dy0=%d, dy1=%d, d=%d, dp=%d, da=%d, distance=%d", dx0, dx1, dy0, dy1, d, dp, da, distance);
|
||||
if (!edge_index || distance < best_distance)
|
||||
{
|
||||
best_edge = edge_index;
|
||||
best_distance = distance;
|
||||
edge_direction = (last_vx * dx1 + last_vy * dy1 >= 0);
|
||||
if (best_edge == current_edge_index && best_distance/Distance(dx1, dy1) < 6)
|
||||
{
|
||||
// Stay on current edge
|
||||
StartEdgeMovement(best_edge, edge_direction);
|
||||
return;
|
||||
}
|
||||
da = BoundBy(da, 0, d); // Da da da! Stay inside edge range!
|
||||
proj_x = x - dx0 + dx1 * da / d;
|
||||
proj_y = y - dy0 + dy1 * da / d;
|
||||
}
|
||||
++edge_index;
|
||||
}
|
||||
current_edge_index = -1;
|
||||
if (!edge_index) return; // No edges. Nothing to do.
|
||||
//Log("Snap to edge %d", best_edge);
|
||||
// Project position onto closest edge
|
||||
SetPosition(proj_x, proj_y);
|
||||
// Start movement along this edge
|
||||
StartEdgeMovement(best_edge, edge_direction);
|
||||
}
|
||||
|
||||
|
||||
/* Properties */
|
||||
|
||||
local ActMap = {
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
Speed=Geschwindigkeit
|
||||
SpeedHelp=Bewegungsgeschwindigkeit in 1/100px pro Frame
|
||||
Movement=Bewegung
|
||||
MovementHelp=In welchem Muster sich dieser Stein bewegem soll.
|
||||
NoMovement=Keine
|
||||
NoMovementHelp=Der Stein schwebt still in der Luft, wie es Steine so tun.
|
||||
Horizontal=Horizontal
|
||||
HorizontalHelp=Horizontal nach links und rechts zwischen zwei Punkten.
|
||||
Vertical=Vertikal
|
||||
VerticalHelp=Vertikal nach oben und unten zwischen zwei Punkten.
|
||||
Graph=Graph
|
||||
GraphHelp=Bewegung auf einem frei definierbaren Graphen. Punkte hinzufuegen/entfernen mit Umschalt+Steuerung.
|
||||
Edge=Kante
|
||||
EdgeHelp=Kanteneigenschaften
|
||||
EdgeSpeedHelp=Bewegungsgeschwindigkeit in 1/100px pro Frame auf dieser Kante.
|
||||
Default=Standard
|
||||
DefaultHelp=Geschwindigkeit wie im Objekt eingestellt.
|
||||
CustomSpeed=Benutzerdefiniert
|
||||
CustomSpeedHelp=Diese Kante hat eine eigene Geschwindigkeit.
|
||||
Vertex=Eckpunkt
|
||||
VertexHelp=Eigenschaften fuer diesen Knotenpunkt.
|
||||
ArrivalAction=Aktion
|
||||
ArrivalActionHelp=Aktion, die bei Ankunft des Steins an diesem Eckpunkt ausgefuehrt wird.
|
||||
VertexWaitTime=Wartezeit
|
||||
VertexWaitTimeHelp=Wie lange der Stein an diesem Eckpunkt warten soll, ehe er sich weiter bewegt.
|
||||
Advancement=Bewegungsrichtung
|
||||
AdvancementHelp=In welche Richtung sich der Stein nach Ankunft an diesem Eckpunkt weiter bewegen soll.
|
||||
Random=Zufaellig
|
||||
RandomAdvancementHelp=Waehlt eine zufaellige Richtung (ausser der Ankunftsrichtung).
|
||||
Clockwise=Im Uhrzeigersinn
|
||||
CWAdvancementHelp=Der Stein bewegt sich im Uhrzeigersinn von der Ankunftsrichtung weiter.
|
||||
Counterclockwise=Gegen den Uhrzeigersinn
|
||||
CCWAdvancementHelp=Der Stein bewegt sich gegen den Uhrzeigersinn von der Ankunftsrichtung weiter.
|
||||
Instant=Instantan
|
||||
InstantSpeedHelp=Der Stein wird sofort zur naechsten Ecke bewegt.
|
|
@ -0,0 +1,35 @@
|
|||
Speed=Speed
|
||||
SpeedHelp=Movement speed in 1/100px per frame.
|
||||
Movement=Movement
|
||||
MovementHelp=In which pattern this brick shall be moved.
|
||||
NoMovement=None
|
||||
NoMovementHelp=The brick does not move.
|
||||
Horizontal=Horizontal
|
||||
HorizontalHelp=Horizontally from left to right between two points.
|
||||
Vertical=Vertical
|
||||
VerticalHelp=Vertically from top to bottom between two points.
|
||||
Graph=Graph
|
||||
GraphHelp=Movement on a freely definable graph. Add/remove points with ctrl/shift.
|
||||
Edge=Edge
|
||||
EdgeHelp=Edge properties
|
||||
EdgeSpeedHelp=Movement speed in 1/100px per frame on this edge only.
|
||||
Default=Default
|
||||
DefaultHelp=Speed as specified in the object.
|
||||
CustomSpeed=Custom
|
||||
CustomSpeedHelp=This edge has a custom speed.
|
||||
Vertex=Vertex
|
||||
VertexHelp=Properties for this vertex.
|
||||
ArrivalAction=Action
|
||||
ArrivalActionHelp=Action when the brick reaches this vertex.
|
||||
VertexWaitTime=Wait time
|
||||
VertexWaitTimeHelp=How long to wait at this location before movement is continued.
|
||||
Advancement=Movement direction
|
||||
AdvancementHelp=In which direction to continue movement after arrival at this edge point.
|
||||
Random=Random
|
||||
RandomAdvancementHelp=Picks a random direction (excluding where it just came from).
|
||||
Clockwise=Clockwise
|
||||
CWAdvancementHelp=The brick moves clockwise relative to where it came from.
|
||||
Counterclockwise=Counter-clockwise
|
||||
CCWAdvancementHelp=The brick moves counter-clockwise relative to where it came from.
|
||||
Instant=Instantanuous
|
||||
InstantSpeedHelp=The brick is beamed directly to the next vertex.
|
Loading…
Reference in New Issue