cable cars: fix finding crossing for power supply when previous fails

master
Maikel de Vries 2018-04-11 14:17:57 +02:00
parent 051863db5f
commit 618b4039b3
4 changed files with 72 additions and 21 deletions

View File

@ -83,8 +83,15 @@ public func DoMovement()
if (lib_ccar_direction == nil) return;
if (!lib_ccar_has_power)
{
RegisterPowerRequest(GetNeededPower());
lib_ccar_requesting_power = true;
if (!lib_ccar_requesting_power)
{
RegisterPowerRequest(GetNeededPower());
lib_ccar_requesting_power = true;
}
else
{
CheckPowerCrossing();
}
return;
}
@ -156,7 +163,6 @@ public func GetInteractionMenus(object clonk)
Priority = 20
};
PushBack(menus, cablecar_menu);
return menus;
}
@ -329,10 +335,10 @@ public func SetDestination(dest)
// Whenever a crossing is reached it must be queried for the next crossing to go to
public func CrossingReached()
{
var target;
if (lib_ccar_destination != lib_ccar_rail)
{
if (target = lib_ccar_rail->GetNextWaypoint(lib_ccar_destination))
var target = lib_ccar_rail->GetNextWaypoint(lib_ccar_destination);
if (target)
MoveTo(target);
else
DestinationFailed();
@ -447,14 +453,21 @@ public func GetActualPowerConsumer()
// in the wrong network.
if (lib_ccar_rail && !lib_ccar_requesting_power)
{
var power_crossing = lib_ccar_rail;
if (!power_crossing->~IsCableCrossing())
power_crossing = power_crossing->GetActionTarget(0) ?? power_crossing->GetActionTarget(1);
var power_crossing = GetClosestCrossing();
lib_ccar_power_crossing = GetBestPowerCrossing(power_crossing);
}
return lib_ccar_power_crossing;
}
// Returns the closest crossing the car is connected to.
public func GetClosestCrossing()
{
var power_crossing = lib_ccar_rail;
if (!power_crossing->~IsCableCrossing())
power_crossing = power_crossing->GetActionTarget(0) ?? power_crossing->GetActionTarget(1);
return power_crossing;
}
// Returns the best crossing in the network of this crossing.
public func GetBestPowerCrossing(object crossing)
{
@ -466,26 +479,51 @@ public func GetBestPowerCrossing(object crossing)
continue;
PushBack(network_crossings, item[Library_CableStation.const_finaldestination]);
}
// Find the crossing with a positive power balance.
// Find the crossing with the most positive power balance.
var best_crossing = crossing;
var power_overflow = nil;
for (var test_crossing in network_crossings)
{
var power_network = Library_Power->GetPowerNetwork(test_crossing);
if (power_network->IsNeutralNetwork())
continue;
if (power_network->GetBarePowerAvailable() > power_network->GetPowerConsumptionNeed())
return test_crossing;
var overflow = power_network->GetBarePowerAvailable() - power_network->GetPowerConsumptionNeed();
if (overflow > power_overflow || power_overflow == nil)
{
best_crossing = test_crossing;
power_overflow = overflow;
}
}
// Fallback to this crossing.
return this;
return best_crossing;
}
public func OnNotEnoughPower()
// Checks whether the current crossing is optimal for powering this cable car.
public func CheckPowerCrossing()
{
if (lib_ccar_requesting_power)
{
var power_crossing = GetClosestCrossing();
if (lib_ccar_power_crossing != GetBestPowerCrossing(power_crossing))
{
// Unregister current power request such that a new crossing can be chosen.
UnregisterPowerRequest();
lib_ccar_has_power = false;
lib_ccar_requesting_power = false;
}
}
return;
}
public func OnNotEnoughPower(int amount, bool initial_call)
{
lib_ccar_has_power = false;
// Check the need for updating to a new crossing as the power source.
if (!initial_call)
CheckPowerCrossing();
return _inherited(...);
}
public func OnEnoughPower()
public func OnEnoughPower(int amount)
{
lib_ccar_has_power = true;
// Do movement again because this frame there would be no movement otherwise.

View File

@ -13,7 +13,7 @@
The network will then continously search for available power to deliver to
this consumer and will notify it via the callbacks
* OnEnoughPower(int amount)
* OnNotEnoughPower()
* OnNotEnoughPower(int amount, bool initial_call)
The last callback will be called when the consumer had enough power and the
network stopped delivering to this consumer, due to whatever reason except
the consumer itself unregistering the request for power.
@ -99,7 +99,7 @@ public func OnEnoughPower(int amount)
// functionality, since not enough power is available. return inherited(amount, ...)
// to add the no-power symbol. It is not allowed to (un)register a power request
// in this callback.
public func OnNotEnoughPower(int amount)
public func OnNotEnoughPower(int amount, bool initial_call)
{
// Show the no-power symbol.
ShowStatusSymbol(Library_PowerConsumer);

View File

@ -14,7 +14,7 @@
Callbacks to the power consumers (see consumer library for details):
* OnEnoughPower(int amount)
* OnNotEnoughPower(int amount)
* OnNotEnoughPower(int amount, bool initial_call)
* GetConsumerPriority()
* GetActualPowerConsumer()
@ -493,7 +493,7 @@ public func AddPowerConsumer(object consumer, int amount, int prio)
// Consumer was in neither list, so add it to the list of waiting consumers.
PushBack(lib_power.waiting_consumers, {obj = consumer, cons_amount = amount, priority = prio});
// On not enough power callback to not yet active consumer.
consumer->OnNotEnoughPower(amount);
consumer->OnNotEnoughPower(amount, true);
// Check the power balance of this network, since a change has been made.
CheckPowerBalance();
return;
@ -773,7 +773,7 @@ private func RefreshConsumers(int power_available)
PushBack(lib_power.waiting_consumers, link);
RemoveArrayIndex(lib_power.active_consumers, idx);
// On not enough power callback to the deactivated consumer.
link.obj->OnNotEnoughPower(consumption);
link.obj->OnNotEnoughPower(consumption, false);
VisualizePowerChange(link.obj, consumption, 0, true);
}
}
@ -968,6 +968,19 @@ private func LogState(string tag)
return;
}
// Definition call: registers a power producer with specified amount.
public func LogPowerNetworks()
{
// Definition call safety checks.
if (this != GetPowerSystem())
return FatalError("LogPowerNetworks() not called from definition context.");
GetPowerSystem()->Init();
for (var network in LIB_POWR_Networks)
if (network)
network->LogState("");
return;
}
/*-- Power Visualization --*/

View File

@ -255,7 +255,7 @@ public func OnEnoughPower(int amount)
}
// Callback from the power library saying there is not enough power.
public func OnNotEnoughPower(int amount)
public func OnNotEnoughPower(int amount, bool initial_call)
{
// Stop the consumption of power.
if (GetEffect("ConsumePower", this))