Added diving helmet, must be connect to a pump!

Rudimentary handling of air pumping added to the pump and of course the helmet. The functions of the helmet concerning air pumping can maybe later used for a library.
console-destruction
Clonkonaut 2016-08-17 20:23:18 +02:00
parent 192ccc0203
commit afe5cd3c24
16 changed files with 497 additions and 24 deletions

View File

@ -0,0 +1,14 @@
[DefCore]
id=DivingHelmet
Version=8,0
Category=C4D_Object
Width=10
Height=10
Offset=-5,-5
Vertices=3
VertexX=-3,3,0
VertexY=4,4,-4
VertexFriction=50,50,50
Value=10
Mass=10
Rotate=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

View File

@ -0,0 +1,21 @@
material DiveHelm
{
receive_shadows on
technique
{
pass
{
ambient 0.800000011920929 0.800000011920929 0.800000011920929 1.0
diffuse 0.800000011920929 0.800000011920929 0.800000011920929 1.0
specular 0.44354838132858276 0.44354838132858276 0.44354838132858276 1.0 12.5
emissive 0.0 0.0 0.0 1.0
texture_unit
{
texture DivingHelm.png
tex_address_mode wrap
filtering trilinear
}
}
}
}

View File

@ -0,0 +1,300 @@
/**
Diving Helmet
Connected to a pump it provides the user with air underwater.
@author: pluto, Clonkonaut
*/
#include Library_Wearable
local air_pipe;
local custom_entry =
{
Right = "100%", Bottom = "2em",
BackgroundColor = {Std = 0, OnHover = 0x50ff0000},
image = {Right = "2em"},
text = {Left = "2em"}
};
/*-- Engine Callbacks --*/
func Hit()
{
Sound("Hits::Materials::Metal::DullMetalHit?");
}
/*-- Callbacks --*/
// Called by a connected pump
public func OnAirPumped(object pump)
{
if (IsWorn())
if (Contained())
{
// If nearly max breath just keep the level
if (Contained()->~GetBreath() >= Contained()->~GetMaxBreath() - 10)
Contained()->DoBreath(3);
else // Slowly fill up breath
Contained()->DoBreath(4);
}
}
public func OnPipeLengthChange()
{
// Update usage bar for a possible carrier (the clonk).
var carrier = Contained();
if (carrier)
carrier->~OnInventoryChange();
return;
}
// Display the line length bar over the pipe icon.
public func GetInventoryIconOverlay()
{
var pipe = GetConnectedPipe();
if (!pipe) return;
var percentage = 100 * pipe->GetPipeLength() / pipe.PipeMaxLength;
var red = percentage * 255 / 100;
var green = 255 - red;
// Overlay a usage bar.
var overlay =
{
Bottom = "0.75em",
Margin = ["0.1em", "0.25em"],
BackgroundColor = RGB(0, 0, 0),
margin =
{
Margin = "0.05em",
bar =
{
BackgroundColor = RGB(red, green, 0),
Right = Format("%d%%", percentage),
}
}
};
return overlay;
}
// It is assumed that only suitable pipes (drain / neutral / air pipes) are connected.
public func OnPipeConnect(object pipe)
{
if (!pipe) return;
air_pipe = FindObject(Find_ID(PipeLine), Find_Or(Find_ActionTarget(this), Find_ActionTarget2(this)));
if (!air_pipe) return;
pipe->SetAirPipe();
pipe->Report("$MsgConnectedPipe$");
}
func OnPipeDisconnect(object pipe)
{
if (!air_pipe || !pipe) return;
var other = air_pipe->GetConnectedObject(this);
if (!other || other->GetID() != Pump)
pipe->SetNeutralPipe();
pipe->SetDrainPipe();
other->~CheckState();
}
// Called by the interaction menu (OnPipeControl)
public func DoConnectPipe(object pipe, string specific_pipe_state)
{
if (!pipe) return;
if (GetConnectedPipe())
DoCutPipe(GetConnectedPipe());
pipe->ConnectPipeTo(this, PIPE_STATE_Air);
}
// Called by the interaction menu (OnPipeControl)
public func DoCutPipe(object pipe)
{
if (pipe)
if (pipe->~GetPipeKit())
pipe->GetPipeKit()->CutLineConnection(this);
}
/*-- Usage --*/
public func ControlUse(object clonk)
{
if (IsWorn())
TakeOff();
else
PutOn(clonk);
return true;
}
public func CanConnectPipe()
{
return !GetConnectedPipe();
}
public func GetConnectedPipe()
{
if (!air_pipe) return;
if (!air_pipe->IsConnectedTo(this)) return;
return air_pipe;
}
// Do not accept source pipes
public func QueryConnectPipe(object pipe)
{
if (GetConnectedPipe())
{
pipe->Report("$MsgHasPipe$");
return true;
}
if (pipe->IsSourcePipe())
{
pipe->Report("$MsgPipeProhibited$");
return true;
}
else
{
return false;
}
}
/*-- Interaction --*/
public func HasInteractionMenu() { return true; }
public func GetInteractionMenus(object clonk)
{
var menus = _inherited() ?? [];
var pipe_menu =
{
title = "$MenuPipeControl$",
entries_callback = this.GetPipeControlMenuEntries,
callback = "OnPipeControl",
callback_hover = "OnPipeControlHover",
callback_target = this,
BackgroundColor = RGB(0, 50, 50),
Priority = 30
};
PushBack(menus, pipe_menu);
return menus;
}
public func GetPipeControlMenuEntries(object clonk)
{
var menu_entries = [];
// Add info message about pipe control.
PushBack(menu_entries, {symbol = this, extra_data = "description",
custom =
{
Prototype = custom_entry,
Bottom = "1.2em",
Priority = -1,
BackgroundColor = RGB(25, 100, 100),
text = {Prototype = custom_entry.text, Text = "$MenuPipeControl$"},
image = {Prototype = custom_entry.image, Symbol = Pipe}
}});
var available_pipe = FindAvailablePipe(clonk);
if (GetConnectedPipe())
PushBack(menu_entries, GetHelmetMenuEntry(Icon_Cancel, "$MsgCutPipe$", 1, "cutpipe"));
else if (available_pipe)
PushBack(menu_entries, GetHelmetMenuEntry(available_pipe, "$MsgConnectPipe$", 1, "connectpipe"));
return menu_entries;
}
func GetHelmetMenuEntry(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 OnPipeControlHover(id symbol, string action, desc_menu_target, menu_id)
{
var text = "";
if (action == "cutpipe") text = "$DescCutPipe$";
else if (action == "connectpipe") text = "$DescConnectPipe$";
else if (action == "description") text = this.Description;
GuiUpdateText(text, menu_id, 1, desc_menu_target);
}
public func OnPipeControl(symbol_or_object, string action, bool alt)
{
if (action == "cutpipe")
this->DoCutPipe(air_pipe);
else if (action == "connectpipe")
this->DoConnectPipe(symbol_or_object);
UpdateInteractionMenus(this.GetPipeControlMenuEntries);
}
func FindAvailablePipe(object container)
{
for (var pipe in FindObjects(Find_ID(Pipe), Find_Container(container), Find_Or(Find_Func("IsAirPipe"), Find_Func("IsDrainPipe"), Find_Func("IsNeutralPipe"))))
{
if (!this->~QueryConnectPipe(pipe))
return pipe;
}
return nil;
}
/*-- Production --*/
public func IsWeapon() { return true; }
public func IsArmoryProduct() { return true; }
/*-- Display --*/
public func GetWearPlace()
{
return WEARABLE_Head;
}
public func GetWearTransform()
{
return Trans_Mul(Trans_Rotate(90, 0, 0, 1), Trans_Translate(0, -1000));
}
public func GetCarryMode(object clonk, bool secondary)
{
if (IsWorn() || display_disabled)
return CARRY_None;
return CARRY_BothHands;
}
public func GetCarryPhase(object clonk)
{
return 650;
}
public func GetCarryTransform(object clonk, bool secondary, bool no_hand, bool on_back)
{
return Trans_Mul(Trans_Rotate(80, 0, 0, 1), Trans_Rotate(-90, 0, 1), Trans_Rotate(-45, 0, 0, 1), Trans_Translate(-1000, 4000));
}
func Definition(def)
{
SetProperty("PictureTransformation", Trans_Mul(Trans_Rotate(45, 0, 1), Trans_Rotate(10, 0, 0, 1)),def);
}
/*-- Properties --*/
local Name = "$Name$";
local Description = "$Description$";
local Collectible = true;
local Components = {Wood = 1, Metal = 1};

View File

@ -0,0 +1,12 @@
Name=Taucherhelm
Description=Ermöglicht es dem Clonk unter Wasser zu atmen, solange der Helm an eine funktionstüchtige Pumpe angeschlossen ist. [Benutzen] drücken zum Aufsetzen.
MsgConnectedPipe=Rohr angeschlossen.
MsgPipeProhibited=Es können keine Zuflussrohre an den Taucherhelm angeschlossen werden.
MsgHasPipe=Der Taucherhelm hat schon ein Rohr.
MenuPipeControl=Leitungen
MsgCutPipe=Rohr trennen
MsgConnectPipe=Rohr anschließen
DescCutPipe=Entfernt das angeschlossene Rohr.
DescConnectPipe=Schließt ein Rohr an.

View File

@ -0,0 +1,12 @@
Name=Diving helmet
Description=Wearing this your clonk can breath underwater as long as the helmet is connected to a pump. Press [use] to put on.
MsgConnectedPipe=Connected pipe.
MsgPipeProhibited=Cannot connect source pipes to the diving helmet.
MsgHasPipe=The diving helmet already has a pipe.
MenuPipeControl=Pipe Control
MsgCutPipe=Cut off pipe
MsgConnectPipe=Connect pipe
DescCutPipe=Removes the connected pipe.
DescConnectPipe=Connects a pipe.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -5,7 +5,7 @@
*/
local pipe_kit;
local is_air_pipe = false;
private func Initialize()
{
@ -19,6 +19,7 @@ private func Initialize()
public func SetNeutral()
{
SetProperty("LineColors", [RGB(80, 80, 120), RGB(80, 80, 120)]);
is_air_pipe = false;
}
// Reddish colour.
@ -26,6 +27,7 @@ public func SetNeutral()
public func SetDrain()
{
SetProperty("LineColors", [RGB(238, 102, 0), RGB(238, 102, 0)]);
is_air_pipe = false;
}
// Greenish colour.
@ -33,6 +35,14 @@ public func SetDrain()
public func SetSource()
{
SetProperty("LineColors", [RGB(102, 136, 34), RGB(102, 136, 34)]);
is_air_pipe = false;
}
// Blueish colour.
public func SetAir()
{
SetProperty("LineColors", [RGB(0, 153, 255), RGB(0, 153, 255)]);
is_air_pipe = true;
}
// Returns true if this object is a functioning pipe.
@ -41,6 +51,11 @@ public func IsPipeLine()
return GetAction() == "Connect";
}
public func IsAirPipe()
{
return this.is_air_pipe;
}
// Returns whether this pipe is connected to an object.
// Returns only actually connected objects if the parameter 'strict' is true.
public func IsConnectedTo(object obj, bool strict)
@ -48,7 +63,6 @@ public func IsConnectedTo(object obj, bool strict)
return GetActionTarget(0) == obj || GetActionTarget(1) == obj || (!strict && pipe_kit == obj);
}
// Returns the object which is connected to obj through this pipe.
public func GetConnectedObject(object obj)
{

View File

@ -30,6 +30,7 @@
static const PIPE_STATE_Neutral = nil;
static const PIPE_STATE_Source = "Source";
static const PIPE_STATE_Drain = "Drain";
static const PIPE_STATE_Air = "Air";
local ApertureOffsetX = 0;
local ApertureOffsetY = 3;
@ -130,11 +131,12 @@ func IsDroppedOnDeath(object clonk)
/* ---------- Pipe States ---------- */
func IsNeutralPipe(){ return PipeState == PIPE_STATE_Neutral;}
func IsDrainPipe(){ return PipeState == PIPE_STATE_Drain;}
func IsSourcePipe(){ return PipeState == PIPE_STATE_Source;}
public func IsNeutralPipe(){ return PipeState == PIPE_STATE_Neutral; }
public func IsDrainPipe(){ return PipeState == PIPE_STATE_Drain; }
public func IsSourcePipe(){ return PipeState == PIPE_STATE_Source; }
public func IsAirPipe(){ return PipeState == PIPE_STATE_Air; }
func SetNeutralPipe()
public func SetNeutralPipe()
{
PipeState = PIPE_STATE_Neutral;
@ -149,7 +151,7 @@ func SetNeutralPipe()
}
}
func SetDrainPipe()
public func SetDrainPipe()
{
PipeState = PIPE_STATE_Drain;
@ -165,7 +167,7 @@ func SetDrainPipe()
}
}
func SetSourcePipe()
public func SetSourcePipe()
{
PipeState = PIPE_STATE_Source;
@ -181,7 +183,21 @@ func SetSourcePipe()
}
}
public func SetAirPipe()
{
PipeState = PIPE_STATE_Air;
SetGraphics("Air", Pipe, GFX_Overlay, GFXOV_MODE_Picture);
SetObjDrawTransform(1000, 0, 0, 0, 1000, 10000, GFX_Overlay);
Description = "$DescriptionAir$";
Name = "$NameAir$";
var line = GetConnectedLine();
if (line)
{
line->SetAir();
}
}
/* ---------- Pipe Connection ---------- */

