forked from Mirrors/openclonk
165 lines
3.8 KiB
C
165 lines
3.8 KiB
C
/* Loam */
|
|
|
|
local loamused; // amount of loam already used
|
|
|
|
protected func Construction()
|
|
{
|
|
var graphic = Random(5);
|
|
if (graphic)
|
|
SetGraphics(Format("%d",graphic));
|
|
}
|
|
|
|
// Impact sound
|
|
func Hit()
|
|
{
|
|
Sound("GeneralHit?");
|
|
}
|
|
|
|
// Item activation
|
|
func ControlUseStart(object clonk, int x, int y)
|
|
{
|
|
if (!(clonk->~Bridge()))
|
|
{
|
|
clonk->CancelUse();
|
|
return true;
|
|
}
|
|
// Add bridge effect and pass target coordinates.
|
|
AddEffect("IntBridge", clonk, 1, 1, this, nil, x, y);
|
|
|
|
return true;
|
|
}
|
|
|
|
func HoldingEnabled() { return true; }
|
|
|
|
func FxIntBridgeStart(object clonk, proplist effect, int temp, int x, int y)
|
|
{
|
|
if (temp)
|
|
return FX_OK;
|
|
// Drawing times.
|
|
effect.Begin = 0;
|
|
effect.Last = 0;
|
|
// Last bridge coordinates.
|
|
effect.LastX = GetX();
|
|
effect.LastY = clonk->GetDefBottom() + 4;
|
|
// Target coordinates.
|
|
effect.TargetX = x;
|
|
effect.TargetY = y;
|
|
return FX_OK;
|
|
}
|
|
|
|
func FxIntBridgeTimer(object clonk, proplist effect, int time)
|
|
{
|
|
// something happened - don't try to dig anymore
|
|
if (!(clonk->~IsBridging()))
|
|
{
|
|
clonk->CancelUse();
|
|
return true;
|
|
}
|
|
|
|
// clonk faces bridge direction
|
|
var tdir = 0;
|
|
// get global drawing coordinates
|
|
var x = effect.TargetX + GetX();
|
|
var y = effect.TargetY + GetY();
|
|
if (x > 0) ++tdir;
|
|
clonk->SetDir(tdir);
|
|
|
|
// bridge speed: Build in smaller steps when briding upwards so Clonk moves up with bridge
|
|
var min_dt = 3;
|
|
if (effect.TargetY < -20 && !Abs(effect.TargetX*5/effect.TargetY))
|
|
min_dt = 2;
|
|
|
|
// bridge speed by dig physical
|
|
var speed = clonk.ActMap.Dig.Speed/6;
|
|
|
|
// build bridge in chunks (for better angle precision)
|
|
var dt = time - effect.Last;
|
|
if (dt < min_dt) return FX_OK;
|
|
effect.Last += dt;
|
|
|
|
// draw loam (earth) line
|
|
var line_wdt = 3;
|
|
var line_len = speed * dt;
|
|
var last_x = effect.LastX;
|
|
var last_y = effect.LastY;
|
|
var dx = x-last_x, dy=y-last_y, d=Distance(dx, dy);
|
|
// Quantize angle as a multiple of 30 degrees.
|
|
var quant = 30;
|
|
var angle = Angle(0, 0, dx, dy);
|
|
angle = angle + quant/2 - Sign(angle-quant/2)*((angle-quant/2) % quant);
|
|
dx = Sin(angle, d);
|
|
dy = -Cos(angle, d);
|
|
|
|
// Don't use up loam if the mouse position is reached...
|
|
// wait for the mouse being moved and then continue bridging
|
|
// into that direction
|
|
if(!d) return FX_OK;
|
|
|
|
var ox = dy * line_wdt / d, oy = -dx * line_wdt / d;
|
|
dx = dx * line_len / (d*10);
|
|
dy = dy * line_len / (d*10);
|
|
DrawMaterialQuad("Earth-earth", last_x-ox,last_y-oy, last_x+dx-ox,last_y+dy-oy, last_x+dx+ox,last_y+dy+oy, last_x+ox,last_y+oy, DMQ_Bridge);
|
|
effect.LastX += dx;
|
|
effect.LastY += dy;
|
|
|
|
// bridge time is up?
|
|
loamused += Max(line_len/10,1);
|
|
if (loamused >= BridgeLength)
|
|
{
|
|
clonk->CancelUse();
|
|
}
|
|
return FX_OK;
|
|
}
|
|
|
|
func ControlUseHolding(object clonk, int new_x, int new_y)
|
|
{
|
|
var effect = GetEffect("IntBridge", clonk);
|
|
if (!effect)
|
|
return true;
|
|
// Update target coordinates in bridge effect.
|
|
effect.TargetX = new_x;
|
|
effect.TargetY = new_y;
|
|
return true;
|
|
}
|
|
|
|
public func ControlUseStop(object clonk, int x, int y)
|
|
{
|
|
LoamDone(clonk);
|
|
return true;
|
|
}
|
|
|
|
public func ControlUseCancel(object clonk, int x, int y)
|
|
{
|
|
LoamDone(clonk);
|
|
return true;
|
|
}
|
|
|
|
private func LoamDone(object clonk)
|
|
{
|
|
// Get out of animation
|
|
if (clonk->IsBridging())
|
|
{
|
|
clonk->SetAction("Walk");
|
|
clonk->SetComDir(COMD_Stop);
|
|
}
|
|
// Remove Effect
|
|
RemoveEffect("IntBridge", clonk);
|
|
// Remove loam object if most of it has been consumed
|
|
if (loamused > BridgeLength - 10)
|
|
RemoveObject();
|
|
return;
|
|
}
|
|
|
|
public func IsFoundryProduct() { return true; }
|
|
public func GetLiquidNeed() { return ["Water", 60]; }
|
|
public func GetMaterialNeed() { return ["Earth", 25]; }
|
|
|
|
public func GetMaterialIcon(string mat) { return Earth; }
|
|
|
|
local Collectible = 1;
|
|
local Name = "$Name$";
|
|
local Description = "$Description$";
|
|
local UsageHelp = "$UsageHelp$";
|
|
local Rebuy = true;
|
|
local BridgeLength = 37; // bridge length in pixels
|
|
local Plane = 470; |