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 // TODO split earth fighter and player ship classes
29
30 // TODO don't call GetPreloadedTextureAsset() all the time, use cached texture instead
31
32 // TODO switch to enumeration EngineType in CreateRotateSpaceShipEngine(), CreateSpaceShipEngine()
33
34 #include "space_ship.h"
35 #include "../../assets/texture.h"
36
37 // NOTE switch to nested namespace definition (namespace A::B::C { ... }) (since C++17)
38 namespace viewizard {
39 namespace astromenace {
40
41 namespace {
42
43 struct sEarthSpaceFighterData {
44 float Armor;
45 unsigned int EngineQuantity;
46 std::string Name;
47 };
48
49 const std::vector<sEarthSpaceFighterData> PresetEarthSpaceFighterData{
50 {30, 2, "models/earthfighter/sf-01.vw3d"},
51 {40, 4, "models/earthfighter/sf-02.vw3d"},
52 {60, 4, "models/earthfighter/sf-03.vw3d"},
53 {35, 2, "models/earthfighter/sf-04.vw3d"},
54 {45, 4, "models/earthfighter/sf-05.vw3d"},
55 {50, 2, "models/earthfighter/sf-06.vw3d"},
56 {60, 3, "models/earthfighter/sf-07.vw3d"},
57 {25, 4, "models/earthfighter/sf-08.vw3d"},
58 {55, 2, "models/earthfighter/sf-09.vw3d"},
59 {55, 2, "models/earthfighter/sf-10.vw3d"},
60 {60, 2, "models/earthfighter/sf-11.vw3d"},
61 {70, 2, "models/earthfighter/sf-12.vw3d"},
62 {80, 4, "models/earthfighter/sf-13.vw3d"},
63 {65, 2, "models/earthfighter/sf-14.vw3d"},
64 {70, 2, "models/earthfighter/sf-15.vw3d"},
65 {90, 4, "models/earthfighter/sf-16.vw3d"},
66 {75, 2, "models/earthfighter/sf-17.vw3d"},
67 {110, 4, "models/earthfighter/sf-18.vw3d"},
68 {55, 4, "models/earthfighter/sf-19.vw3d"},
69 {80, 4, "models/earthfighter/sf-20.vw3d"},
70 {80, 2, "models/earthfighter/sf-21.vw3d"},
71 {100, 1, "models/earthfighter/sf-22.vw3d"}
72 };
73
74 } // unnamed namespace
75
76
77 /*
78 * Get engine power.
79 */
GetEnginePower(const int EngineType)80 float GetEnginePower(const int EngineType)
81 {
82 switch (EngineType) {
83 case 1:
84 return 20.0f;
85 case 2:
86 return 25.0f;
87 case 3:
88 return 30.0f;
89 case 4:
90 return 35.0f;
91 default:
92 std::cerr << __func__ << "(): " << "wrong EngineType.\n";
93 break;
94 }
95
96 return 0.0f;
97 }
98
99 /*
100 * Get max engine acceleration.
101 */
GetEngineAcceleration(const int EngineType)102 float GetEngineAcceleration(const int EngineType)
103 {
104 switch (EngineType) {
105 case 1:
106 return 15.0f;
107 case 2:
108 return 19.0f;
109 case 3:
110 return 24.0f;
111 case 4:
112 return 28.0f;
113 default:
114 std::cerr << __func__ << "(): " << "wrong EngineType.\n";
115 break;
116 }
117
118 return 0.0f;
119 }
120
121 /*
122 * Get rotate engine power.
123 */
GetEngineRotatePower(const int EngineType)124 float GetEngineRotatePower(const int EngineType)
125 {
126 switch (EngineType) {
127 case 1:
128 return 15.0f;
129 case 2:
130 return 18.0f;
131 case 3:
132 return 20.0f;
133 case 4:
134 return 23.0f;
135 default:
136 std::cerr << __func__ << "(): " << "wrong EngineType.\n";
137 break;
138 }
139
140 return 0.0f;
141 }
142
143 /*
144 * Setup weapon.
145 */
SetEarthSpaceFighterWeapon(std::weak_ptr<cSpaceShip> & SpaceShip,const int WeaponSlot,const int WeaponNum)146 bool SetEarthSpaceFighterWeapon(std::weak_ptr<cSpaceShip> &SpaceShip, const int WeaponSlot, const int WeaponNum)
147 {
148 auto sharedSpaceShip = SpaceShip.lock();
149 if (!sharedSpaceShip)
150 return false;
151
152 if (static_cast<int>(sharedSpaceShip->WeaponSlots.size()) < WeaponSlot)
153 return false;
154
155 if (!sharedSpaceShip->WeaponSlots[WeaponSlot - 1].Weapon.expired())
156 ReleaseWeapon(sharedSpaceShip->WeaponSlots[WeaponSlot - 1].Weapon);
157
158 sharedSpaceShip->WeaponSlots[WeaponSlot - 1].Weapon = CreateWeapon(WeaponNum);
159
160 auto sharedWeapon = sharedSpaceShip->WeaponSlots[WeaponSlot - 1].Weapon.lock();
161 if (!sharedWeapon)
162 return false;
163
164 if (sharedSpaceShip->WeaponSlots[WeaponSlot - 1].Type < sharedWeapon->WeaponLevel) {
165 ReleaseWeapon(sharedSpaceShip->WeaponSlots[WeaponSlot - 1].Weapon);
166 return false;
167 }
168
169 sharedWeapon->SetLocation(sharedSpaceShip->WeaponSlots[WeaponSlot - 1].Location);
170 sharedWeapon->ObjectStatus = sharedSpaceShip->ObjectStatus;
171
172 return true;
173 }
174
175 /*
176 * Setup engine gfx.
177 */
CreateSpaceShipEngine(std::shared_ptr<cParticleSystem> & ParticleSystem,const int EngineType)178 static void CreateSpaceShipEngine(std::shared_ptr<cParticleSystem> &ParticleSystem, const int EngineType)
179 {
180 ParticleSystem->Texture = GetPreloadedTextureAsset("gfx/flare1.tga");
181
182 static const sRGBCOLOR LightYellow{1.0f, 0.7f, 0.3f};
183 static const sRGBCOLOR Red{1.0f, 0.0f, 0.0f};
184
185 static const sRGBCOLOR MuddyYellow{0.6f, 0.6f, 0.3f};
186 static const sRGBCOLOR LightGreen{0.3f, 1.0f, 0.3f};
187
188 static const sRGBCOLOR Violet{0.5f, 0.5f, 1.0f};
189 static const sRGBCOLOR LightViolet{0.0f, 0.4f, 1.0f};
190
191 static const sRGBCOLOR Turquoise{0.0f, 0.7f, 1.0f};
192 static const sRGBCOLOR LightSkyey{0.7f, 1.0f, 1.0f};
193
194 switch (EngineType) {
195 case 1:
196 ParticleSystem->ColorStart = LightYellow;
197 ParticleSystem->ColorEnd = Red;
198 ParticleSystem->AlphaStart = 1.00f;
199 ParticleSystem->AlphaEnd = 0.10f;
200 ParticleSystem->SizeStart = 0.50f;
201 ParticleSystem->SizeVar = 0.50f;
202 ParticleSystem->SizeEnd = 0.20f;
203 ParticleSystem->Speed = 7.00f;
204 ParticleSystem->SpeedOnCreation = 7.00f;
205 ParticleSystem->SpeedVar = 2.00f;
206 ParticleSystem->Theta = 30.00f;
207 ParticleSystem->Life = 0.50f;
208 ParticleSystem->ParticlesPerSec = 100;
209 ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 1.0f, 0.35f, 0.15f, 0.0f, 0.07f);
210 ParticleSystem->LightNeedDeviation = true;
211 break;
212 case 2:
213 ParticleSystem->ColorStart = MuddyYellow;
214 ParticleSystem->ColorEnd = LightGreen;
215 ParticleSystem->AlphaStart = 1.00f;
216 ParticleSystem->AlphaEnd = 0.00f;
217 ParticleSystem->SizeStart = 0.50f;
218 ParticleSystem->SizeVar = 0.70f;
219 ParticleSystem->SizeEnd = 0.10f;
220 ParticleSystem->Speed = 7.00f;
221 ParticleSystem->SpeedOnCreation = 7.00f;
222 ParticleSystem->SpeedVar = 2.00f;
223 ParticleSystem->Theta = 12.00f;
224 ParticleSystem->Life = 0.50f;
225 ParticleSystem->ParticlesPerSec = 100;
226 ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.4f, 0.75f, 0.15f, 0.0f, 0.07f);
227 ParticleSystem->LightNeedDeviation = true;
228 break;
229 case 3:
230 ParticleSystem->ColorStart = Violet;
231 ParticleSystem->ColorEnd = LightViolet;
232 ParticleSystem->AlphaStart = 1.00f;
233 ParticleSystem->AlphaEnd = 0.00f;
234 ParticleSystem->SizeStart = 0.50f;
235 ParticleSystem->SizeVar = 0.50f;
236 ParticleSystem->SizeEnd = 0.10f;
237 ParticleSystem->Speed = 7.00f;
238 ParticleSystem->SpeedOnCreation = 7.00f;
239 ParticleSystem->SpeedVar = 2.00f;
240 ParticleSystem->Theta = 3.00f;
241 ParticleSystem->Life = 0.50f;
242 ParticleSystem->ParticlesPerSec = 80;
243 ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.25f, 0.25f, 1.0f, 0.0f, 0.07f);
244 ParticleSystem->LightNeedDeviation = true;
245 break;
246 case 4:
247 ParticleSystem->ColorStart = Turquoise;
248 ParticleSystem->ColorEnd = LightSkyey;
249 ParticleSystem->AlphaStart = 1.00f;
250 ParticleSystem->AlphaEnd = 0.00f;
251 ParticleSystem->SizeStart = 0.30f;
252 ParticleSystem->SizeVar = 0.00f;
253 ParticleSystem->SizeEnd = 0.10f;
254 ParticleSystem->Speed = 12.00f;
255 ParticleSystem->SpeedOnCreation = 12.00f;
256 ParticleSystem->Theta = 30.00f;
257 ParticleSystem->Life = 0.30f;
258 ParticleSystem->ParticlesPerSec = 100;
259 ParticleSystem->CreationType = eParticleCreationType::Sphere;
260 ParticleSystem->CreationSize(0.6f, 0.6f, 0.1f);
261 ParticleSystem->IsMagnet = true;
262 ParticleSystem->MagnetFactor = 50.0f;
263 ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.0f, 0.7f, 1.0f, 0.0f, 0.07f);
264 ParticleSystem->LightNeedDeviation = true;
265 break;
266
267 default:
268 std::cerr << __func__ << "(): " << "wrong EngineType.\n";
269 break;
270 }
271 }
272
273 /*
274 * Setup rotate engine gfx.
275 */
CreateRotateSpaceShipEngine(std::shared_ptr<cParticleSystem> & ParticleSystem,const int EngineType)276 static void CreateRotateSpaceShipEngine(std::shared_ptr<cParticleSystem> &ParticleSystem, const int EngineType)
277 {
278 ParticleSystem->Texture = GetPreloadedTextureAsset("gfx/flare1.tga");
279
280 static const sRGBCOLOR LightYellow{1.0f, 0.7f, 0.3f};
281 static const sRGBCOLOR Red{1.0f, 0.0f, 0.0f};
282
283 static const sRGBCOLOR MuddyYellow{0.6f, 0.6f, 0.3f};
284 static const sRGBCOLOR LightGreen{0.3f, 1.0f, 0.3f};
285
286 static const sRGBCOLOR Violet{0.5f, 0.5f, 1.0f};
287 static const sRGBCOLOR LightViolet{0.0f, 0.4f, 1.0f};
288
289 static const sRGBCOLOR Turquoise{0.0f, 0.7f, 1.0f};
290 static const sRGBCOLOR LightSkyey{0.7f, 1.0f, 1.0f};
291
292 switch (EngineType) {
293 case 1:
294 ParticleSystem->ColorStart = LightYellow;
295 ParticleSystem->ColorEnd = Red;
296 ParticleSystem->AlphaStart = 0.60f;
297 ParticleSystem->AlphaEnd = 0.10f;
298 ParticleSystem->SizeStart = 0.50f;
299 ParticleSystem->SizeVar = 0.05f;
300 ParticleSystem->SizeEnd = 0.10f;
301 ParticleSystem->Speed = 5.00f;
302 ParticleSystem->SpeedVar = 5.00f;
303 ParticleSystem->Theta = 40.00f;
304 ParticleSystem->Life = 0.50f;
305 ParticleSystem->IsSuppressed = true;
306 ParticleSystem->ParticlesPerSec = 50;
307 ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 1.0f, 0.35f, 0.15f, 0.0f, 0.2f);
308 ParticleSystem->LightNeedDeviation = true;
309 break;
310 case 2:
311 ParticleSystem->ColorStart = MuddyYellow;
312 ParticleSystem->ColorEnd = LightGreen;
313 ParticleSystem->AlphaStart = 0.60f;
314 ParticleSystem->AlphaEnd = 0.10f;
315 ParticleSystem->SizeStart = 0.5f;
316 ParticleSystem->SizeVar = 0.05f;
317 ParticleSystem->SizeEnd = 0.10f;
318 ParticleSystem->Speed = 5.00f;
319 ParticleSystem->SpeedVar = 5.00f;
320 ParticleSystem->Theta = 30.00f;
321 ParticleSystem->Life = 0.50f;
322 ParticleSystem->IsSuppressed = true;
323 ParticleSystem->ParticlesPerSec = 50;
324 ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.4f, 0.75f, 0.15f, 0.0f, 0.2f);
325 ParticleSystem->LightNeedDeviation = true;
326 break;
327 case 3:
328 ParticleSystem->ColorStart = Violet;
329 ParticleSystem->ColorEnd = LightViolet;
330 ParticleSystem->AlphaStart = 0.60f;
331 ParticleSystem->AlphaEnd = 0.10f;
332 ParticleSystem->SizeStart = 0.5f;
333 ParticleSystem->SizeVar = 0.05f;
334 ParticleSystem->SizeEnd = 0.10f;
335 ParticleSystem->Speed = 5.00f;
336 ParticleSystem->SpeedVar = 5.00f;
337 ParticleSystem->Theta = 30.00f;
338 ParticleSystem->Life = 0.50f;
339 ParticleSystem->IsSuppressed = true;
340 ParticleSystem->ParticlesPerSec = 50;
341 ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.25f, 0.25f, 1.0f, 0.0f, 0.2f);
342 ParticleSystem->LightNeedDeviation = true;
343 break;
344 case 4:
345 ParticleSystem->ColorStart = Turquoise;
346 ParticleSystem->ColorEnd = LightSkyey;
347 ParticleSystem->AlphaStart = 0.60f;
348 ParticleSystem->AlphaEnd = 0.10f;
349 ParticleSystem->SizeStart = 0.5f;
350 ParticleSystem->SizeVar = 0.05f;
351 ParticleSystem->SizeEnd = 0.10f;
352 ParticleSystem->Speed = 5.00f;
353 ParticleSystem->SpeedVar = 5.00f;
354 ParticleSystem->Theta = 30.00f;
355 ParticleSystem->Life = 0.50f;
356 ParticleSystem->IsSuppressed = true;
357 ParticleSystem->ParticlesPerSec = 50;
358 ParticleSystem->Light = vw_CreatePointLight(sVECTOR3D{0.0f, 0.0f, 0.0f}, 0.35f, 0.85f, 1.0f, 0.0f, 0.2f);
359 ParticleSystem->LightNeedDeviation = true;
360 break;
361
362 default:
363 std::cerr << __func__ << "(): " << "wrong EngineType.\n";
364 break;
365 }
366 }
367
368 /*
369 * Setup engines.
370 */
SetEarthSpaceFighterEngine(std::weak_ptr<cSpaceShip> & SpaceShip,const int EngineType)371 void SetEarthSpaceFighterEngine(std::weak_ptr<cSpaceShip> &SpaceShip, const int EngineType)
372 {
373 auto sharedSpaceShip = SpaceShip.lock();
374 if (!sharedSpaceShip)
375 return;
376
377 if (EngineType == 0) {
378 for (auto &tmpEngine : sharedSpaceShip->Engines) {
379 vw_ReleaseParticleSystem(tmpEngine);
380 }
381
382 if (!sharedSpaceShip->EnginesLeft.empty()) {
383 for (auto &tmpEngineLeft : sharedSpaceShip->EnginesLeft) {
384 vw_ReleaseParticleSystem(tmpEngineLeft);
385 }
386 }
387
388 if (!sharedSpaceShip->EnginesRight.empty()) {
389 for (auto &tmpEngineRight : sharedSpaceShip->EnginesRight) {
390 vw_ReleaseParticleSystem(tmpEngineRight);
391 }
392 }
393
394 sharedSpaceShip->MaxSpeed = 0.0f;
395 sharedSpaceShip->MaxAcceler = 0.0f;
396 sharedSpaceShip->MaxSpeedRotate = 0.0f;
397 return;
398 }
399
400 for (unsigned int i = 0; i < sharedSpaceShip->Engines.size(); i++) {
401 vw_ReleaseParticleSystem(sharedSpaceShip->Engines[i]);
402 sharedSpaceShip->Engines[i] = vw_CreateParticleSystem();
403 if (auto sharedEngine = sharedSpaceShip->Engines[i].lock()) {
404 CreateSpaceShipEngine(sharedEngine, EngineType);
405 sharedEngine->SetStartLocation(sharedSpaceShip->EnginesLocation[i]);
406 sharedEngine->Direction = sVECTOR3D{0.0f, 0.0f, -1.0f};
407 }
408 }
409
410 if (!sharedSpaceShip->EnginesLeft.empty()) {
411 for (unsigned int i = 0; i < sharedSpaceShip->EnginesLeft.size(); i++) {
412 vw_ReleaseParticleSystem(sharedSpaceShip->EnginesLeft[i]);
413 sharedSpaceShip->EnginesLeft[i] = vw_CreateParticleSystem();
414 if (auto sharedEngineLeft = sharedSpaceShip->EnginesLeft[i].lock()) {
415 CreateRotateSpaceShipEngine(sharedEngineLeft, EngineType);
416 sharedEngineLeft->SetStartLocation(sharedSpaceShip->EnginesLeftLocation[i]);
417 sharedEngineLeft->Direction = sVECTOR3D{1.0f, 0.0f, 0.6f};
418 sharedEngineLeft->IsSuppressed = true;
419 }
420 }
421 }
422
423 if (!sharedSpaceShip->EnginesRight.empty()) {
424 for (unsigned int i = 0; i < sharedSpaceShip->EnginesRight.size(); i++) {
425 vw_ReleaseParticleSystem(sharedSpaceShip->EnginesRight[i]);
426 sharedSpaceShip->EnginesRight[i] = vw_CreateParticleSystem();
427 if (auto sharedEngineRight = sharedSpaceShip->EnginesRight[i].lock()) {
428 CreateRotateSpaceShipEngine(sharedEngineRight, EngineType);
429 sharedEngineRight->SetStartLocation(sharedSpaceShip->EnginesRightLocation[i]);
430 sharedEngineRight->Direction = sVECTOR3D{-1.0f, 0.0f, 0.6f};
431 sharedEngineRight->IsSuppressed = true;
432 }
433 }
434 }
435
436 sharedSpaceShip->MaxSpeed = GetEnginePower(EngineType) * sharedSpaceShip->Engines.size();
437 sharedSpaceShip->MaxAcceler = GetEngineAcceleration(EngineType) * sharedSpaceShip->Engines.size();
438 sharedSpaceShip->MaxSpeedRotate = GetEngineRotatePower(EngineType) * sharedSpaceShip->Engines.size();
439 }
440
441 /*
442 * Get texture for particular armor.
443 * Note, we use only 4 for player ship, but all 8 could be used by script.
444 */
GetArmorTexture(const int ArmorType)445 static GLtexture GetArmorTexture(const int ArmorType)
446 {
447 switch (ArmorType) {
448 case 0:
449 return GetPreloadedTextureAsset("models/earthfighter/sf-text00.vw2d");
450
451 case 1:
452 return GetPreloadedTextureAsset("models/earthfighter/sf-text04.vw2d");
453
454 case 2:
455 return GetPreloadedTextureAsset("models/earthfighter/sf-text05.vw2d");
456
457 case 3:
458 return GetPreloadedTextureAsset("models/earthfighter/sf-text07.vw2d");
459
460 case 4:
461 return GetPreloadedTextureAsset("models/earthfighter/sf-text08.vw2d");
462
463 case 5:
464 return GetPreloadedTextureAsset("models/earthfighter/sf-text09.vw2d");
465
466 case 6:
467 return GetPreloadedTextureAsset("models/earthfighter/sf-text10.vw2d");
468
469 case 7:
470 return GetPreloadedTextureAsset("models/earthfighter/sf-text06.vw2d");
471
472 default:
473 std::cerr << __func__ << "(): " << "wrong ArmorType.\n";
474 break;
475 }
476
477 return 0;
478 }
479
480 /*
481 * Get illumination texture for particular armor.
482 * Note, we use only 4 for player ship, but all 8 could be used by script.
483 */
GetArmorIllumTexture(const int ArmorType)484 static GLtexture GetArmorIllumTexture(const int ArmorType)
485 {
486 switch (ArmorType) {
487 case 0:
488 return GetPreloadedTextureAsset("models/earthfighter/sf-illum01.vw2d");
489
490 case 1:
491 return GetPreloadedTextureAsset("models/earthfighter/sf-illum02.vw2d");
492
493 case 2:
494 return GetPreloadedTextureAsset("models/earthfighter/sf-illum03.vw2d");
495
496 case 3:
497 return GetPreloadedTextureAsset("models/earthfighter/sf-illum03.vw2d");
498
499 case 4:
500 return GetPreloadedTextureAsset("models/earthfighter/sf-illum03.vw2d");
501
502 case 5:
503 return GetPreloadedTextureAsset("models/earthfighter/sf-illum02.vw2d");
504
505 case 6:
506 return GetPreloadedTextureAsset("models/earthfighter/sf-illum04.vw2d");
507
508 case 7:
509 return GetPreloadedTextureAsset("models/earthfighter/sf-illum03.vw2d");
510
511 default:
512 std::cerr << __func__ << "(): " << "wrong ArmorType.\n";
513 break;
514 }
515
516 return 0;
517 }
518
519 /*
520 * Setup armor.
521 */
SetEarthSpaceFighterArmor(std::weak_ptr<cSpaceShip> & SpaceShip,const int ArmorType)522 void SetEarthSpaceFighterArmor(std::weak_ptr<cSpaceShip> &SpaceShip, const int ArmorType)
523 {
524 auto sharedSpaceShip = SpaceShip.lock();
525 if (!sharedSpaceShip)
526 return;
527
528 for (unsigned int i = 0; i < sharedSpaceShip->Chunks.size(); i++) {
529 sharedSpaceShip->Texture[i] = GetArmorTexture(ArmorType);
530 sharedSpaceShip->TextureIllum[i] = GetArmorIllumTexture(ArmorType);
531 }
532 }
533
534 /*
535 * Get max and min weapon slot angle for particular ship.
536 */
GetShipWeaponSlotAngle(const int ShipNum,const int SlotNum,float & Min,float & Max)537 void GetShipWeaponSlotAngle(const int ShipNum, const int SlotNum, float &Min, float &Max)
538 {
539 Min = 0.0f;
540 Max = 0.0f;
541
542 switch (ShipNum) {
543 case 1:
544 switch (SlotNum) {
545 case 0:
546 Min = -45.0f;
547 Max = 5.0f;
548 break;
549 case 1:
550 Min = -5.0f;
551 Max = 45.0f;
552 break;
553 case 2:
554 Min = -45.0f;
555 Max = 10.0f;
556 break;
557 case 3:
558 Min = -10.0f;
559 Max = 45.0f;
560 break;
561 case 4:
562 Min = -30.0f;
563 Max = 30.0f;
564 break;
565 }
566 break;
567 case 2:
568 switch (SlotNum) {
569 case 0:
570 Min = -45.0f;
571 Max = 5.0f;
572 break;
573 case 1:
574 Min = -5.0f;
575 Max = 45.0f;
576 break;
577 case 2:
578 Min = -45.0f;
579 Max = 10.0f;
580 break;
581 case 3:
582 Min = -10.0f;
583 Max = 45.0f;
584 break;
585 }
586 break;
587 case 3:
588 switch (SlotNum) {
589 case 0:
590 Min = -45.0f;
591 Max = 45.0f;
592 break;
593 case 1:
594 Min = -20.0f;
595 Max = 20.0f;
596 break;
597 case 2:
598 Min = -20.0f;
599 Max = 20.0f;
600 break;
601 }
602 break;
603 case 4:
604 switch (SlotNum) {
605 case 0:
606 Min = -45.0f;
607 Max = 10.0f;
608 break;
609 case 1:
610 Min = -10.0f;
611 Max = 45.0f;
612 break;
613 case 2:
614 Min = -45.0f;
615 Max = 10.0f;
616 break;
617 case 3:
618 Min = -10.0f;
619 Max = 45.0f;
620 break;
621 case 4:
622 Min = -30.0f;
623 Max = 30.0f;
624 break;
625 }
626 break;
627 case 5:
628 switch (SlotNum) {
629 case 0:
630 Min = -45.0f;
631 Max = 5.0f;
632 break;
633 case 1:
634 Min = -5.0f;
635 Max = 45.0f;
636 break;
637 }
638 break;
639 case 6:
640 switch (SlotNum) {
641 case 0:
642 Min = -45.0f;
643 Max = 5.0f;
644 break;
645 case 1:
646 Min = -5.0f;
647 Max = 45.0f;
648 break;
649 case 2:
650 Min = -45.0f;
651 Max = 10.0f;
652 break;
653 case 3:
654 Min = -10.0f;
655 Max = 45.0f;
656 break;
657 case 4:
658 Min = -30.0f;
659 Max = 30.0f;
660 break;
661 }
662 break;
663 case 7:
664 switch (SlotNum) {
665 case 0:
666 Min = -10.0f;
667 Max = 10.0f;
668 break;
669 case 1:
670 Min = -45.0f;
671 Max = 25.0f;
672 break;
673 case 2:
674 Min = -25.0f;
675 Max = 45.0f;
676 break;
677 case 3:
678 Min = -45.0f;
679 Max = 15.0f;
680 break;
681 case 4:
682 Min = -15.0f;
683 Max = 45.0f;
684 break;
685 }
686 break;
687 case 8:
688 switch (SlotNum) {
689 case 0:
690 Min = -10.0f;
691 Max = 10.0f;
692 break;
693 case 1:
694 Min = -10.0f;
695 Max = 10.0f;
696 break;
697 }
698 break;
699 case 9:
700 switch (SlotNum) {
701 case 0:
702 Min = -10.0f;
703 Max = 10.0f;
704 break;
705 case 1:
706 Min = -10.0f;
707 Max = 10.0f;
708 break;
709 }
710 break;
711 case 10:
712 switch (SlotNum) {
713 case 0:
714 Min = -45.0f;
715 Max = 10.0f;
716 break;
717 case 1:
718 Min = -10.0f;
719 Max = 45.0f;
720 break;
721 case 2:
722 Min = -20.0f;
723 Max = 5.0f;
724 break;
725 case 3:
726 Min = -5.0f;
727 Max = 20.0f;
728 break;
729 case 4:
730 Min = -30.0f;
731 Max = 30.0f;
732 break;
733 }
734 break;
735 case 11:
736 switch (SlotNum) {
737 case 0:
738 Min = -30.0f;
739 Max = 0.0f;
740 break;
741 case 1:
742 Min = -0.0f;
743 Max = 30.0f;
744 break;
745 case 2:
746 Min = -30.0f;
747 Max = 30.0f;
748 break;
749 }
750 break;
751 case 12:
752 switch (SlotNum) {
753 case 0:
754 Min = -45.0f;
755 Max = 25.0f;
756 break;
757 case 1:
758 Min = -25.0f;
759 Max = 45.0f;
760 break;
761 case 2:
762 Min = -30.0f;
763 Max = 30.0f;
764 break;
765 }
766 break;
767 case 13:
768 switch (SlotNum) {
769 case 0:
770 Min = -10.0f;
771 Max = 10.0f;
772 break;
773 case 1:
774 Min = -45.0f;
775 Max = 20.0f;
776 break;
777 case 2:
778 Min = -20.0f;
779 Max = 45.0f;
780 break;
781 case 3:
782 Min = -45.0f;
783 Max = 10.0f;
784 break;
785 case 4:
786 Min = -10.0f;
787 Max = 45.0f;
788 break;
789 }
790 break;
791 case 14:
792 switch (SlotNum) {
793 case 0:
794 Min = -30.0f;
795 Max = 5.0f;
796 break;
797 case 1:
798 Min = -5.0f;
799 Max = 30.0f;
800 break;
801 case 2:
802 Min = -35.0f;
803 Max = 5.0f;
804 break;
805 case 3:
806 Min = -5.0f;
807 Max = 35.0f;
808 break;
809 case 4:
810 Min = -15.0f;
811 Max = 15.0f;
812 break;
813 }
814 break;
815 case 15:
816 switch (SlotNum) {
817 case 0:
818 Min = -45.0f;
819 Max = 45.0f;
820 break;
821 case 1:
822 Min = -45.0f;
823 Max = 20.0f;
824 break;
825 case 2:
826 Min = -20.0f;
827 Max = 45.0f;
828 break;
829 }
830 break;
831 case 16:
832 switch (SlotNum) {
833 case 0:
834 Min = -20.0f;
835 Max = 20.0f;
836 break;
837 case 1:
838 Min = -30.0f;
839 Max = 0.0f;
840 break;
841 case 2:
842 Min = -0.0f;
843 Max = 30.0f;
844 break;
845 }
846 break;
847 case 17:
848 switch (SlotNum) {
849 case 0:
850 Min = -30.0f;
851 Max = 5.0f;
852 break;
853 case 1:
854 Min = -5.0f;
855 Max = 30.0f;
856 break;
857 case 2:
858 Min = -45.0f;
859 Max = 10.0f;
860 break;
861 case 3:
862 Min = -10.0f;
863 Max = 45.0f;
864 break;
865 case 4:
866 Min = -20.0f;
867 Max = 20.0f;
868 break;
869 }
870 break;
871 case 18:
872 switch (SlotNum) {
873 case 0:
874 Min = -20.0f;
875 Max = 20.0f;
876 break;
877 case 1:
878 Min = -20.0f;
879 Max = 20.0f;
880 break;
881 case 2:
882 Min = -25.0f;
883 Max = 5.0f;
884 break;
885 case 3:
886 Min = -5.0f;
887 Max = 25.0f;
888 break;
889 }
890 break;
891 case 19:
892 switch (SlotNum) {
893 case 0:
894 Min = -45.0f;
895 Max = 45.0f;
896 break;
897 case 1:
898 Min = -45.0f;
899 Max = 10.0f;
900 break;
901 case 2:
902 Min = -10.0f;
903 Max = 45.0f;
904 break;
905 }
906 break;
907 case 20:
908 switch (SlotNum) {
909 case 0:
910 Min = -10.0f;
911 Max = 10.0f;
912 break;
913 case 1:
914 Min = -10.0f;
915 Max = 10.0f;
916 break;
917 case 2:
918 Min = -45.0f;
919 Max = 20.0f;
920 break;
921 case 3:
922 Min = -20.0f;
923 Max = 45.0f;
924 break;
925 }
926 break;
927 case 21:
928 switch (SlotNum) {
929 case 0:
930 Min = -25.0f;
931 Max = 0.0f;
932 break;
933 case 1:
934 Min = -0.0f;
935 Max = 25.0f;
936 break;
937 case 2:
938 Min = -20.0f;
939 Max = 20.0f;
940 break;
941 }
942 break;
943 case 22:
944 switch (SlotNum) {
945 case 0:
946 Min = -25.0f;
947 Max = 25.0f;
948 break;
949 }
950 break;
951
952 default:
953 std::cerr << __func__ << "(): " << "wrong ShipNum.\n";
954 break;
955 }
956 }
957
958 /*
959 * Get armor for particular ship.
960 */
GetShipArmor(const int SpaceShipNum)961 float GetShipArmor(const int SpaceShipNum)
962 {
963 return PresetEarthSpaceFighterData[SpaceShipNum - 1].Armor;
964 }
965
966 /*
967 * Constructor.
968 */
cEarthSpaceFighter(const int SpaceShipNum)969 cEarthSpaceFighter::cEarthSpaceFighter(const int SpaceShipNum)
970 {
971 if ((SpaceShipNum <= 0) ||
972 (static_cast<unsigned>(SpaceShipNum) > PresetEarthSpaceFighterData.size())) {
973 std::cerr << __func__ << "(): "
974 << "Could not init cEarthSpaceFighter object with Number "
975 << SpaceShipNum << "\n";
976 return;
977 }
978
979 ObjectStatus = eObjectStatus::Ally;
980 ObjectType = eObjectType::EarthFighter;
981 InternalType = SpaceShipNum;
982 PromptDrawDist2 = 100.0f;
983
984 ArmorCurrentStatus = ArmorInitialStatus =
985 PresetEarthSpaceFighterData[SpaceShipNum - 1].Armor; // GameEnemyArmorPenalty for enemies only
986 LoadObjectData(PresetEarthSpaceFighterData[SpaceShipNum - 1].Name, *this);
987
988 Engines.resize(PresetEarthSpaceFighterData[SpaceShipNum - 1].EngineQuantity);
989 EnginesLocation.resize(Engines.size());
990
991 EnginesLeftLocation.resize(1);
992 EnginesLeft.resize(1);
993
994 EnginesRightLocation.resize(1);
995 EnginesRight.resize(1);
996
997 switch (SpaceShipNum) {
998 case 1:
999 WeaponSlots.reserve(5);
1000 WeaponSlots.emplace_back(1, sVECTOR3D{4.4f, -0.1f, -6.0f});
1001 WeaponSlots.emplace_back(1, sVECTOR3D{-4.4f, -0.1f, -6.0f});
1002 WeaponSlots.emplace_back(1, sVECTOR3D{1.9f, -1.25f, 6.5f});
1003 WeaponSlots.emplace_back(1, sVECTOR3D{-1.9f, -1.25f, 6.5f});
1004 WeaponSlots.emplace_back(4, sVECTOR3D{0.0f, -1.20f, 1.0f});
1005 EnginesLocation[0] = sVECTOR3D{3.0f, -1.2f, -4.7f};
1006 EnginesLocation[1] = sVECTOR3D{-3.0f, -1.2f, -4.7f};
1007 EnginesLeftLocation[0] = sVECTOR3D{1.0f, -0.7f, 3.7f};
1008 EnginesRightLocation[0] = sVECTOR3D{-1.0f, -0.7f, 3.7f};
1009 break;
1010
1011 case 2:
1012 WeaponSlots.reserve(4);
1013 WeaponSlots.emplace_back(1, sVECTOR3D{3.45f, 1.03f, -8.5f});
1014 WeaponSlots.emplace_back(1, sVECTOR3D{-3.45f, 1.03f, -8.5f});
1015 WeaponSlots.emplace_back(1, sVECTOR3D{1.7f, -1.03f, 3.9f});
1016 WeaponSlots.emplace_back(1, sVECTOR3D{-1.7f, -1.03f, 3.9f});
1017 EnginesLocation[0] = sVECTOR3D{4.9f, -1.1f, -8.9f};
1018 EnginesLocation[1] = sVECTOR3D{-4.9f, -1.1f, -8.9f};
1019 EnginesLocation[2] = sVECTOR3D{0.75f, 0.7f, -9.6f};
1020 EnginesLocation[3] = sVECTOR3D{-0.75f, 0.7f, -9.6f};
1021 EnginesLeftLocation[0] = sVECTOR3D{1.0f, -0.7f, 5.7f};
1022 EnginesRightLocation[0] = sVECTOR3D{-1.0f, -0.7f, 5.7f};
1023 break;
1024
1025 case 3:
1026 WeaponSlots.reserve(3);
1027 WeaponSlots.emplace_back(5, sVECTOR3D{0.0f, -1.75f, 3.5f});
1028 WeaponSlots.emplace_back(1, sVECTOR3D{7.15f, -0.38f, -4.4f});
1029 WeaponSlots.emplace_back(1, sVECTOR3D{-7.15f, -0.38f, -4.4f});
1030 EnginesLocation[0] = sVECTOR3D{4.4f, -3.0f, -9.7f};
1031 EnginesLocation[1] = sVECTOR3D{-4.4f, -3.0f, -9.7f};
1032 EnginesLocation[2] = sVECTOR3D{4.4f, 3.0f, -9.7f};
1033 EnginesLocation[3] = sVECTOR3D{-4.4f, 3.0f, -9.7f};
1034 EnginesLeftLocation[0] = sVECTOR3D{0.8f, -1.6f, 8.7f};
1035 EnginesRightLocation[0] = sVECTOR3D{-0.8f, -1.6f, 8.7f};
1036 break;
1037
1038 case 4:
1039 WeaponSlots.reserve(5);
1040 WeaponSlots.emplace_back(1, sVECTOR3D{4.10f, 1.4f, -2.5f});
1041 WeaponSlots.emplace_back(1, sVECTOR3D{-4.10f, 1.4f, -2.5f});
1042 WeaponSlots.emplace_back(1, sVECTOR3D{5.10f, -1.2f, -2.5f});
1043 WeaponSlots.emplace_back(1, sVECTOR3D{-5.10f, -1.2f, -2.5f});
1044 WeaponSlots.emplace_back(4, sVECTOR3D{0.0f, -1.5f, 5.3f});
1045 EnginesLocation[0] = sVECTOR3D{0.8f, 0.1f, -9.6f};
1046 EnginesLocation[1] = sVECTOR3D{-0.8f, 0.1f, -9.6f};
1047 EnginesLeftLocation[0] = sVECTOR3D{1.6f, -0.9f, 5.7f};
1048 EnginesRightLocation[0] = sVECTOR3D{-1.6f, -0.9f, 5.7f};
1049 break;
1050
1051 case 5:
1052 WeaponSlots.reserve(2);
1053 WeaponSlots.emplace_back(2, sVECTOR3D{4.0f, -0.5f, 1.0f});
1054 WeaponSlots.emplace_back(2, sVECTOR3D{-4.0f, -0.5f, 1.0f});
1055 EnginesLocation[0] = sVECTOR3D{6.72f, -0.28f, -7.98f};
1056 EnginesLocation[1] = sVECTOR3D{-6.72f, -0.28f, -7.98f};
1057 EnginesLocation[2] = sVECTOR3D{6.72f, -1.96f, -7.28f};
1058 EnginesLocation[3] = sVECTOR3D{-6.72f, -1.96f, -7.28f};
1059 EnginesLeftLocation[0] = sVECTOR3D{1.4f, 0.0f, 3.92f};
1060 EnginesRightLocation[0] = sVECTOR3D{-1.4f, 0.0f, 3.92f};
1061 break;
1062
1063 case 6:
1064 WeaponSlots.reserve(5);
1065 WeaponSlots.emplace_back(2, sVECTOR3D{2.80f, 0.25f, -7.0f});
1066 WeaponSlots.emplace_back(2, sVECTOR3D{-2.80f, 0.25f, -7.0f});
1067 WeaponSlots.emplace_back(1, sVECTOR3D{5.20f, 0.6f, -6.0f});
1068 WeaponSlots.emplace_back(1, sVECTOR3D{-5.20f, 0.6f, -6.0f});
1069 WeaponSlots.emplace_back(4, sVECTOR3D{0.0f, -1.3f, 2.6f});
1070 EnginesLocation[0] = sVECTOR3D{0.6f, 0.45f, -9.9f};
1071 EnginesLocation[1] = sVECTOR3D{-0.6f, 0.45f, -9.9f};
1072 EnginesLeftLocation[0] = sVECTOR3D{1.6f, -0.9f, 4.7f};
1073 EnginesRightLocation[0] = sVECTOR3D{-1.6f, -0.9f, 4.7f};
1074 break;
1075
1076 case 7:
1077 WeaponSlots.reserve(5);
1078 WeaponSlots.emplace_back(5, sVECTOR3D{0.0f, -0.2f, 0.0f});
1079 WeaponSlots.emplace_back(1, sVECTOR3D{4.3f, -1.25f, -1.4f});
1080 WeaponSlots.emplace_back(1, sVECTOR3D{-4.3f, -1.25f, -1.4f});
1081 WeaponSlots.emplace_back(1, sVECTOR3D{8.2f, -0.75f, -3.6f});
1082 WeaponSlots.emplace_back(1, sVECTOR3D{-8.2f, -0.75f, -3.6f});
1083 EnginesLocation[0] = sVECTOR3D{3.75f, -0.5f, -10.9f};
1084 EnginesLocation[1] = sVECTOR3D{0.0f, 0.4f, -8.3f};
1085 EnginesLocation[2] = sVECTOR3D{-3.75f, -0.5f, -10.9f};
1086 EnginesLeftLocation[0] = sVECTOR3D{1.4f, 0.1f, 1.1f};
1087 EnginesRightLocation[0] = sVECTOR3D{-1.4f, 0.1f, 1.1f};
1088 break;
1089
1090 case 8:
1091 WeaponSlots.reserve(2);
1092 WeaponSlots.emplace_back(1, sVECTOR3D{1.0f, -0.3f, 0.4f});
1093 WeaponSlots.emplace_back(1, sVECTOR3D{-1.0f, -0.3f, 0.4f});
1094 EnginesLocation[0] = sVECTOR3D{3.5f, 1.4f, -7.4f};
1095 EnginesLocation[1] = sVECTOR3D{-3.5f, 1.4f, -7.4f};
1096 EnginesLocation[2] = sVECTOR3D{3.65f, 0.5f, -7.9f};
1097 EnginesLocation[3] = sVECTOR3D{-3.65f, 0.5f, -7.9f};
1098 EnginesLeftLocation[0] = sVECTOR3D{1.0f, 0.0f, 2.4f};
1099 EnginesRightLocation[0] = sVECTOR3D{-1.0f, 0.0f, 2.4f};
1100 break;
1101
1102 case 9:
1103 WeaponSlots.reserve(2);
1104 WeaponSlots.emplace_back(2, sVECTOR3D{1.2f, 0.2f, 1.6f});
1105 WeaponSlots.emplace_back(2, sVECTOR3D{-1.2f, 0.2f, 1.6f});
1106 EnginesLocation[0] = sVECTOR3D{3.30f, -1.20f, -0.7f};
1107 EnginesLocation[1] = sVECTOR3D{-3.30f, -1.20f, -0.7f};
1108 EnginesLeftLocation[0] = sVECTOR3D{1.0f, 0.2f, 2.2f};
1109 EnginesRightLocation[0] = sVECTOR3D{-1.0f, 0.2f, 2.2f};
1110 break;
1111
1112 case 10:
1113 WeaponSlots.reserve(5);
1114 WeaponSlots.emplace_back(2, sVECTOR3D{5.05f, -1.8f, -1.7f});
1115 WeaponSlots.emplace_back(2, sVECTOR3D{-5.05f, -1.8f, -1.7f});
1116 WeaponSlots.emplace_back(2, sVECTOR3D{2.55f, -0.7f, -0.7f});
1117 WeaponSlots.emplace_back(2, sVECTOR3D{-2.55f, -0.7f, -0.7f});
1118 WeaponSlots.emplace_back(4, sVECTOR3D{0.0f, -0.9f, 6.1f});
1119 EnginesLocation[0] = sVECTOR3D{0.8f, 0.55f, -9.9f};
1120 EnginesLocation[1] = sVECTOR3D{-0.8f, 0.55f, -9.9f};
1121 EnginesLeftLocation[0] = sVECTOR3D{1.6f, -0.4f, 5.3f};
1122 EnginesRightLocation[0] = sVECTOR3D{-1.6f, -0.4f, 5.3f};
1123 break;
1124
1125 case 11:
1126 WeaponSlots.reserve(3);
1127 WeaponSlots.emplace_back(2, sVECTOR3D{2.0f, -0.55f, -2.2f});
1128 WeaponSlots.emplace_back(2, sVECTOR3D{-2.0f, -0.55f, -2.2f});
1129 WeaponSlots.emplace_back(1, sVECTOR3D{0.0f, -0.7f, 2.2f});
1130 EnginesLocation[0] = sVECTOR3D{4.35f, -0.35f, -4.4f};
1131 EnginesLocation[1] = sVECTOR3D{-4.35f, -0.35f, -4.4f};
1132 EnginesLeftLocation[0] = sVECTOR3D{1.5f, -0.6f, 2.0f};
1133 EnginesRightLocation[0] = sVECTOR3D{-1.5f, -0.6f, 2.0f};
1134 break;
1135
1136 case 12:
1137 WeaponSlots.reserve(3);
1138 WeaponSlots.emplace_back(2, sVECTOR3D{2.25f, -0.85f, 3.3f});
1139 WeaponSlots.emplace_back(2, sVECTOR3D{-2.25f, -0.85f, 3.3f});
1140 WeaponSlots.emplace_back(4, sVECTOR3D{0.0f, -0.35f, 2.8f});
1141 EnginesLocation[0] = sVECTOR3D{4.8f, -1.2f, -2.8f};
1142 EnginesLocation[1] = sVECTOR3D{-4.8f, -1.2f, -2.8f};
1143 EnginesLeftLocation[0] = sVECTOR3D{1.2f, -0.2f, 6.3f};
1144 EnginesRightLocation[0] = sVECTOR3D{-1.2f, -0.2f, 6.3f};
1145 break;
1146
1147 case 13:
1148 WeaponSlots.reserve(5);
1149 WeaponSlots.emplace_back(5, sVECTOR3D{0.0f, -2.15f, -4.4f});
1150 WeaponSlots.emplace_back(4, sVECTOR3D{7.2f, 1.85f, -5.6f});
1151 WeaponSlots.emplace_back(4, sVECTOR3D{-7.2f, 1.85f, -5.6f});
1152 WeaponSlots.emplace_back(1, sVECTOR3D{3.05f, -1.95f, -0.4f});
1153 WeaponSlots.emplace_back(1, sVECTOR3D{-3.05f, -1.95f, -0.4f});
1154 EnginesLocation[0] = sVECTOR3D{2.2f, -1.35f, -9.8f};
1155 EnginesLocation[1] = sVECTOR3D{-2.2f, -1.35f, -9.8f};
1156 EnginesLocation[2] = sVECTOR3D{1.1f, -1.0f, -9.8f};
1157 EnginesLocation[3] = sVECTOR3D{-1.1f, -1.0f, -9.8f};
1158 EnginesLeftLocation[0] = sVECTOR3D{1.4f, -0.1f, 0.5f};
1159 EnginesRightLocation[0] = sVECTOR3D{-1.4f, -0.1f, 0.5f};
1160 break;
1161
1162 case 14:
1163 WeaponSlots.reserve(5);
1164 WeaponSlots.emplace_back(2, sVECTOR3D{1.70f, -1.1f, 5.5f});
1165 WeaponSlots.emplace_back(2, sVECTOR3D{-1.70f, -1.1f, 5.5f});
1166 WeaponSlots.emplace_back(2, sVECTOR3D{4.1f, 0.2f, -6.3f});
1167 WeaponSlots.emplace_back(2, sVECTOR3D{-4.1f, 0.2f, -6.3f});
1168 WeaponSlots.emplace_back(4, sVECTOR3D{0.0f, -0.9f, 3.3f});
1169 EnginesLocation[0] = sVECTOR3D{0.85f, 0.1f, -8.1f};
1170 EnginesLocation[1] = sVECTOR3D{-0.85f, 0.1f, -8.1f};
1171 EnginesLeftLocation[0] = sVECTOR3D{1.3f, -0.7f, 6.3f};
1172 EnginesRightLocation[0] = sVECTOR3D{-1.3f, -0.7f, 6.3f};
1173 break;
1174
1175 case 15:
1176 WeaponSlots.reserve(3);
1177 WeaponSlots.emplace_back(4, sVECTOR3D{0.0f, -0.7f, 1.3f});
1178 WeaponSlots.emplace_back(3, sVECTOR3D{7.1f, -0.2f, -5.8f});
1179 WeaponSlots.emplace_back(3, sVECTOR3D{-7.1f, -0.2f, -5.8f});
1180 EnginesLocation[0] = sVECTOR3D{4.75f, -0.5f, -7.2f};
1181 EnginesLocation[1] = sVECTOR3D{-4.75f, -0.5f, -7.2f};
1182 EnginesLeftLocation[0] = sVECTOR3D{1.0f, -0.6f, 6.25f};
1183 EnginesRightLocation[0] = sVECTOR3D{-1.0f, -0.6f, 6.25f};
1184 break;
1185
1186 case 16:
1187 WeaponSlots.reserve(3);
1188 WeaponSlots.emplace_back(3, sVECTOR3D{0.0f, -1.2f, 7.7f});
1189 WeaponSlots.emplace_back(4, sVECTOR3D{2.0f, -1.05f, 0.4f});
1190 WeaponSlots.emplace_back(4, sVECTOR3D{-2.0f, -1.05f, 0.4f});
1191 EnginesLocation[0] = sVECTOR3D{3.8f, -0.75f, -11.4f};
1192 EnginesLocation[1] = sVECTOR3D{-3.8f, -0.75f, -11.4f};
1193 EnginesLocation[2] = sVECTOR3D{3.5f, 0.85f, -10.85f};
1194 EnginesLocation[3] = sVECTOR3D{-3.5f, 0.85f, -10.85f};
1195 EnginesLeftLocation[0] = sVECTOR3D{1.6f, -0.6f, 6.25f};
1196 EnginesRightLocation[0] = sVECTOR3D{-1.6f, -0.6f, 6.25f};
1197 break;
1198
1199 case 17:
1200 WeaponSlots.reserve(5);
1201 WeaponSlots.emplace_back(3, sVECTOR3D{3.10f, 0.2f, -4.6f});
1202 WeaponSlots.emplace_back(3, sVECTOR3D{-3.10f, 0.2f, -4.6f});
1203 WeaponSlots.emplace_back(2, sVECTOR3D{5.85f, -0.5f, -5.6f});
1204 WeaponSlots.emplace_back(2, sVECTOR3D{-5.85f, -0.5f, -5.6f});
1205 WeaponSlots.emplace_back(4, sVECTOR3D{0.0f, -0.5f, -0.5f});
1206 EnginesLocation[0] = sVECTOR3D{0.65f, 0.2f, -8.2f};
1207 EnginesLocation[1] = sVECTOR3D{-0.65f, 0.2f, -8.2f};
1208 EnginesLeftLocation[0] = sVECTOR3D{1.4f, -0.5f, 6.25f};
1209 EnginesRightLocation[0] = sVECTOR3D{-1.4f, -0.5f, 6.25f};
1210 break;
1211
1212 case 18:
1213 WeaponSlots.reserve(4);
1214 WeaponSlots.emplace_back(5, sVECTOR3D{1.7f, -2.5f, -4.4f});
1215 WeaponSlots.emplace_back(5, sVECTOR3D{-1.7f, -2.5f, -4.4f});
1216 WeaponSlots.emplace_back(3, sVECTOR3D{5.1f, -1.0f, -5.4f});
1217 WeaponSlots.emplace_back(3, sVECTOR3D{-5.1f, -1.0f, -5.4f});
1218 EnginesLocation[0] = sVECTOR3D{7.5f, 0.15f, -9.1f};
1219 EnginesLocation[1] = sVECTOR3D{-7.5f, 0.15f, -9.1f};
1220 EnginesLocation[2] = sVECTOR3D{7.7f, -1.15f, -9.6f};
1221 EnginesLocation[3] = sVECTOR3D{-7.7f, -1.15f, -9.6f};
1222 EnginesLeftLocation[0] = sVECTOR3D{1.9f, -1.6f, 6.25f};
1223 EnginesRightLocation[0] = sVECTOR3D{-1.9f, -1.6f, 6.25f};
1224 break;
1225
1226 case 19:
1227 WeaponSlots.reserve(3);
1228 WeaponSlots.emplace_back(2, sVECTOR3D{0.0f, -0.75f, 0.0f});
1229 WeaponSlots.emplace_back(2, sVECTOR3D{4.7f, -0.4f, -5.0f});
1230 WeaponSlots.emplace_back(2, sVECTOR3D{-4.7f, -0.4f, -5.0f});
1231 EnginesLocation[0] = sVECTOR3D{6.3f, 0.60f, -8.1f};
1232 EnginesLocation[1] = sVECTOR3D{-6.3f, 0.60f, -8.1f};
1233 EnginesLocation[2] = sVECTOR3D{6.7f, -0.60f, -8.8f};
1234 EnginesLocation[3] = sVECTOR3D{-6.7f, -0.60f, -8.8f};
1235 EnginesLeftLocation[0] = sVECTOR3D{1.45f, 0.05f, 5.0f};
1236 EnginesRightLocation[0] = sVECTOR3D{-1.45f, 0.05f, 5.0f};
1237 break;
1238
1239 case 20:
1240 WeaponSlots.reserve(4);
1241 WeaponSlots.emplace_back(3, sVECTOR3D{0.80f, -0.8f, -2.3f});
1242 WeaponSlots.emplace_back(3, sVECTOR3D{-0.80f, -0.8f, -2.3f});
1243 WeaponSlots.emplace_back(4, sVECTOR3D{3.9f, -1.25f, -3.2f});
1244 WeaponSlots.emplace_back(4, sVECTOR3D{-3.9f, -1.25f, -3.2f});
1245 EnginesLocation[0] = sVECTOR3D{3.45f, -0.3f, -7.3f};
1246 EnginesLocation[1] = sVECTOR3D{-3.45f, -0.3f, -7.3f};
1247 EnginesLocation[2] = sVECTOR3D{4.55f, -0.5f, -7.0f};
1248 EnginesLocation[3] = sVECTOR3D{-4.55f, -0.5f, -7.0f};
1249 EnginesLeftLocation[0] = sVECTOR3D{1.0f, -0.4f, 1.45f};
1250 EnginesRightLocation[0] = sVECTOR3D{-1.0f, -0.4f, 1.45f};
1251 break;
1252
1253 case 21:
1254 WeaponSlots.reserve(3);
1255 WeaponSlots.emplace_back(2, sVECTOR3D{2.05f, -0.22f, -1.2f});
1256 WeaponSlots.emplace_back(2, sVECTOR3D{-2.05f, -0.22f, -1.2f});
1257 WeaponSlots.emplace_back(2, sVECTOR3D{0.0f, -0.5f, 0.5f});
1258 EnginesLocation[0] = sVECTOR3D{0.7f, 0.0f, -4.4f};
1259 EnginesLocation[1] = sVECTOR3D{-0.7f, 0.0f, -4.4f};
1260 EnginesLeftLocation[0] = sVECTOR3D{1.0f, -0.4f, 3.0f};
1261 EnginesRightLocation[0] = sVECTOR3D{-1.0f, -0.4f, 3.0f};
1262 break;
1263
1264 case 22:
1265 WeaponSlots.emplace_back(3, sVECTOR3D{0.0f, 0.05f, 3.6f});
1266 EnginesLocation[0] = sVECTOR3D{0.0f, 0.3f, -5.2f};
1267 EnginesLeftLocation[0] = sVECTOR3D{1.9f, -0.3f, 2.6f};
1268 EnginesRightLocation[0] = sVECTOR3D{-1.9f, -0.3f, 2.6f};
1269 break;
1270 }
1271
1272 // make sure, that we have all weapon slots properly sorted, since for player's ship we
1273 // need this in weaponry menu and HUD
1274 auto comparison = [] (const sShipWeaponSlot &A, const sShipWeaponSlot &B) {
1275 if (A.Location.z == B.Location.z) {
1276 // for pair, we should have fixed order of weapon slots by X
1277 if (std::fabs(A.Location.x) == std::fabs(B.Location.x))
1278 return A.Location.x > B.Location.x;
1279 // closest to center by X weapon slots should be first
1280 return std::fabs(A.Location.x) < std::fabs(B.Location.x);
1281 }
1282
1283 return A.Location.z > B.Location.z;
1284 };
1285 std::sort(WeaponSlots.begin(), WeaponSlots.end(), comparison);
1286 }
1287
1288 } // astromenace namespace
1289 } // viewizard namespace
1290