forked from Mirrors/openclonk
157 lines
3.6 KiB
C
157 lines
3.6 KiB
C
/**
|
|
Bullet trail
|
|
Draws a trail to any object. That object should fly straight or so fast
|
|
that it looks like it because the trail itself is only drawn straight.
|
|
Any projectile can use the trail by calling (after creating it):
|
|
|
|
Set(object bullet, int width, int length)
|
|
|
|
while width is the width of the trail, length the length of the trail and
|
|
projectile itself. The trail will be removed when the projectile is gone.
|
|
The color is always a light-grey. However each frame, ~TrailColor(int time)
|
|
is called in the projectile which can return the color modulation.
|
|
|
|
@author Newton, Maikel
|
|
*/
|
|
|
|
local for_bullet;
|
|
local width, length;
|
|
local speed, rotation;
|
|
local orig_x, orig_y;
|
|
|
|
public func Set(object bullet, int wdt, int lgt)
|
|
{
|
|
// Store the bullet for which this trail is made.
|
|
for_bullet = bullet;
|
|
|
|
// Change plane to be just behind bullet.
|
|
this.Plane = for_bullet.Plane - 1;
|
|
|
|
// Store trail properties.
|
|
width = 1000 * wdt / ActMap.Travel.Wdt;
|
|
length = 1000 * lgt / ActMap.Travel.Hgt;
|
|
var xdir = for_bullet->GetXDir(1000);
|
|
var ydir = for_bullet->GetYDir(1000);
|
|
speed = Distance(0, 0, xdir, ydir) / Sqrt(1000);
|
|
rotation = Angle(0, 0, xdir, ydir);
|
|
orig_x = for_bullet->GetX();
|
|
orig_y = for_bullet->GetY();
|
|
|
|
// Copy bullet's motion.
|
|
SetAction("Travel");
|
|
SetComDir(COMD_None);
|
|
SetPosition(orig_x, orig_y);
|
|
SetXDir(xdir, 1000);
|
|
SetYDir(ydir, 1000);
|
|
return;
|
|
}
|
|
|
|
private func UpdateTrail()
|
|
{
|
|
// Remove trail if the bullet is gone or the trail is out of the landscape borders.
|
|
if (!for_bullet)
|
|
return Remove();
|
|
if ((GetX() <= 0 && GetXDir() < 0) || (GetX() >= LandscapeWidth() && GetXDir() > 0) || (GetY() <= 0 && GetYDir() < 0) || (GetY() >= LandscapeHeight() && GetYDir() > 0))
|
|
return Remove();
|
|
|
|
// Display.
|
|
DrawTransform();
|
|
// Adjust trail color as specified in bullet.
|
|
if (for_bullet)
|
|
{
|
|
var trail_color = for_bullet->~TrailColor(GetActTime());
|
|
if (trail_color != nil)
|
|
SetClrModulation(for_bullet->~TrailColor(GetActTime()));
|
|
}
|
|
return;
|
|
}
|
|
|
|
public func RemoveTrail()
|
|
{
|
|
// Reduce trail length by its speed every frame.
|
|
length = Max(0, length - speed);
|
|
// Display.
|
|
DrawTransform();
|
|
// Remove trail if its length is zero.
|
|
if (length <= 0)
|
|
return RemoveObject();
|
|
return;
|
|
}
|
|
|
|
public func Hit()
|
|
{
|
|
// Remove trail if it hit something.
|
|
return Remove();
|
|
}
|
|
|
|
private func Remove()
|
|
{
|
|
SetXDir(0);
|
|
SetYDir(0);
|
|
return SetAction("Remove");
|
|
}
|
|
|
|
public func DrawTransform()
|
|
{
|
|
// Determine length, width and position of the trail.
|
|
var distance = Distance(orig_x, orig_y, GetX(), GetY());
|
|
var relative_length = 1000 * distance / ActMap.Travel.Hgt;
|
|
|
|
var h = Min(length, relative_length);
|
|
|
|
var fsin = -Sin(rotation, 1000);
|
|
var fcos = Cos(rotation, 1000);
|
|
|
|
var xoff = -ActMap.Travel.Wdt * width / 2 + 750;
|
|
var yoff = 0;
|
|
|
|
// Set object draw transformation.
|
|
var draw_width = +fcos * width / 1000;
|
|
var draw_height = +fcos * h / 1000;
|
|
var xskew = +fsin * h / 1000;
|
|
var yskew = -fsin * width / 1000;
|
|
var xadjust = (+fcos * xoff + fsin * yoff) / 1000;
|
|
var yadjust = (-fsin * xoff + fcos * yoff) / 1000;
|
|
return SetObjDrawTransform(draw_width, xskew, xadjust, yskew, draw_height, yadjust);
|
|
}
|
|
|
|
public func SaveScenarioObject() { return false; }
|
|
|
|
|
|
/*-- Properties --*/
|
|
|
|
local Plane = 300;
|
|
|
|
local ActMap = {
|
|
Travel = {
|
|
Prototype = Action,
|
|
Name = "Travel",
|
|
Procedure = DFA_FLOAT,
|
|
NextAction = "Travel",
|
|
Length = 1,
|
|
Delay = 1,
|
|
X = 0,
|
|
Y = 0,
|
|
Wdt = 5,
|
|
Hgt = 25,
|
|
OffX = 0,
|
|
OffY = 2,
|
|
StartCall = "UpdateTrail"
|
|
},
|
|
Remove = {
|
|
Prototype = Action,
|
|
Name = "Remove",
|
|
Procedure = DFA_FLOAT,
|
|
NextAction = "Remove",
|
|
Length = 1,
|
|
Delay = 1,
|
|
X = 0,
|
|
Y = 0,
|
|
Wdt = 5,
|
|
Hgt = 25,
|
|
OffX = 0,
|
|
OffY = 2,
|
|
StartCall = "RemoveTrail"
|
|
}
|
|
};
|