fix power loss bug when producer moves out of base area (#1447)

shapetextures
Maikel de Vries 2015-11-28 18:05:17 +01:00
parent 004bd3c59e
commit 7a8de4fc55
5 changed files with 119 additions and 9 deletions

View File

@ -11,6 +11,8 @@ protected func Initialize()
{
// Set the right owner based on the flag's ownership radiuses.
SetOwner(GetOwnerOfPosition(0, 0));
// A movement check is needed because structures can move out of flag radiuses.
AddEffect("IntMovementCheck", this, 100, 12, this);
return _inherited(...);
}
@ -37,3 +39,33 @@ public func IsInteractable(object clonk)
return false;
return _inherited(clonk, ...);
}
/*-- Movement Check --*/
protected func FxIntMovementCheckStart(object target, proplist effect, int temp)
{
if (temp)
return FX_OK;
effect.Interval = 9;
// Store initial x and y.
effect.x = GetX();
effect.y = GetY();
return FX_OK;
}
protected func FxIntMovementCheckTimer(object target, proplist effect)
{
// Check whether the structure has moved.
if (GetX() != effect.x || GetY() != effect.y)
{
// Determine if owner has changed.
var new_owner = GetOwnerOfPosition(0, 0);
if (GetOwner() != new_owner)
SetOwner(new_owner);
// Update new x and y.
effect.x = target->GetX();
effect.y = target->GetY();
}
return FX_OK;
}

View File

@ -71,7 +71,7 @@ private func UnregisterPowerRequest()
// the power network of this consumer.
private func UpdatePowerRequest()
{
Library_Power->UpdateForPowerLink(this);
Library_Power->UpdateNetworkForPowerLink(this);
return;
}
@ -140,6 +140,13 @@ protected func Destruction()
return _inherited(...);
}
// When ownership has changed, the consumer may have moved out of or into a new network.
public func OnOwnerChanged(int new_owner, int old_owner)
{
Library_Power->TransferPowerLink(this);
return _inherited(new_owner, old_owner, ...);
}
// By calling this function you can make this consumer ignore the power need. This is
// used by the power need rule and can be used by scripters to temporarily turn off the
// need for power in a certain consumer.
@ -147,7 +154,7 @@ public func SetNoPowerNeed(bool no_need)
{
lib_power.power_need = !no_need;
// Make sure the power balance of the network is updated.
UpdatePowerRequest();
UpdatePowerRequest();
return;
}

View File

@ -101,3 +101,10 @@ protected func Destruction()
UnregisterPowerProduction();
return _inherited(...);
}
// When ownership has changed, the producer may have moved out of or into a new network.
public func OnOwnerChanged(int new_owner, int old_owner)
{
Library_Power->TransferPowerLink(this);
return _inherited(new_owner, old_owner, ...);
}

View File

@ -123,12 +123,50 @@ public func UnregisterPowerConsumer(object consumer)
return;
}
// Definition call: updates the network for this power link.
public func UpdateForPowerLink(object link)
// Definition call: transfers a power link from the network it is registered in to
// the network it is currently in (base radius).
public func TransferPowerLink(object link)
{
// Definition call safety checks.
if (this != Library_Power || !link)
return FatalError("UpdateForPowerLink() either not called from definition context or no link specified.");
return FatalError("TransferPowerLink() either not called from definition context or no link specified.");
// Get the new network for this power link.
var new_network = GetPowerNetwork(link);
// Loop over existing networks and find the link.
var old_network;
for (var network in LIB_POWR_Networks)
{
if (network->ContainsPowerLink(link))
{
old_network = network;
break;
}
}
// Only perform a transfer if the link was registered in an old network which is not equal to the new network.
if (old_network && old_network != new_network)
{
var producer = old_network->GetProducerLink(link);
if (producer)
{
old_network->RemovePowerProducer(producer.obj);
new_network->AddPowerProducer(producer.obj, producer.prod_amount, producer.priority);
}
var consumer = old_network->GetConsumerLink(link);
if (consumer)
{
old_network->RemovePowerConsumer(consumer.obj);
new_network->AddPowerConsumer(consumer.obj, consumer.cons_amount, consumer.priority);
}
}
return;
}
// Definition call: updates the network for this power link.
public func UpdateNetworkForPowerLink(object link)
{
// Definition call safety checks.
if (this != Library_Power || !link)
return FatalError("UpdateNetworkForPowerLink() either not called from definition context or no link specified.");
// Find the network for this link and update it.
var network = GetPowerNetwork(link);
network->CheckPowerBalance();
@ -705,6 +743,30 @@ public func IsEmpty()
&& GetLength(lib_power.active_consumers) == 0;
}
// Returns whether this network contains a power link.
public func ContainsPowerLink(object link)
{
return !!GetProducerLink(link) || !!GetConsumerLink(link);
}
// Returns the producer link in this network.
public func GetProducerLink(object link)
{
for (var test_link in Concatenate(lib_power.idle_producers, lib_power.active_producers))
if (test_link.obj == link)
return test_link;
return;
}
// Returns the consumer link in this network.
public func GetConsumerLink(object link)
{
for (var test_link in Concatenate(lib_power.waiting_consumers, lib_power.active_consumers))
if (test_link.obj == link)
return test_link;
return;
}
/*-- Logging --*/

View File

@ -1057,13 +1057,15 @@ global func Test18_OnStart(int plr)
// Power consumer: one workshop.
var workshop = CreateObjectAbove(ToolsWorkshop, 110, 160, plr);
workshop->CreateContents(Wood, 4);
workshop->CreateContents(Metal, 4);
workshop->AddToQueue(Shovel, 4);
workshop->CreateContents(Wood, 2);
workshop->CreateContents(Metal, 2);
workshop->AddToQueue(Shovel, 2);
// Move workshop.
ScheduleCall(workshop, "SetPosition", 2 * 36, 0, 250, 140);
ScheduleCall(workshop, "SetPosition", 8 * 36, 0, 110, 140);
ScheduleCall(workshop, "SetPosition", 12 * 36, 0, 250, 140);
ScheduleCall(workshop, "SetPosition", 16 * 36, 0, 110, 140);
// Log what the test is about.
Log("A steady power source (wind generator) supplying an on-demand consumer (workshop), the consumer moves out and into the power range.");
@ -1072,7 +1074,7 @@ global func Test18_OnStart(int plr)
global func Test18_Completed()
{
if (ObjectCount(Find_ID(Shovel)) >= 4)
if (ObjectCount(Find_ID(Shovel)) >= 2)
return true;
return false;
}