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

201 lines
4.6 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 300 units of power independent of the fuel. However, the fuel
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
local DefaultFlagRadius = 200;
2009-12-29 13:44:16 +00:00
static const SteamEngine_produced_power = 300;
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)
{
2013-05-23 16:37:01 +00:00
Sound("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;
}
/*-- 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.
if (fuel_amount <= 0)
{
2014-12-30 19:24:13 +00:00
// Search for new fuel among the contents.
var fuel = FindObject(Find_Container(this), Find_Func("IsFuel"));
if (!fuel)
return false;
// Extract the fuel amount from the new piece of fuel.
fuel_amount += fuel->~GetFuelAmount() * 18;
fuel->RemoveObject();
}
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.
public func OnPowerProductionStop()
{
// 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("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()
{
2014-12-30 19:24:13 +00:00
// Reduce the fuel amount by 1 per frame.
fuel_amount -= 2;
// Check if there is still enough fuel available.
if (fuel_amount <= 0)
{
// Search for new fuel among the contents.
var fuel = FindObject(Find_Container(this), Find_Func("IsFuel"));
if (!fuel)
{
// Set action to idle and unregister this producer as available from the network.
SetAction("Idle");
UnregisterPowerProduction();
return;
}
// Extract the fuel amount from the new piece of fuel.
fuel_amount += fuel->~GetFuelAmount() * 18;
fuel->RemoveObject();
}
// 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);
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("SteamEngine", false, nil, nil, -1);
return;
}
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$";