openclonk/planet/Objects.ocd/Items.ocd/Tools.ocd/DynamiteBox.ocd/Fuse.ocd/Script.c

139 lines
3.6 KiB
C

/**
Dynamite Fuse
Line object that connects the dynamite sticks with the igniter.
@author Newton, Maikel
*/
protected func Initialize()
{
SetProperty("LineColors", [RGB(100, 50, 0), RGB(1, 1, 1)]);
// Put the first to vertices on the actual position.
SetVertex(0, 0, GetX()); SetVertex(0, 1, GetY());
SetVertex(1, 0, GetX()); SetVertex(1, 1, GetY());
return;
}
public func IsFuse() { return true; }
public func Connect(object target1, object target2)
{
SetAction("Connect", target1, target2);
}
public func StartFusing(object controller)
{
var effect;
if (effect = GetEffect("IntFusing", this))
{
// Double fuse start scheduled? Ignore.
if (effect.fuse_source == controller) return false;
// Fuse from both sides not supported
return RemoveObject();
}
var fuse_dir;
var fuse_call;
var fuse_vertex;
if (GetActionTarget(0) == controller)
{
fuse_dir = +1;
fuse_call = GetActionTarget(1);
fuse_vertex = 0;
}
else
{
fuse_dir = -1;
fuse_call = GetActionTarget(0);
fuse_vertex = GetVertexNum()-1;
}
effect = AddEffect("IntFusing", this, 100, 1, this);
effect.fuse_dir = fuse_dir;
effect.fuse_source = controller;
effect.fuse_call = fuse_call;
effect.fuse_vertex = fuse_vertex;
effect.fuse_x = GetVertex(fuse_vertex, VTX_X) * 10;
effect.fuse_y = GetVertex(fuse_vertex, VTX_Y) * 10;
return true;
}
protected func FxIntFusingStart(object target, proplist effect, int temporary)
{
if (temporary)
return FX_OK;
SetAction("Fusing");
Sound("Fire::FuseLoop", false, 75, nil, 1);
return FX_OK;
}
protected func FxIntFusingTimer(object target, proplist effect, int time)
{
var target_x = GetVertex(effect.fuse_vertex + effect.fuse_dir, VTX_X) * 10;
var target_y = GetVertex(effect.fuse_vertex + effect.fuse_dir, VTX_Y)*10;
var speed = 20;
if (Distance(effect.fuse_x, effect.fuse_y, target_x, target_y) < speed)
{
RemoveVertex(effect.fuse_vertex);
if (effect.fuse_dir == -1)
effect.fuse_vertex--;
speed -= Distance(effect.fuse_x, effect.fuse_y, target_x, target_y);
if ((effect.fuse_vertex == 0 && effect.fuse_dir == -1) || (effect.fuse_vertex == GetVertexNum() - 1 && effect.fuse_dir == +1))
{
if (effect.fuse_call)
effect.fuse_call->~OnFuseFinished(this);
if (effect.fuse_call)
RemoveObject();
return FX_Execute_Kill;
}
effect.fuse_x = GetVertex(effect.fuse_vertex, VTX_X) * 10;
effect.fuse_y = GetVertex(effect.fuse_vertex, VTX_Y) * 10;
target_x = GetVertex(effect.fuse_vertex + effect.fuse_dir, VTX_X) * 10;
target_y = GetVertex(effect.fuse_vertex + effect.fuse_dir, VTX_Y) * 10;
}
// Move spark position
var angle = Angle(effect.fuse_x, effect.fuse_y, target_x, target_y);
effect.fuse_x += Sin(angle, speed);
effect.fuse_y +=-Cos(angle, speed);
CreateParticle("Fire", effect.fuse_x / 10 - GetX(), effect.fuse_y / 10 - GetY(), PV_Random(-10, 10), PV_Random(-10, 10), PV_Random(10, 40), Particles_Glimmer(), 3);
SetVertexXY(effect.fuse_vertex, effect.fuse_x / 10, effect.fuse_y / 10);
return FX_OK;
}
protected func FxIntFusingStop(object target, proplist effect, int reason, bool temporary)
{
if (temporary)
return FX_OK;
Sound("Fire::FuseLoop", false, 75, nil, -1);
return FX_OK;
}
// Only the main dynamite pack is stored.
public func SaveScenarioObject() { return false;}
/*-- Properties --*/
local ActMap = {
Connect = {
Prototype = Action,
Name = "Connect",
Length = 0,
Delay = 0,
Procedure = DFA_CONNECT,
NextAction = "Connect",
},
Fusing = {
Prototype = Action,
Name = "Fusing",
Length = 0,
Delay = 0,
Procedure = DFA_NONE,
NextAction = "Fusing",
},
};
local Name = "$Name$";