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 ostringstream is not so fast, move all string initialization into setup,
29 // all ostringstream-related code should be called only one time in init
30
31 // TODO translate comments
32
33 #include "../game.h"
34 #include "../config/config.h"
35 #include "../ui/font.h"
36 #include "../assets/texture.h"
37 #include "../object3d/space_ship/space_ship.h"
38 #include <sstream>
39 #include <iomanip>
40
41 // NOTE switch to nested namespace definition (namespace A::B::C { ... }) (since C++17)
42 namespace viewizard {
43 namespace astromenace {
44
45 extern std::weak_ptr<cSpaceShip> WorkshopFighterGame;
46 extern std::weak_ptr<cSpaceShip> WorkshopNewFighter;
47 extern int CurrentWorkshopNewFighter;
48 extern int CurrentWorkshopNewWeapon;
49 extern float CurrentAlert2;
50 extern float CurrentAlert3;
51
52 void WorkshopDrawShip(std::weak_ptr<cSpaceShip> &SpaceShip, int Mode);
53 void WorkshopCreateNewShip();
54 int GetSystemCost(int Num);
55 int GetWeaponCost(int Num, int Ammo, int AmmoStart);
56 int GetWeaponBaseCost(int Num);
57
58 // что рисовать в диалоге 6,7,8
59 extern std::weak_ptr<cSpaceShip> DialogSpaceShip;
60
61
62
63
64
65
66 //------------------------------------------------------------------------------------
67 // название корабля
68 //------------------------------------------------------------------------------------
GetWorkshopShipName(int Num)69 const char *GetWorkshopShipName(int Num)
70 {
71 switch (Num) {
72 case 1:
73 return "Cobra";
74 case 2:
75 return "SpaceEagle";
76 case 3:
77 return "FireStorm";
78 case 4:
79 return "Hedgehog";
80 case 5:
81 return "Thunder";
82 case 6:
83 return "Excalibur";
84 case 7:
85 return "DarkStar";
86 case 8:
87 return "Scorpion";
88 case 9:
89 return "Runner";
90 case 10:
91 return "Kronos";
92 case 11:
93 return "Chameleon";
94 case 12:
95 return "Falcon";
96 case 13:
97 return "DeathRipple";
98 case 14:
99 return "AstroSword";
100 case 15:
101 return "Pulser";
102 case 16:
103 return "ClumsyMace";
104 case 17:
105 return "Raptor";
106 case 18:
107 return "Destroyer";
108 case 19:
109 return "AstroSpear";
110 case 20:
111 return "Mite";
112 case 21:
113 return "Viper";
114 case 22:
115 return "BlackIce";
116
117 default:
118 std::cerr << __func__ << "(): " << "wrong Num.\n";
119 break;
120 }
121
122 return nullptr;
123 }
124
125
126
127
128 //------------------------------------------------------------------------------------
129 // тип корабля
130 //------------------------------------------------------------------------------------
GetShipGroupTitle(int Num)131 const char *GetShipGroupTitle(int Num)
132 {
133 switch (Num) {
134 case 1:
135 case 4:
136 case 6:
137 case 10:
138 case 12:
139 case 14:
140 case 15:
141 case 17:
142 case 20:
143 return "Fighter";
144 case 2:
145 case 5:
146 case 19:
147 return "Interceptor";
148 case 3:
149 case 16:
150 case 18:
151 return "Bomber";
152 case 7:
153 case 13:
154 return "Attack Ship";
155 case 8:
156 case 9:
157 case 11:
158 case 21:
159 case 22:
160 return "Scout";
161
162 default:
163 std::cerr << __func__ << "(): " << "wrong Num.\n";
164 break;
165 }
166
167 return nullptr;
168 }
169
170
171
172 //------------------------------------------------------------------------------------
173 // стоимость корпуса
174 //------------------------------------------------------------------------------------
GetWorkshopShipCost(int Num)175 int GetWorkshopShipCost(int Num)
176 {
177 switch (Num) {
178 case 1:
179 return 1100;
180 case 2:
181 return 900;
182 case 3:
183 return 1500;
184 case 4:
185 return 1300;
186 case 5:
187 return 1350;
188 case 6:
189 return 2400;
190 case 7:
191 return 3000;
192 case 8:
193 return 3500;
194 case 9:
195 return 4000;
196 case 10:
197 return 6000;
198 case 11:
199 return 4500;
200 case 12:
201 return 5000;
202 case 13:
203 return 9000;
204 case 14:
205 return 7500;
206 case 15:
207 return 7000;
208 case 16:
209 return 9000;
210 case 17:
211 return 10000;
212 case 18:
213 return 12000;
214 case 19:
215 return 5000;
216 case 20:
217 return 9000;
218 case 21:
219 return 10000;
220 case 22:
221 return 8000;
222
223 default:
224 std::cerr << __func__ << "(): " << "wrong Num.\n";
225 break;
226 }
227
228 return 0;
229 }
230
231
232
233
234
235
GetWorkshopShipRepairCost(int Num,std::weak_ptr<cSpaceShip> & Fighter)236 int GetWorkshopShipRepairCost(int Num, std::weak_ptr<cSpaceShip> &Fighter)
237 {
238 int ShipCost = GetWorkshopShipCost(Num) * GameConfig().Profile[CurrentProfile].ShipHullUpgrade;
239 // расчет стоимости ремонта корабля
240 if (auto sharedFighter = Fighter.lock())
241 ShipCost -= (int)(ShipCost * (sharedFighter->ArmorCurrentStatus / sharedFighter->ArmorInitialStatus));
242 return ShipCost;
243 }
244
245
246
247
248
249
GetWorkshopShipFullCost(int Num,std::weak_ptr<cSpaceShip> & Fighter)250 int GetWorkshopShipFullCost(int Num, std::weak_ptr<cSpaceShip> &Fighter)
251 {
252 // полная стоимость корпуса корабля с повреждениями корабля
253 int ShipCost = GetWorkshopShipCost(Num) * GameConfig().Profile[CurrentProfile].ShipHullUpgrade -
254 GetWorkshopShipRepairCost(Num, Fighter);
255
256
257 // прибавить стоимость оружия
258 if (auto sharedWorkshopFighterGame = WorkshopFighterGame.lock()) {
259 if (!sharedWorkshopFighterGame->WeaponSlots.empty()) {
260 for (auto &tmpWeaponSlot : sharedWorkshopFighterGame->WeaponSlots) {
261 if (auto sharedWeapon = tmpWeaponSlot.Weapon.lock())
262 ShipCost += GetWeaponCost(sharedWeapon->InternalType,
263 sharedWeapon->Ammo,
264 sharedWeapon->AmmoStart);
265 }
266 }
267 }
268
269 // прибавить стоимость систем
270 if (GameConfig().Profile[CurrentProfile].EngineSystem)
271 ShipCost += GetSystemCost(GameConfig().Profile[CurrentProfile].EngineSystem);
272 if (GameConfig().Profile[CurrentProfile].PowerSystem)
273 ShipCost += GetSystemCost(GameConfig().Profile[CurrentProfile].PowerSystem + 4);
274 if (GameConfig().Profile[CurrentProfile].TargetingSystem)
275 ShipCost += GetSystemCost(GameConfig().Profile[CurrentProfile].TargetingSystem + 8);
276 if (GameConfig().Profile[CurrentProfile].TargetingMechanicSystem)
277 ShipCost += GetSystemCost(GameConfig().Profile[CurrentProfile].TargetingMechanicSystem + 12);
278 if (GameConfig().Profile[CurrentProfile].AdvancedProtectionSystem)
279 ShipCost += GetSystemCost(GameConfig().Profile[CurrentProfile].AdvancedProtectionSystem + 16);
280
281 return ShipCost;
282 }
283
284
285
286
287
288
289
290
291
292 //------------------------------------------------------------------------------------
293 // создание корабля игрока при покупке нового корпуса
294 //------------------------------------------------------------------------------------
WorkshopCreateBuyShip()295 void WorkshopCreateBuyShip()
296 {
297 // продаем все оружие и все системы
298 // 1 - Системы
299 int EngineSystem = GameConfig().Profile[CurrentProfile].EngineSystem;
300 if (GameConfig().Profile[CurrentProfile].EngineSystem)
301 ChangeGameConfig().Profile[CurrentProfile].Money += GetSystemCost(GameConfig().Profile[CurrentProfile].EngineSystem);
302 ChangeGameConfig().Profile[CurrentProfile].EngineSystem = 0;
303
304 int PowerSystem = GameConfig().Profile[CurrentProfile].PowerSystem;
305 if (GameConfig().Profile[CurrentProfile].PowerSystem)
306 ChangeGameConfig().Profile[CurrentProfile].Money += GetSystemCost(GameConfig().Profile[CurrentProfile].PowerSystem+4);
307 ChangeGameConfig().Profile[CurrentProfile].PowerSystem = 0;
308
309 int TargetingSystem = GameConfig().Profile[CurrentProfile].TargetingSystem;
310 if (GameConfig().Profile[CurrentProfile].TargetingSystem)
311 ChangeGameConfig().Profile[CurrentProfile].Money += GetSystemCost(GameConfig().Profile[CurrentProfile].TargetingSystem+8);
312 ChangeGameConfig().Profile[CurrentProfile].TargetingSystem = 0;
313
314 int TargetingMechanicSystem = GameConfig().Profile[CurrentProfile].TargetingMechanicSystem;
315 if (GameConfig().Profile[CurrentProfile].TargetingMechanicSystem)
316 ChangeGameConfig().Profile[CurrentProfile].Money += GetSystemCost(GameConfig().Profile[CurrentProfile].TargetingMechanicSystem+12);
317 ChangeGameConfig().Profile[CurrentProfile].TargetingMechanicSystem = 0;
318
319 int AdvancedProtectionSystem = GameConfig().Profile[CurrentProfile].AdvancedProtectionSystem;
320 if (GameConfig().Profile[CurrentProfile].AdvancedProtectionSystem)
321 ChangeGameConfig().Profile[CurrentProfile].Money += GetSystemCost(GameConfig().Profile[CurrentProfile].AdvancedProtectionSystem+16);
322 ChangeGameConfig().Profile[CurrentProfile].AdvancedProtectionSystem = 0;
323
324 // 2 - Оружие
325 unsigned OldWeaponQuantity = 0;
326 if (auto sharedWorkshopFighterGame = WorkshopFighterGame.lock()) {
327 OldWeaponQuantity = sharedWorkshopFighterGame->WeaponSlots.size();
328 for (auto &tmpWeaponSlot : sharedWorkshopFighterGame->WeaponSlots) {
329 if (auto sharedWeapon = tmpWeaponSlot.Weapon.lock()) {
330 ChangeGameConfig().Profile[CurrentProfile].Money += GetWeaponCost(sharedWeapon->InternalType,
331 sharedWeapon->Ammo,
332 sharedWeapon->AmmoStart);
333 ReleaseWeapon(tmpWeaponSlot.Weapon);
334 }
335 }
336 }
337
338 // 3 - корпус
339 ChangeGameConfig().Profile[CurrentProfile].Money +=
340 GetWorkshopShipCost(ChangeGameConfig().Profile[CurrentProfile].ShipHull) *
341 GameConfig().Profile[CurrentProfile].ShipHullUpgrade -
342 GetWorkshopShipRepairCost(ChangeGameConfig().Profile[CurrentProfile].ShipHull, WorkshopFighterGame);
343
344
345 // сейчас у нас все в "деньгах", покупаем корпус
346 ChangeGameConfig().Profile[CurrentProfile].ShipHull = CurrentWorkshopNewFighter;
347 ChangeGameConfig().Profile[CurrentProfile].Money -= GetWorkshopShipCost(GameConfig().Profile[CurrentProfile].ShipHull);
348
349
350
351 // создаем объект
352 ReleaseSpaceShip(WorkshopFighterGame);
353
354 int TMPGameEnemyArmorPenalty = GameEnemyArmorPenalty;
355 GameEnemyArmorPenalty = 1;
356
357 WorkshopFighterGame = CreateEarthSpaceFighter(GameConfig().Profile[CurrentProfile].ShipHull);
358 auto sharedWorkshopFighterGame = WorkshopFighterGame.lock();
359 if (!sharedWorkshopFighterGame)
360 return;
361
362 sharedWorkshopFighterGame->ObjectStatus = eObjectStatus::none;
363 sharedWorkshopFighterGame->EngineDestroyType = true;
364 sharedWorkshopFighterGame->ShowStatus = false;
365 ChangeGameConfig().Profile[CurrentProfile].ArmorStatus = sharedWorkshopFighterGame->ArmorCurrentStatus;
366 ChangeGameConfig().Profile[CurrentProfile].ShipHullUpgrade = 1;
367
368
369 // пытаемся купить
370
371 // 1 - Системы
372 if (EngineSystem != 0)
373 if (GameConfig().Profile[CurrentProfile].Money >= GetSystemCost(EngineSystem)) {
374 ChangeGameConfig().Profile[CurrentProfile].Money -= GetSystemCost(EngineSystem);
375 ChangeGameConfig().Profile[CurrentProfile].EngineSystem = EngineSystem;
376 }
377 if (PowerSystem != 0)
378 if (GameConfig().Profile[CurrentProfile].Money >= GetSystemCost(PowerSystem+4)) {
379 ChangeGameConfig().Profile[CurrentProfile].Money -= GetSystemCost(PowerSystem+4);
380 ChangeGameConfig().Profile[CurrentProfile].PowerSystem = PowerSystem;
381 }
382 if (TargetingSystem != 0)
383 if (GameConfig().Profile[CurrentProfile].Money >= GetSystemCost(TargetingSystem+8)) {
384 ChangeGameConfig().Profile[CurrentProfile].Money -= GetSystemCost(TargetingSystem+8);
385 ChangeGameConfig().Profile[CurrentProfile].TargetingSystem = TargetingSystem;
386 }
387 if (TargetingMechanicSystem != 0)
388 if (GameConfig().Profile[CurrentProfile].Money >= GetSystemCost(TargetingMechanicSystem+12)) {
389 ChangeGameConfig().Profile[CurrentProfile].Money -= GetSystemCost(TargetingMechanicSystem+12);
390 ChangeGameConfig().Profile[CurrentProfile].TargetingMechanicSystem = TargetingMechanicSystem;
391 }
392 if (AdvancedProtectionSystem != 0)
393 if (GameConfig().Profile[CurrentProfile].Money >= GetSystemCost(AdvancedProtectionSystem+16)) {
394 ChangeGameConfig().Profile[CurrentProfile].Money -= GetSystemCost(AdvancedProtectionSystem+16);
395 ChangeGameConfig().Profile[CurrentProfile].AdvancedProtectionSystem = AdvancedProtectionSystem;
396 }
397
398
399
400 // покупаем оружие, если можем... нет - ставим что продали его (это сделали ранее)
401 // всегда покупаем новое, т.е. с полным боекомплектом!
402 for (unsigned i = 0; i < sharedWorkshopFighterGame->WeaponSlots.size(); i++) {
403 if (GameConfig().Profile[CurrentProfile].Weapon[i] != 0) {
404 if (GameConfig().Profile[CurrentProfile].Money >= GetWeaponBaseCost(GameConfig().Profile[CurrentProfile].Weapon[i])) {
405 if (SetEarthSpaceFighterWeapon(WorkshopFighterGame, i + 1, GameConfig().Profile[CurrentProfile].Weapon[i])) {
406 if (auto sharedWeapon = sharedWorkshopFighterGame->WeaponSlots[i].Weapon.lock()) {
407 if (auto sharedFire = sharedWeapon->Fire.lock())
408 vw_ReleaseLight(sharedFire->Light);
409
410 ChangeGameConfig().Profile[CurrentProfile].Money -= GetWeaponBaseCost(GameConfig().Profile[CurrentProfile].Weapon[i]);
411 ChangeGameConfig().Profile[CurrentProfile].WeaponAmmo[i] = sharedWeapon->AmmoStart;
412 ChangeGameConfig().Profile[CurrentProfile].WeaponSlotYAngle[i] = 0.0f;
413 }
414 } else { // если поставить не смогли - не такой слот
415 ChangeGameConfig().Profile[CurrentProfile].Weapon[i] = 0;
416 ChangeGameConfig().Profile[CurrentProfile].WeaponAmmo[i] = 0;
417 }
418 } else { // если не хватило денег снова купить
419 ChangeGameConfig().Profile[CurrentProfile].Weapon[i] = 0;
420 ChangeGameConfig().Profile[CurrentProfile].WeaponAmmo[i] = 0;
421 }
422 }
423 }
424 // если было больше слотов чем есть сейчас
425 if (OldWeaponQuantity > sharedWorkshopFighterGame->WeaponSlots.size()) {
426 for (unsigned j = 0; j < OldWeaponQuantity; j++) {
427 if (sharedWorkshopFighterGame->WeaponSlots.size() <= j)
428 ChangeGameConfig().Profile[CurrentProfile].Weapon[j] = 0;
429 }
430 }
431
432
433 // создаем системы (визуальные)
434 SetEarthSpaceFighterEngine(WorkshopFighterGame, GameConfig().Profile[CurrentProfile].EngineSystem);
435 SetEarthSpaceFighterArmor(WorkshopFighterGame, GameConfig().Profile[CurrentProfile].ShipHullUpgrade - 1);
436
437 GameEnemyArmorPenalty = TMPGameEnemyArmorPenalty;
438 sharedWorkshopFighterGame->SetLocation(sVECTOR3D{1000.0f,
439 -1000.0f - (sharedWorkshopFighterGame->Height / 2.0f + sharedWorkshopFighterGame->AABB[6].y),
440 -(sharedWorkshopFighterGame->Length / 2.0f + sharedWorkshopFighterGame->AABB[6].z)});
441 // чтобы оружие заняло свое место...
442 sharedWorkshopFighterGame->Update(vw_GetTimeThread(0));
443
444 sharedWorkshopFighterGame->SetRotation(sVECTOR3D{0.0f, 150.0f, 0.0f});
445 }
446
447
448
449
450
BuyShip()451 void BuyShip()
452 {
453 // сбрасываем особенные настройки слотов оружия
454 if (auto sharedWorkshopFighterGame = WorkshopFighterGame.lock()) {
455 for (unsigned i = 0; i < sharedWorkshopFighterGame->WeaponSlots.size(); i++) {
456 ChangeGameConfig().Profile[CurrentProfile].WeaponSlotYAngle[i] = 0;
457 }
458 }
459
460 // создаем новый корабль
461 WorkshopCreateBuyShip();
462
463 // переводим на другой корабль
464 CurrentWorkshopNewFighter++;
465 if (CurrentWorkshopNewFighter == GameConfig().Profile[CurrentProfile].ShipHull)
466 CurrentWorkshopNewFighter++;
467 if (CurrentWorkshopNewFighter > 22)
468 CurrentWorkshopNewFighter = 1;
469 // если это 1-й, переводим на 2-й
470 if (CurrentWorkshopNewFighter == GameConfig().Profile[CurrentProfile].ShipHull)
471 CurrentWorkshopNewFighter++;
472 WorkshopCreateNewShip();
473 }
474
475
476
477
478
479
RepairShip()480 void RepairShip()
481 {
482 auto sharedWorkshopFighterGame = WorkshopFighterGame.lock();
483 if (!sharedWorkshopFighterGame)
484 return;
485
486 // смотрим, если денег достаточно для полного ремонта - делаем его
487 if (GameConfig().Profile[CurrentProfile].Money >= GetWorkshopShipRepairCost(GameConfig().Profile[CurrentProfile].ShipHull, WorkshopFighterGame)) {
488 ChangeGameConfig().Profile[CurrentProfile].Money -= GetWorkshopShipRepairCost(GameConfig().Profile[CurrentProfile].ShipHull, WorkshopFighterGame);
489 ChangeGameConfig().Profile[CurrentProfile].ArmorStatus = sharedWorkshopFighterGame->ArmorInitialStatus;
490 sharedWorkshopFighterGame->ArmorCurrentStatus = sharedWorkshopFighterGame->ArmorInitialStatus;
491 return;
492 }
493
494
495 // вычисляем, сколько можем отремонтировать
496 float ArmorRepair = sharedWorkshopFighterGame->ArmorInitialStatus - sharedWorkshopFighterGame->ArmorCurrentStatus;
497 float RepairCost = static_cast<float>(GetWorkshopShipRepairCost(GameConfig().Profile[CurrentProfile].ShipHull, WorkshopFighterGame));
498 // сколько можем отремонтировать
499 float CanRepair = ArmorRepair * (GameConfig().Profile[CurrentProfile].Money / RepairCost);
500 // ремонтируем сколько можем
501 sharedWorkshopFighterGame->ArmorCurrentStatus += CanRepair;
502 ChangeGameConfig().Profile[CurrentProfile].ArmorStatus = sharedWorkshopFighterGame->ArmorCurrentStatus;
503 // это будет стоить все имеющиеся деньги
504 ChangeGameConfig().Profile[CurrentProfile].Money = 0;
505
506 // выводим диалог с надписью, что не достаточно денег для полного ремонта
507 SetCurrentDialogBox(eDialogBox::RepairShip);
508 }
509
510
511
512
513
UpgradeShip()514 void UpgradeShip()
515 {
516 auto sharedWorkshopFighterGame = WorkshopFighterGame.lock();
517 if (!sharedWorkshopFighterGame)
518 return;
519
520 // ув. данные о базовой прочности корабля
521 float OldStr = sharedWorkshopFighterGame->ArmorInitialStatus;
522 sharedWorkshopFighterGame->ArmorInitialStatus /= GameConfig().Profile[CurrentProfile].ShipHullUpgrade;
523
524 // ув. данные о номере апгрейда
525 ChangeGameConfig().Profile[CurrentProfile].ShipHullUpgrade++;
526
527 sharedWorkshopFighterGame->ArmorInitialStatus *= GameConfig().Profile[CurrentProfile].ShipHullUpgrade;
528 sharedWorkshopFighterGame->ArmorCurrentStatus = sharedWorkshopFighterGame->ArmorInitialStatus - OldStr +
529 GameConfig().Profile[CurrentProfile].ArmorStatus;
530
531 ChangeGameConfig().Profile[CurrentProfile].ArmorStatus = sharedWorkshopFighterGame->ArmorCurrentStatus;
532
533
534 // вычитаем деньги за апгрейд
535 ChangeGameConfig().Profile[CurrentProfile].Money -= GetWorkshopShipCost(GameConfig().Profile[CurrentProfile].ShipHull);
536
537
538 // сообщаем о новых возможностях и т.п. которые дает этот апгрейд
539 SetEarthSpaceFighterArmor(WorkshopFighterGame, GameConfig().Profile[CurrentProfile].ShipHullUpgrade - 1);
540 }
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558 //------------------------------------------------------------------------------------
559 // покупка-апгрейд корпуса
560 //------------------------------------------------------------------------------------
Workshop_Shipyard()561 void Workshop_Shipyard()
562 {
563
564 // затемнение при выводе
565 int SizeI;
566 sRECT SrcRect, DstRect;
567
568
569 // затемнение
570 SrcRect(0,0,256,256 );
571 DstRect(GameConfig().InternalWidth/2-480, 100-32, GameConfig().InternalWidth/2-32, 450+32);
572 vw_Draw2D(DstRect, SrcRect, GetPreloadedTextureAsset("menu/back_spot2.tga"), true, 0.45f * MenuContentTransp);
573 DstRect(GameConfig().InternalWidth/2+32, 100-32, GameConfig().InternalWidth/2+480, 450+32);
574 vw_Draw2D(DstRect, SrcRect, GetPreloadedTextureAsset("menu/back_spot2.tga"), true, 0.45f * MenuContentTransp);
575
576
577
578 vw_End2DMode();
579 WorkshopDrawShip(WorkshopFighterGame, 3);
580 WorkshopDrawShip(WorkshopNewFighter, 2);
581 vw_Start2DMode(-1,1);
582
583
584 // условия, при которых корабль купить можно
585 bool CanBuy = false;
586 if (GetWorkshopShipFullCost(GameConfig().Profile[CurrentProfile].ShipHull, WorkshopFighterGame) +
587 GameConfig().Profile[CurrentProfile].Money >= GetWorkshopShipCost(CurrentWorkshopNewFighter))
588 CanBuy = true;
589
590
591 // на новом корабле
592 vw_SetFontSize(24);
593 vw_DrawTextUTF32(GameConfig().InternalWidth/2-445, 600, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, MenuContentTransp, vw_GetTextUTF32("Ship Stock"));
594 ResetFontSize();
595
596
597 // вывод названия корабля
598 std::ostringstream tmpStream;
599 tmpStream << std::fixed << std::setprecision(0)
600 << vw_GetText(GetWorkshopShipName(CurrentWorkshopNewFighter)) << " Mk" << 1;
601 vw_DrawText(GameConfig().InternalWidth/2-448, 50+6, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::yellow}, MenuContentTransp, tmpStream.str());
602 if (DrawButton128_2(GameConfig().InternalWidth/2-197,50, vw_GetTextUTF32("Info"), MenuContentTransp, false)) {
603 SetCurrentDialogBox(eDialogBox::ShowShipInfo);
604 DialogSpaceShip = WorkshopNewFighter;
605 }
606
607 auto sharedWorkshopNewFighter = WorkshopNewFighter.lock();
608 if (!sharedWorkshopNewFighter)
609 return;
610
611 // находим смещение, чтобы было красиво
612 int SmSizeI = vw_TextWidthUTF32(vw_GetTextUTF32("Armor:"));
613 int SmSizeI2 = vw_TextWidthUTF32(vw_GetTextUTF32("Weapon Slots:"));
614 int SmSizeI3 = vw_TextWidthUTF32(vw_GetTextUTF32("Slot Levels:"));
615 SmSizeI = std::max({SmSizeI, SmSizeI2, SmSizeI3});
616
617 vw_DrawTextUTF32(GameConfig().InternalWidth/2-440, 110, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, 0.5f*MenuContentTransp, vw_GetTextUTF32("Armor:"));
618 tmpStream.clear();
619 tmpStream.str(std::string{});
620 tmpStream << sharedWorkshopNewFighter->ArmorInitialStatus;
621 vw_DrawText(GameConfig().InternalWidth/2-440+14+SmSizeI, 110, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, 0.5f*MenuContentTransp, tmpStream.str());
622
623 vw_DrawTextUTF32(GameConfig().InternalWidth/2-440, 130, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, 0.5f*MenuContentTransp, vw_GetTextUTF32("Weapon Slots:"));
624 tmpStream.clear();
625 tmpStream.str(std::string{});
626 tmpStream << sharedWorkshopNewFighter->WeaponSlots.size();
627 vw_DrawText(GameConfig().InternalWidth/2-440+14+SmSizeI, 130, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, 0.5f*MenuContentTransp, tmpStream.str());
628
629 vw_DrawTextUTF32(GameConfig().InternalWidth/2-440, 150, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, 0.5f*MenuContentTransp, vw_GetTextUTF32("Slot Levels:"));
630 tmpStream.clear();
631 tmpStream.str(std::string{});
632 if (!sharedWorkshopNewFighter->WeaponSlots.empty())
633 tmpStream << sharedWorkshopNewFighter->WeaponSlots[0].Type;
634 for (unsigned i = 1; i < sharedWorkshopNewFighter->WeaponSlots.size(); i++) {
635 tmpStream << "/" << sharedWorkshopNewFighter->WeaponSlots[i].Type;
636 }
637 vw_DrawText(GameConfig().InternalWidth/2-440+14+SmSizeI, 150, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, 0.5f*MenuContentTransp, tmpStream.str());
638
639 // вывод стоимости корабля
640 float tmpTransp{MenuContentTransp};
641 sRGBCOLOR tmpColor{eRGBCOLOR::white};
642 if (!CanBuy) {
643 tmpTransp = MenuContentTransp * CurrentAlert3;
644 tmpColor = sRGBCOLOR{eRGBCOLOR::orange};
645 }
646 tmpStream.clear();
647 tmpStream.str(std::string{});
648 tmpStream << vw_GetText("Ship Hull Cost") << ": " << GetWorkshopShipCost(CurrentWorkshopNewFighter);
649 vw_DrawText(GameConfig().InternalWidth/2-438, 420, 0, 0, 1.0f, tmpColor, tmpTransp, tmpStream.str());
650
651
652 // рамки
653 SrcRect(0,0,400,35 );
654 DstRect(GameConfig().InternalWidth/2-457, 100-11, GameConfig().InternalWidth/2-57, 100+35-11);
655 vw_Draw2D(DstRect, SrcRect, GetPreloadedTextureAsset("menu/workshop_panel4.tga"), true, MenuContentTransp);
656
657 SrcRect(0,0,400,173 );
658 DstRect(GameConfig().InternalWidth/2-457, 450-13, GameConfig().InternalWidth/2-57, 450+173-13);
659 vw_Draw2D(DstRect, SrcRect, GetPreloadedTextureAsset("menu/workshop_panel1.tga"), true, MenuContentTransp);
660
661
662 // проверяем колесо мышки
663 DstRect(GameConfig().InternalWidth/2-457, 100+35-11, GameConfig().InternalWidth/2-57, 450-13);
664 if (vw_MouseOverRect(DstRect)) {
665 if (vw_GetWheelStatus() != 0 && !isDialogBoxDrawing()) {
666 CurrentWorkshopNewFighter += vw_GetWheelStatus();
667
668 if (CurrentWorkshopNewFighter < 1)
669 CurrentWorkshopNewFighter = 22;
670 if (CurrentWorkshopNewFighter > 22)
671 CurrentWorkshopNewFighter = 1;
672
673 WorkshopCreateNewShip();
674
675 vw_ResetWheelStatus();
676 }
677 } else if (vw_GetWheelStatus() != 0) {
678 vw_ResetWheelStatus();
679 }
680
681 if (DrawButton128_2(GameConfig().InternalWidth/2-395, 482, vw_GetTextUTF32("Prev"), MenuContentTransp, false)) {
682 CurrentWorkshopNewFighter--;
683 if (CurrentWorkshopNewFighter < 1)
684 CurrentWorkshopNewFighter = 22;
685 WorkshopCreateNewShip();
686 }
687 if (DrawButton128_2(GameConfig().InternalWidth/2-247, 482, vw_GetTextUTF32("Next"), MenuContentTransp, false)) {
688 CurrentWorkshopNewFighter++;
689 if (CurrentWorkshopNewFighter > 22)
690 CurrentWorkshopNewFighter = 1;
691 WorkshopCreateNewShip();
692 }
693 if (DrawButton200_2(GameConfig().InternalWidth/2-357, 533, vw_GetTextUTF32("Buy Ship"), MenuContentTransp, !CanBuy))
694 BuyShip();
695
696
697
698
699
700
701
702
703 // на корабле игрока
704 vw_SetFontSize(24);
705 vw_DrawTextUTF32(GameConfig().InternalWidth/2+445-vw_TextWidthUTF32(vw_GetTextUTF32("Player Ship")), 600, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, MenuContentTransp, vw_GetTextUTF32("Player Ship"));
706 ResetFontSize();
707
708 // вывод названия корабля
709 tmpStream.clear();
710 tmpStream.str(std::string{});
711 tmpStream << vw_GetText(GetWorkshopShipName(GameConfig().Profile[CurrentProfile].ShipHull))
712 << " Mk" << static_cast<int>(GameConfig().Profile[CurrentProfile].ShipHullUpgrade);
713 vw_DrawText(GameConfig().InternalWidth/2+64, 56, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::yellow}, MenuContentTransp, tmpStream.str());
714
715 if (DrawButton128_2(GameConfig().InternalWidth/2+315, 50, vw_GetTextUTF32("Info"), MenuContentTransp, false)) {
716 SetCurrentDialogBox(eDialogBox::ShowShipInfo);
717 DialogSpaceShip = WorkshopFighterGame;
718 }
719
720
721
722 auto sharedWorkshopFighterGame = WorkshopFighterGame.lock();
723 if (!sharedWorkshopFighterGame)
724 return;
725
726
727 int LinePos = 420;
728
729 // вывод стомости модернизации
730 // модернизация корпуса
731 bool CanUpgrade = false;
732 if (GameConfig().Profile[CurrentProfile].ShipHullUpgrade < 4)
733 CanUpgrade = true;
734
735 if (CanUpgrade) {
736 if (GameConfig().Profile[CurrentProfile].Money < GetWorkshopShipCost(GameConfig().Profile[CurrentProfile].ShipHull))
737 CanUpgrade = false;
738
739 tmpTransp = MenuContentTransp;
740 tmpColor = sRGBCOLOR{eRGBCOLOR::white};
741 tmpStream.clear();
742 tmpStream.str(std::string{});
743 if (!CanUpgrade) {
744 tmpTransp = MenuContentTransp * CurrentAlert3;
745 tmpColor = sRGBCOLOR{eRGBCOLOR::orange};
746 }
747 tmpStream << vw_GetText("Upgrade Hull Cost") << ": " << GetWorkshopShipCost(GameConfig().Profile[CurrentProfile].ShipHull);
748 vw_DrawText(GameConfig().InternalWidth/2+438-vw_TextWidth(tmpStream.str()), LinePos, 0, 0, 1.0f, tmpColor, tmpTransp, tmpStream.str());
749
750 LinePos -= 20;
751 }
752
753
754 // вывод стомости ремонта, если нужно
755 bool NeedRepair = false;
756 if (GetWorkshopShipRepairCost(GameConfig().Profile[CurrentProfile].ShipHull, WorkshopFighterGame) > 0) {
757 tmpStream.clear();
758 tmpStream.str(std::string{});
759 tmpStream << vw_GetText("Repair Hull Cost") << ": "
760 << GetWorkshopShipRepairCost(GameConfig().Profile[CurrentProfile].ShipHull, WorkshopFighterGame);
761 SizeI = vw_TextWidth(tmpStream.str());
762 vw_DrawText(GameConfig().InternalWidth/2+438-SizeI, LinePos, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::red}, CurrentAlert3*MenuContentTransp, tmpStream.str());
763 LinePos -= 20;
764 NeedRepair = true;
765
766 // надпись Armor, красная
767 vw_DrawTextUTF32(GameConfig().InternalWidth/2+74, 110, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, 0.5f*MenuContentTransp, vw_GetTextUTF32("Armor:"));
768 tmpStream.clear();
769 tmpStream.str(std::string{});
770 tmpStream << static_cast<int>(sharedWorkshopFighterGame->ArmorCurrentStatus) << "/"
771 << static_cast<int>(sharedWorkshopFighterGame->ArmorInitialStatus);
772 vw_DrawText(GameConfig().InternalWidth/2+74+14+SmSizeI, 110, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::red}, CurrentAlert3*MenuContentTransp, tmpStream.str());
773 } else {
774 // надпись Armor, нормальная
775 vw_DrawTextUTF32(GameConfig().InternalWidth/2+74, 110, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, 0.5f*MenuContentTransp, vw_GetTextUTF32("Armor:"));
776 tmpStream.clear();
777 tmpStream.str(std::string{});
778 tmpStream << static_cast<int>(sharedWorkshopFighterGame->ArmorCurrentStatus) << "/"
779 << static_cast<int>(sharedWorkshopFighterGame->ArmorInitialStatus);
780 vw_DrawText(GameConfig().InternalWidth/2+74+14+SmSizeI, 110, 0, 0,1.0f, sRGBCOLOR{eRGBCOLOR::white}, 0.5f*MenuContentTransp, tmpStream.str());
781 }
782
783 vw_DrawTextUTF32(GameConfig().InternalWidth/2+74, 130, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, 0.5f*MenuContentTransp, vw_GetTextUTF32("Weapon Slots:"));
784 tmpStream.clear();
785 tmpStream.str(std::string{});
786 tmpStream << sharedWorkshopFighterGame->WeaponSlots.size();
787 vw_DrawText(GameConfig().InternalWidth/2+74+14+SmSizeI, 130, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, 0.5f*MenuContentTransp, tmpStream.str());
788
789
790 vw_DrawTextUTF32(GameConfig().InternalWidth/2+74, 150, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, 0.5f*MenuContentTransp, vw_GetTextUTF32("Slot Levels:"));
791 tmpStream.clear();
792 tmpStream.str(std::string{});
793 if (!sharedWorkshopFighterGame->WeaponSlots.empty())
794 tmpStream << sharedWorkshopFighterGame->WeaponSlots[0].Type;
795 for (unsigned i = 1; i < sharedWorkshopFighterGame->WeaponSlots.size(); i++) {
796 tmpStream << "/" << sharedWorkshopFighterGame->WeaponSlots[i].Type;
797 }
798 vw_DrawText(GameConfig().InternalWidth/2+74+14+SmSizeI, 150, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, 0.5f*MenuContentTransp, tmpStream.str());
799
800
801
802
803 // вывод стоимости корабля (со всеми системами)
804 tmpStream.clear();
805 tmpStream.str(std::string{});
806 tmpStream << vw_GetText("Ship Cost") << ": "
807 << GetWorkshopShipFullCost(GameConfig().Profile[CurrentProfile].ShipHull, WorkshopFighterGame);
808 SizeI = vw_TextWidth(tmpStream.str());
809 vw_DrawText(GameConfig().InternalWidth/2+438-SizeI, LinePos, 0, 0, 1.0f, sRGBCOLOR{eRGBCOLOR::white}, MenuContentTransp, tmpStream.str());
810
811
812 // рамки
813 SrcRect(0,0,400,35 );
814 DstRect(GameConfig().InternalWidth/2+57, 100-11, GameConfig().InternalWidth/2+457, 100+35-11);
815 vw_Draw2D(DstRect, SrcRect, GetPreloadedTextureAsset("menu/workshop_panel4.tga"), true, MenuContentTransp);
816
817 SrcRect(0,0,400,173 );
818 DstRect(GameConfig().InternalWidth/2+57, 450-13, GameConfig().InternalWidth/2+457, 450+173-13);
819 vw_Draw2D(DstRect, SrcRect, GetPreloadedTextureAsset("menu/workshop_panel1+.tga"), true, MenuContentTransp);
820
821
822
823 if (DrawButton200_2(GameConfig().InternalWidth/2+153, 482, vw_GetTextUTF32("Repair Hull"), MenuContentTransp, !NeedRepair))
824 RepairShip();
825
826 if (DrawButton200_2(GameConfig().InternalWidth/2+153, 533, vw_GetTextUTF32("Upgrade Hull"), MenuContentTransp, !CanUpgrade))
827 UpgradeShip();
828
829
830
831 // вывод информации
832 vw_SetFontSize(20);
833
834 tmpTransp = MenuContentTransp;
835 tmpColor = sRGBCOLOR{eRGBCOLOR::yellow};
836 tmpStream.clear();
837 tmpStream.str(std::string{});
838 tmpStream << vw_GetText("Money") << ": "
839 << GameConfig().Profile[CurrentProfile].Money;
840 SizeI = (GameConfig().InternalWidth - vw_TextWidth(tmpStream.str())) / 2;
841 if (!CanBuy) {
842 tmpTransp = MenuContentTransp * CurrentAlert3;
843 tmpColor = sRGBCOLOR{eRGBCOLOR::orange};
844 }
845 vw_DrawText(SizeI, 630, 0, 0, 1.0f, tmpColor, tmpTransp, tmpStream.str());
846
847 ResetFontSize();
848 }
849
850 } // astromenace namespace
851 } // viewizard namespace
852