1 /************************************************************************************
2 
3 	AstroMenace
4 	Hardcore 3D space scroll-shooter with spaceship upgrade possibilities.
5 	Copyright (c) 2006-2019 Mikhail Kurinnoi, Viewizard
6 
7 
8 	AstroMenace is free software: you can redistribute it and/or modify
9 	it under the terms of the GNU General Public License as published by
10 	the Free Software Foundation, either version 3 of the License, or
11 	(at your option) any later version.
12 
13 	AstroMenace is distributed in the hope that it will be useful,
14 	but WITHOUT ANY WARRANTY; without even the implied warranty of
15 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 	GNU General Public License for more details.
17 
18 	You should have received a copy of the GNU General Public License
19 	along with AstroMenace. If not, see <https://www.gnu.org/licenses/>.
20 
21 
22 	Website: https://viewizard.com/
23 	Project: https://github.com/viewizard/astromenace
24 	E-mail: viewizard@viewizard.com
25 
26 *************************************************************************************/
27 
28 // FIXME probably, for mines GetClosestTargetToMine() should be used instead of FindTargetAndInterceptCourse()
29 
30 // TODO don't call GetPreloadedTextureAsset() all the time, use cached texture instead
31 
32 // TODO remove goto statement
33 
34 // TODO codestyle should be fixed
35 
36 // NOTE we use ReleaseProjectile() in weapon code for beam, since we use beam weapon for
37 //      player and motherships only (rare enough). If enemy will have beam weapon, revise
38 //      weapon code and/or projectile STL container (std::list is using now).
39 
40 /*
41 
42 Note, all enemy's projectiles and missiles without penalty should be about 30% faster
43 and maneuverable than player's projectiles and missiles. In this way, even x3 penalty
44 will not kill their speed and maneuverability and we will have nice difficulty matrix.
45 
46 */
47 
48 #include "projectile.h"
49 #include "functions.h"
50 #include "../explosion/explosion.h"
51 #include "../../assets/texture.h"
52 
53 // NOTE switch to nested namespace definition (namespace A::B::C { ... }) (since C++17)
54 namespace viewizard {
55 namespace astromenace {
56 
57 namespace {
58 
59 struct sProjectileData {
60 	float Radius;
61 	float DamageKinetic;
62 	float DamageEM;
63 	// 0-projectile, 1-with 3d model, 2-beam, 3- flares/alien mine, 4-mine with 3d model
64 	int ProjectileType;
65 	float Speed;
66 	float Age;
67 	int GraphicFXQuantity;
68 };
69 
70 const std::string MissileTrailTextures[]{{"gfx/trail1.tga"},
71 					 {"gfx/trail2.tga"},
72 					 {"gfx/trail3.tga"},
73 					 {"gfx/trail4.tga"},
74 					 {"gfx/trail5.tga"}};
75 
76 // earth 1-99
77 const std::vector<sProjectileData> PresetEarthProjectileData{
78 	// Kinetic
79 	{0.3f, 5, 0,	0, 50, 4, 1},
80 	{0.6f, 20, 0,	0, 45, 4, 1},
81 	{0.6f, 40, 0,	0, 45, 4, 1},
82 	{0.4f, 10, 0,	0, 50, 4, 1},
83 	// Ion
84 	{1.5f, 0, 10,	0, 40, 4, 1},
85 	{1.5f, 0, 30,	0, 40, 4, 2},
86 	{2.0f, 0, 50,	0, 40, 4, 2},
87 	// Plasma
88 	{1.0f, 30, 5,	0, 40, 4, 1},
89 	{1.3f, 40, 25,	0, 40, 4, 3},
90 	{1.3f, 50, 50,	0, 45, 4, 3},
91 	// Maser
92 	{0.6f, 50, 0,	2, 0, 2, 1},
93 	{1.0f, 80, 0,	2, 0, 2, 2},
94 	// Antimatter
95 	{1.0f, 80, 10,	0, 70, 3, 1},
96 	// Laser
97 	{0.4f, 150, 0,	2, 0, 1, 1},
98 	// Gauss
99 	{1.1f, 100, 0,	0, 80, 3, 1},
100 	// Missiles
101 	{0.2f, 100, 0,	1, 40, 8, 2},
102 	{0.2f, 20, 0,	1, 40, 6, 2},
103 	{0.2f, 400, 0,	1, 35, 7, 2},
104 	{0.2f, 800, 0,	1, 30, 6, 2}
105 };
106 
107 // alien 101-199
108 const std::vector<sProjectileData> PresetAlienProjectileData{
109 	// like Kinetic1
110 	{0.3f, 5, 0,	0, 70, 4, 1},
111 	// homing, like Kinetic2
112 	{0.6f, 10, 0,	0, 50, 4, 2},
113 	// like Kinetic3
114 	{0.6f, 20, 0,	0, 60, 4, 1},
115 	// homing, like Kinetic3
116 	{0.6f, 20, 0,	0, 60, 4, 2},
117 	// like Kinetic2
118 	{0.6f, 10, 0,	0, 50, 4, 1},
119 	// emergy mine 1
120 	{2.0f, 60, 0,	3, 0, 16, 1},
121 	// emergy mine 2, with homing
122 	{2.0f, 120, 0,	3, 7, 16, 1},
123 	// like Plasma3
124 	{1.3f, 50, 50,	0, 55, 4, 3},
125 	// like Plasma2
126 	{1.3f, 40, 25,	0, 55, 4, 3},
127 	// like Laser (for matherships)
128 	{1.0f, 250, 0,	2, 0, 1, 1}
129 
130 };
131 
132 // pirate 201-299
133 const std::vector<sProjectileData> PresetPirateProjectileData{
134 	// turrent 1
135 	{0.3f, 5, 0,	0, 60, 4, 1},
136 	// turrent 2
137 	{0.6f, 20, 0,	0, 45, 4, 1},
138 	// flares
139 	{3.0f, 5, 0,	3, 5, 5, 1},
140 
141 	// like Kinetic1
142 	{0.3f, 5, 0,	0, 60, 4, 1},
143 	// like Missile1
144 	{0.2f, 40, 0,	1, 60, 6, 2},
145 	// like Missile2
146 	{0.2f, 20, 0,	1, 60, 6, 2},
147 	// like Ion2
148 	{1.5f, 0, 30,	0, 40, 4, 2},
149 	// like Antimatter
150 	{1.0f, 80, 10,	0, 70, 3, 1},
151 	// like Missile3 (torpedo)
152 	{0.2f, 400, 0,	1, 55, 7, 2},
153 	// like Missile4 (bomb)
154 	{0.2f, 1000, 0,	1, 50, 6, 2},
155 	// like Kinetic2
156 	{0.6f, 20, 0,	0, 45, 4, 1},
157 	// like Kinetic3
158 	{0.6f, 40, 0,	0, 45, 4, 1},
159 	// like Plasma2
160 	{1.3f, 40, 25,	0, 40, 4, 3},
161 
162 	// mine 1
163 	{1.2f, 50, 0,	4, 0, -1, 1},
164 	// mine 2
165 	{1.2f, 100, 0,	4, 7, -1, 1},
166 	// mine 3
167 	{1.2f, 150, 0,	4, 0, -1, 1},
168 	// mine 4
169 	{1.2f, 200, 0,	4, 0, -1, 1}
170 };
171 
172 std::list<std::shared_ptr<cProjectile>> ProjectileList{};
173 
174 } // unnamed namespace
175 
176 
177 /*
178  * Create cProjectile object.
179  */
CreateProjectile(const int ProjectileNum)180 std::weak_ptr<cProjectile> CreateProjectile(const int ProjectileNum)
181 {
182 	// NOTE emplace_front() return reference to the inserted element (since C++17)
183 	//      this two lines could be combined
184 	ProjectileList.emplace_front(new cProjectile{ProjectileNum}, [](cProjectile *p) {delete p;});
185 	return ProjectileList.front();
186 }
187 
188 /*
189  * Update and remove (erase) dead objects.
190  */
UpdateAllProjectile(float Time)191 void UpdateAllProjectile(float Time)
192 {
193 	// NOTE use std::erase_if here (since C++20)
194 	for (auto iter = ProjectileList.begin(); iter != ProjectileList.end();) {
195 		if (!iter->get()->Update(Time))
196 			iter = ProjectileList.erase(iter);
197 		else
198 			++iter;
199 	}
200 }
201 
202 /*
203  * Draw all objects.
204  */
DrawAllProjectiles(bool VertexOnlyPass,unsigned int ShadowMap)205 void DrawAllProjectiles(bool VertexOnlyPass, unsigned int ShadowMap)
206 {
207 	for (auto &tmpProjectile : ProjectileList) {
208 		tmpProjectile->Draw(VertexOnlyPass, ShadowMap);
209 	}
210 }
211 
212 /*
213  * Release particular projectile object.
214  */
ReleaseProjectile(std::weak_ptr<cProjectile> & Object)215 void ReleaseProjectile(std::weak_ptr<cProjectile> &Object)
216 {
217 	auto sharedObject = Object.lock();
218 	if (!sharedObject)
219 		return;
220 
221 	for (auto iter = ProjectileList.begin(); iter != ProjectileList.end();) {
222 		if (iter->get() == sharedObject.get()) {
223 			ProjectileList.erase(iter);
224 			return;
225 		}
226 		++iter;
227 	}
228 }
229 
230 /*
231  * Release all objects.
232  */
ReleaseAllProjectiles()233 void ReleaseAllProjectiles()
234 {
235 	ProjectileList.clear();
236 }
237 
238 /*
239  * Cycle for each projectile.
240  * Note, caller must guarantee, that 'Object' will not released in callback function call.
241  */
ForEachProjectile(std::function<void (cProjectile & Object)> function)242 void ForEachProjectile(std::function<void (cProjectile &Object)> function)
243 {
244 	for (auto &tmpProjectile : ProjectileList) {
245 		function(*tmpProjectile);
246 	}
247 }
248 
249 /*
250  * Managed cycle for each projectile.
251  * Note, caller must guarantee, that 'Object' will not released in callback function call.
252  */
ForEachProjectile(std::function<void (cProjectile & Object,eProjectileCycle & Command)> function)253 void ForEachProjectile(std::function<void (cProjectile &Object, eProjectileCycle &Command)> function)
254 {
255 	// NOTE use std::erase_if here (since C++20)
256 	for (auto iter = ProjectileList.begin(); iter != ProjectileList.end();) {
257 		eProjectileCycle Command{eProjectileCycle::Continue};
258 		function(*iter->get(), Command);
259 
260 		switch (Command) {
261 		case eProjectileCycle::Continue:
262 			++iter;
263 			break;
264 		case eProjectileCycle::Break:
265 			return;
266 		case eProjectileCycle::DeleteObjectAndContinue:
267 			iter = ProjectileList.erase(iter);
268 			break;
269 		case eProjectileCycle::DeleteObjectAndBreak:
270 			ProjectileList.erase(iter);
271 			return;
272 		}
273 	}
274 }
275 
276 /*
277  * Managed cycle for each projectile pair.
278  * Note, caller must guarantee, that 'FirstObject' and 'SecondObject' will not released in callback function call.
279  */
ForEachProjectilePair(std::function<void (cProjectile & FirstObject,cProjectile & SecondObject,eProjectilePairCycle & Command)> function)280 void ForEachProjectilePair(std::function<void (cProjectile &FirstObject,
281 					       cProjectile &SecondObject,
282 					       eProjectilePairCycle &Command)> function)
283 {
284 	for (auto iterFirst = ProjectileList.begin(); iterFirst != ProjectileList.end();) {
285 		eProjectilePairCycle Command{eProjectilePairCycle::Continue};
286 
287 		for (auto iterSecond = std::next(iterFirst, 1); iterSecond != ProjectileList.end();) {
288 			Command = eProjectilePairCycle::Continue;
289 			function(*iterFirst->get(), *iterSecond->get(), Command);
290 
291 			// NOTE (?) use std::erase_if here (since C++20)
292 			if ((Command == eProjectilePairCycle::DeleteSecondObjectAndContinue) ||
293 			    (Command == eProjectilePairCycle::DeleteBothObjectsAndContinue))
294 				iterSecond = ProjectileList.erase(iterSecond);
295 			else
296 				++iterSecond;
297 
298 			// break second cycle
299 			if ((Command == eProjectilePairCycle::DeleteFirstObjectAndContinue) ||
300 			    (Command == eProjectilePairCycle::DeleteBothObjectsAndContinue))
301 				break;
302 		}
303 
304 		// NOTE (?) use std::erase_if here (since C++20)
305 		if ((Command == eProjectilePairCycle::DeleteFirstObjectAndContinue) ||
306 		    (Command == eProjectilePairCycle::DeleteBothObjectsAndContinue))
307 			iterFirst = ProjectileList.erase(iterFirst);
308 		else
309 			++iterFirst;
310 	}
311 }
312 
313 /*
314  * Get object ptr by reference.
315  */
GetProjectilePtr(const cProjectile & Object)316 std::weak_ptr<cObject3D> GetProjectilePtr(const cProjectile &Object)
317 {
318 	for (auto &tmpProjectile : ProjectileList) {
319 		if (tmpProjectile.get() == &Object)
320 			return tmpProjectile;
321 	}
322 
323 	return std::weak_ptr<cObject3D>{};
324 }
325 
326 /*
327  * Get projectile fly range.
328  */
GetProjectileRange(int Num)329 float GetProjectileRange(int Num)
330 {
331 	if ((Num >= 1) &&
332 	    (Num <= 99)) {
333 		float Return = PresetEarthProjectileData[Num - 1].Age * PresetEarthProjectileData[Num - 1].Speed;
334 		if (Num == 11)
335 			Return = 100.0f;
336 		if (Num == 12)
337 			Return = 110.0f;
338 		if (Num == 14)
339 			Return = 120.0f;
340 		return Return;
341 	} else if ((Num >= 101) &&
342 		   (Num <= 199)) {
343 		if (Num == 110)
344 			return 200.0f;
345 		return PresetAlienProjectileData[Num - 101].Age * PresetAlienProjectileData[Num - 101].Speed;
346 	} else if ((Num >= 201) &&
347 		   (Num <= 299))
348 		return PresetPirateProjectileData[Num - 201].Age * PresetPirateProjectileData[Num - 201].Speed;
349 
350 	return 0.0f;
351 }
352 
353 /*
354  * Get projectile kinetic damage.
355  */
GetProjectileDamageKinetic(const int Num)356 int GetProjectileDamageKinetic(const int Num)
357 {
358 	if ((Num >= 1) &&
359 	    (Num <= 99)) {
360 		// missile swarm
361 		if (Num == 17)
362 			return 10 * (int)PresetEarthProjectileData[Num - 1].DamageKinetic;
363 		return (int)PresetEarthProjectileData[Num - 1].DamageKinetic;
364 	} else if ((Num >= 101) &&
365 		   (Num <= 199))
366 		return (int)PresetAlienProjectileData[Num - 101].DamageKinetic;
367 	else if ((Num >= 201) &&
368 		 (Num <= 299))
369 		return (int)PresetPirateProjectileData[Num - 201].DamageKinetic;
370 
371 	return 0;
372 }
373 
374 /*
375  * Get projectile EM damage.
376  */
GetProjectileDamageEM(const int Num)377 int GetProjectileDamageEM(const int Num)
378 {
379 	if ((Num >= 1) &&
380 	    (Num <= 99)) {
381 		// missile swarm
382 		if (Num == 17)
383 			return 10 * (int)PresetEarthProjectileData[Num - 1].DamageEM;
384 		return (int)PresetEarthProjectileData[Num - 1].DamageEM;
385 	} else if ((Num >= 101) &&
386 		   (Num <= 199))
387 		return (int)PresetAlienProjectileData[Num - 101].DamageEM;
388 	else if ((Num >= 201) &&
389 		 (Num <= 299))
390 		return (int)PresetPirateProjectileData[Num - 201].DamageEM;
391 
392 	return 0;
393 }
394 
395 /*
396  * Get projectile speed.
397  */
GetProjectileSpeed(int Num)398 float GetProjectileSpeed(int Num)
399 {
400 	if ((Num >= 1) &&
401 	    (Num <= 99))
402 		return PresetEarthProjectileData[Num - 1].Speed;
403 	else if ((Num >= 101) &&
404 		 (Num <= 199))
405 		return PresetAlienProjectileData[Num - 101].Speed;
406 	else if ((Num >= 201) &&
407 		 (Num <= 299))
408 		return PresetPirateProjectileData[Num - 201].Speed;
409 
410 	return 0.0f;
411 }
412 
413 /*
414  * Setup gfx.
415  */
SetProjectileGFX(std::shared_ptr<cParticleSystem> & ParticleSystem,int GFXNum)416 static void SetProjectileGFX(std::shared_ptr<cParticleSystem> &ParticleSystem, int GFXNum)
417 {
418 	ParticleSystem->Texture = GetPreloadedTextureAsset("gfx/flare1.tga");
419 
420 	switch (GFXNum) {
421 	case 1: // Kinetic
422 		ParticleSystem->ColorStart.r = 1.00f;
423 		ParticleSystem->ColorStart.g = 0.70f;
424 		ParticleSystem->ColorStart.b = 0.30f;
425 		ParticleSystem->ColorEnd.r = 1.00f;
426 		ParticleSystem->ColorEnd.g = 0.00f;
427 		ParticleSystem->ColorEnd.b = 0.00f;
428 		ParticleSystem->AlphaStart = 1.00f;
429 		ParticleSystem->AlphaEnd   = 1.00f;
430 		ParticleSystem->SizeStart  = 0.30f;
431 		ParticleSystem->SizeVar    = 0.00f;
432 		ParticleSystem->SizeEnd    = 0.00f;
433 		ParticleSystem->Speed      = 1.00f;
434 		ParticleSystem->SpeedVar   = 0.00f;
435 		ParticleSystem->Theta      = 0.00f;
436 		ParticleSystem->Life       = 0.15f;
437 		ParticleSystem->ParticlesPerSec = 300;
438 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 1.0f, 0.35f, 0.15f, 0.0f, 0.2f);
439 		break;
440 
441 	case 2: // Kinetic
442 		ParticleSystem->ColorStart.r = 1.00f;
443 		ParticleSystem->ColorStart.g = 0.70f;
444 		ParticleSystem->ColorStart.b = 0.30f;
445 		ParticleSystem->ColorEnd.r = 1.00f;
446 		ParticleSystem->ColorEnd.g = 0.00f;
447 		ParticleSystem->ColorEnd.b = 0.00f;
448 		ParticleSystem->AlphaStart = 1.00f;
449 		ParticleSystem->AlphaEnd   = 1.00f;
450 		ParticleSystem->SizeStart  = 0.50f;
451 		ParticleSystem->SizeVar    = 0.00f;
452 		ParticleSystem->SizeEnd    = 0.00f;
453 		ParticleSystem->Speed      = 2.00f;
454 		ParticleSystem->SpeedVar   = 3.00f;
455 		ParticleSystem->Theta      = 360.00f;
456 		ParticleSystem->Life       = 0.30f;
457 		ParticleSystem->ParticlesPerSec = 200;
458 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 1.0f, 0.35f, 0.15f, 0.0f, 0.15f);
459 		break;
460 
461 	case 3: // Kinetic
462 		ParticleSystem->ColorStart.r = 1.00f;
463 		ParticleSystem->ColorStart.g = 0.70f;
464 		ParticleSystem->ColorStart.b = 0.30f;
465 		ParticleSystem->ColorEnd.r = 1.00f;
466 		ParticleSystem->ColorEnd.g = 0.00f;
467 		ParticleSystem->ColorEnd.b = 0.00f;
468 		ParticleSystem->AlphaStart = 1.00f;
469 		ParticleSystem->AlphaEnd   = 1.00f;
470 		ParticleSystem->SizeStart  = 0.60f;
471 		ParticleSystem->SizeVar    = 0.00f;
472 		ParticleSystem->SizeEnd    = 0.10f;
473 		ParticleSystem->Speed      = 2.00f;
474 		ParticleSystem->SpeedVar   = 3.00f;
475 		ParticleSystem->Theta      = 360.00f;
476 		ParticleSystem->Life       = 0.50f;
477 		ParticleSystem->ParticlesPerSec = 200;
478 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 1.0f, 0.35f, 0.15f, 0.0f, 0.1f);
479 		break;
480 
481 	case 4: // Kinetic
482 		ParticleSystem->ColorStart.r = 1.00f;
483 		ParticleSystem->ColorStart.g = 0.70f;
484 		ParticleSystem->ColorStart.b = 0.30f;
485 		ParticleSystem->ColorEnd.r = 1.00f;
486 		ParticleSystem->ColorEnd.g = 0.00f;
487 		ParticleSystem->ColorEnd.b = 0.00f;
488 		ParticleSystem->AlphaStart = 1.00f;
489 		ParticleSystem->AlphaEnd   = 1.00f;
490 		ParticleSystem->SizeStart  = 0.40f;
491 		ParticleSystem->SizeVar    = 0.00f;
492 		ParticleSystem->SizeEnd    = 0.00f;
493 		ParticleSystem->Speed      = 0.00f;
494 		ParticleSystem->SpeedVar   = 0.00f;
495 		ParticleSystem->Theta      = 0.00f;
496 		ParticleSystem->Life       = 0.20f;
497 		ParticleSystem->ParticlesPerSec = 300;
498 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 1.0f, 0.35f, 0.15f, 0.0f, 0.17f);
499 		break;
500 
501 	case 5: // Ion
502 		ParticleSystem->ColorStart.r = 0.70f;
503 		ParticleSystem->ColorStart.g = 1.00f;
504 		ParticleSystem->ColorStart.b = 0.70f;
505 		ParticleSystem->ColorEnd.r = 0.00f;
506 		ParticleSystem->ColorEnd.g = 0.00f;
507 		ParticleSystem->ColorEnd.b = 0.00f;
508 		ParticleSystem->AlphaStart = 1.00f;
509 		ParticleSystem->AlphaEnd   = 0.00f;
510 		ParticleSystem->SizeStart  = 0.20f;
511 		ParticleSystem->SizeVar    = 0.20f;
512 		ParticleSystem->SizeEnd    = 0.20f;
513 		ParticleSystem->Speed      = 0.00f;
514 		ParticleSystem->SpeedOnCreation	   = -1.00f;
515 		ParticleSystem->Theta      = 360.00f;
516 		ParticleSystem->Life       = 1.00f;
517 		ParticleSystem->ParticlesPerSec = 60;
518 		ParticleSystem->CreationType = eParticleCreationType::Sphere;
519 		ParticleSystem->CreationSize = sVECTOR3D{2.0f, 2.0f, 0.5f};
520 		ParticleSystem->DeadZone = 1.5f;
521 		ParticleSystem->AlphaShowHide = true;
522 		ParticleSystem->IsMagnet = true;
523 		ParticleSystem->MagnetFactor = 25.0f;
524 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.35f, 0.5f, 0.35f, 0.0f, 0.1f);
525 		break;
526 
527 	case 6: // Ion
528 		ParticleSystem->ColorStart.r = 0.70f;
529 		ParticleSystem->ColorStart.g = 1.00f;
530 		ParticleSystem->ColorStart.b = 0.70f;
531 		ParticleSystem->ColorEnd.r = 0.00f;
532 		ParticleSystem->ColorEnd.g = 0.00f;
533 		ParticleSystem->ColorEnd.b = 0.00f;
534 		ParticleSystem->AlphaStart = 1.00f;
535 		ParticleSystem->AlphaEnd   = 0.00f;
536 		ParticleSystem->SizeStart  = 0.50f;
537 		ParticleSystem->SizeVar    = 0.30f;
538 		ParticleSystem->SizeEnd    = 0.20f;
539 		ParticleSystem->Speed      = 0.00f;
540 		ParticleSystem->Theta      = 360.00f;
541 		ParticleSystem->Life       = 0.50f;
542 		ParticleSystem->ParticlesPerSec = 30;
543 		ParticleSystem->AlphaShowHide = true;
544 		ParticleSystem->IsMagnet = true;
545 		ParticleSystem->MagnetFactor = -20.0f;
546 		break;
547 
548 	case 7: // Plasma
549 		ParticleSystem->ColorStart.r = 0.00f;
550 		ParticleSystem->ColorStart.g = 0.50f;
551 		ParticleSystem->ColorStart.b = 1.00f;
552 		ParticleSystem->ColorEnd.r = 0.70f;
553 		ParticleSystem->ColorEnd.g = 1.00f;
554 		ParticleSystem->ColorEnd.b = 1.00f;
555 		ParticleSystem->AlphaStart = 1.00f;
556 		ParticleSystem->AlphaEnd   = 0.00f;
557 		ParticleSystem->SizeStart  = 0.50f;
558 		ParticleSystem->SizeVar    = 0.20f;
559 		ParticleSystem->SizeEnd    = 0.30f;
560 		ParticleSystem->Speed      = 6.40f;
561 		ParticleSystem->Theta      = 360.00f;
562 		ParticleSystem->Life       = 0.50f;
563 		ParticleSystem->ParticlesPerSec = 50;
564 		ParticleSystem->AlphaShowHide = true;
565 		ParticleSystem->IsMagnet = true;
566 		ParticleSystem->NeedStop = true;
567 		ParticleSystem->AlphaShowHide = true;
568 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.35f, 0.75f, 1.0f, 0.0f, 0.15f);
569 		break;
570 
571 	case 8: // Plasma
572 		ParticleSystem->ColorStart.r = 0.00f;
573 		ParticleSystem->ColorStart.g = 0.50f;
574 		ParticleSystem->ColorStart.b = 1.00f;
575 		ParticleSystem->ColorEnd.r = 0.70f;
576 		ParticleSystem->ColorEnd.g = 1.00f;
577 		ParticleSystem->ColorEnd.b = 1.00f;
578 		ParticleSystem->AlphaStart = 1.00f;
579 		ParticleSystem->AlphaEnd   = 0.00f;
580 		ParticleSystem->SizeStart  = 0.30f;
581 		ParticleSystem->SizeVar    = 0.10f;
582 		ParticleSystem->SizeEnd    = 0.10f;
583 		ParticleSystem->Speed      = 0.00f;
584 		ParticleSystem->Theta      = 360.00f;
585 		ParticleSystem->Life       = 0.80f;
586 		ParticleSystem->ParticlesPerSec = 50;
587 		ParticleSystem->CreationType = eParticleCreationType::Sphere;
588 		ParticleSystem->CreationSize = sVECTOR3D{1.3f, 1.3f, 0.2f};
589 		ParticleSystem->DeadZone = 1.2f;
590 		ParticleSystem->AlphaShowHide = true;
591 		ParticleSystem->IsMagnet = true;
592 		ParticleSystem->MagnetFactor = 2.0f;
593 		break;
594 
595 	case 9: // Plasma
596 		ParticleSystem->ColorStart.r = 0.00f;
597 		ParticleSystem->ColorStart.g = 0.50f;
598 		ParticleSystem->ColorStart.b = 1.00f;
599 		ParticleSystem->ColorEnd.r = 0.70f;
600 		ParticleSystem->ColorEnd.g = 1.00f;
601 		ParticleSystem->ColorEnd.b = 1.00f;
602 		ParticleSystem->AlphaStart = 1.00f;
603 		ParticleSystem->AlphaEnd   = 0.00f;
604 		ParticleSystem->SizeStart  = 0.30f;
605 		ParticleSystem->SizeVar    = 0.10f;
606 		ParticleSystem->SizeEnd    = 0.20f;
607 		ParticleSystem->Speed      = 0.00f;
608 		ParticleSystem->Theta      = 360.00f;
609 		ParticleSystem->Life       = 0.80f;
610 		ParticleSystem->ParticlesPerSec = 50;
611 		ParticleSystem->CreationType = eParticleCreationType::Sphere;
612 		ParticleSystem->CreationSize = sVECTOR3D{1.3f, 0.2f, 1.3f};
613 		ParticleSystem->DeadZone = 1.2f;
614 		ParticleSystem->AlphaShowHide = true;
615 		ParticleSystem->IsMagnet = true;
616 		ParticleSystem->MagnetFactor = 2.0f;
617 		break;
618 
619 	case 10: // Plasma
620 		ParticleSystem->ColorStart.r = 0.00f;
621 		ParticleSystem->ColorStart.g = 0.50f;
622 		ParticleSystem->ColorStart.b = 1.00f;
623 		ParticleSystem->ColorEnd.r = 0.70f;
624 		ParticleSystem->ColorEnd.g = 1.00f;
625 		ParticleSystem->ColorEnd.b = 1.00f;
626 		ParticleSystem->AlphaStart = 1.00f;
627 		ParticleSystem->AlphaEnd   = 0.00f;
628 		ParticleSystem->SizeStart  = 0.80f;
629 		ParticleSystem->SizeVar    = 0.20f;
630 		ParticleSystem->SizeEnd    = 0.10f;
631 		ParticleSystem->Speed      = 4.00f;
632 		ParticleSystem->Theta      = 360.00f;
633 		ParticleSystem->Life       = 0.50f;
634 		ParticleSystem->ParticlesPerSec = 30;
635 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.35f, 0.75f, 1.0f, 0.0f, 0.10f);
636 		break;
637 
638 	case 11: // Plasma
639 		ParticleSystem->ColorStart.r = 0.00f;
640 		ParticleSystem->ColorStart.g = 0.50f;
641 		ParticleSystem->ColorStart.b = 1.00f;
642 		ParticleSystem->ColorEnd.r = 0.70f;
643 		ParticleSystem->ColorEnd.g = 1.00f;
644 		ParticleSystem->ColorEnd.b = 1.00f;
645 		ParticleSystem->AlphaStart = 1.00f;
646 		ParticleSystem->AlphaEnd   = 1.00f;
647 		ParticleSystem->SizeStart  = 0.60f;
648 		ParticleSystem->SizeVar    = 0.00f;
649 		ParticleSystem->SizeEnd    = 0.10f;
650 		ParticleSystem->Speed      = 2.00f;
651 		ParticleSystem->SpeedVar   = 1.00f;
652 		ParticleSystem->Theta      = 360.00f;
653 		ParticleSystem->Life       = 0.20f;
654 		ParticleSystem->ParticlesPerSec = 150;
655 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.35f, 0.75f, 1.0f, 0.0f, 0.08f);
656 		break;
657 
658 	case 12: // Ion
659 		ParticleSystem->ColorStart.r = 0.70f;
660 		ParticleSystem->ColorStart.g = 1.00f;
661 		ParticleSystem->ColorStart.b = 0.70f;
662 		ParticleSystem->ColorEnd.r = 0.00f;
663 		ParticleSystem->ColorEnd.g = 0.00f;
664 		ParticleSystem->ColorEnd.b = 0.00f;
665 		ParticleSystem->AlphaStart = 1.00f;
666 		ParticleSystem->AlphaEnd   = 1.00f;
667 		ParticleSystem->SizeStart  = 0.40f;
668 		ParticleSystem->SizeVar    = 0.20f;
669 		ParticleSystem->SizeEnd    = 0.10f;
670 		ParticleSystem->Speed      = 2.00f;
671 		ParticleSystem->SpeedVar   = 1.00f;
672 		ParticleSystem->Theta      = 360.00f;
673 		ParticleSystem->Life       = 0.20f;
674 		ParticleSystem->ParticlesPerSec = 200;
675 		break;
676 
677 	case 13: // Missile
678 		ParticleSystem->ColorStart.r = 1.00f;
679 		ParticleSystem->ColorStart.g = 0.70f;
680 		ParticleSystem->ColorStart.b = 0.30f;
681 		ParticleSystem->ColorEnd.r = 1.00f;
682 		ParticleSystem->ColorEnd.g = 0.00f;
683 		ParticleSystem->ColorEnd.b = 0.00f;
684 		ParticleSystem->AlphaStart = 1.00f;
685 		ParticleSystem->AlphaEnd   = 0.00f;
686 		ParticleSystem->SizeStart  = 0.35f;
687 		ParticleSystem->SizeVar    = 0.00f;
688 		ParticleSystem->SizeEnd    = 0.00f;
689 		ParticleSystem->Speed      = 1.00f;
690 		ParticleSystem->SpeedVar   = 1.00f;
691 		ParticleSystem->Theta      = 360.00f;
692 		ParticleSystem->Life       = 0.40f;
693 		ParticleSystem->ParticlesPerSec = 250;
694 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 1.0f, 0.35f, 0.15f, 0.0f, 0.1f);
695 		break;
696 
697 	case 14: // Torpedo
698 		ParticleSystem->ColorStart.r = 0.70f;
699 		ParticleSystem->ColorStart.g = 1.00f;
700 		ParticleSystem->ColorStart.b = 0.30f;
701 		ParticleSystem->ColorEnd.r = 0.00f;
702 		ParticleSystem->ColorEnd.g = 1.00f;
703 		ParticleSystem->ColorEnd.b = 0.00f;
704 		ParticleSystem->AlphaStart = 1.00f;
705 		ParticleSystem->AlphaEnd   = 0.00f;
706 		ParticleSystem->SizeStart  = 0.35f;
707 		ParticleSystem->SizeVar    = 0.00f;
708 		ParticleSystem->SizeEnd    = 0.00f;
709 		ParticleSystem->Speed      = 1.00f;
710 		ParticleSystem->SpeedVar   = 1.00f;
711 		ParticleSystem->Theta      = 360.00f;
712 		ParticleSystem->Life       = 0.50f;
713 		ParticleSystem->ParticlesPerSec = 250;
714 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.35f, 1.0f, 0.15f, 0.0f, 0.075f);
715 		break;
716 
717 	case 15: // Nuke
718 		ParticleSystem->ColorStart.r = 0.30f;
719 		ParticleSystem->ColorStart.g = 0.70f;
720 		ParticleSystem->ColorStart.b = 1.00f;
721 		ParticleSystem->ColorEnd.r = 0.00f;
722 		ParticleSystem->ColorEnd.g = 0.00f;
723 		ParticleSystem->ColorEnd.b = 1.00f;
724 		ParticleSystem->AlphaStart = 1.00f;
725 		ParticleSystem->AlphaEnd   = 0.00f;
726 		ParticleSystem->SizeStart  = 0.40f;
727 		ParticleSystem->SizeVar    = 0.00f;
728 		ParticleSystem->SizeEnd    = 0.00f;
729 		ParticleSystem->Speed      = 1.00f;
730 		ParticleSystem->SpeedVar   = 1.00f;
731 		ParticleSystem->Theta      = 360.00f;
732 		ParticleSystem->Life       = 0.50f;
733 		ParticleSystem->ParticlesPerSec = 250;
734 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.15f, 0.35f, 1.0f, 0.0f, 0.05f);
735 		break;
736 
737 	case 16: // Swarm
738 		ParticleSystem->ColorStart.r = 1.00f;
739 		ParticleSystem->ColorStart.g = 0.70f;
740 		ParticleSystem->ColorStart.b = 0.30f;
741 		ParticleSystem->ColorEnd.r = 1.00f;
742 		ParticleSystem->ColorEnd.g = 0.00f;
743 		ParticleSystem->ColorEnd.b = 0.00f;
744 		ParticleSystem->AlphaStart = 1.00f;
745 		ParticleSystem->AlphaEnd   = 0.00f;
746 		ParticleSystem->SizeStart  = 0.25f;
747 		ParticleSystem->SizeVar    = 0.00f;
748 		ParticleSystem->SizeEnd    = 0.00f;
749 		ParticleSystem->Speed      = 1.00f;
750 		ParticleSystem->SpeedVar   = 1.00f;
751 		ParticleSystem->Theta      = 360.00f;
752 		ParticleSystem->Life       = 0.30f;
753 		ParticleSystem->ParticlesPerSec = 250;
754 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 1.0f, 0.35f, 0.15f, 0.0f, 0.2f);
755 		break;
756 
757 	case 17: // maser
758 		ParticleSystem->ColorStart.r = 0.00f;
759 		ParticleSystem->ColorStart.g = 1.00f;
760 		ParticleSystem->ColorStart.b = 0.00f;
761 		ParticleSystem->ColorEnd.r = 0.00f;
762 		ParticleSystem->ColorEnd.g = 1.00f;
763 		ParticleSystem->ColorEnd.b = 0.00f;
764 		ParticleSystem->AlphaStart = 1.00f;
765 		ParticleSystem->AlphaEnd   = 0.00f;
766 		ParticleSystem->SizeStart  = 0.40f;
767 		ParticleSystem->SizeVar    = 0.10f;
768 		ParticleSystem->SizeEnd    = 0.00f;
769 		ParticleSystem->Speed      = 0.00f;
770 		ParticleSystem->Theta      = 360.00f;
771 		ParticleSystem->Life       = 1.00f;
772 		ParticleSystem->ParticlesPerSec = 600;
773 		ParticleSystem->CreationType = eParticleCreationType::Tube;
774 		ParticleSystem->CreationSize = sVECTOR3D{0.4f, 0.4f, 0.2f};
775 		ParticleSystem->AlphaShowHide = true;
776 		break;
777 
778 	case 18: // maser2
779 		ParticleSystem->ColorStart.r = 1.00f;
780 		ParticleSystem->ColorStart.g = 1.00f;
781 		ParticleSystem->ColorStart.b = 0.00f;
782 		ParticleSystem->ColorEnd.r = 1.00f;
783 		ParticleSystem->ColorEnd.g = 1.00f;
784 		ParticleSystem->ColorEnd.b = 0.00f;
785 		ParticleSystem->AlphaStart = 1.00f;
786 		ParticleSystem->AlphaEnd   = 0.00f;
787 		ParticleSystem->SizeStart  = 0.40f;
788 		ParticleSystem->SizeVar    = 0.10f;
789 		ParticleSystem->SizeEnd    = 0.00f;
790 		ParticleSystem->Speed      = 0.00f;
791 		ParticleSystem->Theta      = 360.00f;
792 		ParticleSystem->Life       = 1.00f;
793 		ParticleSystem->ParticlesPerSec = 400;
794 		ParticleSystem->CreationType = eParticleCreationType::Tube;
795 		ParticleSystem->CreationSize = sVECTOR3D{0.8f, 0.8f, 0.2f};
796 		ParticleSystem->AlphaShowHide = true;
797 		break;
798 
799 	case 19: // Antimatter
800 		ParticleSystem->ColorStart.r = 0.50f;
801 		ParticleSystem->ColorStart.g = 1.00f;
802 		ParticleSystem->ColorStart.b = 0.00f;
803 		ParticleSystem->ColorEnd.r = 0.50f;
804 		ParticleSystem->ColorEnd.g = 1.00f;
805 		ParticleSystem->ColorEnd.b = 0.00f;
806 		ParticleSystem->AlphaStart = 1.00f;
807 		ParticleSystem->AlphaEnd   = 1.00f;
808 		ParticleSystem->SizeStart  = 0.30f;
809 		ParticleSystem->SizeVar    = 0.10f;
810 		ParticleSystem->SizeEnd    = 0.10f;
811 		ParticleSystem->Speed      = 0.00f;
812 		ParticleSystem->Theta      = 360.00f;
813 		ParticleSystem->Life       = 1.00f;
814 		ParticleSystem->ParticlesPerSec = 100;
815 		ParticleSystem->CreationType = eParticleCreationType::Sphere;
816 		ParticleSystem->CreationSize = sVECTOR3D{0.8f, 0.1f, 0.8f};
817 		ParticleSystem->AlphaShowHide = true;
818 		ParticleSystem->IsMagnet = true;
819 		ParticleSystem->MagnetFactor = -20.0f;
820 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.5f, 1.0f, 0.0f, 0.0f, 0.05f);
821 		break;
822 
823 	case 20: // Laser
824 		ParticleSystem->ColorStart.r = 1.00f;
825 		ParticleSystem->ColorStart.g = 1.00f;
826 		ParticleSystem->ColorStart.b = 0.00f;
827 		ParticleSystem->ColorEnd.r = 1.00f;
828 		ParticleSystem->ColorEnd.g = 1.00f;
829 		ParticleSystem->ColorEnd.b = 0.00f;
830 		ParticleSystem->AlphaStart = 1.00f;
831 		ParticleSystem->AlphaEnd   = 0.00f;
832 		ParticleSystem->SizeStart  = 0.20f;
833 		ParticleSystem->SizeVar    = 0.05f;
834 		ParticleSystem->SizeEnd    = 0.20f;
835 		ParticleSystem->Speed      = 0.00f;
836 		ParticleSystem->Theta      = 360.00f;
837 		ParticleSystem->Life       = 0.20f;
838 		ParticleSystem->ParticlesPerSec = 3000;
839 		ParticleSystem->CreationType = eParticleCreationType::Tube;
840 		ParticleSystem->CreationSize = sVECTOR3D{0.2f, 0.2f, 0.1f};
841 		break;
842 
843 	case 21: // Antimatter
844 		ParticleSystem->ColorStart.r = 1.00f;
845 		ParticleSystem->ColorStart.g = 0.50f;
846 		ParticleSystem->ColorStart.b = 0.00f;
847 		ParticleSystem->ColorEnd.r = 1.00f;
848 		ParticleSystem->ColorEnd.g = 0.50f;
849 		ParticleSystem->ColorEnd.b = 0.00f;
850 		ParticleSystem->AlphaStart = 1.00f;
851 		ParticleSystem->AlphaEnd   = 1.00f;
852 		ParticleSystem->SizeStart  = 0.20f;
853 		ParticleSystem->SizeVar    = 0.10f;
854 		ParticleSystem->SizeEnd    = 0.30f;
855 		ParticleSystem->Speed      = 1.00f;
856 		ParticleSystem->Theta      = 360.00f;
857 		ParticleSystem->Life       = 0.50f;
858 		ParticleSystem->ParticlesPerSec = 150;
859 		ParticleSystem->CreationType = eParticleCreationType::Sphere;
860 		ParticleSystem->CreationSize = sVECTOR3D{1.0f, 1.0f, 0.1f};
861 		ParticleSystem->IsMagnet = true;
862 		ParticleSystem->MagnetFactor = -40.0f;
863 		break;
864 
865 	case 22: // alien weapon 1
866 		ParticleSystem->ColorStart.r = 0.00f;
867 		ParticleSystem->ColorStart.g = 0.70f;
868 		ParticleSystem->ColorStart.b = 1.00f;
869 		ParticleSystem->ColorEnd.r = 0.70f;
870 		ParticleSystem->ColorEnd.g = 1.00f;
871 		ParticleSystem->ColorEnd.b = 1.00f;
872 		ParticleSystem->AlphaStart = 1.00f;
873 		ParticleSystem->AlphaEnd   = 1.00f;
874 		ParticleSystem->SizeStart  = 0.30f;
875 		ParticleSystem->SizeVar    = 0.00f;
876 		ParticleSystem->SizeEnd    = 0.00f;
877 		ParticleSystem->Speed      = 1.00f;
878 		ParticleSystem->SpeedVar   = 0.00f;
879 		ParticleSystem->Theta      = 0.00f;
880 		ParticleSystem->Life       = 0.15f;
881 		ParticleSystem->ParticlesPerSec = 300;
882 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.35f, 0.85f, 1.0f, 0.0f, 0.2f);
883 		break;
884 
885 	case 23: // alien weapon 2
886 		ParticleSystem->ColorStart.r = 0.00f;
887 		ParticleSystem->ColorStart.g = 0.70f;
888 		ParticleSystem->ColorStart.b = 1.00f;
889 		ParticleSystem->ColorEnd.r = 0.70f;
890 		ParticleSystem->ColorEnd.g = 1.00f;
891 		ParticleSystem->ColorEnd.b = 1.00f;
892 		ParticleSystem->AlphaStart = 1.00f;
893 		ParticleSystem->AlphaEnd   = 1.00f;
894 		ParticleSystem->SizeStart  = 0.50f;
895 		ParticleSystem->SizeVar    = 0.00f;
896 		ParticleSystem->SizeEnd    = 0.00f;
897 		ParticleSystem->Speed      = 2.00f;
898 		ParticleSystem->SpeedVar   = 3.00f;
899 		ParticleSystem->Theta      = 360.00f;
900 		ParticleSystem->Life       = 0.30f;
901 		ParticleSystem->ParticlesPerSec = 200;
902 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.35f, 0.85f, 1.0f, 0.0f, 0.1f);
903 		break;
904 
905 	case 24: // alien weapon 2
906 		ParticleSystem->ColorStart.r = 0.00f;
907 		ParticleSystem->ColorStart.g = 0.70f;
908 		ParticleSystem->ColorStart.b = 1.00f;
909 		ParticleSystem->ColorEnd.r = 0.70f;
910 		ParticleSystem->ColorEnd.g = 1.00f;
911 		ParticleSystem->ColorEnd.b = 1.00f;
912 		ParticleSystem->AlphaStart = 1.00f;
913 		ParticleSystem->AlphaEnd   = 1.00f;
914 		ParticleSystem->SizeStart  = 0.60f;
915 		ParticleSystem->SizeVar    = 0.00f;
916 		ParticleSystem->SizeEnd    = 0.10f;
917 		ParticleSystem->Speed      = 2.00f;
918 		ParticleSystem->SpeedVar   = 3.00f;
919 		ParticleSystem->Theta      = 360.00f;
920 		ParticleSystem->Life       = 0.50f;
921 		ParticleSystem->ParticlesPerSec = 200;
922 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.35f, 0.85f, 1.0f, 0.0f, 0.1f);
923 		break;
924 
925 	case 25: // flares
926 		ParticleSystem->ColorStart.r = 1.00f;
927 		ParticleSystem->ColorStart.g = 0.50f;
928 		ParticleSystem->ColorStart.b = 0.10f;
929 		ParticleSystem->ColorEnd.r = 0.00f;
930 		ParticleSystem->ColorEnd.g = 0.00f;
931 		ParticleSystem->ColorEnd.b = 0.00f;
932 		ParticleSystem->AlphaStart = 1.00f;
933 		ParticleSystem->AlphaEnd   = 0.00f;
934 		ParticleSystem->SizeStart  = 1.00f;
935 		ParticleSystem->SizeVar    = 0.50f;
936 		ParticleSystem->SizeEnd    = 0.00f;
937 		ParticleSystem->Speed      = 0.00f;
938 		ParticleSystem->SpeedOnCreation	   = -1.00f;
939 		ParticleSystem->Theta      = 360.00f;
940 		ParticleSystem->Life       = 0.50f;
941 		ParticleSystem->ParticlesPerSec = 200;
942 		ParticleSystem->CreationType = eParticleCreationType::Sphere;
943 		ParticleSystem->CreationSize = sVECTOR3D{4.0f, 4.0f, 4.0f};
944 		ParticleSystem->Texture = GetPreloadedTextureAsset("gfx/flare.tga");
945 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.5f, 0.25f, 0.05f, 0.0f, 0.05f);
946 		break;
947 
948 	case 26: // pirate 1, like Kinetic
949 		ParticleSystem->ColorStart.r = 0.60f;
950 		ParticleSystem->ColorStart.g = 0.60f;
951 		ParticleSystem->ColorStart.b = 0.30f;
952 		ParticleSystem->ColorEnd.r = 0.30f;
953 		ParticleSystem->ColorEnd.g = 1.00f;
954 		ParticleSystem->ColorEnd.b = 0.30f;
955 		ParticleSystem->AlphaStart = 1.00f;
956 		ParticleSystem->AlphaEnd   = 1.00f;
957 		ParticleSystem->SizeStart  = 0.30f;
958 		ParticleSystem->SizeVar    = 0.00f;
959 		ParticleSystem->SizeEnd    = 0.00f;
960 		ParticleSystem->Speed      = 1.00f;
961 		ParticleSystem->SpeedVar   = 0.00f;
962 		ParticleSystem->Theta      = 0.00f;
963 		ParticleSystem->Life       = 0.15f;
964 		ParticleSystem->ParticlesPerSec = 300;
965 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.45f, 0.8f, 0.3f, 0.0f, 0.2f);
966 		break;
967 
968 	case 27: // pirate 2, like Kinetic
969 		ParticleSystem->ColorStart.r = 0.60f;
970 		ParticleSystem->ColorStart.g = 0.60f;
971 		ParticleSystem->ColorStart.b = 0.30f;
972 		ParticleSystem->ColorEnd.r = 0.30f;
973 		ParticleSystem->ColorEnd.g = 1.00f;
974 		ParticleSystem->ColorEnd.b = 0.30f;
975 		ParticleSystem->AlphaStart = 1.00f;
976 		ParticleSystem->AlphaEnd   = 0.00f;
977 		ParticleSystem->SizeStart  = 0.35f;
978 		ParticleSystem->SizeVar    = 0.00f;
979 		ParticleSystem->SizeEnd    = 0.00f;
980 		ParticleSystem->Speed      = 1.00f;
981 		ParticleSystem->SpeedVar   = 1.00f;
982 		ParticleSystem->Theta      = 360.00f;
983 		ParticleSystem->Life       = 0.40f;
984 		ParticleSystem->ParticlesPerSec = 250;
985 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.45f, 0.8f, 0.3f, 0.0f, 0.1f);
986 		break;
987 
988 	case 28: // mine 2
989 		ParticleSystem->ColorStart.r = 1.00f;
990 		ParticleSystem->ColorStart.g = 0.70f;
991 		ParticleSystem->ColorStart.b = 0.30f;
992 		ParticleSystem->ColorEnd.r = 1.00f;
993 		ParticleSystem->ColorEnd.g = 0.00f;
994 		ParticleSystem->ColorEnd.b = 0.00f;
995 		ParticleSystem->AlphaStart = 1.00f;
996 		ParticleSystem->AlphaEnd   = 0.00f;
997 		ParticleSystem->SizeStart  = 0.30f;
998 		ParticleSystem->SizeVar    = 0.20f;
999 		ParticleSystem->SizeEnd    = 0.10f;
1000 		ParticleSystem->Speed      = 3.00f;
1001 		ParticleSystem->SpeedOnCreation	   = -1.00f;
1002 		ParticleSystem->SpeedVar   = 2.00f;
1003 		ParticleSystem->Theta      = 180.00f;
1004 		ParticleSystem->Life       = 0.50f;
1005 		ParticleSystem->ParticlesPerSec = 100;
1006 		ParticleSystem->AlphaShowHide= true;
1007 		ParticleSystem->Direction = sVECTOR3D{0.0f, -1.0f, 0.0f};
1008 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 1.0f, 0.35f, 0.15f, 0.0f, 0.2f);
1009 		break;
1010 
1011 	case 29: // mine 3
1012 		ParticleSystem->ColorStart.r = 1.00f;
1013 		ParticleSystem->ColorStart.g = 0.70f;
1014 		ParticleSystem->ColorStart.b = 0.30f;
1015 		ParticleSystem->ColorEnd.r = 1.00f;
1016 		ParticleSystem->ColorEnd.g = 0.00f;
1017 		ParticleSystem->ColorEnd.b = 0.00f;
1018 		ParticleSystem->AlphaStart = 1.00f;
1019 		ParticleSystem->AlphaEnd   = 0.00f;
1020 		ParticleSystem->SizeStart  = 0.30f;
1021 		ParticleSystem->SizeVar    = 0.20f;
1022 		ParticleSystem->SizeEnd    = 0.10f;
1023 		ParticleSystem->Speed      = 3.00f;
1024 		ParticleSystem->SpeedOnCreation	   = -1.00f;
1025 		ParticleSystem->SpeedVar   = 2.00f;
1026 		ParticleSystem->Theta      = 60.00f;
1027 		ParticleSystem->Life       = 0.50f;
1028 		ParticleSystem->ParticlesPerSec = 100;
1029 		ParticleSystem->AlphaShowHide= true;
1030 		ParticleSystem->Direction = sVECTOR3D{0.0f, -1.0f, 0.0f};
1031 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 1.0f, 0.35f, 0.15f, 0.0f, 0.15f);
1032 		break;
1033 
1034 	case 30: // mine 4
1035 		ParticleSystem->ColorStart.r = 1.00f;
1036 		ParticleSystem->ColorStart.g = 0.70f;
1037 		ParticleSystem->ColorStart.b = 0.30f;
1038 		ParticleSystem->ColorEnd.r = 1.00f;
1039 		ParticleSystem->ColorEnd.g = 0.00f;
1040 		ParticleSystem->ColorEnd.b = 0.00f;
1041 		ParticleSystem->AlphaStart = 1.00f;
1042 		ParticleSystem->AlphaEnd   = 0.00f;
1043 		ParticleSystem->SizeStart  = 0.30f;
1044 		ParticleSystem->SizeVar    = 0.20f;
1045 		ParticleSystem->SizeEnd    = 0.10f;
1046 		ParticleSystem->Speed      = 3.00f;
1047 		ParticleSystem->SpeedOnCreation	   = -1.00f;
1048 		ParticleSystem->SpeedVar   = 2.00f;
1049 		ParticleSystem->Theta      = 180.00f;
1050 		ParticleSystem->Life       = 0.50f;
1051 		ParticleSystem->ParticlesPerSec = 150;
1052 		ParticleSystem->AlphaShowHide= true;
1053 		ParticleSystem->CreationType = eParticleCreationType::Sphere;
1054 		ParticleSystem->CreationSize = sVECTOR3D{1.5f, 0.1f, 1.5f};
1055 		ParticleSystem->Direction = sVECTOR3D{0.0f, -1.0f, 0.0f};
1056 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 1.0f, 0.35f, 0.15f, 0.0f, 0.1f);
1057 		break;
1058 
1059 	case 31: // pirate missile swarm
1060 		ParticleSystem->ColorStart.r = 0.60f;
1061 		ParticleSystem->ColorStart.g = 0.60f;
1062 		ParticleSystem->ColorStart.b = 0.30f;
1063 		ParticleSystem->ColorEnd.r = 0.30f;
1064 		ParticleSystem->ColorEnd.g = 1.00f;
1065 		ParticleSystem->ColorEnd.b = 0.30f;
1066 		ParticleSystem->AlphaStart = 1.00f;
1067 		ParticleSystem->AlphaEnd   = 0.00f;
1068 		ParticleSystem->SizeStart  = 0.25f;
1069 		ParticleSystem->SizeVar    = 0.00f;
1070 		ParticleSystem->SizeEnd    = 0.00f;
1071 		ParticleSystem->Speed      = 1.00f;
1072 		ParticleSystem->SpeedVar   = 1.00f;
1073 		ParticleSystem->Theta      = 360.00f;
1074 		ParticleSystem->Life       = 0.30f;
1075 		ParticleSystem->ParticlesPerSec = 250;
1076 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.45f, 0.8f, 0.3f, 0.0f, 0.2f);
1077 		break;
1078 
1079 	case 32: // pirate torpedo
1080 		ParticleSystem->ColorStart.r = 0.70f;
1081 		ParticleSystem->ColorStart.g = 1.00f;
1082 		ParticleSystem->ColorStart.b = 0.30f;
1083 		ParticleSystem->ColorEnd.r = 0.00f;
1084 		ParticleSystem->ColorEnd.g = 1.00f;
1085 		ParticleSystem->ColorEnd.b = 0.00f;
1086 		ParticleSystem->AlphaStart = 1.00f;
1087 		ParticleSystem->AlphaEnd   = 0.00f;
1088 		ParticleSystem->SizeStart  = 0.35f;
1089 		ParticleSystem->SizeVar    = 0.00f;
1090 		ParticleSystem->SizeEnd    = 0.00f;
1091 		ParticleSystem->Speed      = 1.00f;
1092 		ParticleSystem->SpeedVar   = 1.00f;
1093 		ParticleSystem->Theta      = 360.00f;
1094 		ParticleSystem->Life       = 0.50f;
1095 		ParticleSystem->ParticlesPerSec = 250;
1096 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.35f, 1.0f, 0.15f, 0.0f, 0.075f);
1097 		break;
1098 
1099 	case 33: // pirate bomb
1100 		ParticleSystem->ColorStart.r = 0.30f;
1101 		ParticleSystem->ColorStart.g = 0.70f;
1102 		ParticleSystem->ColorStart.b = 1.00f;
1103 		ParticleSystem->ColorEnd.r = 0.00f;
1104 		ParticleSystem->ColorEnd.g = 0.00f;
1105 		ParticleSystem->ColorEnd.b = 1.00f;
1106 		ParticleSystem->AlphaStart = 1.00f;
1107 		ParticleSystem->AlphaEnd   = 0.00f;
1108 		ParticleSystem->SizeStart  = 0.40f;
1109 		ParticleSystem->SizeVar    = 0.00f;
1110 		ParticleSystem->SizeEnd    = 0.00f;
1111 		ParticleSystem->Speed      = 1.00f;
1112 		ParticleSystem->SpeedVar   = 1.00f;
1113 		ParticleSystem->Theta      = 360.00f;
1114 		ParticleSystem->Life       = 0.50f;
1115 		ParticleSystem->ParticlesPerSec = 250;
1116 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.15f, 0.35f, 1.0f, 0.0f, 0.05f);
1117 		break;
1118 
1119 	case 34: // pirate, like Kinetic2
1120 		ParticleSystem->ColorStart.r = 0.60f;
1121 		ParticleSystem->ColorStart.g = 0.60f;
1122 		ParticleSystem->ColorStart.b = 0.30f;
1123 		ParticleSystem->ColorEnd.r = 0.30f;
1124 		ParticleSystem->ColorEnd.g = 1.00f;
1125 		ParticleSystem->ColorEnd.b = 0.30f;
1126 		ParticleSystem->AlphaStart = 1.00f;
1127 		ParticleSystem->AlphaEnd   = 1.00f;
1128 		ParticleSystem->SizeStart  = 0.50f;
1129 		ParticleSystem->SizeVar    = 0.00f;
1130 		ParticleSystem->SizeEnd    = 0.00f;
1131 		ParticleSystem->Speed      = 2.00f;
1132 		ParticleSystem->SpeedVar   = 3.00f;
1133 		ParticleSystem->Theta      = 360.00f;
1134 		ParticleSystem->Life       = 0.30f;
1135 		ParticleSystem->ParticlesPerSec = 200;
1136 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.45f, 0.8f, 0.3f, 0.0f, 0.15f);
1137 		break;
1138 
1139 	case 35: // pirate, like Kinetic3
1140 		ParticleSystem->ColorStart.r = 0.60f;
1141 		ParticleSystem->ColorStart.g = 0.60f;
1142 		ParticleSystem->ColorStart.b = 0.30f;
1143 		ParticleSystem->ColorEnd.r = 0.30f;
1144 		ParticleSystem->ColorEnd.g = 1.00f;
1145 		ParticleSystem->ColorEnd.b = 0.30f;
1146 		ParticleSystem->AlphaStart = 1.00f;
1147 		ParticleSystem->AlphaEnd   = 1.00f;
1148 		ParticleSystem->SizeStart  = 0.60f;
1149 		ParticleSystem->SizeVar    = 0.00f;
1150 		ParticleSystem->SizeEnd    = 0.10f;
1151 		ParticleSystem->Speed      = 2.00f;
1152 		ParticleSystem->SpeedVar   = 3.00f;
1153 		ParticleSystem->Theta      = 360.00f;
1154 		ParticleSystem->Life       = 0.50f;
1155 		ParticleSystem->ParticlesPerSec = 200;
1156 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.45f, 0.8f, 0.3f, 0.0f, 0.1f);
1157 		break;
1158 
1159 	case 36: // alien, energy mine 1
1160 		ParticleSystem->ColorStart.r = 0.00f;
1161 		ParticleSystem->ColorStart.g = 0.70f;
1162 		ParticleSystem->ColorStart.b = 1.00f;
1163 		ParticleSystem->ColorEnd.r = 0.70f;
1164 		ParticleSystem->ColorEnd.g = 1.00f;
1165 		ParticleSystem->ColorEnd.b = 1.00f;
1166 		ParticleSystem->AlphaStart = 1.00f;
1167 		ParticleSystem->AlphaEnd   = 1.00f;
1168 		ParticleSystem->SizeStart  = 0.01f;
1169 		ParticleSystem->SizeVar    = 0.02f;
1170 		ParticleSystem->SizeEnd    = 0.40f;
1171 		ParticleSystem->Speed      = 0.00f;
1172 		ParticleSystem->SpeedOnCreation	   = -1.00f;
1173 		ParticleSystem->Theta      = 360.00f;
1174 		ParticleSystem->Life       = 0.40f;
1175 		ParticleSystem->ParticlesPerSec = 200;
1176 		ParticleSystem->CreationType = eParticleCreationType::Sphere;
1177 		ParticleSystem->CreationSize = sVECTOR3D{2.0, 2.0f, 2.0f};
1178 		ParticleSystem->DeadZone = 1.9f;
1179 		ParticleSystem->IsMagnet = true;
1180 		ParticleSystem->MagnetFactor = 25.0f;
1181 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.35f, 0.75f, 1.0f, 0.0f, 0.1f);
1182 		break;
1183 
1184 	case 37: // alien, energy mine 2
1185 		ParticleSystem->ColorStart.r = 1.00f;
1186 		ParticleSystem->ColorStart.g = 0.20f;
1187 		ParticleSystem->ColorStart.b = 0.20f;
1188 		ParticleSystem->ColorEnd.r = 1.00f;
1189 		ParticleSystem->ColorEnd.g = 0.20f;
1190 		ParticleSystem->ColorEnd.b = 0.20f;
1191 		ParticleSystem->AlphaStart = 1.00f;
1192 		ParticleSystem->AlphaEnd   = 1.00f;
1193 		ParticleSystem->SizeStart  = 0.3f;
1194 		ParticleSystem->SizeVar    = 0.02f;
1195 		ParticleSystem->SizeEnd    = 0.1f;
1196 		ParticleSystem->Speed      = 0.00f;
1197 		ParticleSystem->SpeedOnCreation	   = -1.00f;
1198 		ParticleSystem->Theta      = 360.00f;
1199 		ParticleSystem->Life       = 0.40f;
1200 		ParticleSystem->ParticlesPerSec = 200;
1201 		ParticleSystem->CreationType = eParticleCreationType::Sphere;
1202 		ParticleSystem->CreationSize = sVECTOR3D{2.0, 0.2f, 2.0f};
1203 		ParticleSystem->DeadZone = 1.9f;
1204 		ParticleSystem->IsMagnet = true;
1205 		ParticleSystem->MagnetFactor = 2.0f;
1206 		ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 1.0f, 0.2f, 0.2f, 0.0f, 0.1f);
1207 		break;
1208 
1209 	case 38: // alien mothership, Laser
1210 		ParticleSystem->ColorStart.r = 1.00f;
1211 		ParticleSystem->ColorStart.g = 1.00f;
1212 		ParticleSystem->ColorStart.b = 0.30f;
1213 		ParticleSystem->ColorEnd.r = 1.00f;
1214 		ParticleSystem->ColorEnd.g = 0.30f;
1215 		ParticleSystem->ColorEnd.b = 0.00f;
1216 		ParticleSystem->AlphaStart = 1.00f;
1217 		ParticleSystem->AlphaEnd   = 0.00f;
1218 		ParticleSystem->SizeStart  = 0.40f;
1219 		ParticleSystem->SizeVar    = 0.05f;
1220 		ParticleSystem->SizeEnd    = 0.20f;
1221 		ParticleSystem->Speed      = 0.00f;
1222 		ParticleSystem->Theta      = 360.00f;
1223 		ParticleSystem->Life       = 0.20f;
1224 		ParticleSystem->ParticlesPerSec = 9000;
1225 		ParticleSystem->CreationType = eParticleCreationType::Tube;
1226 		ParticleSystem->CreationSize = sVECTOR3D{0.2f, 0.2f, 0.1f};
1227 		ParticleSystem->AlphaShowHide = true;
1228 		break;
1229 
1230 	case 101: // earth/pirate missile trail
1231 		ParticleSystem->Texture = GetPreloadedTextureAsset(MissileTrailTextures[vw_uRandNum(4)]);
1232 		ParticleSystem->ColorStart.r = 1.00f;
1233 		ParticleSystem->ColorStart.g = 1.00f;
1234 		ParticleSystem->ColorStart.b = 1.00f;
1235 		ParticleSystem->ColorEnd.r = 1.00f;
1236 		ParticleSystem->ColorEnd.g = 1.00f;
1237 		ParticleSystem->ColorEnd.b = 1.00f;
1238 		ParticleSystem->AlphaStart = 0.06f;
1239 		ParticleSystem->AlphaEnd   = 0.00f;
1240 		ParticleSystem->SizeStart  = 0.20f;
1241 		ParticleSystem->SizeVar    = 0.20f;
1242 		ParticleSystem->SizeEnd    = 2.50f;
1243 		ParticleSystem->Speed      = 0.20f;
1244 		ParticleSystem->SpeedVar   = 0.30f;
1245 		ParticleSystem->Theta      = 360.00f;
1246 		ParticleSystem->Life       = 5.00f;
1247 		ParticleSystem->LifeVar    = 5.00f;
1248 		ParticleSystem->ParticlesPerSec = 150;
1249 		ParticleSystem->TextureBlend = true;
1250 		break;
1251 
1252 	case 102: // alien missile trail
1253 		ParticleSystem->Texture = GetPreloadedTextureAsset(MissileTrailTextures[vw_uRandNum(4)]);
1254 		ParticleSystem->ColorStart.r = 0.00f;
1255 		ParticleSystem->ColorStart.g = 0.70f;
1256 		ParticleSystem->ColorStart.b = 1.00f;
1257 		ParticleSystem->ColorEnd.r = 0.00f;
1258 		ParticleSystem->ColorEnd.g = 0.70f;
1259 		ParticleSystem->ColorEnd.b = 1.00f;
1260 		ParticleSystem->AlphaStart = 0.08f;
1261 		ParticleSystem->AlphaEnd   = 0.00f;
1262 		ParticleSystem->SizeStart  = 0.20f;
1263 		ParticleSystem->SizeVar    = 0.10f;
1264 		ParticleSystem->SizeEnd    = 2.00f;
1265 		ParticleSystem->Speed      = 0.20f;
1266 		ParticleSystem->SpeedVar   = 0.30f;
1267 		ParticleSystem->Theta      = 360.00f;
1268 		ParticleSystem->Life       = 5.00f;
1269 		ParticleSystem->LifeVar    = 5.00f;
1270 		ParticleSystem->ParticlesPerSec = 100;
1271 		ParticleSystem->TextureBlend = true;
1272 		break;
1273 
1274 	default:
1275 		std::cerr << __func__ << "(): " << "wrong GFXNum.\n";
1276 		break;
1277 	}
1278 }
1279 
1280 /*
1281  * Constructor.
1282  */
cProjectile(const int ProjectileNum)1283 cProjectile::cProjectile(const int ProjectileNum)
1284 {
1285 	ObjectStatus = eObjectStatus::Ally;
1286 	ObjectType = eObjectType::Projectile;
1287 
1288 	Radius = 0.0f;
1289 
1290 	Ambient[0] = Ambient[1] = Ambient[2] = Ambient[3] = 0.35f;
1291 
1292 	if (ProjectileNum <= 0) {
1293 		std::cerr << __func__ << "(): " << "Could not init cProjectile object with Number "
1294 			  << ProjectileNum << "\n";
1295 		return;
1296 	} else if ((ProjectileNum >= 1) &&
1297 		   (ProjectileNum <= 99) &&
1298 		   ((unsigned int)ProjectileNum > PresetEarthProjectileData.size())) {
1299 		std::cerr << __func__ << "(): " << "Could not init cProjectile(1) object with Number "
1300 			  << ProjectileNum << "\n";
1301 		return;
1302 	} else if ((ProjectileNum >= 101) &&
1303 		   (ProjectileNum <= 199) &&
1304 		   ((unsigned int)ProjectileNum - 100 > PresetAlienProjectileData.size())) {
1305 		std::cerr << __func__ << "(): " << "Could not init cProjectile(2) object with Number "
1306 			  << ProjectileNum << "\n";
1307 		return;
1308 	} else if ((ProjectileNum >= 201) &&
1309 		   (ProjectileNum <= 299) &&
1310 		   ((unsigned int)ProjectileNum-200 > PresetPirateProjectileData.size())) {
1311 		std::cerr << __func__ << "(): " << "Could not init cProjectile(3) object with Number "
1312 			  << ProjectileNum << "\n";
1313 		return;
1314 	}
1315 
1316 	Num = ProjectileNum;
1317 
1318 	int IntNum = ProjectileNum;
1319 	int GraphicFXQuantity{0};
1320 
1321 	if ((Num >= 1) &&
1322 	    (Num <= 99)) {
1323 		Radius = PresetEarthProjectileData[IntNum - 1].Radius;
1324 		Damage.Kinetic() = PresetEarthProjectileData[IntNum - 1].DamageKinetic;
1325 		Damage.EM() = PresetEarthProjectileData[IntNum - 1].DamageEM;
1326 		ProjectileType = PresetEarthProjectileData[IntNum - 1].ProjectileType;
1327 		SpeedStart = SpeedEnd = Speed = PresetEarthProjectileData[IntNum - 1].Speed;
1328 		Age = Lifetime = PresetEarthProjectileData[IntNum - 1].Age;
1329 		GraphicFXQuantity = PresetEarthProjectileData[IntNum - 1].GraphicFXQuantity;
1330 	} else if ((Num >= 101) &&
1331 		   (Num <= 199)) {
1332 		IntNum = ProjectileNum - 100;
1333 		Radius = PresetAlienProjectileData[IntNum - 1].Radius;
1334 		Damage.Kinetic() = PresetAlienProjectileData[IntNum - 1].DamageKinetic;
1335 		Damage.EM() = PresetAlienProjectileData[IntNum - 1].DamageEM;
1336 		ProjectileType = PresetAlienProjectileData[IntNum - 1].ProjectileType;
1337 		SpeedStart = SpeedEnd = Speed = PresetAlienProjectileData[IntNum - 1].Speed;
1338 		Age = Lifetime = PresetAlienProjectileData[IntNum - 1].Age;
1339 		GraphicFXQuantity = PresetAlienProjectileData[IntNum - 1].GraphicFXQuantity;
1340 	} else if ((Num >= 201) &&
1341 		   (Num <= 299)) {
1342 		IntNum = ProjectileNum - 200;
1343 		Radius = PresetPirateProjectileData[IntNum - 1].Radius;
1344 		Damage.Kinetic() = PresetPirateProjectileData[IntNum - 1].DamageKinetic;
1345 		Damage.EM() = PresetPirateProjectileData[IntNum - 1].DamageEM;
1346 		ProjectileType = PresetPirateProjectileData[IntNum - 1].ProjectileType;
1347 		SpeedStart = SpeedEnd = Speed = PresetPirateProjectileData[IntNum - 1].Speed;
1348 		Age = Lifetime = PresetPirateProjectileData[IntNum - 1].Age;
1349 		GraphicFXQuantity = PresetPirateProjectileData[IntNum - 1].GraphicFXQuantity;
1350 	}
1351 
1352 	GraphicFXLocation.resize(GraphicFXQuantity, sVECTOR3D{0.0f, 0.0f, 0.0f});
1353 	GraphicFX.resize(GraphicFXQuantity);
1354 
1355 	if (ProjectileType == 1)
1356 		ArmorCurrentStatus = ArmorInitialStatus = 1.0f;
1357 
1358 	switch (ProjectileNum) {
1359 	// Kinetic
1360 	case 1:
1361 		GraphicFX[0] = vw_CreateParticleSystem();
1362 		if (auto sharedGFX = GraphicFX[0].lock())
1363 			SetProjectileGFX(sharedGFX, 1);
1364 		break;
1365 	case 2:
1366 		GraphicFX[0] = vw_CreateParticleSystem();
1367 		if (auto sharedGFX = GraphicFX[0].lock())
1368 			SetProjectileGFX(sharedGFX, 2);
1369 		break;
1370 	case 3:
1371 		GraphicFX[0] = vw_CreateParticleSystem();
1372 		if (auto sharedGFX = GraphicFX[0].lock())
1373 			SetProjectileGFX(sharedGFX, 3);
1374 		break;
1375 	case 4:
1376 		GraphicFX[0] = vw_CreateParticleSystem();
1377 		if (auto sharedGFX = GraphicFX[0].lock())
1378 			SetProjectileGFX(sharedGFX, 4);
1379 		break;
1380 	// Ion
1381 	case 5:
1382 		GraphicFX[0] = vw_CreateParticleSystem();
1383 		if (auto sharedGFX = GraphicFX[0].lock())
1384 			SetProjectileGFX(sharedGFX, 5);
1385 		break;
1386 	case 6:
1387 		GraphicFX[0] = vw_CreateParticleSystem();
1388 		if (auto sharedGFX = GraphicFX[0].lock())
1389 			SetProjectileGFX(sharedGFX, 6);
1390 		GraphicFX[1] = vw_CreateParticleSystem();
1391 		if (auto sharedGFX = GraphicFX[1].lock()) {
1392 			SetProjectileGFX(sharedGFX, 5);
1393 			sharedGFX->CreationSize = sVECTOR3D{2.5f, 2.5f, 0.5f};
1394 			sharedGFX->DeadZone = 1.9f;
1395 		}
1396 		break;
1397 	case 7:
1398 		GraphicFX[0] = vw_CreateParticleSystem();
1399 		if (auto sharedGFX = GraphicFX[0].lock())
1400 			SetProjectileGFX(sharedGFX, 12);
1401 		GraphicFX[1] = vw_CreateParticleSystem();
1402 		if (auto sharedGFX = GraphicFX[1].lock())
1403 			SetProjectileGFX(sharedGFX, 5);
1404 		break;
1405 	// Plasma
1406 	case 8:
1407 		GraphicFX[0] = vw_CreateParticleSystem();
1408 		if (auto sharedGFX = GraphicFX[0].lock())
1409 			SetProjectileGFX(sharedGFX, 7);
1410 		break;
1411 	case 9:
1412 		GraphicFX[0] = vw_CreateParticleSystem();
1413 		if (auto sharedGFX = GraphicFX[0].lock())
1414 			SetProjectileGFX(sharedGFX, 10);
1415 		GraphicFX[1] = vw_CreateParticleSystem();
1416 		if (auto sharedGFX = GraphicFX[1].lock())
1417 			SetProjectileGFX(sharedGFX, 8);
1418 		GraphicFX[2] = vw_CreateParticleSystem();
1419 		if (auto sharedGFX = GraphicFX[2].lock())
1420 			SetProjectileGFX(sharedGFX, 9);
1421 		break;
1422 	case 10:
1423 		GraphicFX[0] = vw_CreateParticleSystem();
1424 		if (auto sharedGFX = GraphicFX[0].lock())
1425 			SetProjectileGFX(sharedGFX, 8);
1426 		GraphicFX[1] = vw_CreateParticleSystem();
1427 		if (auto sharedGFX = GraphicFX[1].lock())
1428 			SetProjectileGFX(sharedGFX, 9);
1429 		GraphicFX[2] = vw_CreateParticleSystem();
1430 		if (auto sharedGFX = GraphicFX[2].lock())
1431 			SetProjectileGFX(sharedGFX, 11);
1432 		break;
1433 	// Maser
1434 	case 11:
1435 		ProjectileCenter = sVECTOR3D{0.0f, 0.0f, 50.0f};
1436 		NeedStopPartic = true;
1437 		GraphicFX[0] = vw_CreateParticleSystem();
1438 		if (auto sharedGFX = GraphicFX[0].lock()) {
1439 			SetProjectileGFX(sharedGFX, 17);
1440 			sharedGFX->CreationSize = sVECTOR3D{0.8f, 0.8f, 100.0f};
1441 
1442 			float MinX = -sharedGFX->CreationSize.x / 2;
1443 			float MaxX = sharedGFX->CreationSize.x / 2;
1444 			float MinY = -sharedGFX->CreationSize.y / 2;
1445 			float MaxY = sharedGFX->CreationSize.y / 2;
1446 			float MinZ = -sharedGFX->CreationSize.z / 2;
1447 			float MaxZ = sharedGFX->CreationSize.z / 2;
1448 			OBB.Box[0] = AABB[0] = sVECTOR3D{MaxX, MaxY, MaxZ};
1449 			OBB.Box[1] = AABB[1] = sVECTOR3D{MinX, MaxY, MaxZ};
1450 			OBB.Box[2] = AABB[2] = sVECTOR3D{MinX, MaxY, MinZ};
1451 			OBB.Box[3] = AABB[3] = sVECTOR3D{MaxX, MaxY, MinZ};
1452 			OBB.Box[4] = AABB[4] = sVECTOR3D{MaxX, MinY, MaxZ};
1453 			OBB.Box[5] = AABB[5] = sVECTOR3D{MinX, MinY, MaxZ};
1454 			OBB.Box[6] = AABB[6] = sVECTOR3D{MinX, MinY, MinZ};
1455 			OBB.Box[7] = AABB[7] = sVECTOR3D{MaxX, MinY, MinZ};
1456 			OBB.Location = sVECTOR3D{0.0f, 0.0f, 0.0f};
1457 			Width = fabsf(MaxX - MinX);
1458 			Height = fabsf(MaxY - MinY);
1459 			Length = fabsf(MaxZ - MinZ);
1460 		}
1461 		break;
1462 	case 12:
1463 		ProjectileCenter = sVECTOR3D{0.0f, 0.0f, 55.0f};
1464 		NeedStopPartic = true;
1465 		GraphicFX[1] = vw_CreateParticleSystem();
1466 		if (auto sharedGFX = GraphicFX[1].lock()) {
1467 			SetProjectileGFX(sharedGFX, 18);
1468 			sharedGFX->CreationSize = sVECTOR3D{1.6f, 1.6f, 110.0f};
1469 		}
1470 		GraphicFX[0] = vw_CreateParticleSystem();
1471 		if (auto sharedGFX = GraphicFX[0].lock()) {
1472 			SetProjectileGFX(sharedGFX, 17);
1473 			sharedGFX->CreationSize = sVECTOR3D{0.8f, 0.8f, 110.0f};
1474 
1475 			float MinX = -sharedGFX->CreationSize.x / 2;
1476 			float MaxX = sharedGFX->CreationSize.x / 2;
1477 			float MinY = -sharedGFX->CreationSize.y / 2;
1478 			float MaxY = sharedGFX->CreationSize.y / 2;
1479 			float MinZ = -sharedGFX->CreationSize.z / 2;
1480 			float MaxZ = sharedGFX->CreationSize.z / 2;
1481 			OBB.Box[0] = AABB[0] = sVECTOR3D{MaxX, MaxY, MaxZ};
1482 			OBB.Box[1] = AABB[1] = sVECTOR3D{MinX, MaxY, MaxZ};
1483 			OBB.Box[2] = AABB[2] = sVECTOR3D{MinX, MaxY, MinZ};
1484 			OBB.Box[3] = AABB[3] = sVECTOR3D{MaxX, MaxY, MinZ};
1485 			OBB.Box[4] = AABB[4] = sVECTOR3D{MaxX, MinY, MaxZ};
1486 			OBB.Box[5] = AABB[5] = sVECTOR3D{MinX, MinY, MaxZ};
1487 			OBB.Box[6] = AABB[6] = sVECTOR3D{MinX, MinY, MinZ};
1488 			OBB.Box[7] = AABB[7] = sVECTOR3D{MaxX, MinY, MinZ};
1489 			OBB.Location = sVECTOR3D{0.0f, 0.0f, 0.0f};
1490 			Width = fabsf(MaxX - MinX);
1491 			Height = fabsf(MaxY - MinY);
1492 			Length = fabsf(MaxZ - MinZ);
1493 		}
1494 		break;
1495 	// Antimatter
1496 	case 13:
1497 		GraphicFX[0] = vw_CreateParticleSystem();
1498 		if (auto sharedGFX = GraphicFX[0].lock())
1499 			SetProjectileGFX(sharedGFX, 19);
1500 		break;
1501 	// Laser
1502 	case 14:
1503 		ProjectileCenter = sVECTOR3D{0.0f, 0.0f, 60.0f};
1504 		NeedStopPartic = true;
1505 		GraphicFX[0] = vw_CreateParticleSystem();
1506 		if (auto sharedGFX = GraphicFX[0].lock()) {
1507 			SetProjectileGFX(sharedGFX, 20);
1508 			sharedGFX->CreationSize = sVECTOR3D{0.4f, 0.4f, 120.0f};
1509 
1510 			float MinX = -sharedGFX->CreationSize.x / 2;
1511 			float MaxX = sharedGFX->CreationSize.x / 2;
1512 			float MinY = -sharedGFX->CreationSize.y / 2;
1513 			float MaxY = sharedGFX->CreationSize.y / 2;
1514 			float MinZ = -sharedGFX->CreationSize.z / 2;
1515 			float MaxZ = sharedGFX->CreationSize.z / 2;
1516 			OBB.Box[0] = AABB[0] = sVECTOR3D{MaxX, MaxY, MaxZ};
1517 			OBB.Box[1] = AABB[1] = sVECTOR3D{MinX, MaxY, MaxZ};
1518 			OBB.Box[2] = AABB[2] = sVECTOR3D{MinX, MaxY, MinZ};
1519 			OBB.Box[3] = AABB[3] = sVECTOR3D{MaxX, MaxY, MinZ};
1520 			OBB.Box[4] = AABB[4] = sVECTOR3D{MaxX, MinY, MaxZ};
1521 			OBB.Box[5] = AABB[5] = sVECTOR3D{MinX, MinY, MaxZ};
1522 			OBB.Box[6] = AABB[6] = sVECTOR3D{MinX, MinY, MinZ};
1523 			OBB.Box[7] = AABB[7] = sVECTOR3D{MaxX, MinY, MinZ};
1524 			OBB.Location = sVECTOR3D{0.0f, 0.0f, 0.0f};
1525 			Width = fabsf(MaxX - MinX);
1526 			Height = fabsf(MaxY - MinY);
1527 			Length = fabsf(MaxZ - MinZ);
1528 		}
1529 		break;
1530 	// Gauss
1531 	case 15:
1532 		GraphicFX[0] = vw_CreateParticleSystem();
1533 		if (auto sharedGFX = GraphicFX[0].lock())
1534 			SetProjectileGFX(sharedGFX, 21);
1535 		break;
1536 	// missile
1537 	case 16:
1538 		LoadObjectData("models/earthfighter/missile.vw3d", *this);
1539 		Texture[0] = GetPreloadedTextureAsset("models/earthfighter/rockets.tga");
1540 		GraphicFX[0] = vw_CreateParticleSystem();
1541 		if (auto sharedGFX = GraphicFX[0].lock())
1542 			SetProjectileGFX(sharedGFX, 13);
1543 		GraphicFXLocation[0] = sVECTOR3D{0.0f, 0.0f, -Length / 2.0f};
1544 		NeedStopPartic = true;
1545 		// missile trail
1546 		GraphicFX[1] = vw_CreateParticleSystem();
1547 		if (auto sharedGFX = GraphicFX[1].lock())
1548 			SetProjectileGFX(sharedGFX, 101);
1549 		GraphicFXLocation[1] = GraphicFXLocation[0];
1550 		break;
1551 	// swarm
1552 	case 17:
1553 		LoadObjectData("models/earthfighter/swarm.vw3d", *this);
1554 		Texture[0] = GetPreloadedTextureAsset("models/earthfighter/rockets.tga");
1555 		GraphicFX[0] = vw_CreateParticleSystem();
1556 		if (auto sharedGFX = GraphicFX[0].lock())
1557 			SetProjectileGFX(sharedGFX, 16);
1558 		GraphicFXLocation[0] = sVECTOR3D{0.0f, 0.0f, -Length / 2.0f};
1559 		NeedStopPartic = true;
1560 		// missile trail
1561 		GraphicFX[1] = vw_CreateParticleSystem();
1562 		if (auto sharedGFX = GraphicFX[1].lock()) {
1563 			SetProjectileGFX(sharedGFX, 101);
1564 			sharedGFX->Life = 1.00f;
1565 		}
1566 		GraphicFXLocation[1] = GraphicFXLocation[0];
1567 		break;
1568 	// torpedo
1569 	case 18:
1570 		LoadObjectData("models/earthfighter/torpedo.vw3d", *this);
1571 		Texture[0] = GetPreloadedTextureAsset("models/earthfighter/rockets.tga");
1572 		GraphicFX[0] = vw_CreateParticleSystem();
1573 		if (auto sharedGFX = GraphicFX[0].lock())
1574 			SetProjectileGFX(sharedGFX, 14);
1575 		GraphicFXLocation[0] = sVECTOR3D{0.0f, 0.0f, -Length / 2.0f};
1576 		NeedStopPartic = true;
1577 		// missile trail
1578 		GraphicFX[1] = vw_CreateParticleSystem();
1579 		if (auto sharedGFX = GraphicFX[1].lock())
1580 			SetProjectileGFX(sharedGFX, 101);
1581 		GraphicFXLocation[1] = GraphicFXLocation[0];
1582 		break;
1583 	// bomb
1584 	case 19:
1585 		LoadObjectData("models/earthfighter/nuke.vw3d", *this);
1586 		Texture[0] = GetPreloadedTextureAsset("models/earthfighter/rockets.tga");
1587 		GraphicFX[0] = vw_CreateParticleSystem();
1588 		if (auto sharedGFX = GraphicFX[0].lock())
1589 			SetProjectileGFX(sharedGFX, 15);
1590 		GraphicFXLocation[0] = sVECTOR3D{0.0f, 0.0f, -Length / 2.0f};
1591 		NeedStopPartic = true;
1592 		// missile trail
1593 		GraphicFX[1] = vw_CreateParticleSystem();
1594 		if (auto sharedGFX = GraphicFX[1].lock())
1595 			SetProjectileGFX(sharedGFX, 101);
1596 		GraphicFXLocation[1] = GraphicFXLocation[0];
1597 		break;
1598 
1599 	// alien, like Kinetic1
1600 	case 101:
1601 		GraphicFX[0] = vw_CreateParticleSystem();
1602 		if (auto sharedGFX = GraphicFX[0].lock())
1603 			SetProjectileGFX(sharedGFX, 22);
1604 		break;
1605 	// alien, homing, like Kinetic2
1606 	case 102:
1607 		GraphicFX[0] = vw_CreateParticleSystem();
1608 		if (auto sharedGFX = GraphicFX[0].lock())
1609 			SetProjectileGFX(sharedGFX, 23);
1610 		NeedStopPartic = true;
1611 		// missile trail
1612 		GraphicFX[1] = vw_CreateParticleSystem();
1613 		if (auto sharedGFX = GraphicFX[1].lock())
1614 			SetProjectileGFX(sharedGFX, 102);
1615 		break;
1616 	// alien, like Kinetic3
1617 	case 103:
1618 		GraphicFX[0] = vw_CreateParticleSystem();
1619 		if (auto sharedGFX = GraphicFX[0].lock())
1620 			SetProjectileGFX(sharedGFX, 24);
1621 		break;
1622 	// alien, homing, like Kinetic3
1623 	case 104:
1624 		GraphicFX[0] = vw_CreateParticleSystem();
1625 		if (auto sharedGFX = GraphicFX[0].lock())
1626 			SetProjectileGFX(sharedGFX, 24);
1627 		NeedStopPartic = true;
1628 		// missile trail
1629 		GraphicFX[1] = vw_CreateParticleSystem();
1630 		if (auto sharedGFX = GraphicFX[1].lock())
1631 			SetProjectileGFX(sharedGFX, 102);
1632 		break;
1633 	// alien, like Kinetic2
1634 	case 105:
1635 		GraphicFX[0] = vw_CreateParticleSystem();
1636 		if (auto sharedGFX = GraphicFX[0].lock())
1637 			SetProjectileGFX(sharedGFX, 23);
1638 		break;
1639 	// alien, energy mine 1
1640 	case 106:
1641 		GraphicFX[0] = vw_CreateParticleSystem();
1642 		if (auto sharedGFX = GraphicFX[0].lock())
1643 			SetProjectileGFX(sharedGFX, 36);
1644 		break;
1645 	// alien, energy mine 2
1646 	case 107:
1647 		GraphicFX[0] = vw_CreateParticleSystem();
1648 		if (auto sharedGFX = GraphicFX[0].lock())
1649 			SetProjectileGFX(sharedGFX, 37);
1650 		break;
1651 	// alien, like Plasma3
1652 	case 108:
1653 		GraphicFX[0] = vw_CreateParticleSystem();
1654 		if (auto sharedGFX = GraphicFX[0].lock())
1655 			SetProjectileGFX(sharedGFX, 8);
1656 		GraphicFX[1] = vw_CreateParticleSystem();
1657 		if (auto sharedGFX = GraphicFX[1].lock())
1658 			SetProjectileGFX(sharedGFX, 9);
1659 		GraphicFX[2] = vw_CreateParticleSystem();
1660 		if (auto sharedGFX = GraphicFX[2].lock())
1661 			SetProjectileGFX(sharedGFX, 11);
1662 		break;
1663 	// alien, like Plasma2
1664 	case 109:
1665 		GraphicFX[0] = vw_CreateParticleSystem();
1666 		if (auto sharedGFX = GraphicFX[0].lock())
1667 			SetProjectileGFX(sharedGFX, 10);
1668 		GraphicFX[1] = vw_CreateParticleSystem();
1669 		if (auto sharedGFX = GraphicFX[1].lock())
1670 			SetProjectileGFX(sharedGFX, 8);
1671 		GraphicFX[2] = vw_CreateParticleSystem();
1672 		if (auto sharedGFX = GraphicFX[2].lock())
1673 			SetProjectileGFX(sharedGFX, 9);
1674 		break;
1675 	// alien, like Laser
1676 	case 110:
1677 		ProjectileCenter = sVECTOR3D{0.0f, 0.0f, 55.0f};
1678 		NeedStopPartic = true;
1679 		GraphicFX[0] = vw_CreateParticleSystem();
1680 		if (auto sharedGFX = GraphicFX[0].lock()) {
1681 			SetProjectileGFX(sharedGFX, 38);
1682 			sharedGFX->CreationSize = sVECTOR3D{2.0f, 2.0f, 110.0f};
1683 
1684 			float MinX = -sharedGFX->CreationSize.x/2;
1685 			float MaxX = sharedGFX->CreationSize.x/2;
1686 			float MinY = -sharedGFX->CreationSize.y/2;
1687 			float MaxY = sharedGFX->CreationSize.y/2;
1688 			float MinZ = -sharedGFX->CreationSize.z/2;
1689 			float MaxZ = sharedGFX->CreationSize.z/2;
1690 			// запоминаем только то, что нужно - float x, float y, float z, float sizeX, float sizeY, float sizeZ
1691 			OBB.Box[0] = AABB[0] = sVECTOR3D{MaxX, MaxY, MaxZ};
1692 			OBB.Box[1] = AABB[1] = sVECTOR3D{MinX, MaxY, MaxZ};
1693 			OBB.Box[2] = AABB[2] = sVECTOR3D{MinX, MaxY, MinZ};
1694 			OBB.Box[3] = AABB[3] = sVECTOR3D{MaxX, MaxY, MinZ};
1695 			OBB.Box[4] = AABB[4] = sVECTOR3D{MaxX, MinY, MaxZ};
1696 			OBB.Box[5] = AABB[5] = sVECTOR3D{MinX, MinY, MaxZ};
1697 			OBB.Box[6] = AABB[6] = sVECTOR3D{MinX, MinY, MinZ};
1698 			OBB.Box[7] = AABB[7] = sVECTOR3D{MaxX, MinY, MinZ};
1699 			OBB.Location = sVECTOR3D{0.0f, 0.0f, 0.0f};
1700 			Width = fabsf(MaxX-MinX);
1701 			Height = fabsf(MaxY-MinY);
1702 			Length = fabsf(MaxZ-MinZ);
1703 		}
1704 		break;
1705 	// pirate, turret 1
1706 	case 201:
1707 		GraphicFX[0] = vw_CreateParticleSystem();
1708 		if (auto sharedGFX = GraphicFX[0].lock())
1709 			SetProjectileGFX(sharedGFX, 26);
1710 		break;
1711 	// pirate, turret 2
1712 	case 202:
1713 		GraphicFX[0] = vw_CreateParticleSystem();
1714 		if (auto sharedGFX = GraphicFX[0].lock())
1715 			SetProjectileGFX(sharedGFX, 34);
1716 		break;
1717 	// flares
1718 	case 203:
1719 		// смотрит вверх
1720 		Orientation = sVECTOR3D{0.0f, 0.5f, 0.5f};
1721 		GraphicFX[0] = vw_CreateParticleSystem();
1722 		if (auto sharedGFX = GraphicFX[0].lock())
1723 			SetProjectileGFX(sharedGFX, 25);
1724 		break;
1725 	// pirate, like Kinetic1
1726 	case 204:
1727 		GraphicFX[0] = vw_CreateParticleSystem();
1728 		if (auto sharedGFX = GraphicFX[0].lock())
1729 			SetProjectileGFX(sharedGFX, 26);
1730 		break;
1731 	// pirate, like Missile1
1732 	case 205:
1733 		LoadObjectData("models/earthfighter/missile.vw3d", *this);
1734 		Texture[0] = GetPreloadedTextureAsset("models/earthfighter/rockets.tga");
1735 		GraphicFX[0] = vw_CreateParticleSystem();
1736 		if (auto sharedGFX = GraphicFX[0].lock())
1737 			SetProjectileGFX(sharedGFX, 27);
1738 		GraphicFXLocation[0] = sVECTOR3D{0.0f, 0.0f, -Length / 2.0f};
1739 		NeedStopPartic = true;
1740 		// missile trail
1741 		GraphicFX[1] = vw_CreateParticleSystem();
1742 		if (auto sharedGFX = GraphicFX[1].lock())
1743 			SetProjectileGFX(sharedGFX, 101);
1744 		GraphicFXLocation[1] = GraphicFXLocation[0];
1745 		break;
1746 	// pirate, like Missile2
1747 	case 206:
1748 		LoadObjectData("models/earthfighter/swarm.vw3d", *this);
1749 		Texture[0] = GetPreloadedTextureAsset("models/earthfighter/rockets.tga");
1750 		GraphicFX[0] = vw_CreateParticleSystem();
1751 		if (auto sharedGFX = GraphicFX[0].lock())
1752 			SetProjectileGFX(sharedGFX, 31);
1753 		GraphicFXLocation[0] = sVECTOR3D{0.0f, 0.0f, -Length / 2.0f};
1754 		NeedStopPartic = true;
1755 		// missile trail
1756 		GraphicFX[1] = vw_CreateParticleSystem();
1757 		if (auto sharedGFX = GraphicFX[1].lock())
1758 			SetProjectileGFX(sharedGFX, 101);
1759 		GraphicFXLocation[1] = GraphicFXLocation[0];
1760 		break;
1761 	// pirate, like Ion2
1762 	case 207:
1763 		GraphicFX[0] = vw_CreateParticleSystem();
1764 		if (auto sharedGFX = GraphicFX[0].lock())
1765 			SetProjectileGFX(sharedGFX, 6);
1766 		GraphicFX[1] = vw_CreateParticleSystem();
1767 		if (auto sharedGFX = GraphicFX[1].lock()) {
1768 			SetProjectileGFX(sharedGFX, 5);
1769 			sharedGFX->CreationSize = sVECTOR3D{2.5f, 2.5f, 0.5f};
1770 			sharedGFX->DeadZone = 1.9f;
1771 		}
1772 		break;
1773 	// pirate, like Antimatter
1774 	case 208:
1775 		GraphicFX[0] = vw_CreateParticleSystem();
1776 		if (auto sharedGFX = GraphicFX[0].lock())
1777 			SetProjectileGFX(sharedGFX, 19);
1778 		break;
1779 	// pirate, like torpedo
1780 	case 209:
1781 		LoadObjectData("models/earthfighter/torpedo.vw3d", *this);
1782 		Texture[0] = GetPreloadedTextureAsset("models/earthfighter/rockets.tga");
1783 		GraphicFX[0] = vw_CreateParticleSystem();
1784 		if (auto sharedGFX = GraphicFX[0].lock())
1785 			SetProjectileGFX(sharedGFX, 32);
1786 		GraphicFXLocation[0] = sVECTOR3D{0.0f, 0.0f, -Length / 2.0f};
1787 		NeedStopPartic = true;
1788 		// missile trail
1789 		GraphicFX[1] = vw_CreateParticleSystem();
1790 		if (auto sharedGFX = GraphicFX[1].lock())
1791 			SetProjectileGFX(sharedGFX, 101);
1792 		GraphicFXLocation[1] = GraphicFXLocation[0];
1793 		break;
1794 	// pirate, like bomb
1795 	case 210:
1796 		LoadObjectData("models/earthfighter/nuke.vw3d", *this);
1797 		Texture[0] = GetPreloadedTextureAsset("models/earthfighter/rockets.tga");
1798 		GraphicFX[0] = vw_CreateParticleSystem();
1799 		if (auto sharedGFX = GraphicFX[0].lock())
1800 			SetProjectileGFX(sharedGFX, 33);
1801 		GraphicFXLocation[0] = sVECTOR3D{0.0f, 0.0f, -Length / 2.0f};
1802 		NeedStopPartic = true;
1803 		// missile trail
1804 		GraphicFX[1] = vw_CreateParticleSystem();
1805 		if (auto sharedGFX = GraphicFX[1].lock())
1806 			SetProjectileGFX(sharedGFX, 101);
1807 		GraphicFXLocation[1] = GraphicFXLocation[0];
1808 		break;
1809 	// pirate, like Kinetic2
1810 	case 211:
1811 		GraphicFX[0] = vw_CreateParticleSystem();
1812 		if (auto sharedGFX = GraphicFX[0].lock())
1813 			SetProjectileGFX(sharedGFX, 34);
1814 		break;
1815 	// pirate, like Kinetic3
1816 	case 212:
1817 		GraphicFX[0] = vw_CreateParticleSystem();
1818 		if (auto sharedGFX = GraphicFX[0].lock())
1819 			SetProjectileGFX(sharedGFX, 35);
1820 		break;
1821 	// pirate, like Plasma2
1822 	case 213:
1823 		GraphicFX[0] = vw_CreateParticleSystem();
1824 		if (auto sharedGFX = GraphicFX[0].lock())
1825 			SetProjectileGFX(sharedGFX, 10);
1826 		GraphicFX[1] = vw_CreateParticleSystem();
1827 		if (auto sharedGFX = GraphicFX[1].lock())
1828 			SetProjectileGFX(sharedGFX, 8);
1829 		GraphicFX[2] = vw_CreateParticleSystem();
1830 		if (auto sharedGFX = GraphicFX[2].lock())
1831 			SetProjectileGFX(sharedGFX, 9);
1832 		break;
1833 	// mine 1
1834 	case 214:
1835 		MineIData = 0.0f;
1836 		ArmorCurrentStatus = ArmorInitialStatus = 10.0f;
1837 		LoadObjectData("models/mine/mine-01.vw3d", *this);
1838 		Texture[0] = GetPreloadedTextureAsset("models/mine/mine1.tga");
1839 		TextureIllum[0] = GetPreloadedTextureAsset("models/mine/mine1i.tga");
1840 		break;
1841 	// mine 2
1842 	case 215:
1843 		MineIData = 0.0f;
1844 		ArmorCurrentStatus = ArmorInitialStatus = 15.0f;
1845 		LoadObjectData("models/mine/mine-02.vw3d", *this);
1846 		Texture[0] = GetPreloadedTextureAsset("models/mine/mine2.tga");
1847 		TextureIllum[0] = GetPreloadedTextureAsset("models/mine/mine2i.tga");
1848 
1849 		GraphicFX[0] = vw_CreateParticleSystem();
1850 		if (auto sharedGFX = GraphicFX[0].lock())
1851 			SetProjectileGFX(sharedGFX, 28);
1852 		GraphicFXLocation[0] = sVECTOR3D{0.0f, -0.8f, 0.0f};
1853 		NeedStopPartic = true;
1854 		break;
1855 	// mine 3
1856 	case 216:
1857 		MineIData = 0.0f;
1858 		ArmorCurrentStatus = ArmorInitialStatus = 20.0f;
1859 		MineReloadTime = MineNextFireTime = 1.0f;
1860 		LoadObjectData("models/mine/mine-03.vw3d", *this);
1861 		Texture[0] = GetPreloadedTextureAsset("models/mine/mine3.tga");
1862 		TextureIllum[0] = GetPreloadedTextureAsset("models/mine/mine3i.tga");
1863 
1864 		GraphicFX[0] = vw_CreateParticleSystem();
1865 		if (auto sharedGFX = GraphicFX[0].lock())
1866 			SetProjectileGFX(sharedGFX, 29);
1867 		GraphicFXLocation[0] = sVECTOR3D{0.0f, -2.5f, 0.0f};
1868 		NeedStopPartic = true;
1869 		break;
1870 	// mine 4
1871 	case 217:
1872 		MineIData = 0.0f;
1873 		ArmorCurrentStatus = ArmorInitialStatus = 40.0f;
1874 		MineReloadTime = MineNextFireTime = 3.0f;
1875 		LoadObjectData("models/mine/mine-04.vw3d", *this);
1876 		Texture[0] = GetPreloadedTextureAsset("models/mine/mine4.tga");
1877 		TextureIllum[0] = GetPreloadedTextureAsset("models/mine/mine4i.tga");
1878 
1879 		GraphicFX[0] = vw_CreateParticleSystem();
1880 		if (auto sharedGFX = GraphicFX[0].lock())
1881 			SetProjectileGFX(sharedGFX, 30);
1882 		GraphicFXLocation[0] = sVECTOR3D{0.0f, -0.7f, 0.0f};
1883 		NeedStopPartic = true;
1884 		break;
1885 
1886 	default:
1887 		std::cerr << __func__ << "(): " << "wrong ProjectileNum.\n";
1888 	}
1889 }
1890 
1891 /*
1892  * Destructor.
1893  */
~cProjectile()1894 cProjectile::~cProjectile()
1895 {
1896 	for (unsigned int i = 0; i < GraphicFX.size(); i++) {
1897 		auto sharedGFX = GraphicFX[i].lock();
1898 		if (!sharedGFX)
1899 			continue;
1900 		if (GraphicFXDestroyType) {
1901 			vw_ReleaseParticleSystem(GraphicFX[i]);
1902 			continue;
1903 		}
1904 
1905 		sharedGFX->IsSuppressed = true;
1906 		sharedGFX->DestroyIfNoParticles = true;
1907 
1908 		if (!NeedStopPartic) {
1909 			sharedGFX->ChangeSpeed(Orientation ^ Speed);
1910 			continue;
1911 		}
1912 
1913 		sharedGFX->StopAllParticles();
1914 
1915 		// small trail dispersion on explosion
1916 		if (i != 1)
1917 			continue;
1918 
1919 		// shock wave setup
1920 		float effective_dist2 = 300;
1921 		switch (Num) {
1922 		case 16:
1923 		case 205:
1924 			effective_dist2 = 500.0f;
1925 			break;
1926 		case 18:
1927 		case 209:
1928 			effective_dist2 = 1000.0f;
1929 			break;
1930 		case 19:
1931 		case 210:
1932 			effective_dist2 = 2000.0f;
1933 			break;
1934 		}
1935 
1936 		switch (Num) {
1937 		case 16:
1938 		case 17:
1939 		case 18:
1940 		case 19:
1941 		case 205:
1942 		case 206:
1943 		case 209:
1944 		case 210:
1945 			// on missile impact and explosion we should calculate "shock wave", that
1946 			// should scatter missile's trails and make scene looks more "realistic",
1947 			// since particles data are private, we call ForEachParticle() with lambda
1948 			sharedGFX->ForEachParticle([this, effective_dist2](sVECTOR3D &pLocation,
1949 									   sVECTOR3D &pVelocity,
1950 									   bool &pNeedStop){
1951 				sVECTOR3D Dist2 = pLocation - this->Location;
1952 				float fDist2 = Dist2.x * Dist2.x + Dist2.y * Dist2.y + Dist2.z * Dist2.z;
1953 				if (fDist2 < 1.0f)
1954 					fDist2 = 3.0f;
1955 
1956 				if (fDist2 < effective_dist2) {
1957 					pVelocity = sVECTOR3D{Dist2.x + 10.0f * vw_fRand0(),
1958 							      Dist2.y + 10.0f * vw_fRand0(),
1959 							      Dist2.z + 10.0f * vw_fRand0()};
1960 					pVelocity.Normalize();
1961 					pVelocity = pVelocity ^ (effective_dist2 / fDist2);
1962 					pNeedStop = true;
1963 				}
1964 			});
1965 			break;
1966 		}
1967 	}
1968 }
1969 
1970 /*
1971  * Set rotation.
1972  */
SetRotation(const sVECTOR3D & NewRotation)1973 void cProjectile::SetRotation(const sVECTOR3D &NewRotation)
1974 {
1975 	cObject3D::SetRotation(NewRotation);
1976 
1977 	for (unsigned int i = 0; i < GraphicFX.size(); i++) {
1978 		if (auto sharedGFX = GraphicFX[i].lock()) {
1979 			vw_Matrix33CalcPoint(GraphicFXLocation[i], OldInvRotationMat);
1980 			vw_Matrix33CalcPoint(GraphicFXLocation[i], CurrentRotationMat);
1981 			if (ProjectileType == 2)
1982 				sharedGFX->RotateSystemAndParticlesByAngle(Rotation);
1983 			else
1984 				sharedGFX->RotateSystemByAngle(Rotation);
1985 		}
1986 	}
1987 }
1988 
1989 /*
1990  * Set location.
1991  */
SetLocation(const sVECTOR3D & NewLocation)1992 void cProjectile::SetLocation(const sVECTOR3D &NewLocation)
1993 {
1994 	cObject3D::SetLocation(NewLocation);
1995 
1996 	if (GraphicFX.empty())
1997 		return;
1998 
1999 	switch (Num) {
2000 	// Kinetic
2001 	case 1:
2002 	case 2:
2003 	case 3:
2004 	case 4:
2005 		if (auto sharedGFX = GraphicFX[0].lock())
2006 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2007 		break;
2008 	// Ion
2009 	case 5:
2010 		if (auto sharedGFX = GraphicFX[0].lock())
2011 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2012 		break;
2013 	case 6:
2014 		if (auto sharedGFX = GraphicFX[0].lock())
2015 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2016 		if (auto sharedGFX = GraphicFX[1].lock())
2017 			sharedGFX->MoveSystem(GraphicFXLocation[1] + Location);
2018 		break;
2019 	case 7:
2020 		if (auto sharedGFX = GraphicFX[0].lock())
2021 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2022 		if (auto sharedGFX = GraphicFX[1].lock())
2023 			sharedGFX->MoveSystem(GraphicFXLocation[1] + Location);
2024 		break;
2025 	// Plasma
2026 	case 8:
2027 		if (auto sharedGFX = GraphicFX[0].lock())
2028 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2029 		break;
2030 	case 9:
2031 		if (auto sharedGFX = GraphicFX[0].lock())
2032 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2033 		if (auto sharedGFX = GraphicFX[1].lock())
2034 			sharedGFX->MoveSystem(GraphicFXLocation[1] + Location);
2035 		if (auto sharedGFX = GraphicFX[2].lock())
2036 			sharedGFX->MoveSystem(GraphicFXLocation[2] + Location);
2037 		break;
2038 	case 10:
2039 		if (auto sharedGFX = GraphicFX[0].lock())
2040 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2041 		if (auto sharedGFX = GraphicFX[1].lock())
2042 			sharedGFX->MoveSystem(GraphicFXLocation[1] + Location);
2043 		if (auto sharedGFX = GraphicFX[2].lock())
2044 			sharedGFX->MoveSystemLocation(GraphicFXLocation[2] + Location);
2045 		break;
2046 	// Maser
2047 	case 11:
2048 		if (auto sharedGFX = GraphicFX[0].lock()) {
2049 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2050 			sharedGFX->SetStartLocation(GraphicFXLocation[0] + Location);
2051 		}
2052 		break;
2053 	case 12:
2054 		if (auto sharedGFX = GraphicFX[0].lock()) {
2055 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2056 			sharedGFX->SetStartLocation(GraphicFXLocation[0] + Location);
2057 		}
2058 		if (auto sharedGFX = GraphicFX[1].lock()) {
2059 			sharedGFX->MoveSystem(GraphicFXLocation[1] + Location);
2060 			sharedGFX->SetStartLocation(GraphicFXLocation[1] + Location);
2061 		}
2062 		break;
2063 	// Antimatter
2064 	case 13:
2065 		if (auto sharedGFX = GraphicFX[0].lock())
2066 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2067 		break;
2068 	// Laser
2069 	case 14:
2070 		if (auto sharedGFX = GraphicFX[0].lock()) {
2071 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2072 			sharedGFX->SetStartLocation(GraphicFXLocation[0] + Location);
2073 		}
2074 		break;
2075 	// Gauss
2076 	case 15:
2077 		if (auto sharedGFX = GraphicFX[0].lock())
2078 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2079 		break;
2080 	// Missiles
2081 	case 16:
2082 	case 17:
2083 	case 18:
2084 	case 19:
2085 		if (auto sharedGFX = GraphicFX[0].lock())
2086 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2087 		if (auto sharedGFX = GraphicFX[1].lock())
2088 			sharedGFX->MoveSystemLocation(GraphicFXLocation[1] + Location);
2089 		break;
2090 	// alien, like Kinetic1
2091 	case 101:
2092 		if (auto sharedGFX = GraphicFX[0].lock())
2093 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2094 		break;
2095 	// alien, homing, like Kinetic2
2096 	case 102:
2097 		if (auto sharedGFX = GraphicFX[0].lock())
2098 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2099 		if (auto sharedGFX = GraphicFX[1].lock())
2100 			sharedGFX->MoveSystemLocation(GraphicFXLocation[1] + Location);
2101 		break;
2102 	// alien, like Kinetic3
2103 	case 103:
2104 		if (auto sharedGFX = GraphicFX[0].lock())
2105 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2106 		break;
2107 	// alien, homing, like Kinetic3
2108 	case 104:
2109 		if (auto sharedGFX = GraphicFX[0].lock())
2110 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2111 		if (auto sharedGFX = GraphicFX[1].lock())
2112 			sharedGFX->MoveSystemLocation(GraphicFXLocation[1] + Location);
2113 		break;
2114 	// alien, like Kinetic2
2115 	case 105:
2116 		if (auto sharedGFX = GraphicFX[0].lock())
2117 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2118 		break;
2119 	// alien, energy mine 1
2120 	case 106:
2121 		if (auto sharedGFX = GraphicFX[0].lock())
2122 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2123 		break;
2124 	// alien, energy mine 2
2125 	case 107:
2126 		if (auto sharedGFX = GraphicFX[0].lock())
2127 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2128 		break;
2129 	// alien, like Plasma3
2130 	case 108:
2131 		if (auto sharedGFX = GraphicFX[0].lock())
2132 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2133 		if (auto sharedGFX = GraphicFX[1].lock())
2134 			sharedGFX->MoveSystem(GraphicFXLocation[1] + Location);
2135 		if (auto sharedGFX = GraphicFX[2].lock())
2136 			sharedGFX->MoveSystemLocation(GraphicFXLocation[2] + Location);
2137 		break;
2138 	// alien, like Plasma2
2139 	case 109:
2140 		if (auto sharedGFX = GraphicFX[0].lock())
2141 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2142 		if (auto sharedGFX = GraphicFX[1].lock())
2143 			sharedGFX->MoveSystem(GraphicFXLocation[1] + Location);
2144 		if (auto sharedGFX = GraphicFX[2].lock())
2145 			sharedGFX->MoveSystem(GraphicFXLocation[2] + Location);
2146 		break;
2147 	// alien, like Laser
2148 	case 110:
2149 		if (auto sharedGFX = GraphicFX[0].lock()) {
2150 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2151 			sharedGFX->SetStartLocation(GraphicFXLocation[0] + Location);
2152 		}
2153 		break;
2154 	// pirate, turret 1
2155 	case 201:
2156 		if (auto sharedGFX = GraphicFX[0].lock())
2157 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2158 		break;
2159 	// pirate, turret 2
2160 	case 202:
2161 		if (auto sharedGFX = GraphicFX[0].lock())
2162 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2163 		break;
2164 	// flares
2165 	case 203:
2166 		if (auto sharedGFX = GraphicFX[0].lock())
2167 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2168 		break;
2169 	// pirate, like Kinetic1
2170 	case 204:
2171 		if (auto sharedGFX = GraphicFX[0].lock())
2172 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2173 		break;
2174 	case 205: // pirate, like missile
2175 	case 206: // pirate, like swarm
2176 	case 209: // pirate, like torpedo
2177 	case 210: // pirate, like bomb
2178 		if (auto sharedGFX = GraphicFX[0].lock())
2179 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2180 		if (auto sharedGFX = GraphicFX[1].lock())
2181 			sharedGFX->MoveSystemLocation(GraphicFXLocation[1] + Location);
2182 		break;
2183 	// pirate, like Ion2
2184 	case 207:
2185 		if (auto sharedGFX = GraphicFX[0].lock())
2186 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2187 		if (auto sharedGFX = GraphicFX[1].lock())
2188 			sharedGFX->MoveSystem(GraphicFXLocation[1] + Location);
2189 		break;
2190 	// pirate, like Antimatter
2191 	case 208:
2192 		if (auto sharedGFX = GraphicFX[0].lock())
2193 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2194 		break;
2195 	// pirate, like Kinetic2
2196 	case 211:
2197 	// pirate, like Kinetic3
2198 	case 212:
2199 		if (auto sharedGFX = GraphicFX[0].lock())
2200 			sharedGFX->MoveSystemLocation(GraphicFXLocation[0] + Location);
2201 		break;
2202 	// как Plasma2
2203 	case 213:
2204 		if (auto sharedGFX = GraphicFX[0].lock())
2205 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2206 		if (auto sharedGFX = GraphicFX[1].lock())
2207 			sharedGFX->MoveSystem(GraphicFXLocation[1] + Location);
2208 		if (auto sharedGFX = GraphicFX[2].lock())
2209 			sharedGFX->MoveSystem(GraphicFXLocation[2] + Location);
2210 		break;
2211 	// mine 1
2212 	case 214:
2213 		break;
2214 	// mine 2
2215 	case 215:
2216 		if (auto sharedGFX = GraphicFX[0].lock()) {
2217 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2218 			sharedGFX->SetStartLocation(GraphicFXLocation[0] + Location);
2219 		}
2220 		break;
2221 	// mine 3
2222 	case 216:
2223 		if (auto sharedGFX = GraphicFX[0].lock()) {
2224 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2225 			sharedGFX->SetStartLocation(GraphicFXLocation[0] + Location);
2226 		}
2227 		break;
2228 	// mine 4
2229 	case 217:
2230 		if (auto sharedGFX = GraphicFX[0].lock()) {
2231 			sharedGFX->MoveSystem(GraphicFXLocation[0] + Location);
2232 			sharedGFX->SetStartLocation(GraphicFXLocation[0] + Location);
2233 		}
2234 		break;
2235 	}
2236 }
2237 
2238 /*
2239  * Update.
2240  */
Update(float Time)2241 bool cProjectile::Update(float Time)
2242 {
2243 	if (!cObject3D::Update(Time)) {
2244 		if (ProjectileType == 2)
2245 			return true;
2246 		CreateBulletExplosion(nullptr, *this, -Num, Location, Speed);
2247 		return false;
2248 	}
2249 
2250 	if (TimeDelta == 0.0f)
2251 		return true;
2252 
2253 	Speed = SpeedStart * (Lifetime / Age) + SpeedEnd * ((Age - Lifetime) / Age);
2254 
2255 	sVECTOR3D Velocity = Orientation ^ (Speed * TimeDelta);
2256 	SetLocation(Location + Velocity);
2257 
2258 	float CurrentPenalty{1.0f};
2259 	if (ObjectStatus == eObjectStatus::Enemy)
2260 		CurrentPenalty = static_cast<float>(GameEnemyWeaponPenalty);
2261 
2262 	float RotationSpeed;
2263 
2264 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2265 	// Если что-то надо делать со снарядом (наводить к примеру)
2266 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2267 	switch (Num) {
2268 	// Plasma
2269 	case 9:
2270 	case 109:
2271 		if (auto sharedGFX = GraphicFX[1].lock())
2272 			sharedGFX->RotateSystemAndParticlesByAngle(sVECTOR3D{sharedGFX->Angle.x - 360.0f * TimeDelta,
2273 									     sharedGFX->Angle.y,
2274 									     sharedGFX->Angle.z});
2275 		if (auto sharedGFX = GraphicFX[2].lock())
2276 			sharedGFX->RotateSystemAndParticlesByAngle(sVECTOR3D{sharedGFX->Angle.x - 360.0f * TimeDelta,
2277 									     sharedGFX->Angle.y,
2278 									     sharedGFX->Angle.z});
2279 		break;
2280 	case 10:
2281 	case 108:
2282 	case 213:
2283 		if (auto sharedGFX = GraphicFX[0].lock())
2284 			sharedGFX->RotateSystemAndParticlesByAngle(sVECTOR3D{sharedGFX->Angle.x - 360.0f * TimeDelta,
2285 									     sharedGFX->Angle.y,
2286 									     sharedGFX->Angle.z});
2287 		if (auto sharedGFX = GraphicFX[1].lock())
2288 			sharedGFX->RotateSystemAndParticlesByAngle(sVECTOR3D{sharedGFX->Angle.x - 360.0f * TimeDelta,
2289 									     sharedGFX->Angle.y,
2290 									     sharedGFX->Angle.z});
2291 		break;
2292 
2293 	// Maser
2294 	case 11:
2295 		if (auto sharedGFX = GraphicFX[0].lock()) {
2296 			sharedGFX->RotateParticlesByAngle(sVECTOR3D{0.0f, 0.0f, 360.0f * TimeDelta * 3.0f});
2297 			if (Lifetime <= sharedGFX->Life / 1.5f)
2298 				sharedGFX->IsSuppressed = true;
2299 		}
2300 		break;
2301 	case 12:
2302 		if (auto sharedGFX = GraphicFX[0].lock()) {
2303 			sharedGFX->RotateParticlesByAngle(sVECTOR3D{0.0f, 0.0f, 360.0f * TimeDelta * 4.0f});
2304 			if (Lifetime <= sharedGFX->Life / 1.5f)
2305 				sharedGFX->IsSuppressed = true;
2306 		}
2307 		if (auto sharedGFX = GraphicFX[1].lock()) {
2308 			sharedGFX->RotateParticlesByAngle(sVECTOR3D{0.0f, 0.0f, -360.0f * TimeDelta * 2.0f});
2309 			if (Lifetime <= sharedGFX->Life / 1.5f)
2310 				sharedGFX->IsSuppressed = true;
2311 		}
2312 		break;
2313 
2314 	// Antimatter
2315 	case 13:
2316 	case 208:
2317 		if (auto sharedGFX = GraphicFX[0].lock())
2318 			sharedGFX->RotateSystemAndParticlesByAngle(sVECTOR3D{sharedGFX->Angle.x,
2319 									     sharedGFX->Angle.y - 360.0f * TimeDelta * 2.0f,
2320 									     sharedGFX->Angle.z});
2321 		break;
2322 
2323 	// Laser
2324 	case 14:
2325 	case 110:
2326 		if (auto sharedGFX = GraphicFX[0].lock())
2327 			if (Lifetime <= sharedGFX->Life / 1.5f)
2328 				sharedGFX->IsSuppressed = true;
2329 		break;
2330 
2331 	// Gauss
2332 	case 15:
2333 		if (auto sharedGFX = GraphicFX[0].lock())
2334 			sharedGFX->RotateParticlesByAngle(sVECTOR3D{0.0f, 0.0f, 360.0f * TimeDelta * 6.0f});
2335 		break;
2336 
2337 	// missile
2338 	case 16:
2339 		RotationSpeed = 50.0f;
2340 		goto missile;
2341 	case 17:
2342 		RotationSpeed = 60.0f;
2343 		goto missile;
2344 	case 18:
2345 		RotationSpeed = 35.0f;
2346 		goto missile;
2347 	case 19:
2348 		RotationSpeed = 20.0f;
2349 		goto missile;
2350 	// ракеты пришельцев
2351 	case 102:
2352 		RotationSpeed = 50.0f;
2353 		goto missile;
2354 	case 104:
2355 		RotationSpeed = 60.0f;
2356 		goto missile;
2357 	// ракеты пиратов
2358 	case 205:
2359 		RotationSpeed = 50.0f;
2360 		goto missile;
2361 	case 206:
2362 		RotationSpeed = 60.0f;
2363 		goto missile;
2364 	case 209:
2365 		RotationSpeed = 50.0f;
2366 		goto missile;
2367 	case 210:
2368 		RotationSpeed = 30.0f;
2369 		{
2370 missile:
2371 			RotationSpeed /= CurrentPenalty;
2372 
2373 			sVECTOR3D NeedAngle = Rotation;
2374 
2375 			float EffectiveRange = 1000000.0f;
2376 			if (ObjectStatus == eObjectStatus::Player)
2377 				EffectiveRange = Lifetime * Speed;
2378 
2379 			if (Target.expired()) {
2380 				Target = FindTargetAndInterceptCourse(ObjectStatus, Location, Rotation,
2381 								      CurrentRotationMat, NeedAngle, EffectiveRange);
2382 			} else {
2383 				if (CheckMissileTarget(Target, Location, CurrentRotationMat)) {
2384 					if (!CorrectTargetInterceptCourse(Location, Rotation, CurrentRotationMat,
2385 									  Target, NeedAngle))
2386 						Target = FindTargetAndInterceptCourse(ObjectStatus, Location, Rotation,
2387 										      CurrentRotationMat, NeedAngle,
2388 										      EffectiveRange);
2389 				} else
2390 					Target = FindTargetAndInterceptCourse(ObjectStatus, Location, Rotation,
2391 									      CurrentRotationMat, NeedAngle, EffectiveRange);
2392 			}
2393 
2394 			if (Rotation.y < NeedAngle.y) {
2395 				float NeedAngle_y = Rotation.y + RotationSpeed * TimeDelta;
2396 				if (NeedAngle_y > NeedAngle.y)
2397 					NeedAngle_y = NeedAngle.y;
2398 				NeedAngle.y = NeedAngle_y;
2399 
2400 			}
2401 			if (Rotation.y > NeedAngle.y) {
2402 				float NeedAngle_y = Rotation.y - RotationSpeed * TimeDelta;
2403 				if (NeedAngle_y < NeedAngle.y)
2404 					NeedAngle_y = NeedAngle.y;
2405 				NeedAngle.y = NeedAngle_y;
2406 			}
2407 
2408 			if (Rotation.x < NeedAngle.x) {
2409 				float NeedAngle_x = Rotation.x + RotationSpeed * TimeDelta;
2410 				if (NeedAngle_x > NeedAngle.x)
2411 					NeedAngle_x = NeedAngle.x;
2412 				NeedAngle.x = NeedAngle_x;
2413 
2414 			}
2415 			if (Rotation.x > NeedAngle.x) {
2416 				float NeedAngle_x = Rotation.x - RotationSpeed * TimeDelta;
2417 				if (NeedAngle_x < NeedAngle.x)
2418 					NeedAngle_x = NeedAngle.x;
2419 				NeedAngle.x = NeedAngle_x;
2420 			}
2421 
2422 			SetRotation(NeedAngle - Rotation);
2423 		}
2424 		break;
2425 
2426 	// pirate, mine 1
2427 	case 214:
2428 		MineIData += TimeDelta;
2429 		if (MineIData >= 0.1f) {
2430 			if (!TextureIllum[0])
2431 				TextureIllum[0] = GetPreloadedTextureAsset("models/mine/mine1i.tga");
2432 			else
2433 				TextureIllum[0] = 0;
2434 			MineIData = 0.0f;
2435 		}
2436 		Chunks[0].Rotation.y += 90.0f * TimeDelta;
2437 		while (Chunks[0].Rotation.y > 360.0f) {
2438 			Chunks[0].Rotation.y -= 360.0f;
2439 		}
2440 		// wip, disabled for now
2441 	break;
2442 	// alien, energy mine 1
2443 	case 106: {
2444 		std::weak_ptr<cObject3D> tmpTarget = GetClosestTargetToMine(ObjectStatus, Location);
2445 
2446 		auto sharedTarget = tmpTarget.lock();
2447 		if (sharedTarget) {
2448 			float MineSpeed = 5.0f;
2449 			float SpeedTmp = MineSpeed * TimeDelta;
2450 			if (SpeedTmp > fabs(Location.y - sharedTarget->Location.y))
2451 				SpeedTmp = fabs(Location.y - sharedTarget->Location.y);
2452 
2453 			if (SpeedTmp != 0.0f) {
2454 				if (Location.y > sharedTarget->Location.y)
2455 					SpeedTmp *= -1.0f;
2456 
2457 				sVECTOR3D VelocityUp = sVECTOR3D{0.0f, SpeedTmp, 0.0f};
2458 				SetLocation(Location + VelocityUp);
2459 			}
2460 		}
2461 		if (!GraphicFX.empty()) {
2462 			if (auto sharedGFX = GraphicFX[0].lock())
2463 				sharedGFX->SetStartLocation(GraphicFXLocation[0] + Location);
2464 		}
2465 	}
2466 	break;
2467 	// pirate, mine 2
2468 	case 215:
2469 		MineIData += TimeDelta;
2470 		if (MineIData >= 0.1f) {
2471 			if (!TextureIllum[0])
2472 				TextureIllum[0] = GetPreloadedTextureAsset("models/mine/mine2i.tga");
2473 			else
2474 				TextureIllum[0] = 0;
2475 			MineIData = 0.0f;
2476 		}
2477 		Chunks[0].Rotation.y += 90.0f * TimeDelta;
2478 		while (Chunks[0].Rotation.y > 360.0f) {
2479 			Chunks[0].Rotation.y -= 360.0f;
2480 		}
2481 		// wip, disabled for now
2482 	break;
2483 	// alien, energy mine 2
2484 	case 107:
2485 		RotationSpeed = 180.0f;
2486 		{
2487 			sVECTOR3D NeedAngle = Rotation;
2488 			// устанавливаем в Target на что наведен этот снаряд
2489 			Target = FindTargetAndInterceptCourse(ObjectStatus, Location, Rotation,
2490 							      CurrentRotationMat, NeedAngle, 1000000);
2491 
2492 
2493 			// учитываем скорость поворота по вертикали
2494 			if (Rotation.y < NeedAngle.y) {
2495 				float NeedAngle_y = Rotation.y + RotationSpeed * TimeDelta;
2496 				if (NeedAngle_y > NeedAngle.y)
2497 					NeedAngle_y = NeedAngle.y;
2498 				NeedAngle.y = NeedAngle_y;
2499 
2500 			}
2501 			if (Rotation.y > NeedAngle.y) {
2502 				float NeedAngle_y = Rotation.y - RotationSpeed * TimeDelta;
2503 				if (NeedAngle_y < NeedAngle.y)
2504 					NeedAngle_y = NeedAngle.y;
2505 				NeedAngle.y = NeedAngle_y;
2506 			}
2507 
2508 			NeedAngle.z = Rotation.z;
2509 			NeedAngle.x = Rotation.x;
2510 
2511 			sVECTOR3D TTT = NeedAngle - Rotation;
2512 			SetRotation(TTT);
2513 
2514 
2515 			// если есть цель, поднимаемся на ее уровень
2516 			auto sharedTarget = Target.lock();
2517 			if (sharedTarget) {
2518 				float MineSpeed = 5.0f;
2519 
2520 				// получаем положение ближайшего врага
2521 				sVECTOR3D NeedPoint = sharedTarget->Location;
2522 
2523 				// !!! не учитываем положение плоскости
2524 
2525 				float SpeedTmp = MineSpeed * TimeDelta;
2526 				if (SpeedTmp > fabs(Location.y - NeedPoint.y))
2527 					SpeedTmp = fabs(Location.y - NeedPoint.y);
2528 
2529 				if (SpeedTmp != 0.0f) {
2530 					// находим направление (если нужно вниз, меняем знак)
2531 					if (Location.y > NeedPoint.y)
2532 						SpeedTmp *= -1.0f;
2533 
2534 					sVECTOR3D VelocityUp = sVECTOR3D{0.0f, SpeedTmp, 0.0f};
2535 					SetLocation(Location + VelocityUp);
2536 				}
2537 			}
2538 
2539 			if (!GraphicFX.empty()) {
2540 				if (auto sharedGFX = GraphicFX[0].lock())
2541 					sharedGFX->SetStartLocation(GraphicFXLocation[0] + Location);
2542 			}
2543 
2544 			// сбрасываем установку, чтобы не было голосового предупреждения
2545 			Target.reset();
2546 		}
2547 		break;
2548 
2549 
2550 
2551 	case 216:
2552 		MineIData += TimeDelta;
2553 		if (MineIData >= 0.1f) {
2554 			if (!TextureIllum[0])
2555 				TextureIllum[0] = GetPreloadedTextureAsset("models/mine/mine3i.tga");
2556 			else
2557 				TextureIllum[0] = 0;
2558 			MineIData = 0.0f;
2559 		}
2560 		Chunks[0].Rotation.y += 120.0f * TimeDelta;
2561 		while (Chunks[0].Rotation.y > 360.0f) {
2562 			Chunks[0].Rotation.y -= 360.0f;
2563 		}
2564 
2565 		RotationSpeed = 180.0f;
2566 		{
2567 			sVECTOR3D NeedAngle = Rotation;
2568 			// устанавливаем в Target на что наведен этот снаряд
2569 			Target = FindTargetAndInterceptCourse(ObjectStatus, Location, Rotation,
2570 							      CurrentRotationMat, NeedAngle, 1000000);
2571 
2572 
2573 			// учитываем скорость поворота по вертикали
2574 			if (Rotation.y < NeedAngle.y) {
2575 				float NeedAngle_y = Rotation.y + RotationSpeed * TimeDelta;
2576 				if (NeedAngle_y > NeedAngle.y)
2577 					NeedAngle_y = NeedAngle.y;
2578 				NeedAngle.y = NeedAngle_y;
2579 
2580 			}
2581 			if (Rotation.y > NeedAngle.y) {
2582 				float NeedAngle_y = Rotation.y - RotationSpeed * TimeDelta;
2583 				if (NeedAngle_y < NeedAngle.y)
2584 					NeedAngle_y = NeedAngle.y;
2585 				NeedAngle.y = NeedAngle_y;
2586 			}
2587 
2588 			NeedAngle.z = Rotation.z;
2589 			NeedAngle.x = Rotation.x;
2590 
2591 			SetRotation(NeedAngle - Rotation);
2592 
2593 			auto sharedTarget = Target.lock();
2594 			if (sharedTarget) {
2595 				float MineSpeed = 5.0f;
2596 				sVECTOR3D NeedPoint = sharedTarget->Location;
2597 				float SpeedTmp = MineSpeed*TimeDelta;
2598 
2599 				if (SpeedTmp > fabs(Location.y - 2.0f - NeedPoint.y))
2600 					SpeedTmp = fabs(Location.y - 2.0f - NeedPoint.y);
2601 
2602 				if (SpeedTmp != 0.0f) {
2603 					if (Location.y - 2.0f > NeedPoint.y)
2604 						SpeedTmp *= -1.0f;
2605 
2606 					sVECTOR3D VelocityUp = sVECTOR3D{0.0f, SpeedTmp, 0.0f};
2607 					SetLocation(Location + VelocityUp);
2608 				}
2609 
2610 				MineNextFireTime -= TimeDelta;
2611 				if (MineNextFireTime <= 0.0f) {
2612 					cProjectile *Projectile = new cProjectile{204};
2613 					Projectile->SetLocation(Location + sVECTOR3D{0.0f, -2.0f, 0.0f});
2614 
2615 					Projectile->SetRotation(Rotation);
2616 					for (auto &tmpGFX : Projectile->GraphicFX) {
2617 						if (auto sharedGFX = tmpGFX.lock()) {
2618 							sharedGFX->Direction = Orientation;
2619 							sharedGFX->ParticlesPerSec = (int)(sharedGFX->ParticlesPerSec / CurrentPenalty);
2620 
2621 							sharedGFX->Speed = sharedGFX->Speed / CurrentPenalty;
2622 							sharedGFX->Life = sharedGFX->Life * CurrentPenalty;
2623 							sharedGFX->MagnetFactor = sharedGFX->MagnetFactor / (CurrentPenalty * CurrentPenalty);
2624 						}
2625 					}
2626 					Projectile->ObjectStatus = ObjectStatus;
2627 					Projectile->SpeedStart = Projectile->SpeedEnd = Projectile->SpeedStart / CurrentPenalty;
2628 					Projectile->Age = Projectile->Lifetime = Projectile->Age * CurrentPenalty;
2629 					Projectile->Damage /= CurrentPenalty;
2630 
2631 					MineNextFireTime = MineReloadTime;
2632 				}
2633 			}
2634 			Target.reset();
2635 		}
2636 		break;
2637 
2638 	case 217:
2639 		MineIData += TimeDelta;
2640 		if (MineIData >= 0.1f) {
2641 			if (!TextureIllum[0])
2642 				TextureIllum[0] = GetPreloadedTextureAsset("models/mine/mine4i.tga");
2643 			else
2644 				TextureIllum[0] = 0;
2645 			MineIData = 0.0f;
2646 		}
2647 		Chunks[0].Rotation.y += 90.0f * TimeDelta;
2648 		while (Chunks[0].Rotation.y > 360.0f) {
2649 			Chunks[0].Rotation.y -= 360.0f;
2650 		}
2651 
2652 		RotationSpeed = 180.0f;
2653 		{
2654 			sVECTOR3D NeedAngle = Rotation;
2655 			Target = FindTargetAndInterceptCourse(ObjectStatus, Location, Rotation,
2656 							      CurrentRotationMat, NeedAngle, 1000000);
2657 
2658 			if (Rotation.y < NeedAngle.y) {
2659 				float NeedAngle_y = Rotation.y + RotationSpeed * TimeDelta;
2660 				if (NeedAngle_y > NeedAngle.y)
2661 					NeedAngle_y = NeedAngle.y;
2662 				NeedAngle.y = NeedAngle_y;
2663 			}
2664 			if (Rotation.y > NeedAngle.y) {
2665 				float NeedAngle_y = Rotation.y - RotationSpeed * TimeDelta;
2666 				if (NeedAngle_y < NeedAngle.y)
2667 					NeedAngle_y = NeedAngle.y;
2668 				NeedAngle.y = NeedAngle_y;
2669 			}
2670 
2671 			NeedAngle.z = Rotation.z;
2672 			NeedAngle.x = Rotation.x;
2673 			SetRotation(NeedAngle - Rotation);
2674 
2675 			auto sharedTarget = Target.lock();
2676 			if (sharedTarget) {
2677 				float MineSpeed = 5.0f;
2678 				sVECTOR3D NeedPoint = sharedTarget->Location;
2679 				float SpeedTmp = MineSpeed * TimeDelta;
2680 				if (SpeedTmp > fabs(Location.y + 2.0f - NeedPoint.y))
2681 					SpeedTmp = fabs(Location.y + 2.0f - NeedPoint.y);
2682 
2683 				if (SpeedTmp != 0.0f) {
2684 					if (Location.y + 2.0f > NeedPoint.y)
2685 						SpeedTmp *= -1.0f;
2686 
2687 					sVECTOR3D VelocityUp = sVECTOR3D{0.0f, SpeedTmp, 0.0f};
2688 					SetLocation(Location + VelocityUp);
2689 				}
2690 
2691 				MineNextFireTime -= TimeDelta;
2692 				if (MineNextFireTime <= 0.0f) {
2693 					cProjectile *Projectile = new cProjectile{206};
2694 					Projectile->SetLocation(Location + sVECTOR3D{0.0f, 0.0f, 0.0f});
2695 
2696 					Projectile->SetRotation(Rotation);
2697 					for (auto &tmpGFX : Projectile->GraphicFX) {
2698 						if (auto sharedGFX = tmpGFX.lock()) {
2699 							sharedGFX->Direction = Orientation;
2700 							sharedGFX->ParticlesPerSec = (int)(sharedGFX->ParticlesPerSec / CurrentPenalty);
2701 
2702 							sharedGFX->Speed = sharedGFX->Speed / CurrentPenalty;
2703 							sharedGFX->Life = sharedGFX->Life * CurrentPenalty;
2704 							sharedGFX->MagnetFactor = sharedGFX->MagnetFactor / (CurrentPenalty * CurrentPenalty);
2705 						}
2706 					}
2707 					Projectile->ObjectStatus = ObjectStatus;
2708 					Projectile->SpeedStart = Projectile->SpeedEnd = Projectile->SpeedStart / CurrentPenalty;
2709 					Projectile->Age = Projectile->Lifetime = Projectile->Age * CurrentPenalty;
2710 					Projectile->Damage /= CurrentPenalty;
2711 					MineNextFireTime = MineReloadTime;
2712 				}
2713 			}
2714 			Target.reset();
2715 		}
2716 		break;
2717 	}
2718 
2719 	return true;
2720 }
2721 
2722 } // astromenace namespace
2723 } // viewizard namespace
2724