Refactoring: Pump, pipe, better menu handling

The pipe can be connected from the interaction menu now, too. Expanded the disconnection logic, because more problems arise when the pipe can still be connected to other structures - it would be sufficient to remove the line, but that could be annoying:
- if the pipe is connected to a container, then you can disconnect the pipe from that liquid tank and it will still be connected to the pump
- if you disconnect the pipe from the pump, then it will disconnect from the liquid tank as well

Maybe this is confusing to the user, we can still kick that out later again.
liquid_container
Mark 2016-02-04 21:37:33 +01:00
parent 016922fa2c
commit affb034b86
4 changed files with 188 additions and 73 deletions

View File

@ -24,12 +24,17 @@ public func IsToolProduct() { return true; }
protected func ControlUse(object clonk, int x, int y)
{
// Is this already connected to a liquid pump?
var pipe = FindObject(Find_Func("IsConnectedTo", this));
var pipe = GetConnectedPipe();
if (pipe) return ConnectPipeToLiquidTank(clonk, pipe);
return ConnectPipeToPump(clonk);
}
func CanConnectToLiquidPump()
{
return PipeState == nil;
}
func ConnectPipeToPump(object clonk)
{
// Is there an object which accepts pipes?
@ -49,33 +54,7 @@ func ConnectPipeToPump(object clonk)
return true;
}
// Create and connect pipe.
var pipe = CreateObjectAbove(PipeLine, 0, 0, NO_OWNER);
pipe->SetActionTargets(this, liquid_pump);
Sound("Objects::Connect");
// If liquid pump has no source yet, create one.
if (!liquid_pump->GetSource())
{
liquid_pump->SetSource(pipe);
clonk->Message("$MsgCreatedSource$");
SetGraphics("Source", Pipe, GFX_Overlay, GFXOV_MODE_Picture);
Description = "$DescriptionSource$";
Name = "$NameSource$";
pipe->SetSource();
PipeState = PIPE_STATE_Source;
}
// Otherwise if liquid pump has no drain, create one.
else
{
liquid_pump->SetDrain(pipe);
clonk->Message("$MsgCreatedDrain$");
SetGraphics("Drain", Pipe, GFX_Overlay, GFXOV_MODE_Picture);
Description = "$DescriptionDrain$";
Name = "$NameDrain$";
pipe->SetDrain();
PipeState = PIPE_STATE_Drain;
}
if (!ConnectSourcePipeToPump(liquid_pump, clonk)) ConnectDrainPipeToPump(liquid_pump, clonk);
return true;
}
@ -104,11 +83,100 @@ func ConnectPipeToLiquidTank(object clonk, object pipe)
pipe->SwitchConnection(this, tank);
pipe->SetPipeKit(this);
Sound("Objects::Connect");
clonk->Message("$MsgConnectedToTank$", Name, tank->GetName());
this->OnConnectPipe(tank);
return true;
}
func GetConnectedPipe()
{
return FindObject(Find_Func("IsConnectedTo", this));
}
func CreatePipe(object liquid_pump)
{
// Create and connect pipe.
var pipe = GetConnectedPipe();
if (!pipe)
{
pipe = CreateObjectAbove(PipeLine, 0, 0, NO_OWNER);
pipe->SetActionTargets(this, liquid_pump);
}
return pipe;
}
func ConnectSourcePipeToPump(object liquid_pump, object clonk)
{
// If liquid pump has no source yet, create one.
if (liquid_pump->GetSource()) return false;
var pipe = CreatePipe(liquid_pump);
liquid_pump->SetSource(pipe);
clonk->Message("$MsgCreatedSource$");
SetGraphics("Source", Pipe, GFX_Overlay, GFXOV_MODE_Picture);
Description = "$DescriptionSource$";
Name = "$NameSource$";
pipe->SetSource();
PipeState = PIPE_STATE_Source;
this->OnConnectPipe(liquid_pump);
return true;
}
func ConnectDrainPipeToPump(object liquid_pump, object clonk)
{
// If liquid pump has no drain yet, create one.
if (liquid_pump->GetDrain()) return false;
var pipe = CreatePipe(liquid_pump);
liquid_pump->SetDrain(pipe);
clonk->Message("$MsgCreatedDrain$");
SetGraphics("Drain", Pipe, GFX_Overlay, GFXOV_MODE_Picture);
Description = "$DescriptionDrain$";
Name = "$NameDrain$";
pipe->SetDrain();
PipeState = PIPE_STATE_Drain;
this->OnConnectPipe(liquid_pump);
return true;
}
func OnConnectPipe(object target)
{
target->Sound("Objects::Connect");
}
func CutConnection(object target)
{
var pipe = GetConnectedPipe();
if (!pipe) return;
if (pipe->IsConnectedTo(this, true)) // get a strict connection, i.e. connected only to the kit and a structure
{
pipe->RemoveObject();
}
else if (pipe->IsConnectedTo(target, true)) // we need at least a connection, so that no random guys can cut the pipe
{
Exit();
SetPosition(target->GetX(), target->GetY());
pipe->SwitchConnection(target, this);
// if we get disconnected from the pump, then we also have to disconnect
// from all liquid containers: otherwise we would need a logic how to
// connect from liquid container to pump, which does not exist!
if (target->~IsLiquidPump())
{
CutConnection(this);
}
}
else
{
FatalError(Format("Unexpected error: An object %v is trying to cut the pipe connection, but only objects %v and %v may request a disconnect", target, pipe->GetActionTarget(0), pipe->GetActionTarget(1)));
}
}
// Line broke or something
public func ResetPicture()
{

View File

@ -15,9 +15,11 @@
static const PUMP_Menu_Action_Switch_On = "on";
static const PUMP_Menu_Action_Switch_Off = "off";
static const PUMP_Menu_Action_Switch_Cut_Drain = "cutdrain";
static const PUMP_Menu_Action_Switch_Cut_Source = "cutsource";
static const PUMP_Menu_Action_Switch_Description = "description";
static const PUMP_Menu_Action_Connect_Drain = "connectdrain";
static const PUMP_Menu_Action_Cut_Drain = "cutdrain";
static const PUMP_Menu_Action_Connect_Source = "connectsource";
static const PUMP_Menu_Action_Cut_Source = "cutsource";
static const PUMP_Menu_Action_Description = "description";
local animation; // animation handle
@ -84,7 +86,7 @@ public func GetPumpControlMenuEntries(object clonk)
status = last_status_message;
lightbulb_graphics = "Red";
}
PushBack(menu_entries, {symbol = this, extra_data = PUMP_Menu_Action_Switch_Description,
PushBack(menu_entries, {symbol = this, extra_data = PUMP_Menu_Action_Description,
custom =
{
Prototype = custom_entry,
@ -94,46 +96,42 @@ public func GetPumpControlMenuEntries(object clonk)
text = {Prototype = custom_entry.text, Text = status},
image = {Prototype = custom_entry.image, Symbol = Icon_Lightbulb, GraphicsName = lightbulb_graphics}
}});
var available_pipe = FindAvailablePipe(clonk);
// switch on and off
if (!switched_on)
PushBack(menu_entries, {symbol = Icon_Play, extra_data = PUMP_Menu_Action_Switch_On,
custom =
{
Prototype = custom_entry,
Priority = 1,
text = {Prototype = custom_entry.text, Text = "$MsgTurnOn$"},
image = {Prototype = custom_entry.image, Symbol = Icon_Play}
}});
PushBack(menu_entries, GetPumpMenuEntry(custom_entry, Icon_Play, "$MsgTurnOn$", 1, PUMP_Menu_Action_Switch_On));
else
PushBack(menu_entries, {symbol = Icon_Stop, extra_data = PUMP_Menu_Action_Switch_Off,
custom =
{
Prototype = custom_entry,
Priority = 1,
text = {Prototype = custom_entry.text, Text = "$MsgTurnOff$"},
image = {Prototype = custom_entry.image, Symbol = Icon_Stop}
}});
PushBack(menu_entries, GetPumpMenuEntry(custom_entry, Icon_Stop, "$MsgTurnOff$", 1, PUMP_Menu_Action_Switch_Off));
// handle source pipe connection
if (source_pipe)
PushBack(menu_entries, {symbol = Icon_Cancel, extra_data = PUMP_Menu_Action_Switch_Cut_Source,
custom =
{
Prototype = custom_entry,
Priority = 2,
text = {Prototype = custom_entry.text, Text = "$MsgCutSource$"},
image = {Prototype = custom_entry.image, Symbol = Icon_Cancel}
}});
PushBack(menu_entries, GetPumpMenuEntry(custom_entry, Icon_Cancel, "$MsgCutSource$", 2, PUMP_Menu_Action_Cut_Source));
else if (available_pipe)
PushBack(menu_entries, GetPumpMenuEntry(custom_entry, available_pipe, "$MsgConnectSource$", 2, PUMP_Menu_Action_Connect_Source));
// handle drain pipe connection
if (drain_pipe)
PushBack(menu_entries, {symbol = Icon_Cancel, extra_data = PUMP_Menu_Action_Switch_Cut_Drain,
custom =
{
Prototype = custom_entry,
Priority = 3,
text = {Prototype = custom_entry.text, Text = "$MsgCutDrain$"},
image = {Prototype = custom_entry.image, Symbol = Icon_Cancel}
}});
PushBack(menu_entries, GetPumpMenuEntry(custom_entry, Icon_Cancel, "$MsgCutDrain$", 3, PUMP_Menu_Action_Cut_Drain));
else
PushBack(menu_entries, GetPumpMenuEntry(custom_entry, available_pipe, "$MsgConnectDrain$", 3, PUMP_Menu_Action_Connect_Drain));
return menu_entries;
}
func GetPumpMenuEntry(proplist custom_entry, symbol, string text, int priority, extra_data)
{
return {symbol = symbol, extra_data = extra_data,
custom =
{
Prototype = custom_entry,
Priority = priority,
text = {Prototype = custom_entry.text, Text = text},
image = {Prototype = custom_entry.image, Symbol = symbol}
}};
}
public func GetInteractionMenus(object clonk)
{
var menus = _inherited() ?? [];
@ -156,20 +154,32 @@ public func OnPumpControlHover(id symbol, string action, desc_menu_target, menu_
var text = "";
if (action == PUMP_Menu_Action_Switch_On) text = "$DescTurnOn$";
else if (action == PUMP_Menu_Action_Switch_Off) text = "$DescTurnOff$";
else if (action == PUMP_Menu_Action_Switch_Cut_Drain) text = "$DescCutDrain$";
else if (action == PUMP_Menu_Action_Switch_Cut_Source) text = "$DescCutSource$";
else if (action == PUMP_Menu_Action_Switch_Description) text = this.Description;
else if (action == PUMP_Menu_Action_Cut_Drain) text = "$DescCutDrain$";
else if (action == PUMP_Menu_Action_Cut_Source) text = "$DescCutSource$";
else if (action == PUMP_Menu_Action_Connect_Drain) text = "$DescConnectDrain$";
else if (action == PUMP_Menu_Action_Connect_Source) text = "$DescConnectSource$";
else if (action == PUMP_Menu_Action_Description) text = this.Description;
GuiUpdateText(text, menu_id, 1, desc_menu_target);
}
public func OnPumpControl(id symbol, string action, bool alt)
func FindAvailablePipe(object container)
{
return FindObject(Find_ID(Pipe), Find_Container(container), Find_Func("CanConnectToLiquidPump"));
}
public func OnPumpControl(symbol_or_object, string action, bool alt)
{
if (action == PUMP_Menu_Action_Switch_On || action == PUMP_Menu_Action_Switch_Off)
ToggleOnOff(true);
else if (action == PUMP_Menu_Action_Switch_Cut_Source && source_pipe)
source_pipe->RemoveObject();
else if (action == PUMP_Menu_Action_Switch_Cut_Drain && drain_pipe)
drain_pipe->RemoveObject();
else if (action == PUMP_Menu_Action_Cut_Source && source_pipe)
DoCutPipe(source_pipe);
else if (action == PUMP_Menu_Action_Cut_Drain && drain_pipe)
DoCutPipe(drain_pipe);
else if (action == PUMP_Menu_Action_Connect_Source && !source_pipe)
DoConnectPipe(symbol_or_object, PIPE_STATE_Source);
else if (action == PUMP_Menu_Action_Connect_Drain && !drain_pipe)
DoConnectPipe(symbol_or_object, PIPE_STATE_Drain);
UpdateInteractionMenus(this.GetPumpControlMenuEntries);
}
@ -192,6 +202,35 @@ public func SetSource(object pipe)
CheckState();
}
func DoConnectPipe(object pipe, string pipe_state)
{
var clonk = pipe->Contained();
if (pipe_state == PIPE_STATE_Source)
pipe->ConnectSourcePipeToPump(this, clonk);
else if (pipe_state == PIPE_STATE_Drain)
pipe->ConnectDrainPipeToPump(this, clonk);
else
pipe->ConnectPipeToPump(clonk);
}
func DoCutPipe(object pipe_line)
{
if (pipe_line)
{
var pipe_kit = pipe_line->GetPipeKit();
pipe_kit->CutConnection(this);
// pipe objects have to be reset!
// in the former implementation the pipe object
// was removed when the connection is cut.
// this time the pipe may still be there,
// connected to the steam engine etc.
if (pipe_line == GetDrain()) SetDrain();
if (pipe_line == GetSource()) SetSource();
}
}
/*-- Power stuff --*/
public func GetConsumerPriority() { return 25; }

View File

@ -8,6 +8,10 @@ DescTurnOff=Schaltet die Pumpe ab, so dass keine Fl
DescTurnOn=Aktiviert das Pumpen wieder. Dafür muss mindestens ein Zufluss angeschlossen sein.
DescCutSource=Entfernt das Zuflussrohr. Die Pumpe kann dann nicht mehr pumpen.
DescCutDrain=Entfernt das Abflussrohr. Es wird dann direkt zur Pumpe gepumpt.
MsgConnectSource=Zufluss anschließen
MsgConnectDrain=Abfluss anschließen
DescConnectSource=Schließt ein Zuflussrohr an die Pumpe an. Die Pumpe bezieht dann Flüssigkeiten von diesem Rohr.
DescConnectDrain=Schließt ein Abflussrohr an die Pumpe an. Die Pumpe pumpt dann in dieses Rohr.
Control=Pumpensteuerung
StateOk=Die Pumpe läuft.

View File

@ -8,6 +8,10 @@ DescTurnOff=Disables the pump so that no liquid is transported.
DescTurnOn=Reactivates the pumping. Successful pumping requires at least a connected source pipe.
DescCutSource=Removes the source pipe. The pump will be unable to continue pumping without a source pipe.
DescCutDrain=Removes the drain pipe. Liquids will be pumped directly to the pump.
MsgConnectSource=Connect source
MsgConnectDrain=Connect drain
DescConnectSource=Connects a source pipe to the pump. The pump then gets liquid from that pipe.
DescConnectDrain=Connects a drain pipe to the pump. The pump then directs liquid though that pipe.
Control=Pump Control
StateOk=The pump is working.