1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
/**
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"
}
};
|