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 translate comments
29
30 #include "../core/core.h"
31 #include "../config/config.h"
32 #include "../gfx/shadow_map.h"
33 #include "../command.h"
34 #include "../object3d/weapon/weapon.h"
35 #include "../object3d/space_ship/space_ship.h"
36 #include "../game.h" // FIXME "game.h" should be replaced by individual headers
37
38 // NOTE switch to nested namespace definition (namespace A::B::C { ... }) (since C++17)
39 namespace viewizard {
40 namespace astromenace {
41
42 //------------------------------------------------------------------------------------
43 // переменные
44 //------------------------------------------------------------------------------------
45 std::weak_ptr<cSpaceShip> WorkshopFighterGame{};
46 std::weak_ptr<cSpaceShip> WorkshopNewFighter{};
47 std::weak_ptr<cWeapon> WorkshopNewWeapon{};
48 int CurrentWorkshopNewFighter = 1;
49 int CurrentWorkshopNewWeapon = 1;
50
51
52 sVECTOR3D WorkShopPointCamera;
53 void WorkshopDrawWeapon(cWeapon *Weapon);
54 int CurrentWorkshop = 3;
55
56
57 // небольшая девиация оружия в слотах
58 float CurrentDeviation = 0.0f;
59 float NeedDeviation = vw_fRand0()*5.0f;
60 float CurrentDeviationSum = 0.0f;
61 float CurrentTime = 0.0f;
62
63 // для индикации нужных надписей
64 float CurrentAlert2 = 1.0f;
65 float CurrentAlert3 = 1.0f;
66
67 // можем рисовать
68 bool CanDrawWorkshop = false;
69
70
71 void Workshop_Shipyard();
72 void Workshop_Workshop();
73 void Workshop_Weaponry();
74
75
76 extern bool DragWeapon;
77 extern int DragWeaponNum;
78 extern int DragWeaponLevel;
79 extern int WeaponSetupSlot;
80
81
82
83 //------------------------------------------------------------------------------------
84 // создание корабля игрока, в меню (не при покупке нового корпуса!)
85 //------------------------------------------------------------------------------------
WorkshopCreateShip(int Num)86 void WorkshopCreateShip(int Num)
87 {
88 // создаем объект
89 ReleaseSpaceShip(WorkshopFighterGame);
90
91 int TMPGameEnemyArmorPenalty = GameEnemyArmorPenalty;
92 GameEnemyArmorPenalty = 1;
93
94 WorkshopFighterGame = CreateEarthSpaceFighter(GameConfig().Profile[CurrentProfile].ShipHull);
95 auto sharedWorkshopFighterGame = WorkshopFighterGame.lock();
96 if (!sharedWorkshopFighterGame)
97 return;
98
99 sharedWorkshopFighterGame->ObjectStatus = eObjectStatus::none;
100 sharedWorkshopFighterGame->EngineDestroyType = true;
101 sharedWorkshopFighterGame->ShowStatus = false;
102
103 sharedWorkshopFighterGame->ArmorInitialStatus *= GameConfig().Profile[CurrentProfile].ShipHullUpgrade;
104 sharedWorkshopFighterGame->ArmorCurrentStatus = GameConfig().Profile[CurrentProfile].ArmorStatus;
105
106
107 // создаем оружие
108 for (unsigned i = 0; i < sharedWorkshopFighterGame->WeaponSlots.size(); i++) {
109 if (GameConfig().Profile[CurrentProfile].Weapon[i] &&
110 SetEarthSpaceFighterWeapon(WorkshopFighterGame, i + 1, GameConfig().Profile[CurrentProfile].Weapon[i])) {
111 if (auto sharedWeapon = sharedWorkshopFighterGame->WeaponSlots[i].Weapon.lock()) {
112 // убираем источник света
113 if (auto sharedFire = sharedWeapon->Fire.lock())
114 vw_ReleaseLight(sharedFire->Light);
115
116 sharedWeapon->Ammo = GameConfig().Profile[CurrentProfile].WeaponAmmo[i];
117 sharedWorkshopFighterGame->WeaponSlots[i].YAngle = -GameConfig().Profile[CurrentProfile].WeaponSlotYAngle[i];
118
119 sVECTOR3D NeedAngle = sharedWorkshopFighterGame->Rotation;
120 NeedAngle.y += sharedWorkshopFighterGame->WeaponSlots[i].YAngle;
121 sharedWeapon->SetRotation(NeedAngle);
122 }
123 }
124 }
125
126
127 // создаем системы (визуальные)
128 SetEarthSpaceFighterEngine(WorkshopFighterGame, GameConfig().Profile[CurrentProfile].EngineSystem);
129 SetEarthSpaceFighterArmor(WorkshopFighterGame, GameConfig().Profile[CurrentProfile].ShipHullUpgrade - 1);
130
131 GameEnemyArmorPenalty = TMPGameEnemyArmorPenalty;
132 sharedWorkshopFighterGame->SetLocation(sVECTOR3D{1000.0f,
133 -1000.0f - (sharedWorkshopFighterGame->Height / 2.0f + sharedWorkshopFighterGame->AABB[6].y),
134 -(sharedWorkshopFighterGame->Length / 2.0f + sharedWorkshopFighterGame->AABB[6].z)});
135
136 if (Num == 1)
137 sharedWorkshopFighterGame->SetRotation(sVECTOR3D{0.0f, 150.0f, 0.0f});
138 if (Num == 2)
139 sharedWorkshopFighterGame->SetRotation(sVECTOR3D{0.0f, 170.0f, 0.0f});
140 if (Num == 3)
141 sharedWorkshopFighterGame->SetRotation(sVECTOR3D{0.0f, 180.0f, 0.0f});
142 }
143
144
145
146
147
148
149 //------------------------------------------------------------------------------------
150 // создание корабля для покупки
151 //------------------------------------------------------------------------------------
WorkshopCreateNewShip()152 void WorkshopCreateNewShip()
153 {
154 // создаем объект
155 ReleaseSpaceShip(WorkshopNewFighter);
156
157 int TMPGameEnemyArmorPenalty = GameEnemyArmorPenalty;
158 GameEnemyArmorPenalty = 1;
159
160 WorkshopNewFighter = CreateEarthSpaceFighter(CurrentWorkshopNewFighter);
161 auto sharedWorkshopNewFighter = WorkshopNewFighter.lock();
162 if (!sharedWorkshopNewFighter)
163 return;
164
165 sharedWorkshopNewFighter->ObjectStatus = eObjectStatus::none;
166 sharedWorkshopNewFighter->EngineDestroyType = true;
167
168 GameEnemyArmorPenalty = TMPGameEnemyArmorPenalty;
169 sharedWorkshopNewFighter->SetLocation(sVECTOR3D{2000.0f,
170 -2000.0f - (sharedWorkshopNewFighter->Height / 2.0f + sharedWorkshopNewFighter->AABB[6].y),
171 -(sharedWorkshopNewFighter->Length / 2.0f + sharedWorkshopNewFighter->AABB[6].z)});
172
173 sharedWorkshopNewFighter->SetRotation(sVECTOR3D{0.0f, -45.0f, 0.0f});
174 }
175
176
177
178
179 //------------------------------------------------------------------------------------
180 // создание пушки для покупки
181 //------------------------------------------------------------------------------------
WorkshopCreateNewWeapon()182 void WorkshopCreateNewWeapon()
183 {
184 ReleaseWeapon(WorkshopNewWeapon);
185
186 int TMPGameEnemyArmorPenalty = GameEnemyArmorPenalty;
187 GameEnemyArmorPenalty = 1;
188
189 WorkshopNewWeapon = CreateWeapon(CurrentWorkshopNewWeapon);
190
191 auto sharedWeapon = WorkshopNewWeapon.lock();
192 if (!sharedWeapon)
193 return;
194
195 sharedWeapon->ObjectStatus = eObjectStatus::none;
196 GameEnemyArmorPenalty = TMPGameEnemyArmorPenalty;
197
198 sVECTOR3D Ptmp = sVECTOR3D{0.0f,
199 -(sharedWeapon->Height / 2.0f + sharedWeapon->AABB[6].y),
200 -(sharedWeapon->Length / 2.0f + sharedWeapon->AABB[6].z) - 0.5f};
201 vw_RotatePoint(Ptmp, sVECTOR3D{0.0f, -45.0f, 0.0f});
202
203 sharedWeapon->SetLocation(sVECTOR3D{Ptmp.x + 3000.0f,
204 Ptmp.y - 3000.0f,
205 Ptmp.z});
206
207 sharedWeapon->SetRotation(sVECTOR3D{0.0f, -45.0f, 0.0f});
208
209 // убираем источник света
210 if (auto sharedFire = sharedWeapon->Fire.lock())
211 vw_ReleaseLight(sharedFire->Light);
212 }
213
214
215
216
217
218
219
220 //------------------------------------------------------------------------------------
221 // общая процедура создания
222 //------------------------------------------------------------------------------------
WorkshopCreate()223 void WorkshopCreate()
224 {
225 // все установки в исходные
226 CurrentWorkshopNewFighter = 1;
227 CurrentWorkshopNewWeapon = 1;
228 CurrentDeviation = 0.0f;
229 NeedDeviation = vw_fRand0()*5.0f;
230 CurrentDeviationSum = 0.0f;
231 CurrentTime = 0.0f;
232 CurrentAlert2 = 1.0f;
233 CurrentAlert3 = 1.0f;
234
235 // чтобы только при старте не повоторялись!
236 if (CurrentWorkshopNewFighter == GameConfig().Profile[CurrentProfile].ShipHull)
237 CurrentWorkshopNewFighter++;
238 if (CurrentWorkshopNewFighter > 22)
239 CurrentWorkshopNewFighter = 1;
240
241 WorkshopCreateShip(CurrentWorkshop);
242 WorkshopCreateNewShip();
243 WorkshopCreateNewWeapon();
244
245 // нужно для получение кнопки в веапон
246 NeedCheck = 0;
247
248 CanDrawWorkshop = true;
249 }
250
251
252
253
254
255
256
257
258
259 //------------------------------------------------------------------------------------
260 // удаление всего...
261 //------------------------------------------------------------------------------------
WorkshopDestroyData()262 void WorkshopDestroyData()
263 {
264 ReleaseSpaceShip(WorkshopFighterGame);
265 ReleaseSpaceShip(WorkshopNewFighter);
266 ReleaseWeapon(WorkshopNewWeapon);
267 }
268
269
270
271
272
273
274
275
276
277
278 //------------------------------------------------------------------------------------
279 // покупка-установка и ремонт систем корабля
280 //------------------------------------------------------------------------------------
WorkshopMenu()281 void WorkshopMenu()
282 {
283
284 // небольшое качение... девиация
285 float TimeDelta = vw_GetTimeThread(0) - CurrentTime;
286 if (CurrentTime==0.0f) {
287 CurrentTime = vw_GetTimeThread(0);
288 } else {
289 CurrentTime = vw_GetTimeThread(0);
290 float Sign = 1.0f;
291 // нужно двигать
292 if (NeedDeviation < 0.0f) Sign = -1.0f;
293 if (Sign == 1.0f) {
294 if (NeedDeviation < CurrentDeviationSum)
295 Sign = -1.0f;
296 } else {
297 if (NeedDeviation > CurrentDeviationSum)
298 Sign = 1.0f;
299 }
300
301 CurrentDeviation = Sign*0.7f*TimeDelta;
302
303 if (Sign == 1.0f) {
304 if (NeedDeviation <= CurrentDeviationSum+CurrentDeviation) {
305 CurrentDeviation -= CurrentDeviationSum+CurrentDeviation-NeedDeviation;
306 CurrentDeviationSum += CurrentDeviation;
307 NeedDeviation = vw_fRand0()*5.0f;
308 } else CurrentDeviationSum += CurrentDeviation;
309 } else {
310 if (NeedDeviation >= CurrentDeviationSum+CurrentDeviation) {
311 CurrentDeviation += CurrentDeviationSum+CurrentDeviation-NeedDeviation;
312 CurrentDeviationSum += CurrentDeviation;
313 NeedDeviation = vw_fRand0()*5.0f;
314 } else CurrentDeviationSum += CurrentDeviation;
315 }
316 }
317
318
319
320 // просчитываем индикацию
321 CurrentAlert2 += 0.4f*TimeDelta;
322 if (CurrentAlert2 > 1.0f) CurrentAlert2 = 0.3f;
323 CurrentAlert3 -= 1.9f*TimeDelta;
324 if (CurrentAlert3 < 0.1f) CurrentAlert3 = 1.0f;
325
326
327
328
329
330
331
332
333 // прорисовка 3д части
334 switch (CurrentWorkshop) {
335 // покупка - ремонт корабля
336 case 1:
337 Workshop_Shipyard();
338 break;
339
340
341 // покупка - внутренних систем корабля
342 case 2:
343 Workshop_Workshop();
344 break;
345
346 // покупка - оружия корабля
347 case 3:
348 Workshop_Weaponry();
349 break;
350 }
351
352
353
354
355
356
357 // кнопки
358
359 int X = GameConfig().InternalWidth / 2 - 482;
360 int Y = 180+100*5;
361 if (DrawButton128_2(X,Y, vw_GetTextUTF32("BACK"), MenuContentTransp, false)) {
362 cCommand::GetInstance().Set(eCommand::SWITCH_TO_MISSION);
363 CanDrawWorkshop = false;
364 // ничего не тянем... только включили меню
365 DragWeaponNum = 0;
366 DragWeaponLevel = 0;
367 DragWeapon = false;
368 WeaponSetupSlot = -1;
369 }
370
371
372
373 X = GameConfig().InternalWidth / 2 - 320;
374 bool Off = false;
375 if (CurrentWorkshop == 1)
376 Off = true;
377 if (DrawButton200_2(X,Y, vw_GetTextUTF32("Shipyard"), MenuContentTransp, Off)) {
378 CurrentWorkshop = 1;
379 // используем разные повороты объектов, нужно пересоздать объект
380 WorkshopCreateShip(CurrentWorkshop);
381 WorkshopCreateNewShip();
382 // ничего не тянем... только включили меню
383 DragWeaponNum = 0;
384 DragWeaponLevel = 0;
385 DragWeapon = false;
386 WeaponSetupSlot = -1;
387
388 if (GameConfig().NeedShowHint[1])
389 SetCurrentDialogBox(eDialogBox::ShipyardTipsAndTricks);
390 }
391
392
393 X = GameConfig().InternalWidth / 2 - 100;
394 Off = false;
395 if (CurrentWorkshop == 2)
396 Off = true;
397 if (DrawButton200_2(X,Y, vw_GetTextUTF32("Workshop"), MenuContentTransp, Off)) {
398 CurrentWorkshop = 2;
399 // используем разные повороты объектов, нужно пересоздать объект
400 WorkshopCreateShip(CurrentWorkshop);
401 // ничего не тянем... только включили меню
402 DragWeaponNum = 0;
403 DragWeaponLevel = 0;
404 DragWeapon = false;
405 WeaponSetupSlot = -1;
406
407 if (GameConfig().NeedShowHint[2])
408 SetCurrentDialogBox(eDialogBox::SystemsTipsAndTricks);
409 }
410
411
412 X = GameConfig().InternalWidth / 2 + 120;
413 Off = false;
414 if (CurrentWorkshop == 3)
415 Off = true;
416 if (DrawButton200_2(X,Y, vw_GetTextUTF32("Weaponry"), MenuContentTransp, Off)) {
417 CurrentWorkshop = 3;
418 // используем разные повороты объектов, нужно пересоздать объект
419 WorkshopCreateShip(CurrentWorkshop);
420 WorkshopCreateNewWeapon();
421 // ничего не тянем... только включили меню
422 DragWeaponNum = 0;
423 DragWeaponLevel = 0;
424 DragWeapon = false;
425 WeaponSetupSlot = -1;
426
427 if (GameConfig().NeedShowHint[3])
428 SetCurrentDialogBox(eDialogBox::WeaponryTipsAndTricks);
429 }
430
431
432
433 X = GameConfig().InternalWidth / 2 + 354;
434 if (DrawButton128_2(X,Y, vw_GetTextUTF32("START"), MenuContentTransp, false)) {
435 if (GameConfig().NeedShowHint[4])
436 SetCurrentDialogBox(eDialogBox::ShortkeyTipsAndTricks);
437 else {
438 MenuContentTransp = 0.98f; // небольшая "защелка" от быстрых двойных нажатий на кнопку
439 // ничего не тянем... только включили меню
440 DragWeaponNum = 0;
441 DragWeaponLevel = 0;
442 DragWeapon = false;
443 WeaponSetupSlot = -1;
444 //
445 LastMenuOnOffUpdateTime = vw_GetTimeThread(0);
446 NeedOffMenu = true;
447 }
448 }
449 }
450
451
452
453
454
455
456
457
458
459
460 //------------------------------------------------------------------------------------
461 // Прорисовка 3д части
462 //------------------------------------------------------------------------------------
WorkshopDrawShip(std::weak_ptr<cSpaceShip> & SpaceShip,int Mode)463 void WorkshopDrawShip(std::weak_ptr<cSpaceShip> &SpaceShip, int Mode)
464 {
465 if (!CanDrawWorkshop)
466 return;
467
468 auto sharedSpaceShip = SpaceShip.lock();
469 if (!sharedSpaceShip)
470 return;
471
472 float tmpViewportX, tmpViewportY, tmpViewportWidth, tmpViewportHeight;
473 vw_GetViewport(&tmpViewportX, &tmpViewportY, &tmpViewportWidth, &tmpViewportHeight);
474
475 if (Mode == 1) {
476 WorkShopPointCamera = sVECTOR3D{0.0f, 4.0f, -32.0f};
477 sharedSpaceShip->SetRotation(sVECTOR3D{0.0f, 0.0f, CurrentDeviation});
478 sharedSpaceShip->SetRotation(sVECTOR3D{0.0f, CurrentDeviation / 2.0f, 0.0f});
479
480 vw_SetViewport((GLint)((GameConfig().InternalWidth / 2 - 512) * (tmpViewportWidth / GameConfig().InternalWidth)),
481 0,
482 (GLsizei)(1024 * (tmpViewportWidth / GameConfig().InternalWidth)),
483 (GLsizei)(768 * (tmpViewportHeight / GameConfig().InternalHeight)));
484 vw_ResizeScene(45.0f, 1024.0f/768.0f, 1.0f, 2000.0f);
485 vw_Clear(RI_DEPTH_BUFFER);
486
487 vw_LoadIdentity();
488 vw_SetCameraLocation(sVECTOR3D{WorkShopPointCamera.x + 1000.0f,
489 WorkShopPointCamera.y - 1000.0f,
490 WorkShopPointCamera.z});
491 vw_SetCameraMoveAroundPoint(sVECTOR3D{1000.0f, -1000.0f - 6.0f, 0.0f}, 0.0f, sVECTOR3D{0.0f, 0.0f, 0.0f});
492 vw_CameraLookAt();
493
494
495 bool ShadowMap = false;
496
497 if (GameConfig().ShadowMap > 0) {
498 float EffectiveDistance = 20.0f;
499 ShadowMap_StartRenderToFBO(sVECTOR3D{0.0f, 5.0f, 0.0f}, EffectiveDistance, EffectiveDistance * 2);
500
501 sharedSpaceShip->Draw(true);
502 if (!sharedSpaceShip->WeaponSlots.empty()) {
503 for (auto &tmpWeaponSlot : sharedSpaceShip->WeaponSlots) {
504 if (auto sharedWeapon = tmpWeaponSlot.Weapon.lock())
505 sharedWeapon->Draw(true);
506 }
507 }
508
509 ShadowMap_EndRenderToFBO();
510 ShadowMap = true;
511 ShadowMap_StartFinalRender();
512 }
513
514 sharedSpaceShip->Draw(false, ShadowMap);
515 if (!sharedSpaceShip->WeaponSlots.empty()) {
516 for (auto &tmpWeaponSlot : sharedSpaceShip->WeaponSlots) {
517 if (auto sharedWeapon = tmpWeaponSlot.Weapon.lock())
518 sharedWeapon->Draw(false, ShadowMap);
519 }
520 }
521
522 if (GameConfig().ShadowMap > 0)
523 ShadowMap_EndFinalRender();
524
525 // рисуем эффекты двигателей только для этой модели
526 vw_DrawParticleSystems(sharedSpaceShip->Engines);
527
528 vw_SetCameraLocation(sVECTOR3D{-50.0f, 30.0f, -50.0f});
529 vw_SetViewport(tmpViewportX, tmpViewportY, tmpViewportWidth, tmpViewportHeight);
530 vw_ResizeScene(45.0f, GameConfig().InternalWidth / GameConfig().InternalHeight, 1.0f, 2000.0f);
531 return;
532 }
533
534
535
536 if (Mode == 4) {
537 WorkShopPointCamera = sVECTOR3D{0.0f, 35.0f, -0.01f};
538 sharedSpaceShip->SetRotation(sVECTOR3D{0.0f, 0.0f, CurrentDeviation});
539 vw_SetViewport((GLint)((GameConfig().InternalWidth / 2) * (tmpViewportWidth / GameConfig().InternalWidth)),
540 (GLint)(30 * (tmpViewportHeight / GameConfig().InternalHeight)),
541 (GLsizei)(512 * (tmpViewportWidth / GameConfig().InternalWidth)),
542 (GLsizei)(638 * (tmpViewportHeight / GameConfig().InternalHeight)));
543 vw_ResizeScene(45.0f, 512.0f/608.0f, 1.0f, 2000.0f);
544 vw_Clear(RI_DEPTH_BUFFER);
545 vw_LoadIdentity();
546 vw_SetCameraLocation(sVECTOR3D{WorkShopPointCamera.x + 1000.0f,
547 WorkShopPointCamera.y - 1000.0f,
548 WorkShopPointCamera.z});
549 vw_SetCameraMoveAroundPoint(sVECTOR3D{1000.0f, -1000.0f, 0.0f}, 0.0f, sVECTOR3D{0.0f, 180.0f, 0.0f});
550 vw_CameraLookAt();
551
552
553 bool ShadowMap = false;
554
555 if (GameConfig().ShadowMap > 0) {
556 float EffectiveDistance = 20.0f;
557 ShadowMap_StartRenderToFBO(sVECTOR3D{0.0f, 0.0f, 0.0f}, EffectiveDistance, EffectiveDistance*2);
558
559 sharedSpaceShip->Draw(true);
560 if (!sharedSpaceShip->WeaponSlots.empty()) {
561 for (auto &tmpWeaponSlot : sharedSpaceShip->WeaponSlots) {
562 if (auto sharedWeapon = tmpWeaponSlot.Weapon.lock())
563 sharedWeapon->Draw(true);
564 }
565 }
566
567 ShadowMap_EndRenderToFBO();
568 ShadowMap = true;
569 ShadowMap_StartFinalRender();
570 }
571
572 sharedSpaceShip->Draw(false, ShadowMap);
573 if (!sharedSpaceShip->WeaponSlots.empty()) {
574 for (auto &tmpWeaponSlot : sharedSpaceShip->WeaponSlots) {
575 if (auto sharedWeapon = tmpWeaponSlot.Weapon.lock())
576 sharedWeapon->Draw(false, ShadowMap);
577 }
578 }
579
580 if (GameConfig().ShadowMap > 0)
581 ShadowMap_EndFinalRender();
582
583 // рисуем эффекты двигателей только для этой модели
584 vw_DrawParticleSystems(sharedSpaceShip->Engines);
585
586 vw_SetCameraLocation(sVECTOR3D{-50.0f, 30.0f, -50.0f});
587 vw_SetViewport(tmpViewportX, tmpViewportY, tmpViewportWidth, tmpViewportHeight);
588 vw_ResizeScene(45.0f, GameConfig().InternalWidth / GameConfig().InternalHeight, 1.0f, 2000.0f);
589 return;
590 }
591
592
593
594
595
596
597 if (Mode == 3) {
598 WorkShopPointCamera = sVECTOR3D{0.0f, 10.0f, -34.0f};
599 sharedSpaceShip->SetRotation(sVECTOR3D{0.0f, CurrentDeviation / 2.0f, 0.0f});
600 vw_SetViewport((GLint)((GameConfig().InternalWidth / 2) * (tmpViewportWidth / GameConfig().InternalWidth)),
601 0,
602 (GLsizei)(512 * (tmpViewportWidth / GameConfig().InternalWidth)),
603 (GLsizei)(512 * (tmpViewportHeight / GameConfig().InternalHeight)));
604 vw_ResizeScene(45.0f, 512.0f/512.0f, 1.0f, 2000.0f);
605 vw_Clear(RI_DEPTH_BUFFER);
606 vw_LoadIdentity();
607 vw_SetCameraLocation(sVECTOR3D{WorkShopPointCamera.x / 1.2f + 1000.0f,
608 WorkShopPointCamera.y / 1.2f - 1000.0f,
609 WorkShopPointCamera.z / 1.2f});
610 vw_SetCameraMoveAroundPoint(sVECTOR3D{1000.0f, -1000.0f - sharedSpaceShip->AABB[6].y - sharedSpaceShip->Height / 3.0f, 0.0f}, 0.0f, sVECTOR3D{0.0f, 0.0f, 0.0f});
611 }
612 if (Mode == 2) {
613 WorkShopPointCamera = sVECTOR3D{0.0f, 10.0f, -34.0f};
614 sVECTOR3D PointCameraTMP = WorkShopPointCamera;
615 vw_RotatePoint(PointCameraTMP, sVECTOR3D{0.0f, -90.0f, 0.0f});
616 sharedSpaceShip->SetRotation(sVECTOR3D{0.0f, CurrentDeviation / 2.0f, 0.0f});
617 vw_SetViewport((GLint)((GameConfig().InternalWidth / 2 - 512) * (tmpViewportWidth / GameConfig().InternalWidth)),
618 0,
619 (GLsizei)(512 * (tmpViewportWidth / GameConfig().InternalWidth)),
620 (GLsizei)(512 * (tmpViewportHeight / GameConfig().InternalHeight)));
621 vw_ResizeScene(45.0f, 512.0f/512.0f, 1.0f, 2000.0f);
622 vw_Clear(RI_DEPTH_BUFFER);
623 vw_LoadIdentity();
624 vw_SetCameraLocation(sVECTOR3D{PointCameraTMP.x / 1.2f + 2000.0f,
625 PointCameraTMP.y / 1.2f - 2000.0f,
626 PointCameraTMP.z / 1.2f});
627 vw_SetCameraMoveAroundPoint(sVECTOR3D{2000.0f, -2000.0f - sharedSpaceShip->AABB[6].y - sharedSpaceShip->Height / 3.0f, 0.0f}, 0.0f, sVECTOR3D{0.0f, 170.0f, 0.0f});
628 }
629 vw_CameraLookAt();
630
631
632 bool ShadowMap = false;
633
634 if (GameConfig().ShadowMap > 0) {
635 float EffectiveDistance = 20.0f;
636 ShadowMap_StartRenderToFBO(sVECTOR3D{0.0f, -2.0f, 0.0f}, EffectiveDistance, EffectiveDistance * 2.0f);
637
638 sharedSpaceShip->Draw(true);
639 if (!sharedSpaceShip->WeaponSlots.empty()) {
640 for (auto &tmpWeaponSlot : sharedSpaceShip->WeaponSlots) {
641 if (auto sharedWeapon = tmpWeaponSlot.Weapon.lock())
642 sharedWeapon->Draw(true);
643 }
644 }
645
646 ShadowMap_EndRenderToFBO();
647 ShadowMap = true;
648 ShadowMap_StartFinalRender();
649 }
650
651 sharedSpaceShip->Draw(false, ShadowMap);
652
653 if (!sharedSpaceShip->WeaponSlots.empty()) {
654 for (auto &tmpWeaponSlot : sharedSpaceShip->WeaponSlots) {
655 if (auto sharedWeapon = tmpWeaponSlot.Weapon.lock())
656 sharedWeapon->Draw(false, ShadowMap);
657 }
658 }
659
660 if (GameConfig().ShadowMap > 0)
661 ShadowMap_EndFinalRender();
662
663 // рисуем эффекты двигателей только для этой модели
664 vw_DrawParticleSystems(sharedSpaceShip->Engines);
665
666 vw_SetCameraLocation(sVECTOR3D{-50.0f, 30.0f, -50.0f});
667 vw_SetViewport(tmpViewportX, tmpViewportY, tmpViewportWidth, tmpViewportHeight);
668 vw_ResizeScene(45.0f, GameConfig().InternalWidth / GameConfig().InternalHeight, 1.0f, 2000.0f);
669
670 }
671
672
WorkshopDrawWeapon(cWeapon * Weapon)673 void WorkshopDrawWeapon(cWeapon *Weapon)
674 {
675 if (!CanDrawWorkshop || (Weapon == nullptr))
676 return;
677
678 float tmpViewportX, tmpViewportY, tmpViewportWidth, tmpViewportHeight;
679 vw_GetViewport(&tmpViewportX, &tmpViewportY, &tmpViewportWidth, &tmpViewportHeight);
680
681 // удаление относительно размеров оружия
682 if (Weapon->InternalType == 18 || Weapon->InternalType == 19)
683 WorkShopPointCamera = sVECTOR3D{0.0f, 1.25f, -5.0f};
684 else
685 WorkShopPointCamera = sVECTOR3D{0.0f, 1.0f, -4.0f};
686
687 sVECTOR3D PointCameraTMP = WorkShopPointCamera;
688 vw_RotatePoint(PointCameraTMP, sVECTOR3D{0.0f, -90.0f, 0.0f});
689
690 Weapon->SetRotation(sVECTOR3D{0.0f, CurrentDeviation / 2.0f, 0.0f});
691 vw_SetViewport((GLint)((GameConfig().InternalWidth / 2 - 448) * (tmpViewportWidth / GameConfig().InternalWidth)),
692 (GLint)(105 * (tmpViewportHeight / GameConfig().InternalHeight)),
693 (GLsizei)(384 * (tmpViewportWidth / GameConfig().InternalWidth)),
694 (GLsizei)(350 * (tmpViewportHeight / GameConfig().InternalHeight)));
695 vw_ResizeScene(45.0f, 384.0f/350.0f, 1.0f, 2000.0f);
696 vw_Clear(RI_DEPTH_BUFFER);
697 vw_LoadIdentity();
698 vw_SetCameraLocation(sVECTOR3D{PointCameraTMP.x + 3000.0f,
699 PointCameraTMP.y - 3000.0f,
700 PointCameraTMP.z});
701 vw_SetCameraMoveAroundPoint(sVECTOR3D{3000.0f, -3000.0f, 0.0f}, 0.0f, sVECTOR3D{0.0f, 170.0f, 0.0f});
702 vw_CameraLookAt();
703
704 Weapon->Draw(false);
705
706 vw_SetCameraLocation(sVECTOR3D{-50.0f, 30.0f, -50.0f});
707 vw_ResizeScene(45.0f, GameConfig().InternalWidth / GameConfig().InternalHeight, 1.0f, 2000.0f);
708 vw_SetViewport(tmpViewportX, tmpViewportY, tmpViewportWidth, tmpViewportHeight);
709 }
710
711 } // astromenace namespace
712 } // viewizard namespace
713