From cd38671f61c28453495658b5e245608932877761 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 28 Dec 2018 00:14:54 +0100 Subject: [PATCH] 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 --- .../Experimental.ocd/LiquidTank.ocd/Script.c | 33 +---- .../LiquidTank.ocd/StringTblDE.txt | 6 +- .../LiquidTank.ocd/StringTblUS.txt | 6 +- .../PipeControl.ocd/Script.c | 129 +++++++++++++++++- .../PipeControl.ocd/StringTblDE.txt | 15 +- .../PipeControl.ocd/StringTblUS.txt | 15 +- .../Structures.ocd/Foundry.ocd/Script.c | 31 +---- .../Foundry.ocd/StringTblDE.txt | 4 - .../Foundry.ocd/StringTblUS.txt | 4 - .../Structures.ocd/SteamEngine.ocd/Script.c | 33 +---- .../Vehicles.ocd/Locomotive.ocd/Script.c | 23 +--- .../Locomotive.ocd/StringTblDE.txt | 2 - .../Locomotive.ocd/StringTblUS.txt | 2 - 13 files changed, 174 insertions(+), 129 deletions(-) diff --git a/planet/Experimental.ocd/LiquidTank.ocd/Script.c b/planet/Experimental.ocd/LiquidTank.ocd/Script.c index bb2617a60..dfca15157 100644 --- a/planet/Experimental.ocd/LiquidTank.ocd/Script.c +++ b/planet/Experimental.ocd/LiquidTank.ocd/Script.c @@ -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; \ No newline at end of file +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; diff --git a/planet/Experimental.ocd/LiquidTank.ocd/StringTblDE.txt b/planet/Experimental.ocd/LiquidTank.ocd/StringTblDE.txt index 5b9159c1d..ccd425660 100644 --- a/planet/Experimental.ocd/LiquidTank.ocd/StringTblDE.txt +++ b/planet/Experimental.ocd/LiquidTank.ocd/StringTblDE.txt @@ -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 \ No newline at end of file +MsgCloseTank=Ventil schließen diff --git a/planet/Experimental.ocd/LiquidTank.ocd/StringTblUS.txt b/planet/Experimental.ocd/LiquidTank.ocd/StringTblUS.txt index 630389196..8ff90ca83 100644 --- a/planet/Experimental.ocd/LiquidTank.ocd/StringTblUS.txt +++ b/planet/Experimental.ocd/LiquidTank.ocd/StringTblUS.txt @@ -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 \ No newline at end of file +MsgCloseTank=Close valve diff --git a/planet/Objects.ocd/Libraries.ocd/LiquidControl.ocd/PipeControl.ocd/Script.c b/planet/Objects.ocd/Libraries.ocd/LiquidControl.ocd/PipeControl.ocd/Script.c index abafd7954..5e2d4023a 100755 --- a/planet/Objects.ocd/Libraries.ocd/LiquidControl.ocd/PipeControl.ocd/Script.c +++ b/planet/Objects.ocd/Libraries.ocd/LiquidControl.ocd/PipeControl.ocd/Script.c @@ -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); diff --git a/planet/Objects.ocd/Libraries.ocd/LiquidControl.ocd/PipeControl.ocd/StringTblDE.txt b/planet/Objects.ocd/Libraries.ocd/LiquidControl.ocd/PipeControl.ocd/StringTblDE.txt index a6e86c519..e7c28b640 100755 --- a/planet/Objects.ocd/Libraries.ocd/LiquidControl.ocd/PipeControl.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Libraries.ocd/LiquidControl.ocd/PipeControl.ocd/StringTblDE.txt @@ -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. \ No newline at end of file +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 diff --git a/planet/Objects.ocd/Libraries.ocd/LiquidControl.ocd/PipeControl.ocd/StringTblUS.txt b/planet/Objects.ocd/Libraries.ocd/LiquidControl.ocd/PipeControl.ocd/StringTblUS.txt index 5910438e1..7a4c26a13 100755 --- a/planet/Objects.ocd/Libraries.ocd/LiquidControl.ocd/PipeControl.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Libraries.ocd/LiquidControl.ocd/PipeControl.ocd/StringTblUS.txt @@ -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. \ No newline at end of file +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 diff --git a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Script.c index d5b62f81c..575adaa10 100644 --- a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/Script.c @@ -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; diff --git a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblDE.txt b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblDE.txt index 7a504994a..c423289ea 100644 --- a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblDE.txt @@ -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. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblUS.txt b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblUS.txt index 508271e3f..b88a2af41 100644 --- a/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Structures.ocd/Foundry.ocd/StringTblUS.txt @@ -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. \ No newline at end of file diff --git a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/Script.c b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/Script.c index b2a21ad3a..d53205f8a 100644 --- a/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/Script.c +++ b/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/Script.c @@ -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}; \ No newline at end of file +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; diff --git a/planet/Objects.ocd/Vehicles.ocd/Locomotive.ocd/Script.c b/planet/Objects.ocd/Vehicles.ocd/Locomotive.ocd/Script.c index 17ba71904..73c082d22 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Locomotive.ocd/Script.c +++ b/planet/Objects.ocd/Vehicles.ocd/Locomotive.ocd/Script.c @@ -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; diff --git a/planet/Objects.ocd/Vehicles.ocd/Locomotive.ocd/StringTblDE.txt b/planet/Objects.ocd/Vehicles.ocd/Locomotive.ocd/StringTblDE.txt index d7e9af4db..2f4289830 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Locomotive.ocd/StringTblDE.txt +++ b/planet/Objects.ocd/Vehicles.ocd/Locomotive.ocd/StringTblDE.txt @@ -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. \ No newline at end of file diff --git a/planet/Objects.ocd/Vehicles.ocd/Locomotive.ocd/StringTblUS.txt b/planet/Objects.ocd/Vehicles.ocd/Locomotive.ocd/StringTblUS.txt index cb4bba1b4..2dc6715c4 100644 --- a/planet/Objects.ocd/Vehicles.ocd/Locomotive.ocd/StringTblUS.txt +++ b/planet/Objects.ocd/Vehicles.ocd/Locomotive.ocd/StringTblUS.txt @@ -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. \ No newline at end of file