openclonk/planet/Objects.ocd/Structures.ocd/SteamEngine.ocd/Script.c

288 lines
5.9 KiB
C
Raw Normal View History

2014-12-30 19:24:13 +00:00
/**
Steam Engine
Burns fuels like coal, wood and oil to produce power. The steam engine
produces 120 units of power independent of the fuel. However, the fuel
2014-12-30 19:24:13 +00:00
determines the amount of fuel and thereby the burn time.
@author Maikel
*/
2009-12-29 13:44:16 +00:00
#include Library_Structure
#include Library_Ownable
#include Library_PowerProducer
#include Library_Flag
#include Library_Tank
local DefaultFlagRadius = 200;
2009-12-29 13:44:16 +00:00
static const SteamEngine_produced_power = 120;
2014-12-30 19:24:13 +00:00
// Variable to store the fuel amount currently held in the engine.
local fuel_amount;
2009-12-29 13:44:16 +00:00
2014-12-30 19:24:13 +00:00
protected func Construction()
2009-12-29 13:44:16 +00:00
{
2014-12-30 19:24:13 +00:00
fuel_amount = 0;
return _inherited(...);
}
2014-12-30 19:24:13 +00:00
protected func Initialize()
{
SetAction("Idle");
AddTimer("ContentsCheck", 10);
2014-12-30 19:24:13 +00:00
return _inherited(...);
2009-12-29 13:44:16 +00:00
}
public func IsContainer() { return true; }
2014-12-30 19:24:13 +00:00
protected func RejectCollect(id item, object obj)
{
if (obj->~IsFuel())
return false;
return true;
}
2014-12-30 19:24:13 +00:00
protected func Collection(object obj, bool put)
{
Sound("Objects::Clonk");
}
2014-12-30 19:24:13 +00:00
public func ContentsCheck()
2009-12-29 13:44:16 +00:00
{
2014-12-30 19:24:13 +00:00
// Ejects non fuel items immediately
var fuel;
if(fuel = FindObject(Find_Container(this), Find_Not(Find_Func("IsFuel"))))
{
2014-12-30 19:24:13 +00:00
fuel->Exit(-53, 21, -20, -1, -1, -30);
Sound("Chuff");
}
2014-12-30 19:24:13 +00:00
// If active don't do anything.
if (GetAction() == "Work")
return;
// If there is fuel available let the network know.
if (fuel_amount > 0 || FindObject(Find_Container(this), Find_Func("IsFuel")))
RegisterPowerProduction(SteamEngine_produced_power);
return;
}
2015-03-09 17:55:18 +00:00
public func GetFuelAmount()
{
return fuel_amount;
}
2014-12-30 19:24:13 +00:00
/*-- Power Production --*/
// Produces power on demand, so not steady.
public func IsSteadyPowerProducer() { return false; }
// Low priority so that other sources of power are drained before burning fuel.
public func GetProducerPriority() { return 0; }
// Callback from the power library for production of power request.
public func OnPowerProductionStart(int amount)
{
// Check if there is fuel.
RefillFuel();
2014-12-30 19:24:13 +00:00
// There is enough fuel so start producing power and notify network of this.
if (GetAction() == "Idle")
SetAction("Work");
return true;
2009-12-29 13:44:16 +00:00
}
2014-12-30 19:24:13 +00:00
// Callback from the power library requesting to stop power production.
2015-02-03 11:05:47 +00:00
public func OnPowerProductionStop(int amount)
2014-12-30 19:24:13 +00:00
{
// Set action to idle when it was working.
if (GetAction() == "Work")
SetAction("Idle");
return true;
2009-12-29 13:44:16 +00:00
}
2014-12-30 19:24:13 +00:00
// Start call from working action.
protected func WorkStart()
{
Sound("Structures::SteamEngine", false, nil, nil, 1);
2014-12-30 19:24:13 +00:00
return;
}
2014-12-30 19:24:13 +00:00
// Phase call from working action, every two frames.
protected func Working()
{
BurnFuel(2); // Reduce the fuel amount by 1 per frame.
RefillFuel(true); // Check if there is still enough fuel available.
Smoking(); // Smoke from the exhaust shaft.
2014-12-30 19:24:13 +00:00
return;
}
2014-12-30 19:24:13 +00:00
// Stop call from working action.
protected func WorkStop()
{
2014-12-30 19:24:13 +00:00
// Don't kill the sound in this call, since that would interupt the sound effect.
return;
}
2014-12-30 19:24:13 +00:00
// Abort call from working action.
protected func WorkAbort()
{
2014-12-30 19:24:13 +00:00
// Sound can be safely stopped here since this action will always end with an abort call.
Sound("Structures::SteamEngine", false, nil, nil, -1);
2014-12-30 19:24:13 +00:00
return;
}
func RefillFuel(bool cancel)
{
// Check if there is still enough fuel available.
if (fuel_amount <= 0)
{
var fuel_extracted;
// Search for new fuel among the contents.
var fuel = GetFuelContents();
if (!fuel)
{
// Extract the fuel amount from stored liquids
var fuel_stored = RemoveLiquid(nil, nil);
fuel_extracted = GetFuelValue(fuel_stored[0], fuel_stored[1]);
}
else
{
// Extract the fuel amount from the new piece of fuel.
fuel_extracted = fuel->~GetFuelAmount(true);
if (!fuel->~OnFuelRemoved(fuel_extracted)) fuel->RemoveObject();
}
if (!fuel_extracted)
{
// Set action to idle and unregister this producer as available from the network.
if (cancel)
{
// Set action to idle and unregister this producer as available from the network.
SetAction("Idle");
UnregisterPowerProduction();
}
return false;
}
fuel_amount += fuel_extracted * 18;
}
}
func GetFuelContents()
{
return FindObject(Find_Container(this), Find_Func("IsFuel"));
}
func BurnFuel(int amount)
{
fuel_amount -= amount;
}
func Smoking()
{
// Smoke from the exhaust shaft
Smoke(-20 * GetCalcDir() + RandomX(-2, 2), -26, 10);
Smoke(-20 * GetCalcDir() + RandomX(-2, 2), -24, 8);
Smoke(-20 * GetCalcDir() + RandomX(-2, 2), -24, 10);
}
2014-12-30 19:24:13 +00:00
func GetFuelValue(string liquid, int amount)
{
if (liquid == "Oil") return amount;
return 0;
}
func IsLiquidContainerForMaterial(string liquid)
{
return WildcardMatch("Oil", liquid);
}
func GetLiquidContainerMaxFillLevel()
{
return 300; // can store one barrel - this should be enough, so that the pump does not fill too much oil into the engine
}
2014-12-30 19:24:13 +00:00
/*-- Properties --*/
local ActMap = {
2014-12-30 19:24:13 +00:00
Idle = {
Prototype = Action,
2014-12-30 19:24:13 +00:00
Name = "Idle",
Procedure = DFA_NONE,
Directions = 2,
FlipDir = 1,
Length = 1,
Delay = 0,
2014-12-30 19:24:13 +00:00
FacetBase = 1,
NextAction = "Idle",
},
Work = {
Prototype = Action,
Name = "Work",
Procedure = DFA_NONE,
Directions = 2,
FlipDir = 1,
Length = 20,
Delay = 2,
FacetBase = 1,
NextAction = "Work",
Animation = "Work",
2014-12-30 19:24:13 +00:00
PhaseCall = "Working",
StartCall = "WorkStart",
EndCall = "WorkStop",
AbortCall = "WorkAbort",
},
};
2014-12-30 19:24:13 +00:00
protected func Definition(def)
{
SetProperty("MeshTransformation", Trans_Mul(Trans_Rotate(25, 0, 1, 0), Trans_Scale(625)), def);
SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(-4000, -18000, 60000), Trans_Rotate(25, 0, 1, 0), Trans_Scale(625)), def);
2012-04-15 11:13:14 +00:00
}
2014-12-30 19:24:13 +00:00
local ContainBlast = true;
local BlastIncinerate = 130;
local HitPoints = 100;
2012-04-15 11:13:14 +00:00
local Name = "$Name$";
local Description = "$Description$";
func QueryConnectPipe(object pipe)
{
if (GetNeutralPipe())
{
pipe->Report("$MsgHasPipes$");
return true;
}
if (pipe->IsDrainPipe() || pipe->IsNeutralPipe())
{
return false;
}
else
{
pipe->Report("$MsgPipeProhibited$");
return true;
}
}
func OnPipeConnect(object pipe, string specific_pipe_state)
{
SetNeutralPipe(pipe);
pipe->Report("$MsgConnectedPipe$");
}