forked from Mirrors/openclonk
cable cars: improve network deletion and recreation + clean up
This is a rather chaotic commit and does not solve all problems of network creation yet, but is an improvement over the old system where deletion of a cable line would fail the network. However, we probably need a cleaner method to construct a network properly.master
parent
49d03e52c6
commit
d8736a56ac
|
@ -1,6 +1,10 @@
|
|||
/*-- Cable line --*/
|
||||
/**
|
||||
Cable line
|
||||
|
||||
func Initialize()
|
||||
@author Clonkonaut
|
||||
*/
|
||||
|
||||
public func Initialize()
|
||||
{
|
||||
SetAction("Connect");
|
||||
SetVertexXY(0, GetX(), GetY());
|
||||
|
@ -37,28 +41,44 @@ public func GetConnectedObject(object obj)
|
|||
return GetActionTarget(0);
|
||||
}
|
||||
|
||||
/* Breaking */
|
||||
|
||||
func LineBreak(bool no_msg)
|
||||
/*-- Breaking --*/
|
||||
|
||||
public func OnLineBreak(bool no_msg)
|
||||
{
|
||||
Sound("Objects::Connect");
|
||||
if (GetActionTarget(0)) GetActionTarget(0)->~CableDeactivation(activations);
|
||||
if (GetActionTarget(1)) GetActionTarget(1)->~CableDeactivation(activations);
|
||||
var act1 = GetActionTarget(0);
|
||||
var act2 = GetActionTarget(1);
|
||||
|
||||
SetAction("Idle");
|
||||
if (act1)
|
||||
{
|
||||
act1->~CableDeactivation(activations);
|
||||
act1->~RemoveCableConnection(this);
|
||||
}
|
||||
if (act2)
|
||||
{
|
||||
act2->~CableDeactivation(activations);
|
||||
act2->~RemoveCableConnection(this);
|
||||
}
|
||||
if (!no_msg)
|
||||
BreakMessage();
|
||||
}
|
||||
|
||||
func BreakMessage()
|
||||
public func BreakMessage()
|
||||
{
|
||||
var line_end = GetActionTarget(0);
|
||||
if (line_end->GetID() != CableLorryReel)
|
||||
if (!line_end || line_end->GetID() != CableLorryReel)
|
||||
line_end = GetActionTarget(1);
|
||||
if (line_end->Contained()) line_end = line_end->Contained();
|
||||
|
||||
line_end->Message("$TxtLinebroke$");
|
||||
if (line_end && line_end->Contained())
|
||||
line_end = line_end->Contained();
|
||||
if (line_end)
|
||||
line_end->Message("$TxtLinebroke$");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Activation */
|
||||
|
||||
/*-- Activation --*/
|
||||
|
||||
local activations = 0;
|
||||
|
||||
|
@ -67,7 +87,8 @@ local activations = 0;
|
|||
public func Activation(int count)
|
||||
{
|
||||
// Count must be > 0
|
||||
if (count < 1) return FatalError("Cable Line: Activation() was called with count < 1.");
|
||||
if (count < 1)
|
||||
return FatalError("Cable Line: Activation() was called with count < 1.");
|
||||
activations += count;
|
||||
if (GetActionTarget(0)) GetActionTarget(0)->~CableActivation(count);
|
||||
if (GetActionTarget(1)) GetActionTarget(1)->~CableActivation(count);
|
||||
|
@ -78,22 +99,29 @@ public func Activation(int count)
|
|||
public func Deactivation(int count)
|
||||
{
|
||||
// Count must be > 0
|
||||
if (count < 1) return FatalError("Cable Line: Deactivation() was called with count < 1.");
|
||||
if (count < 1)
|
||||
return FatalError("Cable Line: Deactivation() was called with count < 1.");
|
||||
activations -= count;
|
||||
if (GetActionTarget(0)) GetActionTarget(0)->~CableDeactivation(count);
|
||||
if (GetActionTarget(1)) GetActionTarget(1)->~CableDeactivation(count);
|
||||
}
|
||||
|
||||
/* Saving */
|
||||
|
||||
/*-- Saving --*/
|
||||
|
||||
public func SaveScenarioObject(props)
|
||||
{
|
||||
if (!inherited(props, ...)) return false;
|
||||
if (!inherited(props, ...))
|
||||
return false;
|
||||
SaveScenarioObjectAction(props);
|
||||
if (IsCableLine()) props->AddCall("Connection", this, "SetConnectedObjects", GetActionTarget(0), GetActionTarget(1));
|
||||
if (IsCableLine())
|
||||
props->AddCall("Connection", this, "SetConnectedObjects", GetActionTarget(0), GetActionTarget(1));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*-- Properties --*/
|
||||
|
||||
local ActMap = {
|
||||
Connect = {
|
||||
Prototype = Action,
|
||||
|
@ -103,4 +131,4 @@ local ActMap = {
|
|||
}
|
||||
};
|
||||
|
||||
local Name = "$Name$";
|
||||
local Name = "$Name$";
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
/*-- Cable reel --*/
|
||||
/**
|
||||
Cable reel
|
||||
Connects cable stations.
|
||||
|
||||
@author Clonkonaut
|
||||
*/
|
||||
|
||||
protected func Hit()
|
||||
{
|
||||
|
@ -7,6 +12,7 @@ protected func Hit()
|
|||
|
||||
public func IsToolProduct() { return true; }
|
||||
|
||||
|
||||
/*-- Line connection --*/
|
||||
|
||||
protected func ControlUse(object clonk, int x, int y)
|
||||
|
@ -32,7 +38,7 @@ protected func ControlUse(object clonk, int x, int y)
|
|||
else
|
||||
{
|
||||
// Connect existing power line to obj.
|
||||
if(line->GetActionTarget(0) == this)
|
||||
if (line->GetActionTarget(0) == this)
|
||||
line->SetActionTargets(obj, line->GetActionTarget(1));
|
||||
else if(line->GetActionTarget(1) == this)
|
||||
line->SetActionTargets(line->GetActionTarget(0), obj);
|
||||
|
@ -63,6 +69,9 @@ private func Find_CableLine(object obj)
|
|||
return [C4FO_Func, "IsConnectedTo", obj];
|
||||
}
|
||||
|
||||
|
||||
/*-- Properties --*/
|
||||
|
||||
local Name = "$Name$";
|
||||
local Description = "$Description$";
|
||||
local Collectible = 1;
|
||||
|
|
|
@ -24,7 +24,8 @@ local lib_ccar_destination;
|
|||
// Current delivery the car is on, array: [starting station, target station, requested objects, amount]
|
||||
local lib_ccar_delivery;
|
||||
|
||||
/*--- Overloads ---*/
|
||||
|
||||
/*-- Overloads --*/
|
||||
|
||||
// Overload these functions as you feel fit
|
||||
|
||||
|
@ -52,7 +53,8 @@ func OnStart() {}
|
|||
// failed is true if the movement to a destination was cancelled (usually because the path broke in the meantime)
|
||||
func OnStop(bool failed) {}
|
||||
|
||||
/*--- Interface ---*/
|
||||
|
||||
/*-- Interface --*/
|
||||
|
||||
// Sets the speed of the cable car
|
||||
public func SetCableSpeed(int value)
|
||||
|
@ -97,13 +99,14 @@ public func DoMovement()
|
|||
var origin = CreateArray(2), ending = CreateArray(2);
|
||||
lib_ccar_rail->GetActionTarget(start)->GetCablePosition(origin, prec);
|
||||
lib_ccar_rail->GetActionTarget(end)->GetCablePosition(ending, prec);
|
||||
position[0] = origin[0] + (ending[0] - origin[0]) * lib_ccar_progress/lib_ccar_max_progress;
|
||||
position[1] = origin[1] + (ending[1] - origin[1]) * lib_ccar_progress/lib_ccar_max_progress;
|
||||
position[0] = origin[0] + (ending[0] - origin[0]) * lib_ccar_progress / lib_ccar_max_progress;
|
||||
position[1] = origin[1] + (ending[1] - origin[1]) * lib_ccar_progress / lib_ccar_max_progress;
|
||||
GetCableOffset(position, prec);
|
||||
SetPosition(position[0], position[1], 1, prec);
|
||||
}
|
||||
|
||||
/*--- Status ---*/
|
||||
|
||||
/*-- Status --*/
|
||||
|
||||
public func IsCableCar() { return true; }
|
||||
|
||||
|
@ -113,7 +116,8 @@ public func GetRailTarget() { return lib_ccar_rail; }
|
|||
|
||||
public func IsTravelling() { return lib_ccar_destination; }
|
||||
|
||||
/* Interaction */
|
||||
|
||||
/*-- Interaction --*/
|
||||
|
||||
// Provides an own interaction menu.
|
||||
public func HasInteractionMenu() { return true; }
|
||||
|
@ -185,7 +189,9 @@ public func GetCableCarMenuEntries(object clonk)
|
|||
};
|
||||
PushBack(menu_entries, { symbol = this, extra_data = "NoStation", custom = search });
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start the trip
|
||||
if (!IsTravelling())
|
||||
{
|
||||
|
@ -227,12 +233,22 @@ public func OnCableCarHover(symbol, extra_data, desc_menu_target, menu_id)
|
|||
GuiUpdate({ Text = text }, menu_id, 1, desc_menu_target);
|
||||
}
|
||||
|
||||
/*--- Travelling ---*/
|
||||
|
||||
/*-- Travelling --*/
|
||||
|
||||
// Called when the network is updated.
|
||||
public func OnRailNetworkUpdate()
|
||||
{
|
||||
// The car may have been stuck on a request, continue it now.
|
||||
ContinueRequest();
|
||||
return;
|
||||
}
|
||||
|
||||
// Attach the car onto a crossing
|
||||
public func EngageRail(object crossing, bool silent)
|
||||
{
|
||||
if (! crossing->~IsCableCrossing()) return false;
|
||||
if (!crossing->~IsCableCrossing())
|
||||
return false;
|
||||
|
||||
var position = CreateArray(2);
|
||||
crossing->GetCablePosition(position);
|
||||
|
@ -244,7 +260,8 @@ public func EngageRail(object crossing, bool silent)
|
|||
SetComDir(COMD_None);
|
||||
lib_ccar_rail = crossing;
|
||||
lib_ccar_direction = nil;
|
||||
if (!silent) Sound("Objects::Connect");
|
||||
if (!silent)
|
||||
Sound("Objects::Connect");
|
||||
UpdateInteractionMenus(this.GetCableCarMenuEntries);
|
||||
|
||||
Engaged();
|
||||
|
@ -262,21 +279,23 @@ public func DisengageRail()
|
|||
UpdateInteractionMenus(this.GetCableCarMenuEntries);
|
||||
|
||||
Disengaged();
|
||||
if (lib_ccar_rail) lib_ccar_rail->OnCableCarDisengaged(this);
|
||||
if (lib_ccar_rail)
|
||||
lib_ccar_rail->OnCableCarDisengaged(this);
|
||||
}
|
||||
|
||||
// Sets a target point for travelling and starts the movement process
|
||||
public func SetDestination(dest)
|
||||
{
|
||||
if(GetType(dest) == C4V_Int)
|
||||
if (GetType(dest) == C4V_Int)
|
||||
{
|
||||
dest = FindObjects(Find_Func("IsCableCrossing"))[dest];
|
||||
if (!dest) return;
|
||||
if (!dest)
|
||||
return;
|
||||
}
|
||||
|
||||
lib_ccar_destination = dest;
|
||||
|
||||
if(lib_ccar_direction == nil)
|
||||
if (lib_ccar_direction == nil)
|
||||
{
|
||||
OnStart();
|
||||
CrossingReached();
|
||||
|
@ -286,24 +305,25 @@ public func SetDestination(dest)
|
|||
}
|
||||
|
||||
// Whenever a crossing is reached it must be queried for the next crossing to go to
|
||||
func CrossingReached()
|
||||
public func CrossingReached()
|
||||
{
|
||||
var target;
|
||||
if(lib_ccar_destination != lib_ccar_rail)
|
||||
if (lib_ccar_destination != lib_ccar_rail)
|
||||
{
|
||||
if(target = lib_ccar_rail->GetNextWaypoint(lib_ccar_destination))
|
||||
if (target = lib_ccar_rail->GetNextWaypoint(lib_ccar_destination))
|
||||
MoveTo(target);
|
||||
else
|
||||
DestinationFailed();
|
||||
}
|
||||
// Destination reached
|
||||
else {
|
||||
else
|
||||
{
|
||||
DestinationReached();
|
||||
}
|
||||
}
|
||||
|
||||
// When the current destination is reached
|
||||
func DestinationReached()
|
||||
public func DestinationReached()
|
||||
{
|
||||
lib_ccar_destination = nil;
|
||||
lib_ccar_direction = nil;
|
||||
|
@ -321,8 +341,11 @@ func DestinationReached()
|
|||
}
|
||||
|
||||
// When the way to the current destination has vanished somehow
|
||||
func DestinationFailed()
|
||||
public func DestinationFailed()
|
||||
{
|
||||
if (lib_ccar_rail)
|
||||
lib_ccar_rail->OnCableCarStopped(this);
|
||||
|
||||
lib_ccar_destination = nil;
|
||||
lib_ccar_direction = nil;
|
||||
lib_ccar_progress = 0;
|
||||
|
@ -331,8 +354,14 @@ func DestinationFailed()
|
|||
OnStop(true);
|
||||
}
|
||||
|
||||
public func Destruction()
|
||||
{
|
||||
if (lib_ccar_rail)
|
||||
lib_ccar_rail->OnCableCarDestruction(this);
|
||||
}
|
||||
|
||||
// Setup movement process
|
||||
func MoveToIndex(int dest)
|
||||
public func MoveToIndex(int dest)
|
||||
{
|
||||
var dest_obj = FindObjects(Find_Func("IsCableCrossing"))[dest];
|
||||
if (dest_obj) return MoveTo(dest_obj);
|
||||
|
@ -341,19 +370,19 @@ func MoveToIndex(int dest)
|
|||
public func MoveTo(object dest)
|
||||
{
|
||||
var rail = 0;
|
||||
for(var test_rail in FindObjects(Find_Func("IsConnectedTo", lib_ccar_rail)))
|
||||
for (var test_rail in FindObjects(Find_Func("IsConnectedTo", lib_ccar_rail)))
|
||||
{
|
||||
if(test_rail->IsConnectedTo(dest))
|
||||
if (test_rail->IsConnectedTo(dest))
|
||||
{
|
||||
rail = test_rail;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!rail)
|
||||
if (!rail)
|
||||
return DestinationFailed(); // Shouldn't happen
|
||||
|
||||
// Target the first or second action target?
|
||||
if(rail->GetActionTarget(0) == dest)
|
||||
if (rail->GetActionTarget(0) == dest)
|
||||
lib_ccar_direction = 0;
|
||||
else
|
||||
lib_ccar_direction = 1;
|
||||
|
@ -366,14 +395,14 @@ public func MoveTo(object dest)
|
|||
lib_ccar_rail = rail;
|
||||
}
|
||||
|
||||
/* Destination selection */
|
||||
|
||||
/*-- Destination selection --*/
|
||||
|
||||
public func OpenDestinationSelection(object clonk)
|
||||
{
|
||||
if (!clonk) return;
|
||||
if (!GetRailTarget()) return;
|
||||
|
||||
var plr = clonk->GetOwner();
|
||||
// Close interaction menu
|
||||
if (clonk->GetMenu())
|
||||
if (!clonk->TryCancelMenu())
|
||||
|
@ -382,6 +411,7 @@ public func OpenDestinationSelection(object clonk)
|
|||
GUI_DestinationSelectionMenu->CreateFor(clonk, this, GetRailTarget());
|
||||
}
|
||||
|
||||
|
||||
/*-- Delivery --*/
|
||||
|
||||
public func AddRequest(proplist requested, int amount, proplist target, proplist source)
|
||||
|
@ -390,9 +420,17 @@ public func AddRequest(proplist requested, int amount, proplist target, proplist
|
|||
SetDestination(target);
|
||||
}
|
||||
|
||||
func FinishedRequest(object station)
|
||||
public func ContinueRequest()
|
||||
{
|
||||
if (!lib_ccar_delivery)
|
||||
return;
|
||||
var target = lib_ccar_delivery[1];
|
||||
SetDestination(target);
|
||||
}
|
||||
|
||||
public func FinishedRequest(object station)
|
||||
{
|
||||
if (station && lib_ccar_delivery)
|
||||
station->RequestArrived(this, lib_ccar_delivery[2], lib_ccar_delivery[3]);
|
||||
lib_ccar_delivery = nil;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ public func CableDeactivation(int count) { }
|
|||
// Called by arriving cable cars if this station is the final stop
|
||||
public func OnCableCarArrival(object car) { }
|
||||
|
||||
// Called by cable cars if it stopped at this station (usually because of a problem)
|
||||
public func OnCableCarStopped(object car) { }
|
||||
|
||||
// Called by departing cable cars if it just starts a new journey
|
||||
public func OnCableCarDeparture(object car) { }
|
||||
|
||||
|
@ -35,6 +38,9 @@ public func OnCableCarEngaged(object car) { }
|
|||
// Called by a cable car that has been taken off the rail at this station
|
||||
public func OnCableCarDisengaged(object car) { }
|
||||
|
||||
// Called by a cable car that has been destroyed at this station
|
||||
public func OnCableCarDestruction(object car) { }
|
||||
|
||||
// Called when a cable car with a requested delivery arrives
|
||||
public func OnCableCarDelivery(object car, id requested, int amount) { }
|
||||
|
||||
|
@ -56,26 +62,10 @@ public func Construction()
|
|||
return _inherited(...);
|
||||
}
|
||||
|
||||
/* Removes this crossing from the network
|
||||
It first clears every waypoint from the network and then renews the whole information.
|
||||
Optimisation welcome!
|
||||
*/
|
||||
public func Destruction()
|
||||
{
|
||||
for (var connection in FindObjects(Find_Func("IsConnectedTo", this)))
|
||||
{
|
||||
if (!connection->~IsCableLine()) continue;
|
||||
var other_crossing = connection->~GetConnectedObject(this);
|
||||
if (!other_crossing || !other_crossing->~IsCableCrossing()) continue;
|
||||
other_crossing->ClearConnections(this);
|
||||
}
|
||||
for (var connection in FindObjects(Find_Func("IsConnectedTo", this)))
|
||||
{
|
||||
if (!connection->~IsCableLine()) continue;
|
||||
var other_crossing = connection->~GetConnectedObject(this);
|
||||
if (!other_crossing || !other_crossing->~IsCableCrossing()) continue;
|
||||
other_crossing->RenewConnections(this);
|
||||
}
|
||||
// The connection with other stations is broken via the cable and the network updating is handled there.
|
||||
// So there is updating to be performed here.
|
||||
return _inherited(...);
|
||||
}
|
||||
|
||||
|
@ -106,7 +96,8 @@ public func SetCableStation(bool station)
|
|||
// Returns the cable hookup position for proper positioning of a car along the line.
|
||||
public func GetCablePosition(array coordinates, int prec)
|
||||
{
|
||||
if (!prec) prec = 1;
|
||||
if (!prec)
|
||||
prec = 1;
|
||||
coordinates[0] = GetX(prec);
|
||||
coordinates[1] = GetY(prec);
|
||||
if (this.LineAttach)
|
||||
|
@ -153,19 +144,23 @@ public func GetDestinationList(object middle)
|
|||
AddCableConnection(object cable)
|
||||
AddCableDestinations(array new_list, object crossing)
|
||||
AddCableDestination(object new_destination, object crossing, int distance_add)
|
||||
ClearConnections(object crossing)
|
||||
RenewConnections(object crossing)
|
||||
ClearConnections()
|
||||
RenewConnections()
|
||||
*/
|
||||
|
||||
/** Returns the destination array so it can be used by other crossings.
|
||||
*/
|
||||
public func GetDestinations()
|
||||
{
|
||||
return destination_list[:];
|
||||
// This is a nested array, so ensure a proper deep copy is made.
|
||||
var deep_copy = [];
|
||||
for (var dest in destination_list)
|
||||
PushBack(deep_copy, dest[:]);
|
||||
return deep_copy;
|
||||
}
|
||||
|
||||
// Stores the next crossing (waypoint) to take when advancing to a certain final point
|
||||
// Scheme (2D array): [Desired final point, Next waypoint to take, Distance (not airline!) until final point]
|
||||
// Stores the next crossing (waypoint) to take when advancing to a certain final point. The list may not contain the crossing itself.
|
||||
// Scheme (2D array): [Desired final point, Next waypoint to take, Distance (not airline!) until final point].
|
||||
local destination_list;
|
||||
|
||||
// Constants for easier script reading
|
||||
|
@ -181,16 +176,25 @@ local const_distance = 2;
|
|||
public func AddCableConnection(object cable)
|
||||
{
|
||||
// Failsafe
|
||||
if (!cable || ! cable->~IsCableLine())
|
||||
if (!cable || !cable->~IsCableLine())
|
||||
return false;
|
||||
// Line setup finished?
|
||||
var other_crossing = cable->~GetConnectedObject(this);
|
||||
if (! other_crossing->~IsCableCrossing())
|
||||
if (!other_crossing || !other_crossing->~IsCableCrossing())
|
||||
return false;
|
||||
// Acquire destinations of the other crossing, all these are now in reach
|
||||
AddCableDestinations(other_crossing->GetDestinations(), other_crossing);
|
||||
// Send own destinations, now in reach for the other one
|
||||
other_crossing->AddCableDestinations(destination_list[:], this);
|
||||
other_crossing->AddCableDestinations(GetDestinations(), this);
|
||||
// Awesome, more power to the network!
|
||||
DestinationsUpdated();
|
||||
return true;
|
||||
}
|
||||
|
||||
public func RemoveCableConnection(object cable)
|
||||
{
|
||||
// It is easiest to just update all connections.
|
||||
UpdateConnections();
|
||||
// Awesome, more power to the network!
|
||||
DestinationsUpdated();
|
||||
return true;
|
||||
|
@ -200,28 +204,28 @@ public func AddCableConnection(object cable)
|
|||
* @param new_list The new destination list, formated like a crossing's normal destination list
|
||||
* @param crossing The crossing where this list comes from
|
||||
*/
|
||||
public func AddCableDestinations(array new_list, object crossing)
|
||||
public func AddCableDestinations(array new_list, object crossing, bool has_reversed)
|
||||
{
|
||||
// Append crossing to the list
|
||||
if (crossing)
|
||||
{
|
||||
new_list[GetLength(new_list)] = [crossing, crossing];
|
||||
// This value is to be added to every distance
|
||||
var distance_add = ObjectDistance(crossing);
|
||||
}
|
||||
else
|
||||
return false; // Does not compute
|
||||
if (!crossing)
|
||||
return false;
|
||||
// Append crossing itself to the list with zero distance.
|
||||
new_list[GetLength(new_list)] = [crossing, crossing, 0];
|
||||
// This value is to be added to every distance
|
||||
var distance_add = ObjectDistance(crossing);
|
||||
// Check every new destination
|
||||
for (var list_item in new_list)
|
||||
{
|
||||
if (!list_item) continue;
|
||||
// Destination is this
|
||||
if (list_item[const_finaldestination] == this) continue;
|
||||
// Check whether the destination is already in reach
|
||||
if (!list_item)
|
||||
continue;
|
||||
// Destination may not be this crossing.
|
||||
if (list_item[const_finaldestination] == this)
|
||||
continue;
|
||||
// Check whether the destination is already in already in the list.
|
||||
var handled = false;
|
||||
for (var i = 0, destination = false; i < GetLength(destination_list); i++)
|
||||
for (var i = 0, destination = nil; i < GetLength(destination_list); i++)
|
||||
{
|
||||
if (!destination_list[i]) continue;
|
||||
if (!destination_list[i])
|
||||
continue;
|
||||
destination = destination_list[i];
|
||||
if (destination[const_finaldestination] == list_item[const_finaldestination])
|
||||
{
|
||||
|
@ -231,18 +235,55 @@ public func AddCableDestinations(array new_list, object crossing)
|
|||
{
|
||||
// It is shorter, replace, route through crossing
|
||||
destination_list[i] = [list_item[const_finaldestination], crossing, list_item[const_distance] + distance_add];
|
||||
// Inform the destination
|
||||
// Inform the destination.
|
||||
list_item[const_finaldestination]->UpdateCableDestination(this, crossing, distance_add);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Destination is replaced or to be dismissed (because the new path would be longer), do nothing
|
||||
if (handled) continue;
|
||||
// Destination is a new one, add to the list
|
||||
destination_list[GetLength(destination_list)] = [list_item[const_finaldestination], crossing, list_item[const_distance] + distance_add];
|
||||
// Add me to the new destination (the way to me is the same than to crossing)
|
||||
if (list_item[const_finaldestination] != crossing)
|
||||
list_item[const_finaldestination]->AddCableDestination(this, crossing, distance_add);
|
||||
|
||||
// Destination is replaced or to be dismissed (because the new path would be longer), do nothing.
|
||||
if (handled)
|
||||
continue;
|
||||
|
||||
// Destination is a new one, add to the list.
|
||||
AddCableDestination(list_item[const_finaldestination], crossing, list_item[const_distance] + distance_add);
|
||||
// Add me to the new destination (the way to me is the same than to crossing).
|
||||
if (list_item[const_finaldestination] != crossing && !has_reversed)
|
||||
{
|
||||
// This new crossing may have a bunch of other connections that need to be explored and potentially added.
|
||||
// The new crossing is connected to this crossing via the crossing specified as the parameter to this function.
|
||||
// So for the new destinations we want to add, we need to add the distance to the crossing.
|
||||
var add_destinations = list_item[const_finaldestination]->GetDestinations();
|
||||
var add_dest_distance = 0;
|
||||
for (var dest in crossing->GetDestinations())
|
||||
if (dest[const_finaldestination] == list_item[const_finaldestination])
|
||||
add_dest_distance = dest[const_distance];
|
||||
for (var dest in add_destinations)
|
||||
dest[const_distance] += add_dest_distance;
|
||||
this->AddCableDestinations(add_destinations, crossing, has_reversed);
|
||||
|
||||
// However, this crossing and its destinations must also be added in reverse to the new crossing found.
|
||||
var reverse_destinations = this->GetDestinations();
|
||||
PushBack(reverse_destinations, [this, crossing, 0]);
|
||||
var reverse_crossing = nil;
|
||||
for (var dest in list_item[const_finaldestination]->GetDestinations())
|
||||
if (dest[const_finaldestination] == crossing)
|
||||
reverse_crossing = dest[const_nextwaypoint];
|
||||
if (reverse_crossing == nil)
|
||||
return FatalError("AddCableDestinations(): reverse_crossing not found.");
|
||||
var add_reverse_distance = distance_add;
|
||||
if (reverse_crossing != crossing)
|
||||
{
|
||||
for (var dest in reverse_crossing->GetDestinations())
|
||||
if (dest[const_finaldestination] == crossing)
|
||||
add_reverse_distance += dest[const_distance];
|
||||
if (add_reverse_distance == distance_add)
|
||||
return FatalError("AddCableDestinations(): reverse_distance not correct.");
|
||||
}
|
||||
for (var dest in reverse_destinations)
|
||||
dest[const_distance] += add_reverse_distance;
|
||||
list_item[const_finaldestination]->AddCableDestinations(reverse_destinations, reverse_crossing, true);
|
||||
}
|
||||
}
|
||||
DestinationsUpdated();
|
||||
return true;
|
||||
|
@ -253,28 +294,19 @@ public func AddCableDestinations(array new_list, object crossing)
|
|||
* @param crossing The crossing which links to the new destination
|
||||
* @param distance_add The distance between crossing and new_destination
|
||||
*/
|
||||
public func AddCableDestination(object new_destination, object crossing, int distance_add)
|
||||
public func AddCableDestination(object new_destination, object crossing, int distance)
|
||||
{
|
||||
// Failsafe
|
||||
if (!new_destination || !crossing) return false;
|
||||
if (new_destination == this) return false;
|
||||
// Find the entry of crossing to get the next waypoint and the distance
|
||||
var crossing_item;
|
||||
for (var list_item in destination_list)
|
||||
{
|
||||
if (!list_item) continue;
|
||||
if (list_item[const_finaldestination] == crossing)
|
||||
{
|
||||
crossing_item = list_item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Failsafe
|
||||
if (!crossing_item) return false;
|
||||
// Save the new destination
|
||||
destination_list[GetLength(destination_list)] = [new_destination, crossing_item[const_nextwaypoint], crossing_item[const_distance] + distance_add];
|
||||
// Failsafes.
|
||||
if (!new_destination || !crossing)
|
||||
return;
|
||||
if (new_destination == this)
|
||||
return;
|
||||
if (!IsDirectlyConnectToCrossing(crossing))
|
||||
return FatalError(Format("destination to %v for %v is not connected to crossing link %v.", new_destination, this, crossing));
|
||||
// Add to destination list.
|
||||
PushBack(destination_list, [new_destination, crossing, distance]);
|
||||
DestinationsUpdated();
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
/** Updates the path to \a known_destination via \a crossing (e.g. because the path is shorter through \a crossing)
|
||||
|
@ -291,7 +323,8 @@ public func UpdateCableDestination(object known_destination, object crossing, in
|
|||
var crossing_item, destination_item, i = 0;
|
||||
for (var list_item in destination_list)
|
||||
{
|
||||
if (!list_item) continue;
|
||||
if (!list_item)
|
||||
continue;
|
||||
if (list_item[const_finaldestination] == crossing)
|
||||
crossing_item = list_item;
|
||||
if (list_item[const_finaldestination] == known_destination)
|
||||
|
@ -299,7 +332,8 @@ public func UpdateCableDestination(object known_destination, object crossing, in
|
|||
i++;
|
||||
}
|
||||
// Failsafe
|
||||
if (!crossing_item || !destination_item) return false;
|
||||
if (!crossing_item || !destination_item)
|
||||
return false;
|
||||
// Save the updated path
|
||||
destination_list[destination_item][const_nextwaypoint] = crossing_item[const_nextwaypoint];
|
||||
destination_list[destination_item][const_distance] = crossing_item[const_distance] + distance_add;
|
||||
|
@ -309,42 +343,68 @@ public func UpdateCableDestination(object known_destination, object crossing, in
|
|||
|
||||
local clearing;
|
||||
|
||||
/* Called automatically by Destruction, see description there
|
||||
* @param crossing The calling crossing
|
||||
*/
|
||||
public func ClearConnections(object crossing)
|
||||
// Updates the network for this crossing, this is called when a cable to this crossing has changed.
|
||||
// It first clears every waypoint from the network and then renews the whole information.
|
||||
public func UpdateConnections()
|
||||
{
|
||||
if (clearing) return;
|
||||
// Clear this crossing and then other connected crossings.
|
||||
ClearConnections();
|
||||
RenewConnections();
|
||||
return;
|
||||
}
|
||||
|
||||
// Called automatically by UpdateConnections, see description there.
|
||||
public func ClearConnections()
|
||||
{
|
||||
if (clearing)
|
||||
return;
|
||||
clearing = true;
|
||||
destination_list = [];
|
||||
for (var connection in FindObjects(Find_Func("IsConnectedTo", this)))
|
||||
{
|
||||
if (!connection->~IsCableLine()) continue;
|
||||
if (!connection->~IsCableLine())
|
||||
continue;
|
||||
var other_crossing = connection->~GetConnectedObject(this);
|
||||
if (!other_crossing || !other_crossing->~IsCableCrossing()) continue;
|
||||
if (!other_crossing || !other_crossing->~IsCableCrossing())
|
||||
continue;
|
||||
other_crossing->ClearConnections();
|
||||
}
|
||||
}
|
||||
|
||||
/* Called automatically by Destruction, see description there
|
||||
* @param crossing The calling crossing
|
||||
*/
|
||||
public func RenewConnections(object crossing)
|
||||
// Called automatically by UpdateConnections, see description there.
|
||||
public func RenewConnections()
|
||||
{
|
||||
if (!clearing) return;
|
||||
if (!clearing)
|
||||
return;
|
||||
clearing = false;
|
||||
for(var connection in FindObjects(Find_Func("IsConnectedTo", this)))
|
||||
for (var connection in FindObjects(Find_Func("IsConnectedTo", this)))
|
||||
{
|
||||
if (!connection->~IsCableLine()) continue;
|
||||
if (!connection->~IsCableLine())
|
||||
continue;
|
||||
var other_crossing = connection->~GetConnectedObject(this);
|
||||
if (!other_crossing || !other_crossing->~IsCableCrossing()) continue;
|
||||
if (other_crossing == crossing) continue;
|
||||
destination_list[GetLength(destination_list)] = [other_crossing, other_crossing, ObjectDistance(other_crossing)];
|
||||
if (!other_crossing || !other_crossing->~IsCableCrossing())
|
||||
continue;
|
||||
PushBack(destination_list, [other_crossing, other_crossing, ObjectDistance(other_crossing)]);
|
||||
AddCableDestinations(other_crossing->GetDestinations(), other_crossing);
|
||||
other_crossing->RenewConnections();
|
||||
}
|
||||
}
|
||||
|
||||
/*--- Pathfinding ---*/
|
||||
// Returns whether there is a direct conenctions between this and the other crossing.
|
||||
public func IsDirectlyConnectToCrossing(object other_crossing)
|
||||
{
|
||||
for (var connection in FindObjects(Find_Func("IsConnectedTo", this)))
|
||||
{
|
||||
if (!connection->~IsCableLine())
|
||||
continue;
|
||||
if (other_crossing == connection->~GetConnectedObject(this))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*-- Pathfinding --*/
|
||||
|
||||
/* Functions:
|
||||
GetNextWaypoint(object end)
|
||||
|
@ -356,10 +416,12 @@ public func RenewConnections(object crossing)
|
|||
*/
|
||||
public func GetNextWaypoint(object end)
|
||||
{
|
||||
if (!destination_list) return nil;
|
||||
if (!destination_list)
|
||||
return nil;
|
||||
for (var item in destination_list)
|
||||
{
|
||||
if (!item) continue;
|
||||
if (!item)
|
||||
continue;
|
||||
if (item[const_finaldestination] == end)
|
||||
return item[const_nextwaypoint];
|
||||
}
|
||||
|
@ -372,16 +434,19 @@ public func GetNextWaypoint(object end)
|
|||
*/
|
||||
public func GetLengthToTarget(object end)
|
||||
{
|
||||
if (!destination_list) return nil;
|
||||
if (!destination_list)
|
||||
return nil;
|
||||
for (var item in destination_list)
|
||||
{
|
||||
if (!item) continue;
|
||||
if (!item)
|
||||
continue;
|
||||
if (item[const_finaldestination] == end)
|
||||
return item[const_distance];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
/*-- Auto production --*/
|
||||
|
||||
local request_queue;
|
||||
|
@ -410,12 +475,11 @@ public func AddRequest(proplist requested_id, int amount)
|
|||
// Great. Start working immediately
|
||||
PushBack(request_queue, [requested_id, amount]);
|
||||
car->AddRequest(requested_id, amount, this, source);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check all connected stations for available objects
|
||||
func CheckAvailability(proplist requested, int amount)
|
||||
public func CheckAvailability(proplist requested, int amount)
|
||||
{
|
||||
var nearest_station;
|
||||
var length_to;
|
||||
|
@ -494,4 +558,4 @@ public func RemoveRequest(id requested, int amount)
|
|||
return false;
|
||||
RemoveArrayIndex(request_queue, i, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/*--
|
||||
/**
|
||||
Cable Crossing
|
||||
The standard crossing for the cable network.
|
||||
The crossing will automatically be a station if it is at the end of the cable line (i.e. only one cable connected).
|
||||
But the crossing can also manually be set to function as a station.
|
||||
|
||||
Author: Clonkonaut
|
||||
--*/
|
||||
@author Clonkonaut
|
||||
*/
|
||||
|
||||
#include Library_CableStation
|
||||
|
||||
|
@ -32,7 +32,8 @@ func Initialize()
|
|||
// Prevents the automatic change of the station status when manually set to station mode
|
||||
local manual_setting = false;
|
||||
|
||||
/* Library functions: Cable Station */
|
||||
|
||||
/*-- Library functions: Cable Station --*/
|
||||
|
||||
public func DestinationsUpdated()
|
||||
{
|
||||
|
@ -44,6 +45,11 @@ public func DestinationsUpdated()
|
|||
else
|
||||
SetCableStation(false);
|
||||
CheckStationStatus();
|
||||
|
||||
// Inform all cars at station about the update.
|
||||
for (var car in arrived_cars)
|
||||
if (car)
|
||||
car->~OnRailNetworkUpdate();
|
||||
}
|
||||
|
||||
public func IsAvailable(proplist requested, int amount)
|
||||
|
@ -107,7 +113,8 @@ public func OnCableCarDelivery(object car, id requested, int amount)
|
|||
}
|
||||
}
|
||||
|
||||
/* Construction */
|
||||
|
||||
/*-- Construction --*/
|
||||
|
||||
public func IsHammerBuildable() { return true; }
|
||||
|
||||
|
@ -124,7 +131,7 @@ public func ConstructionCombineOffset(proplist other)
|
|||
return;
|
||||
|
||||
// Make sure the station preview is on the same ground level than the other building
|
||||
var ret = [0,0];
|
||||
var ret = [0, 0];
|
||||
ret[1] = other->GetObjHeight()/2 - this->GetDefHeight()/2;
|
||||
return ret;
|
||||
}
|
||||
|
@ -238,7 +245,9 @@ public func ToggleDropOff(bool silent)
|
|||
if (!IsCableStation())
|
||||
ToggleStation(true);
|
||||
setting_dropoff = true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
setting_dropoff = false;
|
||||
}
|
||||
if (!silent)
|
||||
|
@ -246,7 +255,8 @@ public func ToggleDropOff(bool silent)
|
|||
CheckStationStatus();
|
||||
}
|
||||
|
||||
/* Cable Car Management */
|
||||
|
||||
/*-- Cable Car Management --*/
|
||||
|
||||
public func OnCableCarArrival(object car)
|
||||
{
|
||||
|
@ -259,6 +269,11 @@ public func OnCableCarArrival(object car)
|
|||
PushBack(arrived_cars, car);
|
||||
}
|
||||
|
||||
public func OnCableCarStopped(object car)
|
||||
{
|
||||
PushBack(arrived_cars, car);
|
||||
}
|
||||
|
||||
public func OnCableCarDeparture(object car)
|
||||
{
|
||||
RemoveArrayValue(arrived_cars, car, true);
|
||||
|
@ -274,19 +289,23 @@ public func OnCableCarDisengaged(object car)
|
|||
RemoveArrayValue(arrived_cars, car, true);
|
||||
}
|
||||
|
||||
/* Visuals */
|
||||
public func OnCableCarDestruction(object car)
|
||||
{
|
||||
RemoveArrayValue(arrived_cars, car, true);
|
||||
}
|
||||
|
||||
func CheckStationStatus()
|
||||
|
||||
/*-- Visuals --*/
|
||||
|
||||
public func CheckStationStatus()
|
||||
{
|
||||
if (IsCableStation())
|
||||
{
|
||||
// In order of priority
|
||||
if (setting_dropoff)
|
||||
{
|
||||
SetMeshMaterial("CableCarStation_SignDropOff", 1);
|
||||
} else {
|
||||
else
|
||||
SetMeshMaterial("CableCarStation_SignStation", 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
SetMeshMaterial("CableCarStation_Sign", 1);
|
||||
|
@ -294,14 +313,14 @@ func CheckStationStatus()
|
|||
|
||||
local activations = 0;
|
||||
|
||||
func CableActivation(int count)
|
||||
public func CableActivation(int count)
|
||||
{
|
||||
if (activations <= 0)
|
||||
SetAnimationPosition(turn_anim, Anim_Linear(GetAnimationPosition(turn_anim), 0, GetAnimationLength("Engine"), 175, ANIM_Loop));
|
||||
activations += count;
|
||||
}
|
||||
|
||||
func CableDeactivation(int count)
|
||||
public func CableDeactivation(int count)
|
||||
{
|
||||
activations -= count;
|
||||
if (activations <= 0)
|
||||
|
@ -310,9 +329,10 @@ func CableDeactivation(int count)
|
|||
|
||||
public func NoConstructionFlip() { return true; }
|
||||
|
||||
/* Saving */
|
||||
|
||||
func SaveScenarioObject(props)
|
||||
/*-- Saving --*/
|
||||
|
||||
public func SaveScenarioObject(props)
|
||||
{
|
||||
if (!inherited(props, ...)) return false;
|
||||
if (IsCableStation() && manual_setting)
|
||||
|
@ -327,7 +347,8 @@ func SaveScenarioObject(props)
|
|||
|
||||
public func SetManual() { manual_setting = true; return true; }
|
||||
|
||||
/* Properties */
|
||||
|
||||
/*-- Properties --*/
|
||||
|
||||
local Name = "$Name$";
|
||||
local BlastIncinerate = 50;
|
||||
|
|
|
@ -3,5 +3,7 @@ Name=Seilbahnkreuzung
|
|||
StationSettings=Seilbahneinstellungen
|
||||
|
||||
TooltipToggleStation=Bahnhofs-Status umstellen.
|
||||
TooltipToggleDropOff=Toggle item dropping status
|
||||
|
||||
DescToggleStation=Diese Kreuzung von Hand zu einem Bahnhof oder wieder zu einer Kreuzung umschalten. Nur Bahnhöfe sind als Ziel wählbar und nur am Bahnhöfen können Fahrzeuge aufgesetzt werden.
|
||||
DescToggleStation=Diese Kreuzung von Hand zu einem Bahnhof oder wieder zu einer Kreuzung umschalten. Nur Bahnhöfe sind als Ziel wählbar und nur am Bahnhöfen können Fahrzeuge aufgesetzt werden.
|
||||
DescToggleDropOff=All arriving vehicle are emptied upon arrival at this station (giving it is the final stop). Will also be set as a cable station.
|
|
@ -1,20 +1,26 @@
|
|||
/*-- Cable Hoist --*/
|
||||
/**
|
||||
Cable Hoist
|
||||
|
||||
@author Clonkonaut
|
||||
*/
|
||||
|
||||
#include Library_CableCar
|
||||
|
||||
local pickup;
|
||||
|
||||
/* Creation */
|
||||
|
||||
func Construction()
|
||||
/*-- Creation --*/
|
||||
|
||||
public func Construction()
|
||||
{
|
||||
SetProperty("MeshTransformation",Trans_Rotate(13,0,1,0));
|
||||
this.MeshTransformation = Trans_Rotate(13, 0, 1, 0);
|
||||
SetCableSpeed(1);
|
||||
}
|
||||
|
||||
/* Engine Callbacks */
|
||||
|
||||
func Damage(int change, int cause)
|
||||
/*-- Engine Callbacks --*/
|
||||
|
||||
public func Damage(int change, int cause)
|
||||
{
|
||||
if (cause == FX_Call_DmgBlast)
|
||||
{
|
||||
|
@ -26,25 +32,28 @@ func Damage(int change, int cause)
|
|||
}
|
||||
}
|
||||
|
||||
/* Status */
|
||||
|
||||
/*-- Status --*/
|
||||
|
||||
public func IsToolProduct() { return true; }
|
||||
|
||||
/* Cable Car Library */
|
||||
|
||||
func GetCableOffset(array position, int prec)
|
||||
/*-- Cable Car Library --*/
|
||||
|
||||
public func GetCableOffset(array position, int prec)
|
||||
{
|
||||
if (!prec) prec = 1;
|
||||
if (!prec)
|
||||
prec = 1;
|
||||
position[1] += 5 * prec;
|
||||
}
|
||||
|
||||
func Engaged()
|
||||
public func Engaged()
|
||||
{
|
||||
this.Touchable = 0;
|
||||
SetAction("OnRail");
|
||||
}
|
||||
|
||||
func Disengaged()
|
||||
public func Disengaged()
|
||||
{
|
||||
this.Touchable = 1;
|
||||
SetAction("Idle");
|
||||
|
@ -52,9 +61,10 @@ func Disengaged()
|
|||
DropVehicle();
|
||||
}
|
||||
|
||||
func GetCableCarExtraMenuEntries(array menu_entries, proplist custom_entry, object clonk)
|
||||
public func GetCableCarExtraMenuEntries(array menu_entries, proplist custom_entry, object clonk)
|
||||
{
|
||||
if (IsTravelling()) return;
|
||||
if (IsTravelling())
|
||||
return;
|
||||
|
||||
if (!pickup && GetRailTarget())
|
||||
{
|
||||
|
@ -103,7 +113,8 @@ public func OnCableCarHover(symbol, extra_data, desc_menu_target, menu_id)
|
|||
return _inherited(symbol, extra_data, desc_menu_target, menu_id, ...);
|
||||
}
|
||||
|
||||
/* Picking up vehicles */
|
||||
|
||||
/*-- Picking up vehicles --*/
|
||||
|
||||
public func PickupVehicle(object vehicle)
|
||||
{
|
||||
|
@ -155,9 +166,10 @@ local FxCableHoistPickup = new Effect
|
|||
}
|
||||
};
|
||||
|
||||
/* Actions */
|
||||
|
||||
func OnRail()
|
||||
/*-- Actions --*/
|
||||
|
||||
public func OnRail()
|
||||
{
|
||||
DoMovement();
|
||||
}
|
||||
|
@ -180,7 +192,8 @@ local ActMap = {
|
|||
},
|
||||
};
|
||||
|
||||
/* Callbacks */
|
||||
|
||||
/*-- Callbacks --*/
|
||||
|
||||
public func GetAttachedVehicle()
|
||||
{
|
||||
|
@ -230,15 +243,15 @@ public func OverridePriority(proplist requested, int amount, proplist requesting
|
|||
// Check if the connected vehicle holds the requested objects and if yes, override the selection
|
||||
if (pickup && pickup->ContentsCount(requested) >= amount)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Definition */
|
||||
|
||||
func Definition(def)
|
||||
/*-- Definition --*/
|
||||
|
||||
public func Definition(def)
|
||||
{
|
||||
SetProperty("PictureTransformation",Trans_Mul(Trans_Rotate(-25,1,0,0),Trans_Rotate(40,0,1,0)),def);
|
||||
def.PictureTransformation = Trans_Mul(Trans_Rotate(-25, 1, 0, 0), Trans_Rotate(40, 0, 1, 0));
|
||||
}
|
||||
|
||||
local Name = "$Name$";
|
||||
|
|
|
@ -12,23 +12,23 @@ local empty_anim;
|
|||
|
||||
/*-- Engine Callbacks --*/
|
||||
|
||||
func Construction()
|
||||
public func Construction()
|
||||
{
|
||||
SetProperty("MeshTransformation", Trans_Rotate(13, 0, 1, 0));
|
||||
}
|
||||
|
||||
func Initialize()
|
||||
public func Initialize()
|
||||
{
|
||||
drive_anim = PlayAnimation("Drive", 1, Anim_X(0,0, GetAnimationLength("Drive"), 30), Anim_Const(1000));
|
||||
empty_anim = PlayAnimation("Empty", 2, Anim_Const(0), Anim_Const(0));
|
||||
}
|
||||
|
||||
func Hit3()
|
||||
public func Hit3()
|
||||
{
|
||||
Sound("Hits::Materials::Metal::DullMetalHit?");
|
||||
}
|
||||
|
||||
func RejectCollect(id object_id, object obj)
|
||||
public func RejectCollect(id object_id, object obj)
|
||||
{
|
||||
// Collection maybe blocked if this object was just dumped.
|
||||
if (!obj->Contained() && GetEffect("BlockCollectionByLorry", obj))
|
||||
|
@ -59,7 +59,7 @@ func RejectCollect(id object_id, object obj)
|
|||
}
|
||||
|
||||
// Automatic unloading in buildings.
|
||||
func Entrance(object container)
|
||||
public func Entrance(object container)
|
||||
{
|
||||
// Only in buildings
|
||||
if (container->GetCategory() & (C4D_StaticBack | C4D_Structure))
|
||||
|
@ -69,19 +69,19 @@ func Entrance(object container)
|
|||
container->GrabContents(this);
|
||||
}
|
||||
|
||||
func ContactLeft()
|
||||
public func ContactLeft()
|
||||
{
|
||||
if (Stuck() && !Random(5))
|
||||
SetRDir(RandomX(-7, +7));
|
||||
}
|
||||
|
||||
func ContactRight()
|
||||
public func ContactRight()
|
||||
{
|
||||
if (Stuck() && !Random(5))
|
||||
SetRDir(RandomX(-7, +7));
|
||||
}
|
||||
|
||||
func Damage(int change, int cause, int by_player)
|
||||
public func Damage(int change, int cause, int by_player)
|
||||
{
|
||||
// Only explode the lorry on blast damage.
|
||||
if (cause != FX_Call_DmgBlast)
|
||||
|
@ -144,7 +144,7 @@ public func DropContents(proplist station)
|
|||
ScheduleCall(this, "Empty", 35);
|
||||
}
|
||||
|
||||
func Empty()
|
||||
public func Empty()
|
||||
{
|
||||
// Exit everything at once (as opposed to manual dumping below)
|
||||
while (Contents())
|
||||
|
|
|
@ -144,6 +144,7 @@ func InitializeObjects()
|
|||
CableLine019->SetConnectedObjects(CableCrossing019, CableCrossing003);
|
||||
|
||||
var ToolsWorkshop001 = CreateObjectAbove(ToolsWorkshop, 76, 388);
|
||||
CableCrossing019->CombineWith(ToolsWorkshop001);
|
||||
|
||||
var CableHoist001 = CreateObjectAbove(CableHoist, 560, 384);
|
||||
CableHoist001->SetComDir(COMD_None);
|
||||
|
|
|
@ -150,6 +150,10 @@ protected func InitializePlayer(int plr)
|
|||
// No FOW here.
|
||||
//SetFoW(false, plr);
|
||||
JoinPlayer(plr);
|
||||
// Give all knowledge.
|
||||
var index = 0, def;
|
||||
while (def = GetDefinition(index++))
|
||||
SetPlrKnowledge(plr, def);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,10 +56,10 @@ protected func InitializePlayer(int plr)
|
|||
SetPlrKnowledge(plr, def);
|
||||
|
||||
// Add test control effect.
|
||||
var effect = AddEffect("IntTestControl", nil, 100, 2);
|
||||
effect.testnr = 1;
|
||||
effect.launched = false;
|
||||
effect.plr = plr;
|
||||
var fx = AddEffect("IntTestControl", nil, 100, 2);
|
||||
fx.testnr = 7;
|
||||
fx.launched = false;
|
||||
fx.plr = plr;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,7 @@ global func Test1_OnStart(int plr)
|
|||
workshop->AddToQueue(Shovel, 2);
|
||||
|
||||
// Log what the test is about.
|
||||
Log("A workshop needs material to produce 2 shovels, lorry in system has materials.");
|
||||
Log("A workshop needs material to produce shovels, lorry in system has materials.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -288,11 +288,13 @@ global func Test3_OnStart(int plr)
|
|||
|
||||
var workshop = CreateObjectAbove(ToolsWorkshop, 40, 160, plr);
|
||||
crossing1->CombineWith(workshop);
|
||||
workshop->AddToQueue(Shovel, 2);
|
||||
workshop->AddToQueue(Shovel, 1);
|
||||
|
||||
ScheduleCall(line_to_break, "OnLineBreak", 36, 0, true);
|
||||
ScheduleCall(line_to_break, "RemoveObject", 37, 0, true);
|
||||
ScheduleCall(nil, "PrintCableCarNetwork", 38, 0);
|
||||
ScheduleCall(nil, "CreateCableCrossingsConnection", 240, 0, crossing2, crossing3);
|
||||
ScheduleCall(nil, "PrintCableCarNetwork", 241, 0);
|
||||
|
||||
// Log what the test is about.
|
||||
Log("Check if a delivery is continued when a cable breaks and is repaired.");
|
||||
|
@ -301,7 +303,7 @@ global func Test3_OnStart(int plr)
|
|||
|
||||
global func Test3_Completed()
|
||||
{
|
||||
if (ObjectCount(Find_ID(Shovel)) >= 2)
|
||||
if (ObjectCount(Find_ID(Shovel)) >= 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -319,26 +321,30 @@ global func Test4_OnStart(int plr)
|
|||
|
||||
var crossing1 = CreateObjectAbove(CableCrossing, 70, 160, plr);
|
||||
var crossing2 = CreateObjectAbove(CableCrossing, 216, 64, plr);
|
||||
var crossing3 = CreateObjectAbove(CableCrossing, 272, 64, plr);
|
||||
var crossing4 = CreateObjectAbove(CableCrossing, 450, 104, plr);
|
||||
var crossing3 = CreateObjectAbove(CableCrossing, 244, 64, plr);
|
||||
var crossing4 = CreateObjectAbove(CableCrossing, 272, 64, plr);
|
||||
var crossing5 = CreateObjectAbove(CableCrossing, 450, 104, plr);
|
||||
|
||||
CreateCableCrossingsConnection(crossing1, crossing2);
|
||||
CreateCableCrossingsConnection(crossing2, crossing3);
|
||||
CreateCableCrossingsConnection(crossing3, crossing4);
|
||||
CreateCableCrossingsConnection(crossing4, crossing5);
|
||||
|
||||
var hoist = crossing4->CreateObject(CableHoist);
|
||||
hoist->EngageRail(crossing4);
|
||||
var lorry = crossing4->CreateObject(CableLorry);
|
||||
var hoist = crossing5->CreateObject(CableHoist);
|
||||
hoist->EngageRail(crossing5);
|
||||
var lorry = crossing5->CreateObject(CableLorry);
|
||||
hoist->PickupVehicle(lorry);
|
||||
lorry->CreateContents(Metal, 2);
|
||||
lorry->CreateContents(Wood, 2);
|
||||
|
||||
var workshop = CreateObjectAbove(ToolsWorkshop, 40, 160, plr);
|
||||
crossing1->CombineWith(workshop);
|
||||
workshop->AddToQueue(Shovel, 2);
|
||||
workshop->AddToQueue(Shovel, 1);
|
||||
|
||||
ScheduleCall(crossing2, "RemoveObject", 36, 0, true);
|
||||
ScheduleCall(nil, "CreateCableCrossingsConnection", 240, 0, crossing1, crossing3);
|
||||
ScheduleCall(crossing3, "RemoveObject", 36, 0, true);
|
||||
ScheduleCall(nil, "PrintCableCarNetwork", 37, 0);
|
||||
ScheduleCall(nil, "CreateCableCrossingsConnection", 240, 0, crossing2, crossing4);
|
||||
ScheduleCall(nil, "PrintCableCarNetwork", 241, 0);
|
||||
|
||||
// Log what the test is about.
|
||||
Log("Check if a delivery is continued when a station is destroyed.");
|
||||
|
@ -347,7 +353,7 @@ global func Test4_OnStart(int plr)
|
|||
|
||||
global func Test4_Completed()
|
||||
{
|
||||
if (ObjectCount(Find_ID(Shovel)) >= 2)
|
||||
if (ObjectCount(Find_ID(Shovel)) >= 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -358,7 +364,6 @@ global func Test4_OnFinished()
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
global func Test5_OnStart(int plr)
|
||||
{
|
||||
SetWindFixed(50);
|
||||
|
@ -464,7 +469,7 @@ global func Test6_OnStart(int plr)
|
|||
var drain = CreateObjectAbove(Pipe, 80, 300, plr);
|
||||
drain->ConnectPipeTo(pump, PIPE_STATE_Drain);
|
||||
|
||||
Schedule(nil, "CreateObject(Dynamite, 482, 266)->Fuse()", 180, 10**6);
|
||||
Schedule(nil, "CreateObject(Rock, 480, 274)", 36, 10**6);
|
||||
|
||||
// Log what the test is about.
|
||||
Log("Test automated concrete production line.");
|
||||
|
@ -539,6 +544,141 @@ global func Test7_OnFinished()
|
|||
return;
|
||||
}
|
||||
|
||||
global func Test8_OnStart(int plr)
|
||||
{
|
||||
ClearFreeRect(0, 0, LandscapeWidth(), LandscapeHeight());
|
||||
|
||||
var nr_crossings = RandomX(6, 12);
|
||||
var connect_chance = 20; // In percent.
|
||||
var start_time = GetTime();
|
||||
var crossings = [];
|
||||
for (var cnt = 0; cnt < nr_crossings; cnt++)
|
||||
PushBack(crossings, CreateObjectAbove(CableCrossing, RandomX(10, LandscapeWidth() - 10), RandomX(20, LandscapeHeight() - 20), plr));
|
||||
|
||||
var nr_connections = 0;
|
||||
for (var c1 in crossings)
|
||||
{
|
||||
for (var c2 in crossings)
|
||||
{
|
||||
if (c1 != c2 && Random(100) < connect_chance)
|
||||
{
|
||||
CreateCableCrossingsConnection(c1, c2);
|
||||
nr_connections++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Log what the test is about.
|
||||
Log("Test a random network for symmetric distance measures.");
|
||||
var time = GetTime() - start_time;
|
||||
Log("It took %d ms to create %d stations with %d connections.", time, nr_crossings, nr_connections);
|
||||
return true;
|
||||
}
|
||||
|
||||
global func Test8_Completed()
|
||||
{
|
||||
if (IsSymmetricCableCarNetwork())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
global func Test8_OnFinished()
|
||||
{
|
||||
RemoveTestObjects();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*-- Cable Network Functions --*/
|
||||
|
||||
global func CreateCableCrossingsConnection(object c1, object c2)
|
||||
{
|
||||
var cable = c1->CreateObject(CableLine);
|
||||
cable->SetConnectedObjects(c1, c2);
|
||||
// Log the distance the cable covers of the cable.
|
||||
var dummy = CreateObject(Dummy, (c1->GetX() + c2->GetX()) / 2, (c1->GetY() + c2->GetY()) / 2);
|
||||
dummy->SetCategory(C4D_StaticBack);
|
||||
dummy.Visibility = VIS_All;
|
||||
dummy->Message("@<c 141432>%d</c>", ObjectDistance(c1, c2));
|
||||
cable->CreateEffect(FxRemoveWith, 1, 0, dummy);
|
||||
return cable;
|
||||
}
|
||||
|
||||
static const FxRemoveWith = new Effect
|
||||
{
|
||||
Construction = func(object to_remove)
|
||||
{
|
||||
this.to_remove = to_remove;
|
||||
},
|
||||
Destruction = func()
|
||||
{
|
||||
this.to_remove->RemoveObject();
|
||||
}
|
||||
};
|
||||
|
||||
global func CreateObjectAbove(id obj, ...)
|
||||
{
|
||||
var res = _inherited(obj, ...);
|
||||
if (obj == CableCrossing)
|
||||
res->Message("@<c aa0000>%d</c>", res->ObjectNumber());
|
||||
return res;
|
||||
}
|
||||
|
||||
global func PrintCableCarNetwork()
|
||||
{
|
||||
Log("Distances between all of the cable crossings:");
|
||||
var cable_crossings = FindObjects(Find_Func("IsCableCrossing"));
|
||||
var header = "Obj# |";
|
||||
var line = "------";
|
||||
for (var crossing in cable_crossings)
|
||||
{
|
||||
//Log("%v: %v", crossing, crossing->GetDestinations());
|
||||
header = Format("%s %04d", header, crossing->ObjectNumber());
|
||||
line = Format("%s-----", line);
|
||||
}
|
||||
Log(header);
|
||||
Log(line);
|
||||
for (var crossing1 in cable_crossings)
|
||||
{
|
||||
var msg = Format("%04d |", crossing1->ObjectNumber());
|
||||
for (var crossing2 in cable_crossings)
|
||||
{
|
||||
var len = crossing1->GetLengthToTarget(crossing2);
|
||||
msg = Format("%s %04d", msg, len);
|
||||
}
|
||||
Log(msg);
|
||||
}
|
||||
Log(line);
|
||||
if (!IsSymmetricCableCarNetwork())
|
||||
Log("WARNING: distance table is not symmetric.");
|
||||
return;
|
||||
}
|
||||
|
||||
global func IsSymmetricCableCarNetwork()
|
||||
{
|
||||
var cable_crossings = FindObjects(Find_Func("IsCableCrossing"));
|
||||
var dist_table = [];
|
||||
var index1 = 0;
|
||||
for (var crossing1 in cable_crossings)
|
||||
{
|
||||
var index2 = 0;
|
||||
dist_table[index1] = [];
|
||||
for (var crossing2 in cable_crossings)
|
||||
{
|
||||
var len = crossing1->GetLengthToTarget(crossing2);
|
||||
dist_table[index1][index2] = len;
|
||||
index2++;
|
||||
}
|
||||
index1++;
|
||||
}
|
||||
var is_symmetric = true;
|
||||
for (var index1 = 0; index1 < GetLength(dist_table); index1++)
|
||||
for (var index2 = index1 + 1; index2 < GetLength(dist_table); index2++)
|
||||
if (dist_table[index1][index2] != dist_table[index2][index1])
|
||||
is_symmetric = false;
|
||||
return is_symmetric;
|
||||
}
|
||||
|
||||
|
||||
/*-- Helper Functions --*/
|
||||
|
||||
|
@ -608,40 +748,3 @@ global func RemoveTestObjects()
|
|||
));
|
||||
return;
|
||||
}
|
||||
|
||||
global func CreateCableCrossingsConnection(object c1, object c2)
|
||||
{
|
||||
var cable = c1->CreateObject(CableLine);
|
||||
cable->SetConnectedObjects(c1, c2);
|
||||
return cable;
|
||||
}
|
||||
|
||||
|
||||
global func PrintCableCarNetwork()
|
||||
{
|
||||
Log("Distances between all of the cable crossings:");
|
||||
var cable_crossings = FindObjects(Find_Func("IsCableCrossing"));
|
||||
var header = "Obj# |";
|
||||
var line = "------";
|
||||
for (var crossing in cable_crossings)
|
||||
{
|
||||
header = Format("%s %04d", header, crossing->ObjectNumber());
|
||||
line = Format("%s-----", line);
|
||||
}
|
||||
Log(Format("%s tot", header));
|
||||
Log(Format("%s-----", line));
|
||||
for (var crossing1 in cable_crossings)
|
||||
{
|
||||
var msg = Format("%04d |", crossing1->ObjectNumber());
|
||||
var sum = 0;
|
||||
for (var crossing2 in cable_crossings)
|
||||
{
|
||||
var len = crossing1->GetLengthToTarget(crossing2);
|
||||
sum += len;
|
||||
msg = Format("%s %04d", msg, len);
|
||||
}
|
||||
msg = Format("%s %04d", msg, sum);
|
||||
Log(msg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue