1 /**
2 Bullet trail
3 Draws a trail to any object. That object should fly straight or so fast
4 that it looks like it because the trail itself is only drawn straight.
5 Any projectile can use the trail by calling (after creating it):
6
7 Set(object bullet, int width, int length)
8
9 while width is the width of the trail, length the length of the trail and
10 projectile itself. The trail will be removed when the projectile is gone.
11 The color is always a light-grey. However each frame, ~TrailColor(int time)
12 is called in the projectile which can return the color modulation.
13
14 @author Newton, Maikel
15 */
16
17 local for_bullet;
18 local width, length;
19 local speed, rotation;
20 local orig_x, orig_y;
21
Set(object bullet,int wdt,int lgt)22 public func Set(object bullet, int wdt, int lgt)
23 {
24 // Store the bullet for which this trail is made.
25 for_bullet = bullet;
26
27 // Change plane to be just behind bullet.
28 this.Plane = for_bullet.Plane - 1;
29
30 // Store trail properties.
31 width = 1000 * wdt / ActMap.Travel.Wdt;
32 length = 1000 * lgt / ActMap.Travel.Hgt;
33 var xdir = for_bullet->GetXDir(1000);
34 var ydir = for_bullet->GetYDir(1000);
35 speed = Distance(0, 0, xdir, ydir) / Sqrt(1000);
36 rotation = Angle(0, 0, xdir, ydir);
37 orig_x = for_bullet->GetX();
38 orig_y = for_bullet->GetY();
39
40 // Copy bullet's motion.
41 SetAction("Travel");
42 SetComDir(COMD_None);
43 SetPosition(orig_x, orig_y);
44 SetXDir(xdir, 1000);
45 SetYDir(ydir, 1000);
46 return;
47 }
48
UpdateTrail()49 private func UpdateTrail()
50 {
51 // Remove trail if the bullet is gone or the trail is out of the landscape borders.
52 if (!for_bullet)
53 return Remove();
54 if ((GetX() <= 0 && GetXDir() < 0) || (GetX() >= LandscapeWidth() && GetXDir() > 0) || (GetY() <= 0 && GetYDir() < 0) || (GetY() >= LandscapeHeight() && GetYDir() > 0))
55 return Remove();
56
57 // Display.
58 DrawTransform();
59 // Adjust trail color as specified in bullet.
60 if (for_bullet)
61 {
62 var trail_color = for_bullet->~TrailColor(GetActTime());
63 if (trail_color != nil)
64 SetClrModulation(for_bullet->~TrailColor(GetActTime()));
65 }
66 return;
67 }
68
RemoveTrail()69 public func RemoveTrail()
70 {
71 // Reduce trail length by its speed every frame.
72 length = Max(0, length - speed);
73 // Display.
74 DrawTransform();
75 // Remove trail if its length is zero.
76 if (length <= 0)
77 return RemoveObject();
78 return;
79 }
80
Hit()81 public func Hit()
82 {
83 // Remove trail if it hit something.
84 return Remove();
85 }
86
Remove()87 private func Remove()
88 {
89 SetXDir(0);
90 SetYDir(0);
91 return SetAction("Remove");
92 }
93
DrawTransform()94 public func DrawTransform()
95 {
96 // Determine length, width and position of the trail.
97 var distance = Distance(orig_x, orig_y, GetX(), GetY());
98 var relative_length = 1000 * distance / ActMap.Travel.Hgt;
99
100 var h = Min(length, relative_length);
101
102 var fsin = -Sin(rotation, 1000);
103 var fcos = Cos(rotation, 1000);
104
105 var xoff = -ActMap.Travel.Wdt * width / 2 + 750;
106 var yoff = 0;
107
108 // Set object draw transformation.
109 var draw_width = +fcos * width / 1000;
110 var draw_height = +fcos * h / 1000;
111 var xskew = +fsin * h / 1000;
112 var yskew = -fsin * width / 1000;
113 var xadjust = (+fcos * xoff + fsin * yoff) / 1000;
114 var yadjust = (-fsin * xoff + fcos * yoff) / 1000;
115 return SetObjDrawTransform(draw_width, xskew, xadjust, yskew, draw_height, yadjust);
116 }
117
SaveScenarioObject()118 public func SaveScenarioObject() { return false; }
119
120
121 /*-- Properties --*/
122
123 local Plane = 300;
124
125 local ActMap = {
126 Travel = {
127 Prototype = Action,
128 Name = "Travel",
129 Procedure = DFA_FLOAT,
130 NextAction = "Travel",
131 Length = 1,
132 Delay = 1,
133 X = 0,
134 Y = 0,
135 Wdt = 5,
136 Hgt = 25,
137 OffX = 0,
138 OffY = 2,
139 StartCall = "UpdateTrail"
140 },
141 Remove = {
142 Prototype = Action,
143 Name = "Remove",
144 Procedure = DFA_FLOAT,
145 NextAction = "Remove",
146 Length = 1,
147 Delay = 1,
148 X = 0,
149 Y = 0,
150 Wdt = 5,
151 Hgt = 25,
152 OffX = 0,
153 OffY = 2,
154 StartCall = "RemoveTrail"
155 }
156 };
157