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 Ropebridge Post
This serves as the end of a ropebridge, at which the bridge can be retracted.
@author Randrian @author Randrian
*/ */
local double; local double;
local bridge;
local is_static;
public func Initialize() public func Initialize()
{ {
@ -32,6 +35,57 @@ public func Turn(int dir)
return; 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 --*/ /*-- Properties --*/

View File

@ -1,2 +1,3 @@
Name=Hängebrücke Name=Brückenpfosten
Description=Hält die Hängebrücke Description=Hält die Hängebrücke.
MsgRetractBridge=Die Hängebrücke einziehen.

View File

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

View File

@ -79,6 +79,13 @@ public func GetLoadWeight()
return weight; return weight;
} }
public func Destruction()
{
if (double)
double->RemoveObject();
return;
}
// Main bridge object is saved // Main bridge object is saved
func SaveScenarioObject() { return false; } func SaveScenarioObject() { return false; }

View File

@ -9,7 +9,7 @@ Vertices=3
VertexX=0,-3,3 VertexX=0,-3,3
VertexY=4,-3,-3 VertexY=4,-3,-3
VertexFriction=100,100,100 VertexFriction=100,100,100
Value=8 Value=25
Mass=10 Mass=10
Components=Wood=2;Rope=2; Components=Wood=2;Rope=2;
Rotate=1 Rotate=1

View File

@ -12,28 +12,53 @@ static const Ladder_Iterations = 10;
static const Ladder_Precision = 100; static const Ladder_Precision = 100;
static const Ladder_SegmentLength = 5; static const Ladder_SegmentLength = 5;
local bridge_post1;
local bridge_post2;
/*-- Bridge Creation --*/ /*-- Bridge Creation --*/
// Create a rope bridge starting at (x1, y1) and ending at (x2, y2). // 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) if (this != Ropebridge)
return; return;
var bridge_post1 = CreateObjectAbove(Ropebridge_Post, x1, y1); var post1 = CreateObjectAbove(Ropebridge_Post, x1, y1);
var bridge_post2 = CreateObjectAbove(Ropebridge_Post, x2, y2); var post2 = CreateObjectAbove(Ropebridge_Post, x2, y2);
bridge_post2->Turn(DIR_Right);
var bridge = CreateObject(Ropebridge, (x1 + x2) / 2, (y1 + y2) / 2); 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) if (fragile)
bridge->SetFragile(); bridge->SetFragile();
return; 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); 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); SetFixed(true, true);
ConnectPull(); ConnectPull();
AddEffect("IntHang", this, 1, 1, this); 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 --*/ /*-- Rope Mechanics --*/
public func FxIntHangTimer() public func FxIntHangTimer()
@ -77,10 +148,27 @@ private func DeleteSegment(object segment, object previous)
segment->RemoveObject(); segment->RemoveObject();
} }
// When the last segment is removed. // Called if either of the posts got destroyed: consider the bridge lost and remove it.
private func RopeRemoved() public func OnBridgePostDestruction()
{ {
RemoveObject(); 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 segment = lib_rope_segments[i];
var particle = lib_rope_particles[i]; var particle = lib_rope_particles[i];
// Update the position of the segment. // Update the position of the segment.
segment->SetPosition(particle.x, particle.y, 0, LIB_ROPE_Precision); if (segment)
if (segment->GetDouble()) {
segment->GetDouble()->SetPosition(particle.x, particle.y, 0, LIB_ROPE_Precision); 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. // Calculate the angle to the previous segment.
var prev_particle = lib_rope_particles[i - 1]; var prev_particle = lib_rope_particles[i - 1];
var angle = Angle(particle.x, particle.y, prev_particle.x, prev_particle.y); 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?"); Sound("Hits::Materials::Wood::WoodHit?");
} }
public func IsInventorProduct() { return true; }
/*-- Scenario Saving --*/ /*-- Scenario Saving --*/
@ -285,4 +378,5 @@ local ActMap = {
}, },
}; };
local Name = "$Name$"; 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 VertexX=0,-3,3
VertexY=4,-3,-3 VertexY=4,-3,-3
VertexFriction=100,100,100 VertexFriction=100,100,100
Value=8 Value=20
Mass=10 Mass=10
Components=Wood=2;Rope=1; Components=Wood=2;Rope=1;
Rotate=1 Rotate=1

View File

@ -16,12 +16,12 @@ public func Initialize()
Ropebridge->Create(80, 152, 176, 152); Ropebridge->Create(80, 152, 176, 152);
// Series of rope ladders. // Series of rope ladders.
CreateObjectAbove(Ropeladder, 292, 60)->Unroll(-1, COMD_Up); //CreateObjectAbove(Ropeladder, 292, 60)->Unroll(-1, COMD_Up);
CreateObjectAbove(Ropeladder, 332, 60)->Unroll(-1, COMD_Up); //CreateObjectAbove(Ropeladder, 336, 60)->Unroll(-1, COMD_Up);
CreateObjectAbove(Ropeladder, 372, 60)->Unroll(-1, COMD_Up); //CreateObjectAbove(Ropeladder, 380, 60)->Unroll(-1, COMD_Up);
CreateObjectAbove(Ropeladder, 412, 60)->Unroll(-1, COMD_Up); //CreateObjectAbove(Ropeladder, 424, 60)->Unroll(-1, COMD_Up);
CreateObjectAbove(Ropeladder, 452, 60)->Unroll(-1, COMD_Up); //CreateObjectAbove(Ropeladder, 468, 60)->Unroll(-1, COMD_Up);
CreateObjectAbove(Ropeladder, 492, 60)->Unroll(-1, COMD_Up); //CreateObjectAbove(Ropeladder, 502, 60)->Unroll(-1, COMD_Up);
DrawMaterialQuad("Earth", 550, 224, 600, 156, 640, 156, 640, 224); DrawMaterialQuad("Earth", 550, 224, 600, 156, 640, 156, 640, 224);
CreateObjectAbove(Ropeladder, 602, 158)->Unroll(1, -1); CreateObjectAbove(Ropeladder, 602, 158)->Unroll(1, -1);
@ -36,6 +36,7 @@ public func InitializePlayer(int plr)
GetCrew(plr)->CreateContents(GrappleBow, 2); GetCrew(plr)->CreateContents(GrappleBow, 2);
GetCrew(plr)->CreateContents(Ropeladder); GetCrew(plr)->CreateContents(Ropeladder);
GetCrew(plr)->CreateContents(Shovel); GetCrew(plr)->CreateContents(Shovel);
GetCrew(plr)->CreateContents(Ropebridge);
return; return;
} }