forked from Mirrors/openclonk
refactor pump done. Remaining problem: power system (usage)
parent
a6adc2465f
commit
131ec86b98
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!DOCTYPE funcs
|
||||
SYSTEM '../../../clonk.dtd'>
|
||||
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
|
||||
<funcs>
|
||||
<func>
|
||||
<title>CanInsertMaterial</title>
|
||||
<category>Landscape</category>
|
||||
<subcat>Material</subcat>
|
||||
<version>5.4 OC</version>
|
||||
<syntax>
|
||||
<rtype>bool</rtype>
|
||||
<params>
|
||||
<param>
|
||||
<type>int</type>
|
||||
<name>material_index</name>
|
||||
<desc>Material to test to be inserted (see <funclink>Material</funclink>()).</desc>
|
||||
</param>
|
||||
<param>
|
||||
<type>int</type>
|
||||
<name>x</name>
|
||||
<desc>X insert position or offset</desc>
|
||||
<optional />
|
||||
</param>
|
||||
<param>
|
||||
<type>int</type>
|
||||
<name>y</name>
|
||||
<desc>Y insert position or offset</desc>
|
||||
<optional />
|
||||
</param>
|
||||
</params>
|
||||
</syntax>
|
||||
<desc>Tests if a material pixel at the given position can be inserted.</desc>
|
||||
<remark>If the target position already contains material of the same density as the inserted material, the engine will search upwards for a proper insertion position.</remark>
|
||||
<related>
|
||||
<funclink>Material</funclink>
|
||||
</related>
|
||||
</func>
|
||||
<author>Sven2</author><date>2001-11</date>
|
||||
</funcs>
|
|
@ -1,64 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!DOCTYPE funcs
|
||||
SYSTEM '../../../clonk.dtd'>
|
||||
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
|
||||
<funcs>
|
||||
<func>
|
||||
<title>InsertMaterial</title>
|
||||
<category>Landscape</category>
|
||||
<subcat>Material</subcat>
|
||||
<version>5.1 OC</version>
|
||||
<syntax>
|
||||
<rtype>bool</rtype>
|
||||
<params>
|
||||
<param>
|
||||
<type>int</type>
|
||||
<name>material_index</name>
|
||||
<desc>Material to be inserted (see <funclink>Material</funclink>()).</desc>
|
||||
</param>
|
||||
<param>
|
||||
<type>int</type>
|
||||
<name>x</name>
|
||||
<desc>X insert position or offset</desc>
|
||||
<optional />
|
||||
</param>
|
||||
<param>
|
||||
<type>int</type>
|
||||
<name>y</name>
|
||||
<desc>Y insert position or offset</desc>
|
||||
<optional />
|
||||
</param>
|
||||
<param>
|
||||
<type>int</type>
|
||||
<name>xdir</name>
|
||||
<desc>horizontal speed of material pixel to be inserted</desc>
|
||||
<optional />
|
||||
</param>
|
||||
<param>
|
||||
<type>int</type>
|
||||
<name>ydir</name>
|
||||
<desc>vertical speed of material pixel to be inserted</desc>
|
||||
<optional />
|
||||
</param>
|
||||
<param>
|
||||
<type>proplist</type>
|
||||
<name>out_insertpos</name>
|
||||
<desc>If a writeable proplist is passed, members x and y are filled with the actual insertion position.</desc>
|
||||
<optional />
|
||||
</param>
|
||||
<param>
|
||||
<type>bool</type>
|
||||
<name>query_only</name>
|
||||
<desc>If set, the material is not actually inserted. Use this if you are only interested if insertion would be possible and where it would take place.</desc>
|
||||
<optional />
|
||||
</param>
|
||||
</params>
|
||||
</syntax>
|
||||
<desc>Inserts a material pixel at the given position and given speed.</desc>
|
||||
<remark>If the target position already contains material of the same density as the inserted material, the engine will search upwards for a proper insertion position. Use the parameter out_insertpos to find out where material was actually inserted.</remark>
|
||||
<related>
|
||||
<funclink>Material</funclink>
|
||||
</related>
|
||||
</func>
|
||||
<author>Sven2</author><date>2001-11</date>
|
||||
</funcs>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!DOCTYPE funcs
|
||||
SYSTEM '../../../clonk.dtd'>
|
||||
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
|
||||
<funcs>
|
||||
<func>
|
||||
<title>InsertMaterial</title>
|
||||
<category>Landscape</category>
|
||||
<subcat>Material</subcat>
|
||||
<version>5.1 OC</version>
|
||||
<syntax>
|
||||
<rtype>bool</rtype>
|
||||
<params>
|
||||
<param>
|
||||
<type>int</type>
|
||||
<name>material_index</name>
|
||||
<desc>Material to be inserted (see <funclink>Material</funclink>()).</desc>
|
||||
</param>
|
||||
<param>
|
||||
<type>int</type>
|
||||
<name>x</name>
|
||||
<desc>X insert position or offset</desc>
|
||||
<optional />
|
||||
</param>
|
||||
<param>
|
||||
<type>int</type>
|
||||
<name>y</name>
|
||||
<desc>Y insert position or offset</desc>
|
||||
<optional />
|
||||
</param>
|
||||
<param>
|
||||
<type>int</type>
|
||||
<name>xdir</name>
|
||||
<desc>horizontal speed of material pixel to be inserted</desc>
|
||||
<optional />
|
||||
</param>
|
||||
<param>
|
||||
<type>int</type>
|
||||
<name>ydir</name>
|
||||
<desc>vertical speed of material pixel to be inserted</desc>
|
||||
<optional />
|
||||
</param>
|
||||
</params>
|
||||
</syntax>
|
||||
<desc>Inserts a material pixel at the given position and given speed.</desc>
|
||||
<remark>If the target position already contains material of the same density as the inserted material, the engine will search upwards for a proper insertion position.</remark>
|
||||
<related>
|
||||
<funclink>Material</funclink>
|
||||
</related>
|
||||
</func>
|
||||
<author>Sven2</author><date>2001-11</date>
|
||||
</funcs>
|
||||
|
|
|
@ -85,8 +85,8 @@ global func FxDryTimeTimer(object pTarget, effect, int timer)
|
|||
InsertMaterial(Material("Water"),Random(LandscapeWidth()-60)+30,1,Random(7)-3,100+Random(100));
|
||||
return 1;
|
||||
}
|
||||
for(var i=0; i<6+Random(4);i++)
|
||||
ExtractLiquid(310+Random(50),430+Random(10));
|
||||
ExtractLiquidAmount(310+Random(50),430+Random(10),6+Random(4));
|
||||
|
||||
if(!GBackLiquid(335,430))
|
||||
{
|
||||
AddEffect("Rain",nil,100,2);
|
||||
|
|
|
@ -108,8 +108,7 @@ protected func FxIntLiquidDrainStart(object target, proplist effect, int tempora
|
|||
|
||||
protected func FxIntLiquidDrainTimer(object target, proplist effect)
|
||||
{
|
||||
for (var i = 0; i < effect.Strength / 2; i++)
|
||||
ExtractLiquid(AbsX(effect.X), AbsY(effect.Y));
|
||||
ExtractLiquidAmount(AbsX(effect.X), AbsY(effect.Y),effect.Strength / 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,12 +28,7 @@ private func Melt()
|
|||
private func Freeze()
|
||||
{
|
||||
DoCon(1);
|
||||
var i=2;
|
||||
while(i>0)
|
||||
{
|
||||
ExtractLiquid();
|
||||
i=--i;
|
||||
}
|
||||
ExtractMaterialAmount(0,0,Material("Water"),2);
|
||||
}
|
||||
|
||||
local Collectible = 1;
|
||||
|
|
|
@ -1,6 +1,18 @@
|
|||
/*-- Pipe line --*/
|
||||
/*-- Pipe line
|
||||
|
||||
//Author: ST-DDT
|
||||
Author: ST-DDT
|
||||
--*/
|
||||
|
||||
local Name = "$Name$";
|
||||
|
||||
local ActMap = {
|
||||
Connect = {
|
||||
Prototype = Action,
|
||||
Name = "Connect",
|
||||
Procedure = DFA_CONNECT,
|
||||
NextAction = "Connect"
|
||||
}
|
||||
};
|
||||
|
||||
protected func Initialize()
|
||||
{
|
||||
|
@ -11,19 +23,19 @@ protected func Initialize()
|
|||
return;
|
||||
}
|
||||
|
||||
// Returns true if this object is a functioning pipe.
|
||||
/** Returns true if this object is a functioning pipe. */
|
||||
public func IsPipeLine()
|
||||
{
|
||||
return GetAction() == "Connect";
|
||||
}
|
||||
|
||||
// Returns whether this pipe is connected to an object.
|
||||
/** Returns whether this pipe is connected to an object. */
|
||||
public func IsConnectedTo(object obj)
|
||||
{
|
||||
return GetActionTarget(0) == obj || GetActionTarget(1) == obj;
|
||||
}
|
||||
|
||||
// Returns the object which is connected to obj through this pipe.
|
||||
/** Returns the object which is connected to obj through this pipe. */
|
||||
public func GetConnectedObject(object obj)
|
||||
{
|
||||
if (GetActionTarget(0) == obj)
|
||||
|
@ -50,62 +62,3 @@ private func BreakMessage()
|
|||
line_end->Message("$TxtPipeBroke$");
|
||||
return;
|
||||
}
|
||||
|
||||
local ActMap = {
|
||||
Connect = {
|
||||
Prototype = Action,
|
||||
Name = "Connect",
|
||||
Procedure = DFA_CONNECT,
|
||||
NextAction = "Connect"
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Extract liquid from barrel
|
||||
@param sznMaterial: Material to extract; Wildcardsupport
|
||||
@param inMaxAmount: Max Amount of Material being extracted
|
||||
@param pnTarget: Object which extracts the liquid
|
||||
@return [irMaterial,irAmount]
|
||||
-irMaterial: Material being extracted
|
||||
-irAmount: Amount being extracted
|
||||
*/
|
||||
public func GetLiquid(string sznMaterial, int inMaxAmount, object pnTarget, bool bWildcard)
|
||||
{
|
||||
var pConnected = GetConnectedObject(pnTarget);
|
||||
if (!pConnected)
|
||||
return ["", 0];
|
||||
var aMat = pConnected->~LiquidOutput(sznMaterial, inMaxAmount, pnTarget, this, bWildcard);
|
||||
//Bad script? Not needed.
|
||||
if (GetType(aMat) != C4V_Array)
|
||||
return [-1, 0];
|
||||
//Verify data
|
||||
if ((aMat[0] == "") || (GetLength(aMat) == 1))
|
||||
aMat[1] = 0;
|
||||
//Nothing is nothing
|
||||
if (aMat[1] <= 0)
|
||||
{
|
||||
aMat[0] = "";
|
||||
aMat[1] = 0;
|
||||
} //Bad script end
|
||||
return aMat;
|
||||
}
|
||||
|
||||
/**
|
||||
Insert liquid to barrel
|
||||
@param sznMaterial: Material to insert
|
||||
@param inMaxAmount: Max Amount of Material being inserted
|
||||
@param pnSource: Object which inserts the liquid
|
||||
@return inAmount: The inserted amount
|
||||
*/
|
||||
public func PutLiquid(string sznMaterial, int inMaxAmount, object pnSource)
|
||||
{
|
||||
var pConnected = GetConnectedObject(pnSource);
|
||||
if (!pConnected)
|
||||
return 0;
|
||||
if (sznMaterial == "")
|
||||
return 0;
|
||||
return BoundBy(pConnected->~LiquidInput(sznMaterial, inMaxAmount, pnSource, this), 0, inMaxAmount);
|
||||
}
|
||||
|
||||
local Name = "$Name$";
|
||||
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
/*-- Pipe --*/
|
||||
/*-- Pipe
|
||||
|
||||
//Author: ST-DDT
|
||||
Author: ST-DDT
|
||||
--*/
|
||||
|
||||
local Name = "$Name$";
|
||||
local Description = "$Description$";
|
||||
local UsageHelp = "$UsageHelp$";
|
||||
local Collectible = 1;
|
||||
local Rebuy = true;
|
||||
|
||||
protected func Hit()
|
||||
{
|
||||
|
@ -11,17 +18,13 @@ public func IsToolProduct() { return true; }
|
|||
|
||||
/*-- Line connection --*/
|
||||
|
||||
// Called with double dig: will connect power line to building at the clonk's position.
|
||||
/** Will connect power line to building at the clonk's position. */
|
||||
protected func ControlUse(object clonk, int x, int y)
|
||||
{
|
||||
// Is this already connected to a liquid pump?
|
||||
if (FindObject(Find_PipeLine()))
|
||||
if (FindObject(Find_Func("IsConnectedTo",this)))
|
||||
return false;
|
||||
// Only use if clonk is walking.
|
||||
if (!clonk->IsWalking())
|
||||
return true;
|
||||
// Clonk should stand still.
|
||||
clonk->SetComDir(COMD_Stop);
|
||||
|
||||
// Is there an object which accepts power lines?
|
||||
var liquid_pump = FindObject(Find_AtPoint(), Find_Func("IsLiquidPump"));
|
||||
// No liquid pump, display message.
|
||||
|
@ -30,96 +33,33 @@ protected func ControlUse(object clonk, int x, int y)
|
|||
clonk->Message("$MsgNoNewPipe$");
|
||||
return true;
|
||||
}
|
||||
|
||||
// already two pipes connected
|
||||
if(liquid_pump->GetSource() && liquid_pump->GetDrain())
|
||||
{
|
||||
clonk->Message("MsgHasPipes");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Create and connect pipe.
|
||||
var pipe;
|
||||
var pipe = CreateObject(PipeLine, 0, 0, NO_OWNER);
|
||||
pipe->SetActionTargets(this, liquid_pump);
|
||||
Sound("Connect");
|
||||
|
||||
// If liquid pump has no source yet, create one.
|
||||
if (!liquid_pump->GetSource())
|
||||
{
|
||||
pipe = CreateObject(PipeLine, 0, 0, NO_OWNER);
|
||||
pipe->SetActionTargets(this, liquid_pump);
|
||||
liquid_pump->SetSource(pipe);
|
||||
Sound("Connect");
|
||||
clonk->Message("$MsgCreatedSource$");
|
||||
return true;
|
||||
}
|
||||
// Otherwise if liquid pump has no drain, create one.
|
||||
if (!liquid_pump->GetDrain())
|
||||
else
|
||||
{
|
||||
pipe = CreateObject(PipeLine, 0, 0, NO_OWNER);
|
||||
pipe->SetActionTargets(this, liquid_pump);
|
||||
liquid_pump->SetDrain(pipe);
|
||||
Sound("Connect");
|
||||
clonk->Message("$MsgCreatedDrain$");
|
||||
return true;
|
||||
}
|
||||
// Otherwise do nothing and notify player.
|
||||
clonk->Message("MsgHasPipes");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Finds all pipe lines connected to obj (can be nil in local calls).
|
||||
private func Find_PipeLine(object obj)
|
||||
{
|
||||
if (!obj)
|
||||
obj = this;
|
||||
return [C4FO_Func, "IsConnectedTo", obj];
|
||||
}
|
||||
|
||||
/**
|
||||
Extract liquid from this
|
||||
@param sznMaterial: Material to extract. 0 or "*" for any material.
|
||||
@param inMaxAmount: Max Amount of Material being extracted
|
||||
@param pnPump: Object which extracts the liquid
|
||||
@param pnPipe: Pipe which extracts the liquid (connected to pnPump)
|
||||
@param bnWildcard: Usefull to extract random liquids; use '*' for sznMaterial for all Materials
|
||||
@return [irMaterial,irAmount]
|
||||
-irMaterial: Material being extracted
|
||||
-irAmount: Amount being extracted
|
||||
*/
|
||||
public func LiquidOutput(string sznMaterial, int inMaxAmount, object pnPump, object pnPipe, bool bnWildcard)
|
||||
{
|
||||
var itMaterial;
|
||||
//Search liquid to pump
|
||||
if (bnWildcard)
|
||||
{
|
||||
itMaterial = GetMaterial();
|
||||
//nothing?
|
||||
if (itMaterial == -1)
|
||||
return ["", 0];
|
||||
//no liquid?
|
||||
if (GetMaterialVal("Density", "Material", itMaterial) != 25)
|
||||
return ["", 0];
|
||||
//wrong liquid?
|
||||
if (sznMaterial)
|
||||
if (!WildcardMatch(MaterialName(itMaterial),sznMaterial))
|
||||
return ["", 0];
|
||||
sznMaterial = MaterialName(itMaterial);
|
||||
}
|
||||
else
|
||||
itMaterial = Material(sznMaterial);
|
||||
if (GetMaterial() != itMaterial)
|
||||
return ["", 0];
|
||||
var itFound = ExtractMaterialAmount(0, 0, itMaterial, 5);
|
||||
return [sznMaterial, itFound];
|
||||
}
|
||||
|
||||
/**
|
||||
Insert liquid to this
|
||||
@param sznMaterial: Material to insert
|
||||
@param inMaxAmount: Max Amount of Material being inserted
|
||||
@param pnPump: Object which inserts the liquid
|
||||
@param pnPipe: Pipe which inserts the liquid (connected to pnPump)
|
||||
@return irAmount: The inserted amount
|
||||
*/
|
||||
public func LiquidInput(string sznMaterial, int inMaxAmount, object pnPump, object pnPipe)
|
||||
{
|
||||
var i=Max(0,inMaxAmount),itMaterial=Material(sznMaterial), n_inserted;
|
||||
while (i--) if (InsertMaterial(itMaterial)) ++n_inserted; else break;
|
||||
return n_inserted;
|
||||
}
|
||||
|
||||
local Name = "$Name$";
|
||||
local Description = "$Description$";
|
||||
local UsageHelp = "$UsageHelp$";
|
||||
local Collectible = 1;
|
||||
local Rebuy = true;
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
/*--
|
||||
Pump
|
||||
Author: Maikel, ST-DDT, Sven2
|
||||
Author: Maikel, ST-DDT, Sven2, Newton
|
||||
|
||||
Pumps liquids using drain and source pipes. Features include:
|
||||
+ switch on and off
|
||||
+ consume/produce a variable amount of power depending on the height of
|
||||
source and drain
|
||||
|
||||
Pumps liquids using drain and source pipes.
|
||||
--*/
|
||||
|
||||
#include Library_Structure
|
||||
|
@ -10,37 +14,97 @@
|
|||
#include Library_PowerConsumer
|
||||
#include Library_PowerProducer
|
||||
|
||||
local Name = "$Name$";
|
||||
local Description = "$Description$";
|
||||
local BlastIncinerate = 50;
|
||||
local HitPoints = 70;
|
||||
|
||||
/*
|
||||
States
|
||||
"Wait": turned off or source pipe not connected
|
||||
"WaitForPower": turned on but no power (does consume power)
|
||||
"WaitForLiquid": turned on but no liquid (does not consume power)
|
||||
"Pump": currently working and consuming/producing power
|
||||
|
||||
*/
|
||||
local ActMap = {
|
||||
Pump = {
|
||||
Prototype = Action,
|
||||
Name = "Pump",
|
||||
Length = 30,
|
||||
Delay = 3,
|
||||
NextAction = "Pump",
|
||||
StartCall = "CheckState",
|
||||
PhaseCall = "Pumping"
|
||||
},
|
||||
Wait = {
|
||||
Prototype = Action,
|
||||
Name = "Wait",
|
||||
Delay = 90,
|
||||
NextAction = "Wait",
|
||||
EndCall = "CheckState"
|
||||
},
|
||||
WaitForPower = {
|
||||
Prototype = Action,
|
||||
Name = "WaitForPower",
|
||||
Delay = 150,
|
||||
NextAction = "WaitForPower",
|
||||
EndCall = "CheckState"
|
||||
},
|
||||
WaitForLiquid = {
|
||||
Prototype = Action,
|
||||
Name = "WaitForLiquid",
|
||||
Delay = 30,
|
||||
NextAction = "WaitForLiquid",
|
||||
EndCall = "CheckState"
|
||||
}
|
||||
};
|
||||
|
||||
local animation; // animation handle
|
||||
|
||||
local switched_on; // the pump can be switched on and off with interact
|
||||
|
||||
local powered; // whether the pump is powered (either has enough power as consumer or even produces power)
|
||||
|
||||
local stored_material_index; //contained liquid
|
||||
local stored_material_amount;
|
||||
|
||||
local source_pipe;
|
||||
local drain_pipe;
|
||||
|
||||
/** This object is a liquid pump, thus pipes can be connected. */
|
||||
local current_animation; // Current animation handle
|
||||
public func IsLiquidPump() { return true; }
|
||||
|
||||
// Rotate at a 45 degree angle towards viewer and add a litte bit of Random
|
||||
SetProperty("MeshTransformation",Trans_Rotate(RandomX(0,3)*90+45+RandomX(-5,5),0,1,0));
|
||||
public func Definition(def)
|
||||
func Definition(def)
|
||||
{
|
||||
SetProperty("MeshTransformation",Trans_Rotate(45,0,1,0));
|
||||
// for title image
|
||||
SetProperty("PictureTransformation",Trans_Rotate(50,0,1,0),def);
|
||||
// for building preview
|
||||
SetProperty("MeshTransformation",Trans_Rotate(50,0,1,0),def);
|
||||
}
|
||||
|
||||
protected func Initialize()
|
||||
func Construction()
|
||||
{
|
||||
turned_on = true;
|
||||
// Rotate at a 45 degree angle towards viewer and add a litte bit of Random
|
||||
this.MeshTransformation = Trans_Rotate(50 + RandomX(-10,10),0,1,0);
|
||||
}
|
||||
|
||||
func Initialize()
|
||||
{
|
||||
switched_on = true;
|
||||
var start = 0;
|
||||
var end = GetAnimationLength("pump");
|
||||
current_animation = PlayAnimation("pump", 5, Anim_Linear(0, start, end, 90, ANIM_Loop), Anim_Const(1));
|
||||
SetActionKeepPhase("Wait");
|
||||
AddTimer("CheckTimer");
|
||||
return;
|
||||
animation = PlayAnimation("pump", 5, Anim_Linear(GetAnimationPosition(animation), start, end, 35, ANIM_Loop), Anim_Const(1000));
|
||||
SetState("Wait");
|
||||
}
|
||||
|
||||
/*-- Interaction --*/
|
||||
|
||||
local turned_on;
|
||||
|
||||
public func IsInteractable() { return GetCon() >= 100; }
|
||||
|
||||
public func GetInteractionMetaInfo(object clonk)
|
||||
{
|
||||
if (turned_on)
|
||||
if (switched_on)
|
||||
return { Description = "$MsgTurnOff$", IconName = nil, IconID = Icon_Stop };
|
||||
else
|
||||
return { Description = "$MsgTurnOn$", IconName = nil, IconID = Icon_Play };
|
||||
|
@ -49,13 +113,7 @@ public func GetInteractionMetaInfo(object clonk)
|
|||
/** Turn on or off. */
|
||||
public func Interact(object clonk)
|
||||
{
|
||||
turned_on = !turned_on;
|
||||
if(!turned_on) {
|
||||
SetAction("Wait");
|
||||
}
|
||||
else {
|
||||
SetAction("Pump");
|
||||
}
|
||||
switched_on = !switched_on;
|
||||
CheckState();
|
||||
|
||||
return true;
|
||||
|
@ -63,16 +121,13 @@ public func Interact(object clonk)
|
|||
|
||||
/*-- Pipe connection --*/
|
||||
|
||||
local source_pipe;
|
||||
local drain_pipe;
|
||||
|
||||
// Set-Getters for source and drain pipe.
|
||||
public func GetSource() { return source_pipe; }
|
||||
public func SetDrain(object pipe) { drain_pipe = pipe; }
|
||||
public func GetDrain() { return drain_pipe; }
|
||||
|
||||
public func SetSource(object pipe)
|
||||
{
|
||||
Log("source pipe connected");
|
||||
source_pipe = pipe;
|
||||
CheckState();
|
||||
}
|
||||
|
@ -87,38 +142,20 @@ func QueryWaivePowerRequest()
|
|||
|
||||
func OnNotEnoughPower()
|
||||
{
|
||||
// assert: current action is "Pump" or "PumpWaitLiquid"
|
||||
SetAction("PumpWaitPower");
|
||||
Log("not enough power");
|
||||
powered = false;
|
||||
CheckState();
|
||||
return _inherited(...);
|
||||
}
|
||||
|
||||
func OnEnoughPower()
|
||||
{
|
||||
// assert: current action is either PumpWaitPower or Wait
|
||||
SetAction("Pump");
|
||||
Log("enough power");
|
||||
powered = true;
|
||||
CheckState();
|
||||
return _inherited(...);
|
||||
}
|
||||
|
||||
local aMaterials=["", 0]; //contained liquids
|
||||
local pumpable_materials; // materials that can be pumped
|
||||
local pump_amount; // mat amount pumped since last height check
|
||||
|
||||
/** PhaseCall of PumpWaitLiquid */
|
||||
protected func PumpingWaitForLiquid()
|
||||
{
|
||||
// Pump is ready; check for liquids to pump
|
||||
if(!source_pipe) return CheckCurrentState();
|
||||
if(!HasLiquidToPump()) return;
|
||||
// Check stuck drain
|
||||
if (aMaterials[1] && (aMaterials[0] != ""))
|
||||
if (!InsertMaterial(Material(aMaterials[0]), 0,0,0,0, nil, true))
|
||||
return;
|
||||
// OK; let's pump
|
||||
SetAction("Pump");
|
||||
}
|
||||
|
||||
/** Returns object to which the liquid is pumped */
|
||||
private func GetDrainObject()
|
||||
{
|
||||
|
@ -133,110 +170,133 @@ private func GetSourceObject()
|
|||
return this;
|
||||
}
|
||||
|
||||
/** Returns amount of pixels to pump per 30 frames */
|
||||
public func GetPumpSpeed()
|
||||
{
|
||||
return 50;
|
||||
}
|
||||
|
||||
/** PhaseCall of Pump: Pump the liquid from the source to the drain pipe */
|
||||
protected func Pumping()
|
||||
{
|
||||
// at this point we can assert that we have power
|
||||
|
||||
// something went wrong in the meantime?
|
||||
// let the central function handle that
|
||||
if (!source_pipe)
|
||||
return CheckState();
|
||||
|
||||
// nothing to pump right now?
|
||||
if(!HasLiquidToPump())
|
||||
{
|
||||
SetAction("PumpWaitLiquid");
|
||||
|
||||
return;
|
||||
}
|
||||
// let the central function handle that on next check
|
||||
if (!source_pipe) return;
|
||||
|
||||
var pump_ok = true;
|
||||
|
||||
// is empty?
|
||||
if ((aMaterials[1] == 0) || (aMaterials[0] == ""))
|
||||
// is empty? -> try to get liquid
|
||||
if (!stored_material_amount)
|
||||
{
|
||||
// get new materials
|
||||
aMaterials = source_pipe->GetLiquid(pumpable_materials, 5, this, true);
|
||||
// no material to pump?
|
||||
if ((aMaterials[0] == "") || (aMaterials[1] == 0))
|
||||
pump_ok = false;
|
||||
else
|
||||
pump_amount += aMaterials[1];
|
||||
|
||||
// get new materials
|
||||
var aMat = GetSourceObject()->ExtractLiquidAmount(0,0, GetPumpSpeed()/10);
|
||||
|
||||
// no material to pump?
|
||||
if (aMat)
|
||||
{
|
||||
stored_material_index = aMat[0];
|
||||
stored_material_amount = aMat[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
pump_ok = false;
|
||||
}
|
||||
}
|
||||
if (pump_ok)
|
||||
{
|
||||
if (drain_pipe)
|
||||
var i = stored_material_amount;
|
||||
while (i > 0)
|
||||
{
|
||||
var pumped = BoundBy(drain_pipe->PutLiquid(aMaterials[0], aMaterials[1], this), 0, aMaterials[1]);
|
||||
aMaterials[1] -= pumped;
|
||||
// Drain is stuck?
|
||||
if (!pumped) pump_ok = false;
|
||||
if (GetDrainObject()->InsertMaterial(stored_material_index))
|
||||
{
|
||||
i--;
|
||||
}
|
||||
// Drain is stuck.
|
||||
else
|
||||
{
|
||||
pump_ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stored_material_amount = i;
|
||||
if (stored_material_amount <= 0)
|
||||
stored_material_index = nil;
|
||||
|
||||
if(!pump_ok) {Log("cant drain liquid");}
|
||||
}
|
||||
else { Log("cant get liquid"); }
|
||||
|
||||
if(!pump_ok)
|
||||
{
|
||||
SetState("WaitForLiquid");
|
||||
}
|
||||
}
|
||||
|
||||
/** Re check state and change the state if needed */
|
||||
func CheckState()
|
||||
{
|
||||
var is_fullcon = GetCon() >= 100;
|
||||
var can_pump = source_pipe && is_fullcon && switched_on;
|
||||
|
||||
Message("@0");
|
||||
|
||||
// can't pump at all -> wait
|
||||
if (!can_pump)
|
||||
{
|
||||
SetState("Wait");
|
||||
}
|
||||
else
|
||||
{
|
||||
// can pump but has no liquid -> wait for liquid
|
||||
if (!HasLiquidToPump())
|
||||
{
|
||||
SetState("WaitForLiquid");
|
||||
}
|
||||
else
|
||||
{
|
||||
var i = Max(0, aMaterials[1]), itMaterial = Material(aMaterials[0]);
|
||||
while (i)
|
||||
if (InsertMaterial(itMaterial))
|
||||
i--;
|
||||
else
|
||||
{
|
||||
// Drain is stuck.
|
||||
pump_ok = false;
|
||||
break;
|
||||
}
|
||||
aMaterials[1] = i;
|
||||
if (!i) aMaterials[0] = "";
|
||||
}
|
||||
}
|
||||
if (!pump_ok)
|
||||
{
|
||||
// Couldn't pump. Probably drain stuck.
|
||||
SetAction("PumpWaitLiquid");
|
||||
}
|
||||
// maybe add the possibility to empty pump (invaild mats?)
|
||||
return;
|
||||
}
|
||||
|
||||
func CheckState()
|
||||
{
|
||||
if(turned_on)
|
||||
{
|
||||
var is_fullcon = GetCon() >= 100;
|
||||
|
||||
if(GetAction() == "Wait") // waiting: not consuming power
|
||||
{
|
||||
if(source_pipe && is_fullcon)
|
||||
// can pump, has liquid but has no power -> wait for power
|
||||
if (!powered)
|
||||
{
|
||||
SetAction("Pump");
|
||||
SetState("WaitForPower");
|
||||
}
|
||||
}
|
||||
else // not waiting: consuming power
|
||||
{
|
||||
if(!source_pipe || !is_fullcon)
|
||||
// otherwise, pump! :-)
|
||||
else
|
||||
{
|
||||
SetAction("Wait");
|
||||
SetState("Pump");
|
||||
}
|
||||
|
||||
// regularly update the power usage while pumping or waiting for power
|
||||
UpdatePowerUsage();
|
||||
}
|
||||
}
|
||||
UpdatePowerUsage();
|
||||
}
|
||||
|
||||
/** Get current height the pump has to push liquids upwards (input.y - output.y) */
|
||||
private func GetPumpHeight()
|
||||
{
|
||||
var target = {X=GetDrainObject()->GetX(), Y=GetDrainObject()->GetY()};
|
||||
var source = {X=GetSourceObject()->GetX(), Y=GetSourceObject()->GetY()};
|
||||
// compare each the surfaces of the bodies of liquid pumped
|
||||
|
||||
// find Y position of surface of liquid that is pumped to target
|
||||
if (Global->GBackLiquid(source.X, source.Y))
|
||||
var source_y = 0;
|
||||
if (GetSourceObject()->GBackLiquid())
|
||||
{
|
||||
var src_mat = Global->GetMaterial(source.X, source.Y);
|
||||
while (source.Y > 0 && src_mat == Global->GetMaterial(source.X, source.Y-1))
|
||||
--source.Y;
|
||||
var src_mat = GetSourceObject()->GetMaterial();
|
||||
while (src_mat == GetSourceObject()->GetMaterial(0, source_y-1))
|
||||
--source_y;
|
||||
}
|
||||
return source.Y - target.Y;
|
||||
// same for target
|
||||
var target_y = 0;
|
||||
if (GetDrainObject()->GBackLiquid())
|
||||
{
|
||||
var src_mat = GetDrainObject()->GetMaterial();
|
||||
while (src_mat == GetDrainObject()->GetMaterial(0, target_y-1))
|
||||
--target_y;
|
||||
}
|
||||
return (GetSourceObject()->GetY() + source_y) - (GetDrainObject()->GetY() + target_y);
|
||||
}
|
||||
|
||||
/** Recheck power usage/production for current pump height
|
||||
|
@ -260,13 +320,15 @@ private func UpdatePowerUsage()
|
|||
UnmakePowerConsumer();
|
||||
MakePowerProducer(-new_power);
|
||||
}
|
||||
|
||||
Message("@%d",new_power);
|
||||
}
|
||||
|
||||
/** Return whether the pump should be using power in the current state */
|
||||
private func IsUsingPower()
|
||||
{
|
||||
// does also not consume power if waiting (for source pipe)
|
||||
return turned_on && GetAction() != "Wait" && GetAction() != "PumpWaitLiquid";
|
||||
return switched_on && GetAction() != "Wait" && GetAction() != "WaitForLiquid";
|
||||
}
|
||||
|
||||
/** Transform pump height (input.y - output.y) to required power */
|
||||
|
@ -277,105 +339,55 @@ private func PumpHeight2Power(int pump_height)
|
|||
// max power consumed/produced
|
||||
var max_power = 150;
|
||||
|
||||
return BoundBy((pump_height + power_offset)/30*10, -max_power,max_power);
|
||||
return BoundBy((pump_height + power_offset)/15*5, -max_power,max_power);
|
||||
}
|
||||
|
||||
/** Returns whether there is liquid at the source pipe to pump */
|
||||
private func HasLiquidToPump()
|
||||
{
|
||||
// also return false if there is no source (pipe) connected
|
||||
if (!source_pipe)
|
||||
return false;
|
||||
var source = source_pipe->GetConnectedObject(this);
|
||||
if (!source)
|
||||
return false;
|
||||
|
||||
if (!source->GBackLiquid())
|
||||
// source
|
||||
if(!GetSourceObject()->GBackLiquid())
|
||||
return false;
|
||||
// TODO: Account for pumping into buildings.
|
||||
|
||||
// target (test with the very popular liquid "water"
|
||||
if(!GetDrainObject()->CanInsertMaterial(Material("Water"),0,0))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
Set name or wildcard string of materials this pump can pump
|
||||
@param to_val: Material that can be pumped. 0 or "*" for any material.
|
||||
*/
|
||||
public func SetPumpableMaterials(string to_val)
|
||||
/** Set the state of the pump, retaining the animation position and updating the power usage */
|
||||
func SetState(string act)
|
||||
{
|
||||
pumpable_materials = to_val;
|
||||
return true;
|
||||
}
|
||||
if(act == GetAction()) return;
|
||||
|
||||
local Name = "$Name$";
|
||||
local Description = "$Description$";
|
||||
local BlastIncinerate = 50;
|
||||
local HitPoints = 70;
|
||||
Log("setting state %s",act);
|
||||
|
||||
/*
|
||||
States
|
||||
"Wait": turned off or source pipe not connected
|
||||
"Pump": currently working and consuming/producing power
|
||||
"PumpWaitLiquid": waiting for liquid to pump
|
||||
"PumpWaitPower": waiting for power
|
||||
|
||||
*/
|
||||
local ActMap = {
|
||||
Pump = {
|
||||
Prototype = Action,
|
||||
Name = "Pump",
|
||||
Procedure = DFA_NONE,
|
||||
Length = 30,
|
||||
Delay = 3,
|
||||
NextAction = "Pump",
|
||||
PhaseCall = "Pumping"
|
||||
},
|
||||
Wait = {
|
||||
Prototype = Action,
|
||||
Name = "Wait",
|
||||
Procedure = DFA_NONE,
|
||||
Length = 1,
|
||||
Delay = 60,
|
||||
NextAction = "Wait",
|
||||
},
|
||||
PumpWaitPower = {
|
||||
Prototype = Action,
|
||||
Name = "PumpWaitPower",
|
||||
Procedure = DFA_NONE,
|
||||
Length = 30,
|
||||
Delay = 0,
|
||||
StartCall = "PumpWaitPowerStart",
|
||||
AbortCall = "PumpWaitPowerStop",
|
||||
NextAction = "PumpWaitPower"
|
||||
},
|
||||
PumpWaitLiquid = { // Pump waiting for liquid: Move slowly to indicate we're turned on
|
||||
Prototype = Action,
|
||||
Name = "PumpWaitLiquid",
|
||||
Procedure = DFA_NONE,
|
||||
Length = 30,
|
||||
Delay = 10,
|
||||
NextAction = "PumpWaitLiquid",
|
||||
PhaseCall = "PumpingWaitForLiquid"
|
||||
var start = 0;
|
||||
var end = GetAnimationLength("pump");
|
||||
if (act == "Pump")
|
||||
{
|
||||
SetAnimationPosition(animation, Anim_Linear(GetAnimationPosition(animation), start, end, 35, ANIM_Loop));
|
||||
}
|
||||
};
|
||||
|
||||
// Set action while retaining phase from last action
|
||||
func SetActionKeepPhase(string act)
|
||||
{
|
||||
Log("action ist:%s", act);
|
||||
// Action for being off
|
||||
if (act == "PumpWaitPower" || act == "Wait")
|
||||
else if(act == "WaitForLiquid")
|
||||
{
|
||||
SetAnimationPosition(current_animation, Anim_Const(GetAnimationPosition(current_animation)));
|
||||
}
|
||||
else if (act == "PumpWaitLiquid")
|
||||
{
|
||||
var start = 0;
|
||||
var end = GetAnimationLength("pump");
|
||||
SetAnimationPosition(current_animation, Anim_Linear(GetAnimationPosition(current_animation), start, end, 300, ANIM_Loop));
|
||||
SetAnimationPosition(animation, Anim_Linear(GetAnimationPosition(animation), start, end, 350, ANIM_Loop));
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
var start = 0;
|
||||
var end = GetAnimationLength("pump");
|
||||
SetAnimationPosition(current_animation, Anim_Linear(GetAnimationPosition(current_animation), start, end, 90, ANIM_Loop));
|
||||
}
|
||||
SetAnimationPosition(animation, Anim_Const(GetAnimationPosition(animation)));
|
||||
}
|
||||
|
||||
// deactivate power usage on wait
|
||||
if (act == "Wait")
|
||||
{
|
||||
UnmakePowerProducer();
|
||||
UnmakePowerConsumer();
|
||||
Message("@OFF");
|
||||
}
|
||||
// finally, set the action
|
||||
SetAction(act);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
Name=Pumpe
|
||||
Description=Die Pumpe kann beliebige Flüssigkeiten von A nach B pumpen.
|
||||
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
|
|
@ -1,4 +1,4 @@
|
|||
Name=Pump
|
||||
Description=The pump can transport liquid from A to B.
|
||||
Description=The pump can transport liquid from A to B. If it pumps liquids downwards, it even generates a bit of power.
|
||||
MsgTurnOff=Turn off pump
|
||||
MsgTurnOn=Turn on pump
|
|
@ -51,24 +51,42 @@ global func FindPosInMat(string sMat, int iXStart, int iYStart, int iWidth, int
|
|||
return 0; // No location found.
|
||||
}
|
||||
|
||||
// Removes a material pixel from the specified location, if the material is a liquid.
|
||||
// \par x X coordinate. Offset if called in object context.
|
||||
// \par y Y coordinate. Offset if called in object context.
|
||||
// \returns The material index of the removed pixel, or -1 if no liquid was found.
|
||||
/** Removes a material pixel from the specified location, if the material is a liquid.
|
||||
@param x X coordinate
|
||||
@param y Y coordinate
|
||||
@return The material index of the removed pixel, or -1 if no liquid was found. */
|
||||
global func ExtractLiquid(int x, int y)
|
||||
{
|
||||
var mat = GetMaterial(x, y);
|
||||
var density = GetMaterialVal("Density", "Material", mat);
|
||||
if (density < C4M_Liquid || density >= C4M_Solid)
|
||||
return -1;
|
||||
ExtractMaterialAmount(x, y, mat, 1);
|
||||
return mat;
|
||||
var result = ExtractLiquidAmount(x, y, 1);
|
||||
if(!result) return -1;
|
||||
|
||||
return result[0];
|
||||
}
|
||||
|
||||
// Removes a material pixel from the specified location, if the material is flammable.
|
||||
// \par x X coordinate. Offset if called in object context.
|
||||
// \par y Y coordinate. Offset if called in object context.
|
||||
// \returns \c true if material was removed, \c false otherwise.
|
||||
/** Tries to remove amount material pixels from the specified location if the material is a liquid.
|
||||
@param x X coordinate
|
||||
@param y Y coordinate
|
||||
@param amount amount of liquid that should be extracted
|
||||
@return an array with the first position being the material index being extracted and the second the
|
||||
actual amount of pixels extracted OR nil if there was no liquid at all */
|
||||
global func ExtractLiquidAmount(int x, int y, int amount)
|
||||
{
|
||||
var mat = GetMaterial(x, y);
|
||||
if(mat == -1)
|
||||
return nil;
|
||||
var density = GetMaterialVal("Density", "Material", mat);
|
||||
if (density < C4M_Liquid || density >= C4M_Solid)
|
||||
return nil;
|
||||
var amount = ExtractMaterialAmount(x, y, mat, amount);
|
||||
if (amount <= 0)
|
||||
return nil;
|
||||
return [mat, amount];
|
||||
}
|
||||
|
||||
/** Removes a material pixel from the specified location, if the material is flammable
|
||||
@param x X coordinate. Offset if called in object context.
|
||||
@param y Y coordinate. Offset if called in object context.
|
||||
@return true if material was removed, false otherwise. */
|
||||
global func FlameConsumeMaterial(int x, int y)
|
||||
{
|
||||
var mat = GetMaterial(x, y);
|
||||
|
|
|
@ -332,20 +332,21 @@ static bool FnSmoke(C4PropList * _this, long tx, long ty, long level, long dwClr
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool FnInsertMaterial(C4PropList * _this, long mat, long x, long y, long vx, long vy, C4PropList *insert_position, bool query_only)
|
||||
static bool FnInsertMaterial(C4PropList * _this, long mat, long x, long y, long vx, long vy)
|
||||
{
|
||||
if (Object(_this)) { x+=Object(_this)->GetX(); y+=Object(_this)->GetY(); }
|
||||
int32_t insert_x=x, insert_y=y;
|
||||
if (!::Landscape.InsertMaterial(mat,&insert_x,&insert_y,vx,vy,query_only)) return false;
|
||||
// output insertion position if desired
|
||||
if (insert_position && !insert_position->IsFrozen())
|
||||
{
|
||||
insert_position->SetProperty(P_X, C4VInt(insert_x));
|
||||
insert_position->SetProperty(P_Y, C4VInt(insert_y));
|
||||
}
|
||||
return true;
|
||||
return ::Landscape.InsertMaterial(mat,&insert_x,&insert_y,vx,vy);
|
||||
}
|
||||
|
||||
static bool FnCanInsertMaterial(C4PropList * _this, long mat, long x, long y)
|
||||
{
|
||||
if (Object(_this)) { x+=Object(_this)->GetX(); y+=Object(_this)->GetY(); }
|
||||
int32_t insert_x=x, insert_y=y;
|
||||
return ::Landscape.InsertMaterial(mat,&insert_x,&insert_y,0,0,true);
|
||||
}
|
||||
|
||||
|
||||
static long FnGetMaterialCount(C4PropList * _this, long iMaterial, bool fReal)
|
||||
{
|
||||
if (!MatValid(iMaterial)) return -1;
|
||||
|
@ -2349,6 +2350,7 @@ void InitGameFunctionMap(C4AulScriptEngine *pEngine)
|
|||
AddFunc(pEngine, "Material", FnMaterial);
|
||||
AddFunc(pEngine, "BlastFree", FnBlastFree);
|
||||
AddFunc(pEngine, "InsertMaterial", FnInsertMaterial);
|
||||
AddFunc(pEngine, "CanInsertMaterial", FnCanInsertMaterial);
|
||||
AddFunc(pEngine, "LandscapeWidth", FnLandscapeWidth);
|
||||
AddFunc(pEngine, "LandscapeHeight", FnLandscapeHeight);
|
||||
AddFunc(pEngine, "SetSeason", FnSetSeason);
|
||||
|
|
Loading…
Reference in New Issue