Pipe control: Begin integrating limits into the library

Not sure about air pipes yet, those should theoretically be either
source or drain, instead of a separate connection category?

See also:
https://bugs.openclonk.org/view.php?id=1871
master
Mark 2018-12-28 00:14:54 +01:00
parent 2a045a097b
commit cd38671f61
13 changed files with 174 additions and 129 deletions

View File

@ -41,32 +41,6 @@ public func GetLiquidContainerMaxFillLevel(liquid_name)
return this.LiquidCapacity;
}
// The liquid tank may have one drain and one source.
public func QueryConnectPipe(object pipe, bool do_msg)
{
if (GetDrainPipe() && GetSourcePipe())
{
if (do_msg) pipe->Report("$MsgHasPipes$");
return true;
}
else if (GetSourcePipe() && pipe->IsSourcePipe())
{
if (do_msg) pipe->Report("$MsgSourcePipeProhibited$");
return true;
}
else if (GetDrainPipe() && pipe->IsDrainPipe())
{
if (do_msg) pipe->Report("$MsgDrainPipeProhibited$");
return true;
}
else if (pipe->IsAirPipe())
{
if (do_msg) pipe->Report("$MsgPipeProhibited$");
return true;
}
return false;
}
// Set to source or drain pipe.
public func OnPipeConnect(object pipe, string specific_pipe_state)
{
@ -172,4 +146,9 @@ local FireproofContainer = true;
local HitPoints = 90;
local Components = {Wood = 3, Metal = 2};
local LiquidCapacity = 10000;
local DispersionRate = 40;
local DispersionRate = 40;
// The liquid tank may have one drain and one source.
local PipeLimit_Air = 0;
local PipeLimit_Drain = 1;
local PipeLimit_Source = 1;

View File

@ -2,10 +2,6 @@ Name=Tank
Description=Hier können Flüssigkeiten gespeichert werden, aber nur eine Art gleichzeitig.
MsgConnectedPipe=Rohr angeschlossen.
MsgPipeProhibited=Dieses Rohr kann nicht an den Tank angeschlossen werden.
MsgHasPipes=Der Tank hat schon ein Zu- und Abflussrohr.
MsgSourcePipeProhibited=Zuflussrohre können nicht an den Tank angeschlossen werden.
MsgDrainPipeProhibited=Abflussrohre können nicht an den Tank angeschlossen werden.
MsgOpenTank=Ventil öffnen
MsgCloseTank=Ventil schließen
MsgCloseTank=Ventil schließen

View File

@ -2,10 +2,6 @@ Name=Liquid Tank
Description=Liquids can be stored here, but only one type of liquid at the same time.
MsgConnectedPipe=Connected pipe.
MsgPipeProhibited=This pipe cannot be connected to the liquid tank.
MsgHasPipes=Liquid tank already has a source and a drain pipe.
MsgSourcePipeProhibited=Unable to connect source pipe to the liquid tank.
MsgDrainPipeProhibited=Unable to connect drain pipe to the liquid tank.
MsgOpenTank=Open valve
MsgCloseTank=Close valve
MsgCloseTank=Close valve

View File

@ -13,6 +13,7 @@
@author Maikel, Marky
*/
/* --- Constants --- */
static const LIBRARY_PIPE_Menu_Action_Add_Drain = "adddrain";
static const LIBRARY_PIPE_Menu_Action_Add_Source = "addsource";
@ -23,11 +24,22 @@ static const LIBRARY_PIPE_Menu_Action_Cut_Neutral = "cutneutral";
static const LIBRARY_PIPE_Menu_Action_Swap_SourceDrain = "swapsourcedrain";
static const LIBRARY_PIPE_Menu_Action_Description = "description";
/* --- Properties --- */
local lib_pipe_control; // proplist for local variables
local lib_pipe_control; // Proplist for local variables
// Numerical limits for pipe connections, per pipe type; Meaning:
// - nil = unlimited connections allowed
// - 0 = no connections allowed
// - 1 = 1 connection allowed
// - connections > 1 may work, but are not integrated properly yet.
local PipeLimit_Air = nil;
local PipeLimit_Drain = nil;
local PipeLimit_Neutral = nil;
local PipeLimit_Source = nil;
/*-- Callbacks --*/
/* --- Callbacks --- */
public func Construction()
{
@ -48,7 +60,7 @@ public func Construction()
}
/*-- Menu Entries --*/
/* --- Menu Entries --- */
public func HasInteractionMenu() { return true; }
@ -216,12 +228,19 @@ public func GetConnectedPipeDescription(string base_desc, object pipe1, object p
return desc;
}
/*-- Handle Connections --*/
/* --- Handle Connections --- */
public func GetAirPipe() { return lib_pipe_control.air_pipe;}
public func GetDrainPipe() { return lib_pipe_control.drain_pipe;}
public func GetSourcePipe() { return lib_pipe_control.source_pipe;}
public func GetNeutralPipe() { return lib_pipe_control.neutral_pipe;}
public func SetAirPipe(object air_pipe)
{
lib_pipe_control.air_pipe = air_pipe;
return lib_pipe_control.air_pipe;
}
public func SetDrainPipe(object drain_pipe)
{
lib_pipe_control.drain_pipe = drain_pipe;
@ -241,7 +260,7 @@ public func SetNeutralPipe(object neutral_pipe)
}
/*-- Menu Callbacks --*/
/* --- Menu Callbacks --- */
public func DoConnectPipe(object pipe, string specific_pipe_state)
{
@ -300,7 +319,7 @@ public func FindAvailablePipe(object container, find_state)
}
/*-- Pipe Callbacks --*/
/* --- Pipe Callbacks --- */
public func CanConnectPipe(){ return true;}
@ -313,11 +332,107 @@ public func OnPipeDisconnect(object pipe)
}
/*-- Scenario Saving --*/
public func QueryConnectPipe(object pipe, bool report_message)
{
// Do not allow connections from this object to itself
if (pipe->~IsConnectedTo(this)
|| pipe->~GetConnectedLine() && pipe->GetConnectedLine()->~IsConnectedTo(this))
{
if (report_message) pipe->Report(Format("$MsgPipeAlreadyConnected$", this->GetName()));
return true;
}
// All limits hit?
if (AllPipeLimitsReached())
{
if (report_message)
{
var possible_connections;
for (var limit in GetPipeLimits())
{
if (!limit.HasLimit) continue;
if (possible_connections)
{
possible_connections = Format("%s, %s", possible_connections, limit.Description);
}
else
{
possible_connections = limit.Description;
}
}
pipe->Report(Format("$MsgHasPipes$", this->GetName(), possible_connections));
}
return true;
}
// Check limits individually
if (IsPipeLimitReached(pipe, pipe->IsSourcePipe(), this.PipeLimit_Source, GetSourcePipe(), report_message, "$MsgSourcePipeProhibited$")
|| IsPipeLimitReached(pipe, pipe->IsDrainPipe(), this.PipeLimit_Drain, GetDrainPipe(), report_message, "$MsgDrainPipeProhibited$")
|| IsPipeLimitReached(pipe, pipe->IsAirPipe(), this.PipeLimit_Air, GetAirPipe(), report_message, "$MsgAirPipeProhibited$")
|| IsPipeLimitReached(pipe, pipe->IsNeutralPipe(), this.PipeLimit_Neutral, GetNeutralPipe(), report_message, "$MsgNeutralPipeProhibited$"))
{
return true;
}
return false;
}
func IsPipeLimitReached(object pipe, bool apply_limit, int limit, object existing_pipe, bool report_message, string message)
{
// Limit does not even apply?
if (!apply_limit || nil == limit)
{
return false;
}
// Pipes of this type are always prohibited?
if (0 == limit)
{
if (report_message) pipe->Report(Format("$MsgPipeProhibited$", this->GetName()));
return true;
}
// Pipes of this type are limited?
if (!!existing_pipe)
{
if (report_message) pipe->Report(Format(message ?? "$MsgPipeProhibited$", this->GetName()));
return true;
}
return false;
}
func AllPipeLimitsReached()
{
var limits = GetPipeLimits();
var has_limit = false;
for (var limit in limits)
{
if (!limit.HasLimit)
{
continue;
}
has_limit = true;
if (!limit.Current)
{
return false;
}
}
return has_limit;
}
func GetPipeLimits()
{
return [{HasLimit = this.PipeLimit_Air, Current = GetAirPipe(), Description = "$MsgPipeAir$", },
{HasLimit = this.PipeLimit_Drain, Current = GetDrainPipe(), Description = "$MsgPipeDrain$", },
{HasLimit = this.PipeLimit_Neutral, Current = GetNeutralPipe(), Description = "$MsgPipeNeutral$", },
{HasLimit = this.PipeLimit_Source, Current = GetSourcePipe(), Description = "$MsgPipeSource$", }];
}
/* --- Scenario Saving --- */
public func SaveScenarioObject(props)
{
if (!inherited(props, ...)) return false;
if (lib_pipe_control.air_pipe) props->AddCall("AirPipe", this, "SetAirPipe", lib_pipe_control.air_pipe);
if (lib_pipe_control.drain_pipe) props->AddCall("DrainPipe", this, "SetDrainPipe", lib_pipe_control.drain_pipe);
if (lib_pipe_control.source_pipe) props->AddCall("SourcePipe", this, "SetSourcePipe", lib_pipe_control.source_pipe);
if (lib_pipe_control.neutral_pipe) props->AddCall("NeutralPipe", this, "SetNeutralPipe", lib_pipe_control.neutral_pipe);

View File

@ -20,4 +20,17 @@ DescConnectedTo=Dieses Rohr ist momentan verbunden mit {{%i}}.
DescConnectedToMultiple=Dieses Rohr ist momentan verbunden mit {{%i}} und {{%i}}.
MsgSwapSourceDrain=Wechsele Zufluss und Abfluss
DescSwapSourceDrain=Wechselt das Zuflussrohr mit dem Abflussrohr.
DescSwapSourceDrain=Wechselt das Zuflussrohr mit dem Abflussrohr.
MsgConnectedPipe=Rohr angeschlossen.
MsgPipeAlreadyConnected=Dieses Rohr ist bereits an %s angeschlossen.
MsgPipeProhibited=Dieses Rohr kann nicht an %s angeschlossen werden.
MsgHasPipes=Es können keine weiteren Rohre an %s angeschlossen werden. Bereits vorhanden: %s.
MsgAirPipeProhibited=Luftrohre können nicht an %s angeschlossen werden.
MsgDrainPipeProhibited=Abflussrohre können nicht an %s angeschlossen werden.
MsgNeutralPipeProhibited=Beliebige Rohre können nicht an %s angeschlossen werden.
MsgSourcePipeProhibited=Zuflussrohre können nicht an %s angeschlossen werden.
MsgPipeAir=Luftrohr
MsgPipeDrain=Abflussrohr
MsgPipeNeutral=beliebiges Rohr
MsgPipeSource=Zuflussrohr

View File

@ -20,4 +20,17 @@ DescConnectedTo=This pipe is currently connected to {{%i}}.
DescConnectedToMultiple=This pipe is currently connected to {{%i}} and {{%i}}.
MsgSwapSourceDrain=Swap source and drain
DescSwapSourceDrain=Swaps the source and drain pipes.
DescSwapSourceDrain=Swaps the source and drain pipes.
MsgConnectedPipe=Connected pipe.
MsgPipeAlreadyConnected=This pipe is already connected to %s.
MsgPipeProhibited=This pipe cannot be connected to %s.
MsgHasPipes=%s already has all possible pipe connections: %s.
MsgAirPipeProhibited=Unable to connect air pipe to %s.
MsgDrainPipeProhibited=Unable to connect drain pipe to %s.
MsgNeutralPipeProhibited=Unable to connect neutral pipe to %s.
MsgSourcePipeProhibited=Unable to connect source pipe to %s.
MsgPipeAir=air pipe
MsgPipeDrain=drain pipe
MsgPipeNeutral=neutral pipe
MsgPipeSource=source pipe

View File

@ -156,32 +156,6 @@ public func GetLiquidContainerMaxFillLevel(liquid_name)
return 300;
}
// The foundry may have one drain and one source.
public func QueryConnectPipe(object pipe, bool do_msg)
{
if (GetDrainPipe() && GetSourcePipe())
{
if (do_msg) pipe->Report("$MsgHasPipes$");
return true;
}
else if (GetSourcePipe() && pipe->IsSourcePipe())
{
if (do_msg) pipe->Report("$MsgSourcePipeProhibited$");
return true;
}
else if (GetDrainPipe() && pipe->IsDrainPipe())
{
if (do_msg) pipe->Report("$MsgDrainPipeProhibited$");
return true;
}
else if (pipe->IsAirPipe())
{
if (do_msg) pipe->Report("$MsgPipeProhibited$");
return true;
}
return false;
}
// Set to source or drain pipe.
public func OnPipeConnect(object pipe, string specific_pipe_state)
{
@ -235,3 +209,8 @@ local BlastIncinerate = 100;
local HitPoints = 100;
local FireproofContainer = true;
local Components = {Rock = 4, Wood = 2};
// The foundry may have one drain and one source.
local PipeLimit_Air = 0;
local PipeLimit_Drain = 1;
local PipeLimit_Source = 1;

View File

@ -2,7 +2,3 @@ Name=Hochofen
Description=Im Hochofen können Erze zu Barren geschmolzen werden. Dafür wird ein Brennstoff benötigt.
MsgConnectedPipe=Rohr angeschlossen.
MsgPipeProhibited=Dieses Rohr kann nicht an den Hochofen angeschlossen werden.
MsgHasPipes=Der Hochofen hat schon ein Zu- und Abflussrohr.
MsgSourcePipeProhibited=Zuflussrohre können nicht an den Hochofen angeschlossen werden.
MsgDrainPipeProhibited=Abflussrohre können nicht an den Hochofen angeschlossen werden.

View File

@ -2,7 +2,3 @@ Name=Foundry
Description=In the foundry, ore can be smelted into ingots. Fuel, such as coal, is necessary for this.
MsgConnectedPipe=Connected pipe.
MsgPipeProhibited=This pipe cannot be connected to the foundry.
MsgHasPipes=Foundry already has a source and a drain pipe.
MsgSourcePipeProhibited=Unable to connect source pipe to the foundry.
MsgDrainPipeProhibited=Unable to connect drain pipe to the foundry.

View File

@ -213,32 +213,6 @@ public func GetLiquidContainerMaxFillLevel(liquid_name)
return 300;
}
// The foundry may have one drain and one source.
public func QueryConnectPipe(object pipe, bool do_msg)
{
if (GetDrainPipe() && GetSourcePipe())
{
if (do_msg) pipe->Report("$MsgHasPipes$");
return true;
}
else if (GetSourcePipe() && pipe->IsSourcePipe())
{
if (do_msg) pipe->Report("$MsgSourcePipeProhibited$");
return true;
}
else if (GetDrainPipe() && pipe->IsDrainPipe())
{
if (do_msg) pipe->Report("$MsgDrainPipeProhibited$");
return true;
}
else if (pipe->IsAirPipe())
{
if (do_msg) pipe->Report("$MsgPipeProhibited$");
return true;
}
return false;
}
// Set to source or drain pipe.
public func OnPipeConnect(object pipe, string specific_pipe_state)
{
@ -328,4 +302,9 @@ local HitPoints = 100;
local FireproofContainer = true;
local Name = "$Name$";
local Description = "$Description$";
local Components = {Rock = 6, Metal = 3};
local Components = {Rock = 6, Metal = 3};
// The steam engine may have one drain and one source.
local PipeLimit_Air = 0;
local PipeLimit_Drain = 1;
local PipeLimit_Source = 1;

View File

@ -71,24 +71,6 @@ public func GetLiquidContainerMaxFillLevel(liquid_name)
return this.LiquidCapacity;
}
// The locomotive may only have a drain pipe.
public func QueryConnectPipe(object pipe, bool do_msg)
{
if (pipe->IsDrainPipe() && GetDrainPipe())
{
if (do_msg)
pipe->Report("$MsgHasDrainPipe$");
return true;
}
if (pipe->IsSourcePipe() || pipe->IsAirPipe())
{
if (do_msg)
pipe->Report("$MsgPipeProhibited$");
return true;
}
return false;
}
// Set to source or drain pipe.
public func OnPipeConnect(object pipe, string specific_pipe_state)
{
@ -253,3 +235,8 @@ local BorderBound = C4D_Border_Sides;
local ContactCalls = true;
local Components = {Wood = 1, Metal = 4};
local LiquidCapacity = 2400;
// The locomotive may only have a drain pipe.
local PipeLimit_Air = 0;
local PipeLimit_Drain = 1;
local PipeLimit_Source = 0;

View File

@ -7,5 +7,3 @@ MsgNoCoalAndWater=Keine Kohle und kein Wasser verfügbar!
MsgStuck=Lokomotive steckt fest
MsgConnectedPipe=Rohr angeschlossen.
MsgHasDrainPipe=Die Lokomotive hat schon ein Abflussrohr.
MsgPipeProhibited=Es können nur Abflussrohre an die Lokomotive angeschlossen werden.

View File

@ -7,5 +7,3 @@ MsgNoCoalAndWater=No coal and water available!
MsgStuck=Locomotive is stuck
MsgConnectedPipe=Connected pipe.
MsgHasDrainPipe=Locomotive already has a drain pipe.
MsgPipeProhibited=Only connecting a drain pipe is allowed.