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

214 lines
5.0 KiB
C
Raw Normal View History

/*--
Sawmill
Authors: Ringwaul, Clonkonaut
Cuts trees or other objects into wood. Accepts only objects purely made from wood.
--*/
#include Library_Structure
#include Library_Ownable
#include Library_Producer
public func Construction(object creator)
{
SetProperty("MeshTransformation",Trans_Rotate(-20,0,1,0));
SetAction("Default");
return _inherited(creator, ...);
}
public func Initialize()
{
this.SpinAnimation = PlayAnimation("work", 10, Anim_Const(0), Anim_Const(1000));
AddTimer("CollectionZone", 1);
return _inherited(...);
}
/*-- Interaction --*/
// Sawmill can't be accessed as a container.
public func IsContainer() { return false; }
// Sawmill can't be interacted with.
public func IsInteractable() { return false; }
// Automatically search for trees in front of sawmill
// Temporary solution?
protected func FindTrees()
{
var tree = FindObject(Find_AtPoint(), Find_Func("IsTree"), Find_Not(Find_Func("IsStanding")), Find_Func("GetComponent", Wood));
if (!tree) return;
Saw(tree);
}
private func CheckWoodObject(object target)
{
if (target->GetComponent(nil, 0) != Wood) return false;
if (target->GetComponent(nil, 1)) return false;
return true;
}
/*-- Production --*/
private func IgnoreKnowledge() { return true; }
public func Saw(object target)
{
target->Enter(this);
var output = target->GetComponent(Wood);
target->Split2Components();
AddToQueue(Wood, output);
return true;
}
private func IsProduct(id product_id)
{
return product_id->~IsSawmillProduct();
}
private func ProductionTime(id toProduce) { return 100; }
private func PowerNeed() { return 50; }
public func NeedRawMaterial(id rawmat_id)
{
if (rawmat_id->~IsSawmillProduct())
return true;
return false;
}
public func OnProductionStart(id product)
{
if (!GetEffect("Sawing", this))
{
SpinOn();
AddEffect("Sawing", this, 100, 1, this);
}
}
public func OnProductionHold(id product)
{
SpinOff();
RemoveEffect("Sawing", this);
}
public func OnProductionContinued(id product)
{
if (!GetEffect("Sawing", this))
{
SpinOn();
AddEffect("Sawing", this, 100, 1, this);
}
}
public func OnProductionFinish(id product)
{
if (!GetLength(queue))
{
SpinOff();
RemoveEffect("Sawing", this);
}
}
// Timer, check for objects to collect in the designated collection zone
func CollectionZone()
{
if (GetCon() < 100) return;
// Only take one tree at a time
if (!(FrameCounter() % 35))
if (GetLength(queue) == 0)
FindTrees();
}
protected func Collection()
{
Sound("Clonk");
}
public func FxSawingTimer(object target, proplist effect, int time)
{
var dir = GetCalcDir();
if (time >= this.SpinStep * 3 && time % 5)
CreateParticle("WoodChip", PV_Random(-7 * dir, -3 * dir), PV_Random(3, 6), PV_Random(-5 * dir, -11 * dir), PV_Random(-4, -2), PV_Random(36 * 3, 36 * 10), Particles_WoodChip(), 3);
if (!(time % 20))
Smoke(10 * GetCalcDir(),10,10);
}
public func OnProductEjection(object product)
{
product->SetPosition(GetX() - 25 * GetCalcDir(), GetY() - 8);
product->SetSpeed(-7 * GetCalcDir(), 5);
product->SetR(30 - Random(59));
Sound("Pop");
}
protected func RejectCollect(id id_def, object collect)
{
// Don't collect wood
if (id_def == Wood)
return true;
if (collect->~IsSawmillIngredient() || CheckWoodObject(collect))
return false;
return true;
}
/*-- Animation --*/
private func SpinOn(int call)
{
var spin;
// Slowest spin on first call
if (!call) { spin = 100; SetMeshMaterial("Beltspin", 1); ClearScheduleCall(this, "SpinOff"); }
if (call == 1) spin = 75;
if (call == 2) spin = 50;
if (call == 3) { spin = 30; SetMeshMaterial("SawmillBlade.Spin", 2); }
SetAnimationPosition(this.SpinAnimation, Anim_Linear(GetAnimationPosition(this.SpinAnimation), GetAnimationLength("work"), 0, spin, ANIM_Loop));
if (call < 3) ScheduleCall(this, "SpinOn", this.SpinStep, nil, call+1);
else Sound("SawmillRipcut", nil, nil, nil, +1);
}
private func SpinOff(int call, int animation_no)
{
var spin;
if (!call) { spin = 50; SetMeshMaterial("SawmillBlade", 2); Sound("SawmillRipcut", nil, nil, nil, -1); ClearScheduleCall(this, "SpinOn"); }
if (call == 1) spin = 75;
if (call == 2) spin = 100;
if (call == 3) spin = 150;
if (call == 4)
{
SetMeshMaterial("SawmillBelt", 1);
SetAnimationPosition(this.SpinAnimation, Anim_Const(GetAnimationPosition(this.SpinAnimation)));
return;
}
SetAnimationPosition(this.SpinAnimation, Anim_Linear(GetAnimationPosition(this.SpinAnimation), GetAnimationLength("work"), 0, spin, ANIM_Loop));
ScheduleCall(this, "SpinOff", this.SpinStep * 2, nil, call+1);
}
local ActMap = {
Default = {
Prototype = Action,
Name = "Default",
Procedure = DFA_NONE,
Directions = 2,
FlipDir = 1,
Length = 1,
Delay = 0,
FacetBase = 1,
NextAction = "Default",
},
};
func Definition(def) {
SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(2000,0,7000),Trans_Rotate(-20,1,0,0),Trans_Rotate(30,0,1,0)), def);
}
local Name = "$Name$";
2012-04-15 11:13:14 +00:00
local Description = "$Description$";
local SpinStep = 30;
local ContainBlast = true;
local BlastIncinerate = 100;
local HitPoints = 70;