forked from Mirrors/openclonk
rope bridge can now be placed by a clonk
There are still some things to fix/implement: breaking of bridge ropes when the posts move to far apart, animations for placement and retraction.shapetextures
parent
124337a5b5
commit
d4a6c50d4d
|
@ -1,10 +1,13 @@
|
|||
/**
|
||||
Ropebridge Post
|
||||
This serves as the end of a ropebridge, at which the bridge can be retracted.
|
||||
|
||||
@author Randrian
|
||||
*/
|
||||
|
||||
local double;
|
||||
local bridge;
|
||||
local is_static;
|
||||
|
||||
public func Initialize()
|
||||
{
|
||||
|
@ -32,6 +35,57 @@ public func Turn(int dir)
|
|||
return;
|
||||
}
|
||||
|
||||
public func SetBridge(object to_bridge)
|
||||
{
|
||||
bridge = to_bridge;
|
||||
return;
|
||||
}
|
||||
|
||||
public func SetStatic(bool to_static)
|
||||
{
|
||||
is_static = to_static;
|
||||
return;
|
||||
}
|
||||
|
||||
public func Destruction()
|
||||
{
|
||||
if (double)
|
||||
double->RemoveObject();
|
||||
if (bridge)
|
||||
bridge->OnBridgePostDestruction();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-- Interaction --*/
|
||||
|
||||
public func Interact(object clonk)
|
||||
{
|
||||
// Only an interaction for the real post, not the double.
|
||||
if (is_static || !double)
|
||||
return true;
|
||||
if (!bridge)
|
||||
{
|
||||
RemoveObject();
|
||||
return true;
|
||||
}
|
||||
// Make bridge retract itself.
|
||||
// TODO: implement animation, etc.
|
||||
bridge->RemoveObject();
|
||||
clonk->CreateObjectAbove(Ropebridge, 0, clonk->GetBottom());
|
||||
return true;
|
||||
}
|
||||
|
||||
public func IsInteractable(object clonk)
|
||||
{
|
||||
return !is_static && !!double && clonk->IsWalking();
|
||||
}
|
||||
|
||||
public func GetInteractionMetaInfo(object clonk)
|
||||
{
|
||||
return { Description = "$MsgRetractBridge$", IconName = nil, IconID = nil, Selected = false };
|
||||
}
|
||||
|
||||
|
||||
/*-- Properties --*/
|
||||
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
Name=Hängebrücke
|
||||
Description=Hält die Hängebrücke
|
||||
Name=Brückenpfosten
|
||||
Description=Hält die Hängebrücke.
|
||||
MsgRetractBridge=Die Hängebrücke einziehen.
|
|
@ -1,2 +1,3 @@
|
|||
Name=Ropebridge
|
||||
Description=Holds the ropebridge.
|
||||
Name=Bridge post
|
||||
Description=Holds the rope bridge.
|
||||
MsgRetractBridge=Retract the rope bridge.
|
|
@ -79,6 +79,13 @@ public func GetLoadWeight()
|
|||
return weight;
|
||||
}
|
||||
|
||||
public func Destruction()
|
||||
{
|
||||
if (double)
|
||||
double->RemoveObject();
|
||||
return;
|
||||
}
|
||||
|
||||
// Main bridge object is saved
|
||||
func SaveScenarioObject() { return false; }
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ Vertices=3
|
|||
VertexX=0,-3,3
|
||||
VertexY=4,-3,-3
|
||||
VertexFriction=100,100,100
|
||||
Value=8
|
||||
Value=25
|
||||
Mass=10
|
||||
Components=Wood=2;Rope=2;
|
||||
Rotate=1
|
||||
|
|
|
@ -12,28 +12,53 @@ static const Ladder_Iterations = 10;
|
|||
static const Ladder_Precision = 100;
|
||||
static const Ladder_SegmentLength = 5;
|
||||
|
||||
local bridge_post1;
|
||||
local bridge_post2;
|
||||
|
||||
|
||||
/*-- Bridge Creation --*/
|
||||
|
||||
// Create a rope bridge starting at (x1, y1) and ending at (x2, y2).
|
||||
public func Create(int x1, int y1, int x2, int y2, bool fragile)
|
||||
// Set fragile to make the steps break when pressured.
|
||||
// Set portable to make a bridge which can be retracted.
|
||||
public func Create(int x1, int y1, int x2, int y2, bool fragile, bool portable)
|
||||
{
|
||||
if (this != Ropebridge)
|
||||
return;
|
||||
var bridge_post1 = CreateObjectAbove(Ropebridge_Post, x1, y1);
|
||||
var bridge_post2 = CreateObjectAbove(Ropebridge_Post, x2, y2);
|
||||
bridge_post2->Turn(DIR_Right);
|
||||
var post1 = CreateObjectAbove(Ropebridge_Post, x1, y1);
|
||||
var post2 = CreateObjectAbove(Ropebridge_Post, x2, y2);
|
||||
var bridge = CreateObject(Ropebridge, (x1 + x2) / 2, (y1 + y2) / 2);
|
||||
bridge->MakeBridge(bridge_post1, bridge_post2);
|
||||
bridge->MakeBridge(post1, post2);
|
||||
post1->SetStatic(!portable);
|
||||
post2->SetStatic(!portable);
|
||||
if (fragile)
|
||||
bridge->SetFragile();
|
||||
return;
|
||||
}
|
||||
|
||||
public func MakeBridge(object obj1, object obj2)
|
||||
// Creates the rope bridge between the two bridge posts.
|
||||
public func MakeBridge(object post1, object post2)
|
||||
{
|
||||
this.Collectible = 0;
|
||||
if (post1->GetID() != Ropebridge_Post || post2->GetID() != Ropebridge_Post)
|
||||
return FatalError("Ropebridge can only be connected between bridge posts");
|
||||
// Change the properties of the ropebridge object.
|
||||
this.Collectible = false;
|
||||
SetCategory(C4D_StaticBack);
|
||||
StartRopeConnect(obj1, obj2);
|
||||
// Swap the posts if they have inverted x-coordinates.
|
||||
if (post1->GetX() > post2->GetX())
|
||||
{
|
||||
var swap = post1;
|
||||
post1 = post2;
|
||||
post2 = swap;
|
||||
}
|
||||
// Set the bridge posts.
|
||||
bridge_post1 = post1;
|
||||
bridge_post2 = post2;
|
||||
bridge_post1->SetBridge(this);
|
||||
bridge_post2->SetBridge(this);
|
||||
bridge_post1->Turn(DIR_Left);
|
||||
bridge_post2->Turn(DIR_Right);
|
||||
StartRopeConnect(bridge_post1, bridge_post2);
|
||||
SetFixed(true, true);
|
||||
ConnectPull();
|
||||
AddEffect("IntHang", this, 1, 1, this);
|
||||
|
@ -48,6 +73,52 @@ public func SetFragile()
|
|||
}
|
||||
|
||||
|
||||
/*-- Usage --*/
|
||||
|
||||
public func RejectUse(object clonk)
|
||||
{
|
||||
return !clonk->IsWalking();
|
||||
}
|
||||
|
||||
public func ControlUse(object clonk, int x, int y)
|
||||
{
|
||||
// Create the first bridge post at the clonks feet.
|
||||
if (!bridge_post1)
|
||||
{
|
||||
bridge_post1 = CreateObjectAbove(Ropebridge_Post, 0, clonk->GetBottom());
|
||||
return true;
|
||||
}
|
||||
// Check whether the location of the second post is fine.
|
||||
var from_x = bridge_post1->GetX();
|
||||
var from_y = bridge_post1->GetY() + clonk->GetBottom();
|
||||
var to_x = clonk->GetX();
|
||||
var to_y = clonk->GetY() + clonk->GetBottom();
|
||||
var distance = Distance(from_x, from_y, to_x, to_y);
|
||||
var angle = Angle(from_x, from_y, to_x, to_y);
|
||||
if (distance > 120)
|
||||
{
|
||||
clonk->Message("$MsgBridgeLong$");
|
||||
return true;
|
||||
}
|
||||
if (distance < 40)
|
||||
{
|
||||
clonk->Message("$MsgBridgeShort$");
|
||||
return true;
|
||||
}
|
||||
if (!Inside(angle, 240, 300) && !Inside(angle, 60, 120))
|
||||
{
|
||||
clonk->Message("$MsgBridgeUneven$");
|
||||
return true;
|
||||
}
|
||||
// Create the second bridge post at the clonks feet.
|
||||
bridge_post2 = CreateObjectAbove(Ropebridge_Post, 0, clonk->GetBottom());
|
||||
// Exit the ropebridge and connect between the two posts.
|
||||
Exit();
|
||||
MakeBridge(bridge_post1, bridge_post2);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*-- Rope Mechanics --*/
|
||||
|
||||
public func FxIntHangTimer()
|
||||
|
@ -77,10 +148,27 @@ private func DeleteSegment(object segment, object previous)
|
|||
segment->RemoveObject();
|
||||
}
|
||||
|
||||
// When the last segment is removed.
|
||||
private func RopeRemoved()
|
||||
// Called if either of the posts got destroyed: consider the bridge lost and remove it.
|
||||
public func OnBridgePostDestruction()
|
||||
{
|
||||
RemoveObject();
|
||||
return;
|
||||
}
|
||||
|
||||
public func Destruction()
|
||||
{
|
||||
// Make sure both bridge posts are removed as well.
|
||||
if (bridge_post1)
|
||||
{
|
||||
bridge_post1->SetBridge(nil);
|
||||
bridge_post1->RemoveObject();
|
||||
}
|
||||
if (bridge_post2)
|
||||
{
|
||||
bridge_post2->SetBridge(nil);
|
||||
bridge_post2->RemoveObject();
|
||||
}
|
||||
return _inherited(...);
|
||||
}
|
||||
|
||||
|
||||
|
@ -117,10 +205,13 @@ public func UpdateLines()
|
|||
var segment = lib_rope_segments[i];
|
||||
var particle = lib_rope_particles[i];
|
||||
// Update the position of the segment.
|
||||
segment->SetPosition(particle.x, particle.y, 0, LIB_ROPE_Precision);
|
||||
if (segment->GetDouble())
|
||||
segment->GetDouble()->SetPosition(particle.x, particle.y, 0, LIB_ROPE_Precision);
|
||||
|
||||
if (segment)
|
||||
{
|
||||
segment->SetPosition(particle.x, particle.y, 0, LIB_ROPE_Precision);
|
||||
if (segment->GetDouble())
|
||||
segment->GetDouble()->SetPosition(particle.x, particle.y, 0, LIB_ROPE_Precision);
|
||||
}
|
||||
|
||||
// Calculate the angle to the previous segment.
|
||||
var prev_particle = lib_rope_particles[i - 1];
|
||||
var angle = Angle(particle.x, particle.y, prev_particle.x, prev_particle.y);
|
||||
|
@ -257,6 +348,8 @@ public func Hit()
|
|||
Sound("Hits::Materials::Wood::WoodHit?");
|
||||
}
|
||||
|
||||
public func IsInventorProduct() { return true; }
|
||||
|
||||
|
||||
/*-- Scenario Saving --*/
|
||||
|
||||
|
@ -285,4 +378,5 @@ local ActMap = {
|
|||
},
|
||||
};
|
||||
local Name = "$Name$";
|
||||
local Collectible = 1;
|
||||
local Description = "$Description$";
|
||||
local Collectible = true;
|
||||
|
|
|
@ -1 +1,5 @@
|
|||
Name=Hängebrücke
|
||||
Name=Hängebrücke
|
||||
Description=Short rope bridge which can cover small gaps in the landscape. Press [Use] once to place the left and another time to place the right end of the bridge.
|
||||
MsgBridgeLong=Post can't be placed here, bridge would be too long.
|
||||
MsgBridgeShort=Post can't be placed here, bridge would be too short.
|
||||
MsgBridgeUneven=Post can't be placed here, bridge would be too uneven.
|
|
@ -1 +1,5 @@
|
|||
Name=Suspension bridge
|
||||
Name=Rope Bridge
|
||||
Description=Short rope bridge which can cover small gaps in the landscape. Press [Use] once to place the left and another time to place the right end of the bridge.
|
||||
MsgBridgeLong=Post can't be placed here, bridge would be too long.
|
||||
MsgBridgeShort=Post can't be placed here, bridge would be too short.
|
||||
MsgBridgeUneven=Post can't be placed here, bridge would be too uneven.
|
|
@ -9,7 +9,7 @@ Vertices=3
|
|||
VertexX=0,-3,3
|
||||
VertexY=4,-3,-3
|
||||
VertexFriction=100,100,100
|
||||
Value=8
|
||||
Value=20
|
||||
Mass=10
|
||||
Components=Wood=2;Rope=1;
|
||||
Rotate=1
|
||||
|
|
|
@ -16,12 +16,12 @@ public func Initialize()
|
|||
Ropebridge->Create(80, 152, 176, 152);
|
||||
|
||||
// Series of rope ladders.
|
||||
CreateObjectAbove(Ropeladder, 292, 60)->Unroll(-1, COMD_Up);
|
||||
CreateObjectAbove(Ropeladder, 332, 60)->Unroll(-1, COMD_Up);
|
||||
CreateObjectAbove(Ropeladder, 372, 60)->Unroll(-1, COMD_Up);
|
||||
CreateObjectAbove(Ropeladder, 412, 60)->Unroll(-1, COMD_Up);
|
||||
CreateObjectAbove(Ropeladder, 452, 60)->Unroll(-1, COMD_Up);
|
||||
CreateObjectAbove(Ropeladder, 492, 60)->Unroll(-1, COMD_Up);
|
||||
//CreateObjectAbove(Ropeladder, 292, 60)->Unroll(-1, COMD_Up);
|
||||
//CreateObjectAbove(Ropeladder, 336, 60)->Unroll(-1, COMD_Up);
|
||||
//CreateObjectAbove(Ropeladder, 380, 60)->Unroll(-1, COMD_Up);
|
||||
//CreateObjectAbove(Ropeladder, 424, 60)->Unroll(-1, COMD_Up);
|
||||
//CreateObjectAbove(Ropeladder, 468, 60)->Unroll(-1, COMD_Up);
|
||||
//CreateObjectAbove(Ropeladder, 502, 60)->Unroll(-1, COMD_Up);
|
||||
|
||||
DrawMaterialQuad("Earth", 550, 224, 600, 156, 640, 156, 640, 224);
|
||||
CreateObjectAbove(Ropeladder, 602, 158)->Unroll(1, -1);
|
||||
|
@ -36,6 +36,7 @@ public func InitializePlayer(int plr)
|
|||
GetCrew(plr)->CreateContents(GrappleBow, 2);
|
||||
GetCrew(plr)->CreateContents(Ropeladder);
|
||||
GetCrew(plr)->CreateContents(Shovel);
|
||||
GetCrew(plr)->CreateContents(Ropebridge);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue