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
Maikel de Vries 2015-12-26 23:04:39 +01:00
parent 124337a5b5
commit d4a6c50d4d
10 changed files with 195 additions and 29 deletions

View File

@ -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 --*/

View File

@ -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.

View File

@ -1,2 +1,3 @@
Name=Ropebridge
Description=Holds the ropebridge.
Name=Bridge post
Description=Holds the rope bridge.
MsgRetractBridge=Retract the rope bridge.

View File

@ -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; }

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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;
}