View File

@ -1,12 +1,14 @@
Name=Rohr
NameSource=Zuflussrohr
NameDrain=Abflussrohr
NameAir=Luftrohr
Description=Rohre können in Verbindung mit Pumpen zum Transport von Flüssigkeiten verwendet werden. Drücke [Benutzen] vor einer Pumpe um von dort ein Zu- oder Abflussrohr zu legen.
DescriptionSource=Zuflussrohr von dem aus Flüssigkeit in die Pumpe gepumpt wird.
DescriptionDrain=Abflusssrohr aus dem Flüssigkeit aus der Pumpe heraus läuft.
DescriptionAir=Luftrohre können Unterwasser Sauerstoff bereitstellen.
MsgNoNewPipe=Hier ist keine Pumpe.
MsgNoNewPipeToTank=Anschluss hier nicht möglich.
MsgNoNewPipeToTank=Anschluss hier nicht möglich.
MsgCreatedSource=Zuflussrohr angeschlossen.
MsgCreatedDrain=Abflussrohr angeschlossen.
MsgHasPipes=Die Pumpe hat schon ein Zu- und Abflussrohr.

View File

@ -1,9 +1,11 @@
Name=Pipe
NameSource=Source pipe
NameDrain=Drain pipe
NameAir=Air pipe
Description=In conjunction with pumps, pipes can be used to transport liquids. Press [Use] in front of a pump to create a source or drain pipe.
DescriptionSource=Source pipe from which liquid is pulled into the pump.
DescriptionDrain=Drain pipe where liquids are pumped to.
DescriptionAir=Air pipes are a good source of oxygen when underwater.
MsgNoNewPipe=There is no pump here.
MsgNoNewPipeToTank=Connection is not possible here.

