UFO: Alien Invasion
Loading...
Searching...
No Matches
cp_fightequip_callbacks.cpp
Go to the documentation of this file.
1
5
6/*
7Copyright (C) 2002-2025 UFO: Alien Invasion.
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18See the GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24*/
25#include "../../cl_shared.h"
26#include "../../ui/ui_dataids.h"
27#include "cp_campaign.h"
29#include "cp_mapfightequip.h"
30#include "cp_ufo.h"
31
33
37
41static void AIM_CheckAirequipID (void)
42{
43 switch (airequipID) {
44 case AC_ITEM_AMMO:
45 case AC_ITEM_WEAPON:
46 case AC_ITEM_SHIELD:
48 return;
49 default:
51 break;
52 }
53}
54
60static void AIM_CheckAirequipSelectedSlot (const aircraft_t* aircraft)
61{
62 switch (airequipID) {
63 case AC_ITEM_AMMO:
64 case AC_ITEM_WEAPON:
65 if (airequipSelectedSlot >= aircraft->maxWeapons) {
67 }
68 break;
70 if (airequipSelectedSlot >= aircraft->maxElectronics) {
72 }
73 break;
74 default:
75 break;
76 }
77}
78
87{
88 aircraftSlot_t* slot;
89
91 switch (type) {
92 case AC_ITEM_SHIELD:
93 slot = &aircraft->shield;
94 break;
96 slot = aircraft->electronics + airequipSelectedSlot;
97 break;
98 case AC_ITEM_AMMO:
99 case AC_ITEM_WEAPON:
100 slot = aircraft->weapons + airequipSelectedSlot;
101 break;
102 default:
103 cgi->Com_Printf("AII_SelectAircraftSlot: Unknown airequipID: %i\n", type);
104 return nullptr;
105 }
106
107 return slot;
108}
109
115{
116 assert(slot);
117
119 /* you can select ammo only for weapons and ammo */
121 }
122
123 /* You can choose an ammo only if a weapon has already been selected */
124 if (airequipID >= AC_ITEM_AMMO && !slot->item) {
126 }
127}
128
132static inline const char* AIM_AircraftItemtypeName (const int equiptype)
133{
134 switch (equiptype) {
135 case AC_ITEM_WEAPON:
136 return _("Weapons");
137 case AC_ITEM_SHIELD:
138 return _("Armour");
140 return _("Items");
141 case AC_ITEM_AMMO:
142 /* ammo - only available from weapons */
143 return _("Ammo");
144 default:
145 return _("Unknown");
146 }
147}
148
152static bool AIM_CrafttypeFilter (const base_t* base, aircraftItemType_t filterType, const technology_t* tech)
153{
154 const objDef_t* item;
155 if (!base)
156 return false;
157
158 if (!RS_IsResearched_ptr(tech))
159 return false;
160
161 item = INVSH_GetItemByID(tech->provides);
162 if (!item)
163 return false;
164 if (item->isVirtual)
165 return false;
166 if (!B_BaseHasItem(base, item))
167 return false;
168
169 /* filter by type: special case for ammo because more than 1 type is an ammo type */
170 if (filterType != AC_ITEM_AMMO) {
171 if (item->craftitem.type != filterType)
172 return false;
173 } else {
174 if (item->craftitem.type < AC_ITEM_AMMO)
175 return false;
176 }
177
178 /* you can't install an item that does not have an installation time (alien item)
179 * except for ammo which does not have installation time */
180 if (item->craftitem.installationTime == -1 && filterType >= AC_ITEM_AMMO)
181 return false;
182
183 return true;
184}
185
191{
192 linkedList_t* amountList = nullptr;
193 technology_t** techList;
194 technology_t** currentTech;
195 const base_t* base = slot->aircraft->homebase;
196 int count = 0;
197 uiNode_t* AIM_items = nullptr;
198
199 /* Add all items corresponding to airequipID to list */
201
202 /* Count only those which are researched to buffer */
203 currentTech = techList;
204 while (*currentTech) {
205 if (AIM_CrafttypeFilter(base, airequipID, *currentTech))
206 count++;
207 currentTech++;
208 }
209
210 /* List only those which are researched to buffer */
211 currentTech = techList;
212 while (*currentTech) {
213 if (AIM_CrafttypeFilter(base, airequipID, *currentTech)) {
214 const objDef_t* item = INVSH_GetItemByID((*currentTech)->provides);
215 const int amount = B_ItemInBase(item, base);
216
217 cgi->LIST_AddString(&amountList, va("%d", amount));
218 uiNode_t* option = cgi->UI_AddOption(&AIM_items, (*currentTech)->name, _((*currentTech)->name), va("%d", (*currentTech)->idx));
219 if (!AIM_SelectableCraftItem(slot, *currentTech))
220 option->disabled = true;
221 }
222 currentTech++;
223 }
224
225 cgi->UI_RegisterOption(TEXT_LIST, AIM_items);
226 cgi->UI_RegisterLinkedListText(TEXT_LIST2, amountList);
227}
228
233static void AIM_DrawAircraftSlots (const aircraft_t* aircraft)
234{
235 /* initialise model cvars */
236 for (int i = 0; i < AIR_POSITIONS_MAX; i++)
237 cgi->Cvar_Set(va("mn_aircraft_item_model_slot%i", i), "");
238
239 for (int i = 0; i < AIR_POSITIONS_MAX; i++) {
240 const aircraftSlot_t* slot;
241 int max;
242
243 /* Default value */
244 cgi->UI_ExecuteConfunc("airequip_display_slot %i 0", i);
245
246 /* Draw available slots */
247 switch (airequipID) {
248 case AC_ITEM_AMMO:
249 case AC_ITEM_WEAPON:
250 max = aircraft->maxWeapons;
251 slot = aircraft->weapons;
252 break;
254 max = aircraft->maxElectronics;
255 slot = aircraft->electronics;
256 break;
257 /* do nothing for shield: there is only one slot */
258 default:
259 continue;
260 }
261 for (int j = 0; j < max; j++, slot++) {
262 /* check if one of the aircraft slots is at this position */
263 if (slot->pos == i) {
264 /* draw in white if this is the selected slot */
265 if (j == airequipSelectedSlot) {
266 cgi->UI_ExecuteConfunc("airequip_display_slot %i 2", i);
267 } else {
268 cgi->UI_ExecuteConfunc("airequip_display_slot %i 1", i);
269 }
270 if (slot->item) {
271 cgi->Cvar_Set(va("mn_aircraft_item_model_slot%i", i), "%s", RS_GetTechForItem(slot->item)->mdl);
272 } else {
273 cgi->Cvar_Set(va("mn_aircraft_item_model_slot%i", i), "");
274 }
275 }
276 }
277 }
278}
279
285static inline void AIM_EmphazeAmmoSlotText (void)
286{
287 cgi->UI_ExecuteConfunc("airequip_zone2_color \"1 0 0 1\"");
288}
289
295static inline void AIM_NoEmphazeAmmoSlotText (void)
296{
297 cgi->UI_ExecuteConfunc("airequip_zone2_color \"1 1 1 1\"");
298}
299
301{
302 static char smallbuffer1[256];
303 static char smallbuffer2[128];
304 const char* typeName;
305 aircraft_t* aircraft;
306 aircraftSlot_t* slot;
308
309 if (!base)
310 return;
311
312 /* don't let old links appear on this menu */
313 cgi->UI_ResetData(TEXT_AIREQUIP_1);
314 cgi->UI_ResetData(TEXT_AIREQUIP_2);
315 cgi->UI_ResetData(TEXT_ITEMDESCRIPTION);
316 cgi->UI_ResetData(TEXT_LIST);
317
318 aircraft = base->aircraftCurrent;
319
320 assert(aircraft);
321
322 /* Check that airequipSelectedSlot corresponds to an existing slot for this aircraft */
324
325 /* Select slot */
326 slot = AII_SelectAircraftSlot(aircraft, airequipID);
327
328 /* Check that the selected zone is OK */
330
331 /* Fill the list of item you can equip your aircraft with */
333
334 cgi->Cvar_Set("mn_equip_itemtype_name", "%s", AIM_AircraftItemtypeName(airequipID));
335 switch (airequipID) {
337 typeName = "item";
338 break;
339 case AC_ITEM_SHIELD:
340 typeName = "armour";
341 break;
342 case AC_ITEM_AMMO:
343 typeName = "ammo";
344 break;
345 case AC_ITEM_WEAPON:
346 typeName = "weapon";
347 break;
348 default:
349 typeName = "unknown";
350 break;
351 }
352 cgi->Cvar_Set("mn_equip_itemtype", "%s", typeName);
353
354 /* First slot: item currently assigned */
355 if (!slot->item) {
356 Com_sprintf(smallbuffer1, sizeof(smallbuffer1), "%s", _("No item assigned.\n"));
357 Q_strcat(smallbuffer1, sizeof(smallbuffer1), _("This slot is for %s or smaller items."),
358 AII_WeightToName(slot->size));
359 } else {
360 technology_t* itemTech = RS_GetTechForItem(slot->item);
361 technology_t* nextItemTech = slot->nextItem ? RS_GetTechForItem(slot->nextItem) : nullptr;
362 /* Print next item if we are removing item currently installed and a new item has been added. */
363 Com_sprintf(smallbuffer1, sizeof(smallbuffer1), "%s\n", slot->nextItem ? _(nextItemTech->name) : _(itemTech->name));
364 if (!slot->installationTime) {
365 Q_strcat(smallbuffer1, sizeof(smallbuffer1), _("This item is functional.\n"));
366 } else if (slot->installationTime > 0) {
367 Q_strcat(smallbuffer1, sizeof(smallbuffer1), ngettext("This item will be installed in %i hour.\n",
368 "This item will be installed in %i hours.\n", slot->installationTime), slot->installationTime);
369 } else if (slot->nextItem) {
370 Q_strcat(smallbuffer1, sizeof(smallbuffer1), ngettext("%s will be removed in %i hour.\n", "%s will be removed in %i hours.\n",
371 -slot->installationTime), _(itemTech->name), -slot->installationTime);
372 Q_strcat(smallbuffer1, sizeof(smallbuffer1), ngettext("%s will be installed in %i hour.\n",
373 "%s will be installed in %i hours.\n", slot->nextItem->craftitem.installationTime - slot->installationTime),
374 _(nextItemTech->name), slot->nextItem->craftitem.installationTime - slot->installationTime);
375 } else {
376 Q_strcat(smallbuffer1, sizeof(smallbuffer1), ngettext("This item will be removed in %i hour.\n",
377 "This item will be removed in %i hours.\n", -slot->installationTime), -slot->installationTime);
378 }
379 }
380 cgi->UI_RegisterText(TEXT_AIREQUIP_1, smallbuffer1);
381
382 /* Second slot: ammo slot (only used for weapons) */
383 if ((airequipID == AC_ITEM_WEAPON || airequipID == AC_ITEM_AMMO) && slot->item) {
384 if (!slot->ammo) {
386 Com_sprintf(smallbuffer2, sizeof(smallbuffer2), "%s", _("No ammo assigned to this weapon."));
387 } else {
388 const objDef_t* ammo = slot->nextAmmo ? slot->nextAmmo : slot->ammo;
389 const technology_t* tech = RS_GetTechForItem(ammo);
391 if (!ammo->isVirtual)
392 Q_strncpyz(smallbuffer2, _(tech->name), sizeof(smallbuffer2));
393 else
394 Q_strncpyz(smallbuffer2, _("No ammo needed"), sizeof(smallbuffer2));
395 }
396 } else
397 *smallbuffer2 = '\0';
398
399 cgi->UI_RegisterText(TEXT_AIREQUIP_2, smallbuffer2);
400
401 /* Draw existing slots for this aircraft */
402 AIM_DrawAircraftSlots(aircraft);
403}
404
405#define AIM_LOADING_OK 0
406#define AIM_LOADING_NOSLOTSELECTED 1
407#define AIM_LOADING_NOTECHNOLOGYSELECTED 2
408#define AIM_LOADING_ALIENTECH 3
409#define AIM_LOADING_TECHNOLOGYNOTRESEARCHED 4
410#define AIM_LOADING_TOOHEAVY 5
411#define AIM_LOADING_UNKNOWNPROBLEM 6
412#define AIM_LOADING_NOWEAPON 7
413#define AIM_LOADING_NOTUSABLEWITHWEAPON 8
414
421static int AIM_CheckTechnologyIntoSlot (const aircraftSlot_t* slot, const technology_t* tech)
422{
423 const objDef_t* item;
424
425 if (!tech)
427
428 if (!slot)
430
431 if (!RS_IsResearched_ptr(tech))
433
434 item = INVSH_GetItemByID(tech->provides);
435 if (!item)
437
438 if (item->craftitem.type >= AC_ITEM_AMMO) {
439 const objDef_t* weapon = slot->item;
440 int k;
441 if (slot->nextItem != nullptr)
442 weapon = slot->nextItem;
443
444 if (weapon == nullptr)
446
447 /* Is the ammo is usable with the slot */
448 for (k = 0; k < weapon->numAmmos; k++) {
449 const objDef_t* usable = weapon->ammos[k];
450 if (usable && item->idx == usable->idx)
451 break;
452 }
453 if (k >= weapon->numAmmos)
455
456#if 0
459 if (!slot->nextItem && item->weapons[0] != slot->item)
461
462 /* are we trying to change ammos for nextItem? */
463 if (slot->nextItem && item->weapons[0] != slot->nextItem)
465#endif
466 }
467
468 /* you can install an item only if its weight is small enough for the slot */
469 if (AII_GetItemWeightBySize(item) > slot->size)
471
472 /* you can't install an item that you don't possess
473 * virtual ammo don't need to be possessed
474 * installations always have weapon and ammo */
475 if (slot->aircraft) {
476 if (!B_BaseHasItem(slot->aircraft->homebase, item))
478 } else if (slot->base) {
479 if (!B_BaseHasItem(slot->base, item))
481 }
482
483 /* you can't install an item that does not have an installation time (alien item)
484 * except for ammo which does not have installation time */
485 if (item->craftitem.installationTime == -1 && slot->type < AC_ITEM_AMMO)
487
488 return AIM_LOADING_OK;
489}
490
494static void AIM_UpdateItemDescription (bool fromList, bool fromSlot)
495{
496 int status;
497 aircraft_t* aircraft;
498 aircraftSlot_t* slot;
500 assert(base);
501
502 aircraft = base->aircraftCurrent;
503 assert(aircraft);
504 slot = AII_SelectAircraftSlot(aircraft, airequipID);
505
506 /* update mini ufopedia */
508 if (fromList)
510 else if (fromSlot) {
513 else
515 }
516
517 /* update status */
519 switch (status) {
521 cgi->Cvar_Set("mn_aircraft_item_warning", _("No slot selected."));
522 break;
524 cgi->Cvar_Set("mn_aircraft_item_warning", _("No item selected."));
525 break;
527 cgi->Cvar_Set("mn_aircraft_item_warning", _("You can't equip an alien technology."));
528 break;
530 cgi->Cvar_Set("mn_aircraft_item_warning", _("Technology requested is not yet completed."));
531 break;
533 cgi->Cvar_Set("mn_aircraft_item_warning", _("This item is too heavy for the selected slot."));
534 break;
536 cgi->Cvar_Set("mn_aircraft_item_warning", _("Equip a weapon first."));
537 break;
539 cgi->Cvar_Set("mn_aircraft_item_warning", _("Ammo not usable with current weapon."));
540 break;
542 cgi->Cvar_Set("mn_aircraft_item_warning", _("Unknown problem."));
543 break;
544 case AIM_LOADING_OK:
545 cgi->Cvar_Set("mn_aircraft_item_warning", _("Ok"));
546 break;
547 }
548
549 if (*cgi->Cvar_GetString("mn_item") == '\0') {
550 cgi->UI_ExecuteConfunc("airequip_no_item");
551 } else {
552 if (fromSlot) {
553 cgi->UI_ExecuteConfunc("airequip_installed_item");
554 } else {
555 if (status == AIM_LOADING_OK)
556 cgi->UI_ExecuteConfunc("airequip_installable_item");
557 else
558 cgi->UI_ExecuteConfunc("airequip_noinstallable_item");
559 }
560 }
561}
562
568{
569 if (cgi->Cmd_Argc() != 2) {
570 if (airequipID == MAX_ACITEMS) {
571 cgi->Com_Printf("Usage: %s <num>\n", cgi->Cmd_Argv(0));
572 return;
573 }
575 } else {
576 const aircraftItemType_t type = (aircraftItemType_t)atoi(cgi->Cmd_Argv(1));
577 switch (type) {
579 case AC_ITEM_SHIELD:
581 cgi->UI_ExecuteConfunc("airequip_zone2_off");
582 break;
583 case AC_ITEM_AMMO:
584 case AC_ITEM_WEAPON:
586 cgi->UI_ExecuteConfunc("airequip_zone2_on");
587 break;
588 default:
590 break;
591 }
592 }
593
595}
596
602{
603 int i;
604 itemPos_t pos;
605 aircraft_t* aircraft;
607 int updateZone = 0;
608
609 if (!base)
610 return;
611
612 if (cgi->Cmd_Argc() < 2) {
613 cgi->Com_Printf("Usage: %s <arg> <zone1|zone2|item>\n", cgi->Cmd_Argv(0));
614 return;
615 }
616
617 aircraft = base->aircraftCurrent;
618 assert(aircraft);
619
620 i = atoi(cgi->Cmd_Argv(1));
621 pos = (itemPos_t)i;
622
623 if (cgi->Cmd_Argc() == 3) {
624 if (Q_streq(cgi->Cmd_Argv(2), "zone1")) {
625 updateZone = 1;
626 } else if (Q_streq(cgi->Cmd_Argv(2), "zone2")) {
627 updateZone = 2;
628 }
629 }
630
632
633 /* select the slot corresponding to pos, and set airequipSelectedSlot to this slot */
634 switch (airequipID) {
636 /* electronics selected */
637 for (i = 0; i < aircraft->maxElectronics; i++) {
638 if (aircraft->electronics[i].pos == pos) {
640 break;
641 }
642 }
643 if (i == aircraft->maxElectronics)
644 cgi->Com_Printf("this slot hasn't been found in aircraft electronics slots\n");
645 break;
646 case AC_ITEM_AMMO:
647 case AC_ITEM_WEAPON:
648 /* weapon selected */
649 for (i = 0; i < aircraft->maxWeapons; i++) {
650 if (aircraft->weapons[i].pos == pos) {
652 break;
653 }
654 }
655 if (i == aircraft->maxWeapons)
656 cgi->Com_Printf("this slot hasn't been found in aircraft weapon slots\n");
657 break;
658 default:
659 cgi->Com_Printf("AIM_AircraftEquipSlotSelect_f : only weapons and electronics have several slots\n");
660 break;
661 }
662
663 /* Update menu after changing slot */
665
666 /* update description with the selected slot */
667 if (updateZone > 0)
668 AIM_UpdateItemDescription(false, true);
669 else
670 AIM_UpdateItemDescription(true, false);
671}
672
677{
678 int zone;
679 aircraft_t* aircraft;
680 aircraftSlot_t* slot;
682
683 if (!base)
684 return;
685
686 if (cgi->Cmd_Argc() < 2) {
687 cgi->Com_Printf("Usage: %s <arg>\n", cgi->Cmd_Argv(0));
688 return;
689 }
690
691 zone = atoi(cgi->Cmd_Argv(1));
692
693 aircraft = base->aircraftCurrent;
694 assert(aircraft);
695 /* Select slot */
696 slot = AII_SelectAircraftSlot(aircraft, airequipID);
697
698 /* ammos are only available for weapons */
699 switch (airequipID) {
700 /* a weapon was selected - select ammo type corresponding to this weapon */
701 case AC_ITEM_WEAPON:
702 if (zone == ZONE_AMMO) {
703 if (slot->item)
705 }
706 break;
707 /* an ammo was selected - select weapon type corresponding to this ammo */
708 case AC_ITEM_AMMO:
709 if (zone != ZONE_AMMO)
711 break;
712 default :
713 /* ZONE_AMMO is not available for electronics and shields */
714 if (zone == ZONE_AMMO)
715 return;
716 }
718
719 /* update menu */
721 /* Check that the selected zone is OK */
723
724 AIM_UpdateItemDescription(false, true);
725}
726
733{
734 int zone;
735 aircraftSlot_t* slot;
736 aircraft_t* aircraft = nullptr;
738
739 zone = (airequipID == AC_ITEM_AMMO) ? 2 : 1;
740
741 /* proceed only if an item has been selected */
743 return;
744
745 assert(base);
746 aircraft = base->aircraftCurrent;
747 assert(aircraft);
748 base = aircraft->homebase; /* we need to know where items will be removed */
749 slot = AII_SelectAircraftSlot(aircraft, airequipID);
750 if (slot == nullptr)
751 return;
752
753 /* the clicked button doesn't correspond to the selected zone */
754 if (zone != airequipSelectedZone)
755 return;
756
757 /* check if the zone exists */
758 if (zone >= ZONE_MAX)
759 return;
760
761 /* update the new item to slot */
762
763 switch (zone) {
764 case ZONE_MAIN:
765 if (!slot->nextItem) {
766 /* we add the weapon, shield, item if slot is free or the installation of current item just began */
767 if (!slot->item || (slot->item && slot->installationTime == slot->item->craftitem.installationTime)) {
768 AII_RemoveItemFromSlot(base, slot, false);
769 AII_AddItemToSlot(base, aimSelectedTechnology, slot, false); /* Aircraft stats are updated below */
770 AII_AutoAddAmmo(slot);
771 break;
772 } else if (slot->item == INVSH_GetItemByID(aimSelectedTechnology->provides)) {
773 /* the added item is the same than the one in current slot */
774 if (slot->installationTime == -slot->item->craftitem.installationTime) {
775 /* player changed his mind: he just want to re-add the item he just removed */
776 slot->installationTime = 0;
777 break;
778 } else if (!slot->installationTime) {
779 /* player try to add a weapon he already have: just skip */
780 return;
781 }
782 } else {
783 /* We start removing current item in slot, and the selected item will be installed afterwards */
785 /* more below */
786 }
787 } else {
788 /* remove weapon and ammo of next item */
789 AII_RemoveNextItemFromSlot(base, slot, false);
790 /* more below */
791 }
792
793 /* we change the weapon, shield, item, or base defence that will be installed AFTER the removal
794 * of the one in the slot atm */
795 AII_AddItemToSlot(base, aimSelectedTechnology, slot, true);
796 AII_AutoAddAmmo(slot);
797 break;
798 case ZONE_AMMO:
799 /* we can change ammo only if the selected item is an ammo (for weapon or base defence system) */
800 if (airequipID >= AC_ITEM_AMMO) {
802 }
803 break;
804 default:
805 /* Zone higher than ZONE_AMMO shouldn't exist */
806 return;
807 }
808
809 /* Update the values of aircraft stats (just in case an item has an installationTime of 0) */
810 AII_UpdateAircraftStats(aircraft);
811
813}
814
819{
820 int zone;
821 aircraftSlot_t* slot;
822 aircraft_t* aircraft = nullptr;
824
825 zone = (airequipID == AC_ITEM_AMMO) ? 2 : 1;
826
827 assert(base);
828 aircraft = base->aircraftCurrent;
829 assert(aircraft);
830 slot = AII_SelectAircraftSlot(aircraft, airequipID);
831
832 /* no item in slot: nothing to remove */
833 if (!slot->item)
834 return;
835
836 /* update the new item to slot */
837
838 switch (zone) {
839 case ZONE_MAIN:
840 if (!slot->nextItem) {
841 /* we change the weapon, shield, item, or base defence that is already in the slot */
842 /* if the item has been installed since less than 1 hour, you don't need time to remove it */
843 if (slot->installationTime < slot->item->craftitem.installationTime) {
845 AII_RemoveItemFromSlot(base, slot, true); /* we remove only ammo, not item */
846 } else {
847 AII_RemoveItemFromSlot(base, slot, false); /* we remove weapon and ammo */
848 }
849 /* aircraft stats are updated below */
850 } else {
851 /* we change the weapon, shield, item, or base defence that will be installed AFTER the removal
852 * of the one in the slot atm */
853 AII_RemoveNextItemFromSlot(base, slot, false); /* we remove weapon and ammo */
854 /* if you canceled next item for less than 1 hour, previous item is still functional */
855 if (slot->installationTime == -slot->item->craftitem.installationTime) {
856 slot->installationTime = 0;
857 }
858 }
859 break;
860 case ZONE_AMMO:
861 /* we can change ammo only if the selected item is an ammo (for weapon or base defence system) */
862 if (airequipID >= AC_ITEM_AMMO) {
863 if (slot->nextAmmo)
864 AII_RemoveNextItemFromSlot(base, slot, true);
865 else
866 AII_RemoveItemFromSlot(base, slot, true);
867 }
868 break;
869 default:
870 /* Zone higher than ZONE_AMMO shouldn't exist */
871 return;
872 }
873
874 /* Update the values of aircraft stats */
875 AII_UpdateAircraftStats(aircraft);
876
878}
879
885{
886 int techIdx;
887
888 if (cgi->Cmd_Argc() < 2) {
889 cgi->Com_Printf("Usage: %s <num>\n", cgi->Cmd_Argv(0));
890 return;
891 }
892
893 /* Which tech? */
894 techIdx = atoi(cgi->Cmd_Argv(1));
896 AIM_UpdateItemDescription(true, false);
897}
898
903{
905 const char* name;
906
907 if (cgi->Cmd_Argc() != 2) {
908 cgi->Com_Printf("Usage: %s <weapon|ammo|armour|item>\n", cgi->Cmd_Argv(0));
909 return;
910 }
911
912 name = cgi->Cmd_Argv(1);
913
914 if (Q_streq(name, "weapon"))
916 else if (Q_streq(name, "ammo"))
917 i = AC_ITEM_AMMO;
918 else if (Q_streq(name, "armour"))
920 else if (Q_streq(name, "item"))
922 else {
923 cgi->Com_Printf("AIM_AircraftItemtypeByName_f: Invalid itemtype!\n");
924 return;
925 }
926
927 airequipID = i;
928 cgi->Cmd_ExecuteString("airequip_updatemenu %d", airequipID);
929}
930
931static const cmdList_t airequipCmds[] = {
932 {"airequip_updatemenu", AIM_AircraftEquipMenuUpdate_f, "Init function for the aircraft equip menu"},
933 {"airequip_selectcategory", AIM_AircraftItemtypeByName_f, "Select an item category and update the GUI"},
934 {"airequip_list_click", AIM_AircraftEquipMenuClick_f, nullptr},
935 {"airequip_slot_select", AIM_AircraftEquipSlotSelect_f, nullptr},
936 {"airequip_add_item", AIM_AircraftEquipAddItem_f, "Add item to slot"},
937 {"airequip_remove_item", AIM_AircraftEquipRemoveItem_f, "Remove item from slot"},
938 {"airequip_zone_select", AIM_AircraftEquipZoneSelect_f, nullptr},
939 {nullptr, nullptr, nullptr}
940};
942{
943 cgi->Cmd_TableAddList(airequipCmds);
944}
945
947{
948 cgi->Cmd_TableRemoveList(airequipCmds);
949}
Share stuff between the different cgame implementations.
#define _(String)
Definition cl_shared.h:44
itemPos_t
different positions for aircraft items
Definition cp_aircraft.h:55
@ AIR_POSITIONS_MAX
Definition cp_aircraft.h:65
bool B_BaseHasItem(const base_t *base, const objDef_t *item)
Check if an item is available on a base.
Definition cp_base.cpp:2119
base_t * B_GetCurrentSelectedBase(void)
returns the currently selected base
Definition cp_base.cpp:1578
int B_ItemInBase(const objDef_t *item, const base_t *base)
Check if the item has been collected (i.e it is in the storage) in the given base.
Definition cp_base.cpp:2133
Header file for single player campaign control.
const cgame_import_t * cgi
static void AIM_AircraftEquipRemoveItem_f(void)
Delete an object from a zone.
static void AIM_AircraftEquipMenuUpdate(void)
#define AIM_LOADING_NOTUSABLEWITHWEAPON
#define AIM_LOADING_NOWEAPON
static void AIM_CheckAirequipSelectedSlot(const aircraft_t *aircraft)
Check that airequipSelectedSlot is the indice of an existing slot in the aircraft.
#define AIM_LOADING_TECHNOLOGYNOTRESEARCHED
static void AIM_DrawAircraftSlots(const aircraft_t *aircraft)
Draw only slots existing for this aircraft, and emphases selected one.
static technology_t * aimSelectedTechnology
static void AIM_UpdateAircraftItemList(const aircraftSlot_t *slot)
Update the list of item you can choose.
static void AIM_EmphazeAmmoSlotText(void)
Write in red the text in zone ammo (zone 2).
static void AIM_CheckAirequipSelectedZone(aircraftSlot_t *slot)
Check that airequipSelectedZone is available.
static void AIM_AircraftEquipZoneSelect_f(void)
Select the current zone you want to assign the item to.
static void AIM_AircraftEquipAddItem_f(void)
Add selected item to current zone.
static void AIM_UpdateItemDescription(bool fromList, bool fromSlot)
Update the item description according to the tech and the slot selected.
static int AIM_CheckTechnologyIntoSlot(const aircraftSlot_t *slot, const technology_t *tech)
#define AIM_LOADING_ALIENTECH
static const cmdList_t airequipCmds[]
static void AIM_NoEmphazeAmmoSlotText(void)
Write in white the text in zone ammo (zone 2).
#define AIM_LOADING_NOSLOTSELECTED
void AIM_ShutdownCallbacks(void)
static int airequipSelectedZone
void AIM_InitCallbacks(void)
static void AIM_AircraftEquipMenuUpdate_f(void)
Fills the weapon and shield list of the aircraft equip menu.
static void AIM_AircraftEquipMenuClick_f(void)
Set AIM_selectedTechnology to the technology of current selected aircraft item.
static bool AIM_CrafttypeFilter(const base_t *base, aircraftItemType_t filterType, const technology_t *tech)
#define AIM_LOADING_OK
#define AIM_LOADING_NOTECHNOLOGYSELECTED
static const char * AIM_AircraftItemtypeName(const int equiptype)
Returns the userfriendly name for craftitem types (shown in aircraft equip menu).
#define AIM_LOADING_TOOHEAVY
static int airequipSelectedSlot
static void AIM_AircraftEquipSlotSelect_f(void)
Select the current slot you want to assign the item to.
static void AIM_AircraftItemtypeByName_f(void)
Update the GUI with a named itemtype.
static aircraftItemType_t airequipID
#define AIM_LOADING_UNKNOWNPROBLEM
static void AIM_CheckAirequipID(void)
Check airequipID value and set the correct values for aircraft items.
aircraftSlot_t * AII_SelectAircraftSlot(aircraft_t *aircraft, aircraftItemType_t type)
Returns a pointer to the selected slot.
Header file for menu callback functions used for base and aircraft equip menu.
itemWeight_t AII_GetItemWeightBySize(const objDef_t *od)
Returns craftitem weight based on size.
void AII_RemoveItemFromSlot(base_t *base, aircraftSlot_t *slot, bool ammo)
Remove the item from the slot (or optionally its ammo only) and put it the base storage.
void AII_AutoAddAmmo(aircraftSlot_t *slot)
Auto add ammo corresponding to weapon, if there is enough in storage.
const char * AII_WeightToName(itemWeight_t weight)
Translate a weight int to a translated string.
void AII_UpdateAircraftStats(aircraft_t *aircraft)
Update the value of stats array of an aircraft.
technology_t ** AII_GetCraftitemTechsByType(aircraftItemType_t type)
Returns a list of craftitem technologies for the given type.
bool AII_AddItemToSlot(base_t *base, const technology_t *tech, aircraftSlot_t *slot, bool nextItem)
Add an item to an aircraft slot.
bool AII_AddAmmoToSlot(base_t *base, const technology_t *tech, aircraftSlot_t *slot)
Add an ammo to an aircraft weapon slot.
void AII_RemoveNextItemFromSlot(base_t *base, aircraftSlot_t *slot, bool ammo)
Cancel replacing item, move nextItem (or optionally its ammo only) back to the base storage.
bool AIM_SelectableCraftItem(const aircraftSlot_t *slot, const technology_t *tech)
Check if an aircraft item should or should not be displayed in airequip menu.
Header for slot management related stuff.
@ ZONE_MAIN
@ ZONE_NONE
@ ZONE_MAX
@ ZONE_AMMO
technology_t * RS_GetTechForItem(const objDef_t *item)
Returns technology entry for an item.
bool RS_IsResearched_ptr(const technology_t *tech)
Checks whether an item is already researched.
technology_t * RS_GetTechByIDX(int techIdx)
Returns the technology pointer for a tech index. You can use this instead of "&ccs....
void UP_AircraftItemDescription(const objDef_t *item)
Prints the (UFOpaedia and other) description for aircraft items.
#define ngettext(x, y, cnt)
Definition g_local.h:40
const objDef_t * INVSH_GetItemByID(const char *id)
Returns the item that belongs to the given id or nullptr if it wasn't found.
const objDef_t * INVSH_GetItemByIDSilent(const char *id)
Returns the item that belongs to the given id or nullptr if it wasn't found.
aircraftItemType_t
All different types of craft items.
Definition inv_shared.h:197
@ AC_ITEM_WEAPON
Definition inv_shared.h:201
@ AC_ITEM_AMMO
Definition inv_shared.h:211
@ MAX_ACITEMS
Definition inv_shared.h:215
@ AC_ITEM_ELECTRONICS
Definition inv_shared.h:205
@ AC_ITEM_SHIELD
Definition inv_shared.h:204
QGL_EXTERN GLuint count
Definition r_gl.h:99
QGL_EXTERN GLint i
Definition r_gl.h:113
QGL_EXTERN GLint GLenum type
Definition r_gl.h:94
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition r_gl.h:110
#define Q_streq(a, b)
Definition shared.h:136
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition shared.cpp:457
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
Definition shared.cpp:475
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition shared.cpp:494
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
Definition shared.cpp:410
An aircraft with all it's data.
aircraftSlot_t weapons[MAX_AIRCRAFTSLOT]
int maxElectronics
struct base_s * homebase
aircraftSlot_t shield
aircraftSlot_t electronics[MAX_AIRCRAFTSLOT]
slot of aircraft
Definition cp_aircraft.h:78
const objDef_t * item
Definition cp_aircraft.h:85
const objDef_t * nextAmmo
Definition cp_aircraft.h:94
const objDef_t * ammo
Definition cp_aircraft.h:86
struct aircraft_s * aircraft
Definition cp_aircraft.h:82
itemPos_t pos
Definition cp_aircraft.h:95
struct base_s * base
Definition cp_aircraft.h:80
itemWeight_t size
Definition cp_aircraft.h:87
aircraftItemType_t type
Definition cp_aircraft.h:83
const objDef_t * nextItem
Definition cp_aircraft.h:92
A base with all it's data.
Definition cp_base.h:84
aircraft_t * aircraftCurrent
Definition cp_base.h:100
int installationTime
Definition inv_shared.h:252
aircraftItemType_t type
Definition inv_shared.h:247
Defines all attributes of objects used in the inventory.
Definition inv_shared.h:264
const struct objDef_s * ammos[MAX_AMMOS_PER_OBJDEF]
Definition inv_shared.h:307
bool isVirtual
Definition inv_shared.h:284
int numAmmos
Definition inv_shared.h:308
craftItem craftitem
Definition inv_shared.h:331
const struct objDef_s * weapons[MAX_WEAPONS_PER_OBJDEF]
Definition inv_shared.h:311
This is the technology parsed from research.ufo.
char * provides
Atomic structure used to define most of the UI.
Definition ui_nodes.h:80
bool disabled
Definition ui_nodes.h:102
char name[MAX_VAR]
Definition ui_nodes.h:82
@ TEXT_LIST2
Definition ui_dataids.h:32
@ TEXT_AIREQUIP_1
Definition ui_dataids.h:52
@ TEXT_LIST
Definition ui_dataids.h:31
@ TEXT_ITEMDESCRIPTION
Definition ui_dataids.h:70
@ TEXT_AIREQUIP_2
Definition ui_dataids.h:53