View File

@ -179,6 +179,11 @@ func QueryConnectPipe(object pipe)
pipe->Report("$MsgDrainPipeProhibited$");
return true;
}
else if (pipe->IsAirPipe() && GetDrainPipe())
{
pipe->Report("$MsgAirPipeProhibited$");
return true;
}
return false;
}
@ -197,14 +202,24 @@ func OnPipeConnect(object pipe, string specific_pipe_state)
pipe->SetDrainPipe();
pipe->Report("$MsgCreatedDrain$");
}
else if (PIPE_STATE_Air == specific_pipe_state)
{
// Air pipes take up the place of the drain
SetDrainPipe(pipe);
pipe->Report("$MsgCreatedAirDrain$");
}
else
{
// add a drain if we already connected a source pipe,
// or if the line is already connected to a container
var line = pipe->GetConnectedLine();
var pump_target = !line || line->GetConnectedObject(this);
if (pump_target) pump_target = pump_target->~IsLiquidContainer();
if (GetSourcePipe() || pump_target)
if (pump_target) pump_target = pump_target->~IsLiquidContainer();
if (line->IsAirPipe())
{
OnPipeConnect(pipe, PIPE_STATE_Air);
}
else if (GetSourcePipe() || pump_target)
{
OnPipeConnect(pipe, PIPE_STATE_Drain);
}
@ -219,9 +234,12 @@ func OnPipeConnect(object pipe, string specific_pipe_state)
func OnPipeDisconnect(object pipe)
{
pipe->SetNeutralPipe();
_inherited(pipe);
if (!pipe->IsAirPipe())
pipe->SetNeutralPipe();
else // Stop pumping to prevent errors from Pumping()
CheckState();
}
@ -231,6 +249,12 @@ public func SetSourcePipe(object pipe)
CheckState();
}
public func IsAirPipeConnected()
{
if (!GetDrainPipe())
return false;
return GetDrainPipe()->~IsAirPipe();
}
/*-- Power stuff --*/
@ -287,6 +311,15 @@ protected func Pumping()
if (!GetSourcePipe())
return;
// Don't do anything special if pumping air but inform the drain object
if (IsAirPipeConnected())
{
var drain_obj = GetDrainObject();
if (drain_obj)
drain_obj->~OnAirPumped(this);
return;
}
var pump_ok = true;
// is empty? -> try to get liquid
@ -399,6 +432,30 @@ func CheckState()
SetInfoMessage("$StateNoSource$");
SetState("Wait");
}
else if(IsAirPipeConnected())
{
if (!GetAirSourceOk())
{
SetInfoMessage("$StateNoAir$");
SetState("WaitForLiquid");
}
else
{
// can pump, has air but has no power -> wait for power
if (!powered)
{
SetInfoMessage("$StateNoPower$");
SetState("WaitForPower");
}
else
{
SetInfoMessage();
clog_count = 0;
SetState("Pump");
}
UpdatePowerUsage();
}
}
else
{
// Can pump but has no liquid or can't dispense liquid -> wait.
@ -528,6 +585,9 @@ private func PumpHeight2Power(int pump_height)
// Pumping power downwards never costs energy, but only brings something if offset is overcome.
else
used_power = BoundBy(used_power + power_offset - 10, -max_power, 0);
// Pumped air never generates power
if (IsAirPipeConnected())
used_power = BoundBy(used_power, 10, max_power);
return used_power;
}
@ -568,6 +628,20 @@ private func GetLiquidDrainOk(string liquid)
return true;
}
// Returns whether the drain is in free air.
func GetAirSourceOk()
{
var source_obj = GetSourceObject();
if (!source_obj) return false;
var is_air = !source_obj->GBackSemiSolid(source_obj.ApertureOffsetX, source_obj.ApertureOffsetY);
if (!is_air)
{
source_obj->~CycleApertureOffset(this);
return false;
}
return true;
}
// Set the state of the pump, retaining the animation position and updating the power usage.
private func SetState(string act)
{

View File

@ -1,28 +1,31 @@
Name=Pumpe
Description=Die Pumpe kann beliebige Fl�ssigkeiten von A nach B pumpen. Pumpt sie Fl�ssigkeiten abw�rts, erzeugt sie dabei sogar ein wenig Strom.
Description=Die Pumpe kann beliebige Flüssigkeiten von A nach B pumpen. Pumpt sie Flüssigkeiten abwärts, erzeugt sie dabei sogar ein wenig Strom.
MsgTurnOff=Pumpe abschalten
MsgTurnOn=Pumpe anschalten
MsgCutSource=Zufluss trennen
MsgCutDrain=Abfluss trennen
DescTurnOff=Schaltet die Pumpe ab, so dass keine Flüssigkeiten mehr transportiert werden.
DescTurnOn=Aktiviert das Pumpen wieder. Dafür muss mindestens ein Zufluss angeschlossen sein.
DescTurnOff=Schaltet die Pumpe ab, so dass keine Flüssigkeiten mehr transportiert werden.
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.
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.
StateOk=Die Pumpe läuft.
StateNoSource=Es ist kein Zufluss angeschlossen.
StateNoInput=Es gibt keine Flüssigkeiten zu pumpen.
StateNoInput=Es gibt keine Flüssigkeiten zu pumpen.
StateNoOutput=Der Abfluss ist verstopft.
StateNoPower=Die Pumpe hat keinen Strom.
StateNoAir=Der Luftzufluss ist verstopft.
StateTurnedOff=Die Pumpe wurde ausgeschaltet.
MsgSourcePipeProhibited=Zuflussrohre können nicht an die Pumpe angeschlossen werden.
MsgDrainPipeProhibited=Abflussrohre können nicht an die Pumpe angeschlossen werden.
MsgSourcePipeProhibited=Zuflussrohre können nicht an die Pumpe angeschlossen werden.
MsgDrainPipeProhibited=Abflussrohre können nicht an die Pumpe angeschlossen werden.
MsgAirPipeProhibited=Die Pumpe hat bereits ein Abflussrohr, es ist kein Platz für ein Luftrohr.
MsgCreatedSource=Zuflussrohr angeschlossen.
MsgCreatedDrain=Abflussrohr angeschlossen.
MsgCreatedAirDrain=Luftrohr angeschlossen.
MsgHasPipes=Die Pumpe hat schon ein Zu- und Abflussrohr.

View File

@ -19,10 +19,13 @@ StateNoSource=There is no source pipe connected.
StateNoInput=The pump does not have liquid to pump.
StateNoOutput=The drain pipe is clogged.
StateNoPower=The pump does not have power.
StateNoAir=The air source pipe is clogged.
StateTurnedOff=The pump has been turned off.
MsgSourcePipeProhibited=Unable to connect source pipe.
MsgDrainPipeProhibited=Unable to connect drain pipe.
MsgAirPipeProhibited=Pump already has a drain pipe and cannot take an air pipe.
MsgCreatedSource=Connected source pipe.
MsgCreatedDrain=Connected drain pipe.
MsgCreatedAirDrain=Connected air pipe.
MsgHasPipes=Pump already has a source and a drain pipe.