UFO: Alien Invasion
cl_game_team.cpp
Go to the documentation of this file.
1
6/*
7Copyright (C) 2002-2022 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.m
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
26#include "../client.h"
27#include "cl_game.h"
28#include "cl_game_team.h"
29#include "../cl_inventory.h"
30#include "../../shared/parse.h"
31#include "../cl_team.h"
32#include "../ui/ui_main.h"
33#include "../ui/ui_popup.h"
34#include "../ui/node/ui_node_container.h"
35#include "save_team.h"
36#include "save_character.h"
37#include "save_inventory.h"
38
39#define TEAM_SAVE_FILE_VERSION 4
40
43
44typedef struct teamSaveFileHeader_s {
45 uint32_t version;
46 uint32_t soldiercount;
47 char name[32];
48 uint32_t xmlSize;
50
51static void GAME_UpdateActiveTeamList (void)
52{
53 const int teamSize = LIST_Count(chrDisplayList);
55 for (int i = 0; i < teamSize; i++)
56 characterActive[i] = true;
57}
58
59void GAME_AutoTeam (const char* equipmentDefinitionID, int teamMembers)
60{
61 const equipDef_t* ed = INV_GetEquipmentDefinitionByID(equipmentDefinitionID);
62 const char* teamDefID = GAME_GetTeamDef();
64
65 GAME_GenerateTeam(teamDefID, ed, teamMembers);
66}
67
68void GAME_AutoTeam_f (void)
69{
70 if (Cmd_Argc() != 2) {
71 Com_Printf("Usage: %s <equipment-definition>\n", Cmd_Argv(0));
72 return;
73 }
74
77}
78
84{
85 if (Cmd_Argc() != 3) {
86 Com_Printf("Usage: %s <num> <value>\n", Cmd_Argv(0));
87 return;
88 }
89
90 const int ucn = atoi(Cmd_Argv(1));
91 const int value = atoi(Cmd_Argv(2));
92
93 int i = 0;
94 bool found = false;
96 if (ucn == chrTmp->ucn) {
97 found = true;
98 break;
99 }
100 i++;
101 }
102 if (!found)
103 return;
104
105 characterActive[i] = (value != 0);
106}
107
113{
114 int i = 0;
116 if (!characterActive[i++])
118 }
119}
120
125{
126 if (Cmd_Argc() != 2) {
127 Com_Printf("Usage: %s <filename>\n", Cmd_Argv(0));
128 return;
129 }
130
131 const char* team = Cmd_Argv(1);
132 char buf[MAX_OSPATH];
134 Q_strcat(buf, sizeof(buf), "%s", team);
136}
137
142{
143 UI_ExecuteConfunc("teamsaveslotsclear");
144
145 char relSavePath[MAX_OSPATH];
146 GAME_GetRelativeSavePath(relSavePath, sizeof(relSavePath));
147 char pattern[MAX_OSPATH];
148 Q_strncpyz(pattern, relSavePath, sizeof(pattern));
149 Q_strcat(pattern, sizeof(pattern), "*.mpt");
150
151 FS_BuildFileList(pattern);
152 int i = 0;
153 const char* filename;
154 while ((filename = FS_NextFileFromFileList(pattern)) != nullptr) {
156 const char* savePath = va("%s/%s", relSavePath, filename);
157 FS_OpenFile(savePath, &f, FILE_READ);
158 if (!f) {
159 Com_Printf("Warning: Could not open '%s'\n", filename);
160 continue;
161 }
163 const int clen = sizeof(header);
164 if (FS_Read(&header, clen, &f) != clen) {
165 Com_Printf("Warning: Could not read %i bytes from savefile\n", clen);
166 continue;
167 }
169 Com_Printf("Warning: Version mismatch in '%s'\n", filename);
170 continue;
171 }
172
173 char absSavePath[MAX_OSPATH];
174 GAME_GetAbsoluteSavePath(absSavePath, sizeof(absSavePath));
175 const bool uploadable = FS_FileExists("%s/%s", absSavePath, filename);
176 UI_ExecuteConfunc("teamsaveslotadd %i \"%s\" \"%s\" %i %i", i++, filename, header.name, LittleLong(header.soldiercount), uploadable ? 1 : 0);
177 }
179}
180
187{
190 GAME_SaveCharacter(n, chr);
191 }
192}
193
200{
201 const size_t size = GAME_GetCharacterArraySize();
202
205
206 /* header */
207 int i = 0;
210 GAME_LoadCharacter(n, chr);
211 UI_ExecuteConfunc("team_memberadd %i \"%s\" \"%s\" %i", i, chr->name, chr->head, chr->headSkin);
212 LIST_AddPointer(&chrDisplayList, (void*)chr);
213 }
214
216}
217
221static bool GAME_SaveTeam (const char* filename, const char* name)
222{
224 char dummy[2];
226
227 xmlNode_t* topNode = mxmlNewXML("1.0");
228 xmlNode_t* node = XML_AddNode(topNode, SAVE_TEAM_ROOTNODE);
229 OBJZERO(header);
232 Q_strncpyz(header.name, name, sizeof(header.name));
233
234 xmlNode_t* snode = XML_AddNode(node, SAVE_TEAM_NODE);
235 GAME_SaveTeamInfo(snode);
236
237 snode = XML_AddNode(node, SAVE_TEAM_EQUIPMENT);
238 for (int i = 0; i < csi.numODs; i++) {
239 const objDef_t* od = INVSH_GetItemByIDX(i);
240 if (ed->numItems[od->idx] || ed->numItemsLoose[od->idx]) {
241 xmlNode_t* ssnode = XML_AddNode(snode, SAVE_TEAM_ITEM);
242 XML_AddString(ssnode, SAVE_TEAM_ID, od->id);
243 XML_AddIntValue(ssnode, SAVE_TEAM_NUM, ed->numItems[od->idx]);
245 }
246 }
247 const int requiredBufferLength = mxmlSaveString(topNode, dummy, 2, MXML_NO_CALLBACK);
248 /* required for storing compressed */
249 header.xmlSize = LittleLong(requiredBufferLength);
250
251 byte* const buf = Mem_PoolAllocTypeN(byte, requiredBufferLength + 1, cl_genericPool);
252 if (!buf) {
253 mxmlDelete(topNode);
254 Com_Printf("Error: Could not allocate enough memory to save this game\n");
255 return false;
256 }
257 mxmlSaveString(topNode, (char*)buf, requiredBufferLength + 1, MXML_NO_CALLBACK);
258 mxmlDelete(topNode);
259
260 byte* const fbuf = Mem_PoolAllocTypeN(byte, requiredBufferLength + 1 + sizeof(header), cl_genericPool);
261 memcpy(fbuf, &header, sizeof(header));
262 memcpy(fbuf + sizeof(header), buf, requiredBufferLength + 1);
263 Mem_Free(buf);
264
265 /* last step - write data */
266 FS_WriteFile(fbuf, requiredBufferLength + 1 + sizeof(header), filename);
267 Mem_Free(fbuf);
268
269 return true;
270}
271
280{
281 char buf[MAX_OSPATH];
283
284 for (int num = 0; num < 100; num++) {
285 Com_sprintf(filename, size, "%s/team%02i.mpt", buf, num);
286 if (FS_CheckFile("%s", filename) == -1) {
287 return true;
288 }
289 }
290 return false;
291}
292
297{
298 if (Cmd_Argc() != 2) {
299 Com_Printf("Usage: %s <name>\n", Cmd_Argv(0));
300 return;
301 }
302
304 UI_Popup(_("Note"), _("Error saving team. Nothing to save yet."));
305 return;
306 }
307
308 const char* name = Cmd_Argv(1);
309 if (Q_strnull(name))
310 name = _("New Team");
311
312 char filename[MAX_OSPATH];
314 UI_Popup(_("Note"), _("Error saving team. Too many teams!"));
315 return;
316 }
317
319 UI_Popup(_("Note"), _("Error saving team. Check free disk space!"));
320}
321
325static bool GAME_LoadTeam (const char* filename)
326{
327 /* open file */
330 if (!f) {
331 Com_Printf("Couldn't open file '%s'\n", filename);
332 return false;
333 }
334
335 const int clen = FS_FileLength(&f);
336 byte* const cbuf = Mem_PoolAllocTypeN(byte, clen, cl_genericPool);
337 if (FS_Read(cbuf, clen, &f) != clen) {
338 Com_Printf("Warning: Could not read %i bytes from savefile\n", clen);
339 Mem_Free(cbuf);
340 return false;
341 }
342
344 memcpy(&header, cbuf, sizeof(header));
345 /* swap all int values if needed */
346 header.version = LittleLong(header.version);
347 header.xmlSize = LittleLong(header.xmlSize);
348
349 if (header.version != TEAM_SAVE_FILE_VERSION) {
350 Com_Printf("Invalid version number\n");
351 Mem_Free(cbuf);
352 return false;
353 }
354
355 Com_Printf("Loading team (size %d / %i)\n", clen, header.xmlSize);
356
357 xmlNode_t* topNode = XML_Parse((const char*)(cbuf + sizeof(header)));
358 Mem_Free(cbuf);
359 if (!topNode) {
360 Com_Printf("Error: Failure in loading the xml data!");
361 return false;
362 }
363
364 xmlNode_t* node = XML_GetNode(topNode, SAVE_TEAM_ROOTNODE);
365 if (!node) {
366 mxmlDelete(topNode);
367 Com_Printf("Error: Failure in loading the xml data! (node '" SAVE_TEAM_ROOTNODE "' not found)\n");
368 return false;
369 }
370
371 xmlNode_t* snode = XML_GetNode(node, SAVE_TEAM_NODE);
372 if (!snode) {
373 mxmlDelete(topNode);
374 Com_Printf("Error: Failure in loading the xml data! (node '" SAVE_TEAM_NODE "' not found)\n");
375 return false;
376 }
377 GAME_LoadTeamInfo(snode);
378
379 snode = XML_GetNode(node, SAVE_TEAM_EQUIPMENT);
380 if (!snode) {
381 mxmlDelete(topNode);
382 Com_Printf("Error: Failure in loading the xml data! (node '" SAVE_TEAM_EQUIPMENT "' not found)\n");
383 return false;
384 }
385
387 for (xmlNode_t* ssnode = XML_GetNode(snode, SAVE_TEAM_ITEM); ssnode; ssnode = XML_GetNextNode(ssnode, snode, SAVE_TEAM_ITEM)) {
388 const char* objID = XML_GetString(ssnode, SAVE_TEAM_ID);
389 const objDef_t* od = INVSH_GetItemByID(objID);
390
391 if (od) {
392 ed->numItems[od->idx] = XML_GetInt(snode, SAVE_TEAM_NUM, 0);
393 ed->numItemsLoose[od->idx] = XML_GetInt(snode, SAVE_TEAM_NUMLOOSE, 0);
394 }
395 }
396
397 Com_Printf("File '%s' loaded.\n", filename);
398
399 mxmlDelete(topNode);
400
401 return true;
402}
403
413bool GAME_GetTeamFileName (unsigned int index, char* filename, size_t filenameLength)
414{
415 const char* save;
416 /* we will loop the whole team save list, just because i don't want
417 * to specify the filename in the script api of this command. Otherwise
418 * one could upload everything with this command */
419 char buf[MAX_OSPATH];
421 char pattern[MAX_OSPATH];
422 Com_sprintf(pattern, sizeof(pattern), "%s*.mpt", buf);
423 const int amount = FS_BuildFileList(pattern);
424 Com_DPrintf(DEBUG_CLIENT, "found %i entries for %s\n", amount, pattern);
425 while ((save = FS_NextFileFromFileList(pattern)) != nullptr) {
426 if (index == 0)
427 break;
428 index--;
429 }
431 if (index > 0)
432 return false;
433 if (save == nullptr)
434 return false;
435 Com_sprintf(filename, filenameLength, "%s/%s", buf, save);
436 return true;
437}
438
439bool GAME_LoadDefaultTeam (bool force)
440{
442 if (!force)
443 return false;
445 }
446
447 char filename[MAX_OSPATH];
449 return false;
451 return true;
452 }
453
455 return false;
456}
457
462{
463 if (Cmd_Argc() != 2) {
464 Com_Printf("Usage: %s <slotindex>\n", Cmd_Argv(0));
465 return;
466 }
467
468 const int index = atoi(Cmd_Argv(1));
469
470 char filename[MAX_OSPATH];
472 Com_Printf("Could not get the file for the index: %i\n", index);
473 return;
474 }
477 } else {
479 }
480}
481
482static void GAME_UpdateInventory (Inventory* inv, const equipDef_t* ed)
483{
486 else
487 ui_inventory = nullptr;
488
489 /* manage inventory */
491}
492
497static void GAME_GetEquipment (void)
498{
499 const char* equipmentName = Cvar_GetString("cl_equip");
500 /* search equipment definition */
501 const equipDef_t* edFromScript = INV_GetEquipmentDefinitionByID(equipmentName);
502
504 *ed = *edFromScript;
505
508}
509
515{
516 /* reset description */
517 Cvar_Set("mn_itemname", "%s", "");
518 Cvar_Set("mn_item", "%s", "");
520
521 int i = 0;
522 UI_ExecuteConfunc("team_soldierlist_clear");
524 UI_ExecuteConfunc("team_soldierlist_add %d %d \"%s\"", chr->ucn, characterActive[i], chr->name);
525 i++;
526 }
527
529}
530
532{
533 /* check syntax */
534 if (Cmd_Argc() < 2) {
535 Com_Printf("Usage: %s <num>\n", Cmd_Argv(0));
536 return;
537 }
538
539 const int ucn = atoi(Cmd_Argv(1));
540 character_t* chr = nullptr;
542 if (ucn == chrTmp->ucn) {
543 chr = chrTmp;
544 break;
545 }
546 }
547 if (!chr)
548 return;
549
550 /* update menu inventory */
551 if (ui_inventory && ui_inventory != &chr->inv) {
553 /* set 'old' CID_EQUIP to nullptr */
555 }
556 ui_inventory = &chr->inv;
557 /* set info cvars */
559}
560
569static void GAME_SaveItem (xmlNode_t* p, const Item* item, containerIndex_t container, int x, int y)
570{
571 assert(item->def() != nullptr);
572
580 if (item->getAmmoLeft() > NONE_AMMO) {
583 }
584}
585
593static void GAME_SaveInventory (xmlNode_t* p, const Inventory* inv)
594{
595 const Container* cont = nullptr;
596 while ((cont = inv->getNextCont(cont, false))) {
597 Item* item = nullptr;
598 while ((item = cont->getNextItem(item))) {
600 GAME_SaveItem(s, item, cont->id, item->getX(), item->getY());
601 }
602 }
603}
604
614static bool GAME_LoadItem (xmlNode_t* n, Item* item, containerIndex_t* container, int* x, int* y)
615{
616 const char* itemID = XML_GetString(n, SAVE_INVENTORY_WEAPONID);
617 const char* contID = XML_GetString(n, SAVE_INVENTORY_CONTAINER);
618
619 *x = XML_GetInt(n, SAVE_INVENTORY_X, 0);
620 *y = XML_GetInt(n, SAVE_INVENTORY_Y, 0);
621
622 /* reset */
623 OBJZERO(*item);
624 int i;
625 for (i = 0; i < CID_MAX; i++) {
626 if (Q_streq(csi.ids[i].name, contID))
627 break;
628 }
629 *container = i;
630 if (i >= CID_MAX) {
631 Com_Printf("Invalid container id '%s'\n", contID);
632 return false;
633 }
634
635 item->setDef(INVSH_GetItemByID(itemID));
636 if (item->def() == nullptr) {
637 return false;
638 }
642 if (item->getAmmoLeft() > NONE_AMMO) {
644 item->setAmmoDef(INVSH_GetItemByID(itemID));
645
646 /* reset ammo count if ammunition (item) not found */
647 if (!item->ammoDef())
648 item->setAmmoLeft(NONE_AMMO);
649 /* no ammo needed - fire definitions are in the item */
650 } else if (!item->isReloadable()) {
651 item->setAmmoDef(item->def());
652 }
653
654 return true;
655}
656
666static void GAME_LoadInventory (xmlNode_t* p, Inventory* inv, int maxLoad)
667{
669 Item item;
670 containerIndex_t container;
671 int x;
672 int y;
673
674 GAME_LoadItem(s, &item, &container, &x, &y);
675 if (item.def() == nullptr)
676 continue;
677
678 if (INVDEF(container)->temp)
679 Com_Error(ERR_DROP, "GAME_LoadInventory failed, tried to add '%s' to a temp container %i", item.def()->id, container);
680 /* ignore the overload for now */
681 if (!inv->canHoldItemWeight(CID_EQUIP, container, item, maxLoad))
682 Com_Printf("GAME_LoadInventory: Item %s exceeds weight capacity\n", item.def()->id);
683
684 if (!cls.i.addToInventory(inv, &item, INVDEF(container), x, y, 1))
685 Com_Printf("Could not add item '%s' to inventory\n", item.def() ? item.def()->id : "nullptr");
686 }
687}
688
695{
696 assert(chr);
698 /* Store the character data */
714
715 const int implants = lengthof(chr->implants);
717 for (int i = 0; i < implants; i++) {
718 const implant_t& implant = chr->implants[i];
719 if (implant.def == nullptr)
720 continue;
721
722 xmlNode_t* sImplant = XML_AddNode(sImplants, SAVE_CHARACTER_IMPLANT);
726 }
727
729 /* Store wounds */
730 for (int k = 0; k < chr->teamDef->bodyTemplate->numBodyParts(); ++k) {
731 if (!chr->wounds.treatmentLevel[k])
732 continue;
733 xmlNode_t* sWound = XML_AddNode(sInjuries, SAVE_CHARACTER_WOUND);
734
737 }
738
739 const chrScoreGlobal_t* score = &chr->score;
740
742 /* Store skills */
743 for (int k = 0; k <= SKILL_NUM_TYPES; k++) {
744 if (score->experience[k] || score->initialSkills[k]
745 || (k < SKILL_NUM_TYPES && score->skills[k])) {
747 const int initial = score->initialSkills[k];
748 const int experience = score->experience[k];
749
752 XML_AddIntValue(sSkill, SAVE_CHARACTER_EXPERIENCE, experience);
753 if (k < SKILL_NUM_TYPES) {
754 const int skills = *(score->skills + k);
755 const int improve = skills - initial;
757 }
758 }
759 }
760 /* Store kills */
761 for (int k = 0; k < KILLED_NUM_TYPES; k++) {
762 if (score->kills[k] || score->stuns[k]) {
767 }
768 }
771
772 /* Store inventories */
774 GAME_SaveInventory(sInventory, &chr->inv);
775
777 return true;
778}
779
786{
787 bool success = true;
788
789 /* Load the character data */
790 Q_strncpyz(chr->name, XML_GetString(p, SAVE_CHARACTER_NAME), sizeof(chr->name));
791 Q_strncpyz(chr->body, XML_GetString(p, SAVE_CHARACTER_BODY), sizeof(chr->body));
792 Q_strncpyz(chr->path, XML_GetString(p, SAVE_CHARACTER_PATH), sizeof(chr->path));
793 Q_strncpyz(chr->head, XML_GetString(p, SAVE_CHARACTER_HEAD), sizeof(chr->head));
794
795 const int maxSkins = CL_GetActorSkinCount() - 1;
796 const int bodySkin = XML_GetInt(p, SAVE_CHARACTER_BDOY_SKIN, 0);
797 chr->bodySkin = std::min(maxSkins, bodySkin);
800 chr->ucn = XML_GetInt(p, SAVE_CHARACTER_UCN, 0);
802 chr->HP = XML_GetInt(p, SAVE_CHARACTER_HP, 0);
803 chr->STUN = XML_GetInt(p, SAVE_CHARACTER_STUN, 0);
807
808 /* Team-definition */
809 const char* s = XML_GetString(p, SAVE_CHARACTER_TEAMDEF);
811 if (!chr->teamDef)
812 return false;
813
815 /* Load wounds */
816 for (xmlNode_t* sWound = XML_GetNode(sInjuries, SAVE_CHARACTER_WOUND); sWound; sWound = XML_GetNextNode(sWound, sInjuries, SAVE_CHARACTER_WOUND)) {
817 const char* bodyPartId = XML_GetString(sWound, SAVE_CHARACTER_WOUNDEDPART);
818 short bodyPart;
819
820 if (bodyPartId[0] != '\0') {
821 for (bodyPart = 0; bodyPart < chr->teamDef->bodyTemplate->numBodyParts(); ++bodyPart)
822 if (Q_streq(chr->teamDef->bodyTemplate->id(bodyPart), bodyPartId))
823 break;
824 } else {
826 Com_Printf("GAME_LoadCharacter: Body part id not found while loading character wounds, must be an old save\n");
827 bodyPart = XML_GetInt(sWound, SAVE_CHARACTER_WOUNDTYPE, NONE);
828 }
829 if (bodyPart < 0 || bodyPart >= chr->teamDef->bodyTemplate->numBodyParts()) {
830 Com_Printf("GAME_LoadCharacter: Invalid body part id '%s' for %s (ucn: %i)\n", bodyPartId, chr->name, chr->ucn);
831 return false;
832 }
834 }
835
837 /* Load implants */
838 int implantCnt = 0;
839 for (xmlNode_t* sImplant = XML_GetNode(sImplants, SAVE_CHARACTER_IMPLANT); sImplant; sImplant = XML_GetNextNode(sImplant, sImplants, SAVE_CHARACTER_IMPLANT)) {
840 implant_t& implant = chr->implants[implantCnt++];
843 const char* implantDefID = XML_GetString(sImplants, SAVE_CHARACTER_IMPLANT_IMPLANT);
844 implant.def = INVSH_GetImplantByID(implantDefID);
845 }
846
848
850 /* Load Skills */
851 for (xmlNode_t* sSkill = XML_GetNode(sScore, SAVE_CHARACTER_SKILLS); sSkill; sSkill = XML_GetNextNode(sSkill, sScore, SAVE_CHARACTER_SKILLS)) {
852 int idx;
853 const char* type = XML_GetString(sSkill, SAVE_CHARACTER_SKILLTYPE);
854
856 Com_Printf("Invalid skill type '%s' for %s (ucn: %i)\n", type, chr->name, chr->ucn);
857 success = false;
858 break;
859 }
860
863 if (idx < SKILL_NUM_TYPES) {
864 chr->score.skills[idx] = chr->score.initialSkills[idx];
865 chr->score.skills[idx] += XML_GetInt(sSkill, SAVE_CHARACTER_SKILLIMPROVE, 0);
866 }
867 }
868
869 if (!success) {
871 return false;
872 }
873
874 /* Load kills */
875 for (xmlNode_t* sKill = XML_GetNode(sScore, SAVE_CHARACTER_KILLS); sKill; sKill = XML_GetNextNode(sKill, sScore, SAVE_CHARACTER_KILLS)) {
876 int idx;
877 const char* type = XML_GetString(sKill, SAVE_CHARACTER_KILLTYPE);
878
880 Com_Printf("Invalid kill type '%s' for %s (ucn: %i)\n", type, chr->name, chr->ucn);
881 success = false;
882 break;
883 }
884 chr->score.kills[idx] = XML_GetInt(sKill, SAVE_CHARACTER_KILLED, 0);
885 chr->score.stuns[idx] = XML_GetInt(sKill, SAVE_CHARACTER_STUNNED, 0);
886 }
887
888 if (!success) {
890 return false;
891 }
892
895
896 cls.i.destroyInventory(&chr->inv);
898 GAME_LoadInventory(sInventory, &chr->inv, GAME_GetChrMaxLoad(chr));
899
901
902 const char* body = CHRSH_CharGetBody(chr);
903 const char* head = CHRSH_CharGetHead(chr);
904 if (!R_ModelExists(head) || !R_ModelExists(body)) {
905 if (!Com_GetCharacterModel(chr))
906 return false;
907 }
908
909 return true;
910}
#define LittleLong(X)
Definition: byte.h:37
const char * CHRSH_CharGetBody(const character_t *const chr)
Returns the body model for the soldiers for armoured and non armoured soldiers.
Definition: chr_shared.cpp:297
const char * CHRSH_CharGetHead(const character_t *const chr)
Returns the head model for the soldiers for armoured and non armoured soldiers.
Definition: chr_shared.cpp:319
@ SKILL_NUM_TYPES
Definition: chr_shared.h:51
@ KILLED_NUM_TYPES
Definition: chr_shared.h:32
equipDef_t * GAME_GetEquipmentDefinition(void)
Definition: cl_game.cpp:1614
bool GAME_IsTeamEmpty(void)
Definition: cl_game.cpp:388
const char * GAME_GetAbsoluteSavePath(char *buf, size_t bufSize)
Definition: cl_game.cpp:1608
size_t GAME_GetCharacterArraySize(void)
Definition: cl_game.cpp:226
void GAME_GenerateTeam(const char *teamDefID, const equipDef_t *ed, int teamMembers)
Definition: cl_game.cpp:276
character_t * GAME_GetCharacter(int index)
Returns a character that can be used to store the game type specific character values.
Definition: cl_game.cpp:196
int GAME_GetChrMaxLoad(const character_t *chr)
Returns the max weight the given character can carry.
Definition: cl_game.cpp:1768
const char * GAME_GetTeamDef(void)
Definition: cl_game.cpp:1442
void GAME_ResetCharacters(void)
Reset all characters in the static character array.
Definition: cl_game.cpp:243
const char * GAME_GetRelativeSavePath(char *buf, size_t bufSize)
Definition: cl_game.cpp:1602
Shared game type headers.
bool GAME_SaveCharacter(xmlNode_t *p, const character_t *chr)
saves a character to a given xml node
static Inventory game_inventory
void GAME_SaveTeam_f(void)
Stores a team in a specified teamslot.
static void GAME_GetEquipment(void)
Get the equipment definition (from script files) for the current selected team and updates the equipm...
bool GAME_TeamGetFreeFilename(char *filename, size_t size)
Searches a free team filename.
void GAME_UpdateTeamMenuParameters_f(void)
Displays actor info and equipment and unused items in proper (filter) category.
void GAME_AutoTeam_f(void)
static bool GAME_LoadTeam(const char *filename)
Load a team from an xml file.
static void GAME_LoadInventory(xmlNode_t *p, Inventory *inv, int maxLoad)
Load callback for savegames in XML Format.
static bool GAME_SaveTeam(const char *filename, const char *name)
Saves a team in xml format.
void GAME_SaveTeamState_f(void)
Will remove those actors that should not be used in the team.
static bool characterActive[MAX_ACTIVETEAM]
void GAME_TeamDelete_f(void)
Removes a user created team.
static void GAME_SaveItem(xmlNode_t *p, const Item *item, containerIndex_t container, int x, int y)
Save one item.
void GAME_TeamSlotComments_f(void)
Reads the comments from team files.
static void GAME_SaveInventory(xmlNode_t *p, const Inventory *inv)
Save callback for savegames in XML Format.
#define TEAM_SAVE_FILE_VERSION
bool GAME_LoadDefaultTeam(bool force)
static void GAME_LoadTeamInfo(xmlNode_t *p)
Loads the wholeTeam from the xml file.
void GAME_ActorSelect_f(void)
static void GAME_SaveTeamInfo(xmlNode_t *p)
Stores the wholeTeam into a xml structure.
void GAME_AutoTeam(const char *equipmentDefinitionID, int teamMembers)
void GAME_ToggleActorForTeam_f(void)
This will activate/deactivate the actor for the team.
static bool GAME_LoadItem(xmlNode_t *n, Item *item, containerIndex_t *container, int *x, int *y)
Load one item.
void GAME_LoadTeam_f(void)
Loads the selected teamslot.
bool GAME_GetTeamFileName(unsigned int index, char *filename, size_t filenameLength)
Get the filename for the xth team in the file system.
bool GAME_LoadCharacter(xmlNode_t *p, character_t *chr)
Loads a character from a given xml node.
static void GAME_UpdateInventory(Inventory *inv, const equipDef_t *ed)
static void GAME_UpdateActiveTeamList(void)
cgame team management headers.
#define NO_TEAM_SLOT_LOADED
Definition: cl_game_team.h:30
const equipDef_t * INV_GetEquipmentDefinitionByID(const char *name)
Gets equipment definition by id.
client_static_t cls
Definition: cl_main.cpp:83
memPool_t * cl_genericPool
Definition: cl_main.cpp:86
#define _(String)
Definition: cl_shared.h:44
#define INVDEF(containerID)
Definition: cl_shared.h:48
void CL_UpdateCharacterValues(const character_t *chr)
Definition: cl_team.cpp:218
linkedList_t * chrDisplayList
List of currently displayed or equipable characters.
Definition: cl_team.cpp:38
unsigned int CL_GetActorSkinCount(void)
Get number of registered actorskins.
Definition: cl_team.cpp:63
short numBodyParts(void) const
Definition: chr_shared.cpp:389
const char * id(void) const
Definition: chr_shared.cpp:359
Item * getNextItem(const Item *prev) const
Definition: inv_shared.cpp:671
inventory definition with all its containers
Definition: inv_shared.h:525
bool canHoldItemWeight(containerIndex_t from, containerIndex_t to, const Item &item, int maxWeight) const
Check that adding an item to the inventory won't exceed the max permitted weight.
Definition: inv_shared.cpp:919
Item * getEquipContainer() const
Definition: inv_shared.cpp:980
void setContainer(const containerIndex_t idx, Item *cont)
Definition: inv_shared.h:550
void resetContainer(const containerIndex_t idx)
Definition: inv_shared.h:554
const Container * getNextCont(const Container *prev, bool inclTemp=false) const
Definition: inv_shared.cpp:722
void init()
Definition: inv_shared.cpp:703
void destroyInventory(Inventory *const inv)
Destroys inventory.
Definition: inventory.cpp:521
Item * addToInventory(Inventory *const inv, const Item *const item, const invDef_t *container, int x, int y, int amount) __attribute__((warn_unused_result))
Add an item to a specified container in a given inventory.
Definition: inventory.cpp:91
item instance data, with linked list capability
Definition: inv_shared.h:402
const objDef_t * ammoDef(void) const
Definition: inv_shared.h:460
int getAmmoLeft() const
Definition: inv_shared.h:466
int getX() const
Definition: inv_shared.h:454
void setAmount(int value)
Definition: inv_shared.h:438
void setAmmoDef(const objDef_t *od)
Definition: inv_shared.h:435
int rotated
Definition: inv_shared.h:412
int getAmount() const
Definition: inv_shared.h:463
void setDef(const objDef_t *objDef)
Definition: inv_shared.h:444
const objDef_t * def(void) const
Definition: inv_shared.h:469
int getY() const
Definition: inv_shared.h:457
bool isReloadable() const
Definition: inv_shared.h:479
void setAmmoLeft(int value)
Definition: inv_shared.h:441
const char * Cmd_Argv(int arg)
Returns a given argument.
Definition: cmd.cpp:516
int Cmd_Argc(void)
Return the number of arguments of the current command. "command parameter" will result in a argc of 2...
Definition: cmd.cpp:505
csi_t csi
Definition: common.cpp:39
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
Definition: common.cpp:398
void Com_Error(int code, const char *fmt,...)
Definition: common.cpp:417
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
#define ERR_DROP
Definition: common.h:211
cvar_t * Cvar_Set(const char *varName, const char *value,...)
Sets a cvar value.
Definition: cvar.cpp:615
const char * Cvar_GetString(const char *varName)
Returns the value of cvar as string.
Definition: cvar.cpp:210
#define DEBUG_CLIENT
Definition: defines.h:59
#define NONE_AMMO
Definition: defines.h:69
#define NONE
Definition: defines.h:68
#define MAX_ACTIVETEAM
Definition: defines.h:41
void FS_RemoveFile(const char *osPath)
Definition: files.cpp:1692
int FS_CheckFile(const char *fmt,...)
Just returns the filelength and -1 if the file wasn't found.
Definition: files.cpp:298
const char * FS_NextFileFromFileList(const char *files)
Returns the next file that is found in the virtual filesystem identified by the given file pattern.
Definition: files.cpp:1081
int FS_WriteFile(const void *buffer, size_t len, const char *filename)
Definition: files.cpp:1546
int FS_FileLength(qFILE *f)
Returns the size of a given file or -1 if no file is opened.
Definition: files.cpp:91
int FS_Read(void *buffer, int len, qFILE *f)
Definition: files.cpp:371
int FS_OpenFile(const char *filename, qFILE *file, filemode_t mode)
Finds and opens the file in the search path.
Definition: files.cpp:162
int FS_BuildFileList(const char *fileList)
Build a filelist.
Definition: files.cpp:962
bool FS_FileExists(const char *filename,...)
Checks whether a file exists (not in virtual filesystem)
Definition: files.cpp:1583
#define MAX_OSPATH
Definition: filesys.h:44
@ FILE_READ
Definition: filesys.h:111
const objDef_t * INVSH_GetItemByIDX(int index)
Returns the item that belongs to the given index or nullptr if the index is invalid.
Definition: inv_shared.cpp:266
const implantDef_t * INVSH_GetImplantByID(const char *id)
Returns the implant that belongs to the given id or nullptr if it wasn't found.
Definition: inv_shared.cpp:326
const objDef_t * INVSH_GetItemByID(const char *id)
Returns the item that belongs to the given id or nullptr if it wasn't found.
Definition: inv_shared.cpp:282
#define CID_MAX
Definition: inv_shared.h:57
int32_t containerIndex_t
Definition: inv_shared.h:46
#define CID_EQUIP
Definition: inv_shared.h:56
voidpf void uLong size
Definition: ioapi.h:42
const char * filename
Definition: ioapi.h:41
voidpf void * buf
Definition: ioapi.h:42
int LIST_Count(const linkedList_t *list)
Definition: list.cpp:344
void LIST_AddPointer(linkedList_t **listDest, void *data)
Adds just a pointer to a new or to an already existing linked list.
Definition: list.cpp:153
bool LIST_Remove(linkedList_t **list, const void *data)
Definition: list.cpp:213
bool LIST_IsEmpty(const linkedList_t *list)
Checks whether the given list is empty.
Definition: list.cpp:335
#define LIST_Foreach(list, type, var)
Iterates over a linked list, it's safe to delete the returned entry from the list while looping over ...
Definition: list.h:41
#define Mem_PoolAllocTypeN(type, n, pool)
Definition: mem.h:42
#define Mem_Free(ptr)
Definition: mem.h:35
QGL_EXTERN GLuint index
Definition: r_gl.h:110
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
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
bool R_ModelExists(const char *name)
Definition: r_model.cpp:177
XML tag constants for savegame.
#define SAVE_CHARACTER_SCORES
#define SAVE_CHARACTER_SCORE_ASSIGNEDMISSIONS
#define SAVE_CHARACTER_WOUNDSEVERITY
#define SAVE_CHARACTER_IMPLANT
#define SAVE_CHARACTER_KILLTYPE
#define SAVE_CHARACTER_INJURIES
#define SAVE_CHARACTER_KILLED
#define SAVE_CHARACTER_SKILLIMPROVE
#define SAVE_CHARACTER_HP
#define SAVE_CHARACTER_IMPLANT_IMPLANT
#define SAVE_CHARACTER_IMPLANT_INSTALLEDTIME
#define SAVE_CHARACTER_SKILLTYPE_NAMESPACE
#define SAVE_CHARACTER_MORALE
#define SAVE_CHARACTER_PATH
#define SAVE_CHARACTER_HEAD_SKIN
#define SAVE_CHARACTER_KILLS
#define SAVE_CHARACTER_EXPERIENCE
#define SAVE_CHARACTER_IMPLANT_REMOVETIME
#define SAVE_CHARACTER_FIELDSIZE
#define SAVE_CHARACTER_INITSKILL
#define SAVE_CHARACTER_HEAD
#define SAVE_CHARACTER_STATE
#define SAVE_CHARACTER_KILLTYPE_NAMESPACE
#define SAVE_CHARACTER_MAXHP
#define SAVE_CHARACTER_STUN
#define SAVE_CHARACTER_WOUNDTYPE
#define SAVE_CHARACTER_NAME
#define SAVE_CHARACTER_STUNNED
#define SAVE_CHARACTER_SKILLS
#define SAVE_CHARACTER_BODY
#define SAVE_CHARACTER_BDOY_SKIN
#define SAVE_CHARACTER_IMPLANTS
#define SAVE_CHARACTER_SKILLTYPE
#define SAVE_CHARACTER_UCN
#define SAVE_CHARACTER_SCORE_RANK
#define SAVE_CHARACTER_WOUNDEDPART
#define SAVE_CHARACTER_TEAMDEF
#define SAVE_CHARACTER_WOUND
static const constListEntry_t saveCharacterConstants[]
#define SAVE_CHARACTER_GENDER
XML tag constants for savegame.
#define SAVE_INVENTORY_MUNITIONID
#define SAVE_INVENTORY_AMMO
#define SAVE_INVENTORY_ITEM
#define SAVE_INVENTORY_WEAPONID
#define SAVE_INVENTORY_Y
#define SAVE_INVENTORY_ROTATED
#define SAVE_INVENTORY_AMOUNT
#define SAVE_INVENTORY_CONTAINER
#define SAVE_INVENTORY_X
#define SAVE_INVENTORY_INVENTORY
XML tag constants for team savegame.
#define SAVE_TEAM_ITEM
Definition: save_team.h:33
#define SAVE_TEAM_NUM
Definition: save_team.h:35
#define SAVE_TEAM_NUMLOOSE
Definition: save_team.h:36
#define SAVE_TEAM_ROOTNODE
Definition: save_team.h:27
#define SAVE_TEAM_EQUIPMENT
Definition: save_team.h:32
#define SAVE_TEAM_ID
Definition: save_team.h:34
#define SAVE_TEAM_NODE
Definition: save_team.h:29
#define SAVE_TEAM_CHARACTER
Definition: save_team.h:30
const teamDef_t * Com_GetTeamDefinitionByID(const char *team)
Returns the teamDef pointer for the searched team id - or nullptr if not found in the teamDef array.
Definition: scripts.cpp:2345
bool Com_UnregisterConstList(const constListEntry_t constList[])
Unregisters a list of string aliases.
Definition: scripts.cpp:237
bool Com_GetCharacterModel(character_t *chr)
Definition: scripts.cpp:2358
bool Com_GetConstIntFromNamespace(const char *space, const char *variable, int *value)
Searches whether a given value was registered as a string to int mapping.
Definition: scripts.cpp:103
const char * Com_GetConstVariable(const char *space, int value)
Searches the mapping variable for a given integer value and a namespace.
Definition: scripts.cpp:122
void Com_RegisterConstList(const constListEntry_t constList[])
Registers a list of string aliases.
Definition: scripts.cpp:253
#define Q_streq(a, b)
Definition: shared.h:136
bool Q_strnull(const char *string)
Definition: shared.h:138
#define OBJZERO(obj)
Definition: shared.h:178
#define lengthof(x)
Definition: shared.h:105
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
Describes a character with all its attributes.
Definition: chr_shared.h:388
const teamDef_t * teamDef
Definition: chr_shared.h:413
char head[MAX_VAR]
Definition: chr_shared.h:393
char path[MAX_VAR]
Definition: chr_shared.h:391
chrScoreGlobal_t score
Definition: chr_shared.h:406
actorSizeEnum_t fieldSize
Definition: chr_shared.h:409
woundInfo_t wounds
Definition: chr_shared.h:402
char body[MAX_VAR]
Definition: chr_shared.h:392
char name[MAX_VAR]
Definition: chr_shared.h:390
Inventory inv
Definition: chr_shared.h:411
implant_t implants[MAX_CHARACTER_IMPLANTS]
Definition: chr_shared.h:418
Structure of all stats collected for an actor over time.
Definition: chr_shared.h:119
int initialSkills[SKILL_NUM_TYPES+1]
Definition: chr_shared.h:123
int stuns[KILLED_NUM_TYPES]
Definition: chr_shared.h:127
int kills[KILLED_NUM_TYPES]
Definition: chr_shared.h:126
int skills[SKILL_NUM_TYPES]
Definition: chr_shared.h:122
int experience[SKILL_NUM_TYPES+1]
Definition: chr_shared.h:120
int teamSaveSlotIndex
Definition: client.h:78
InventoryInterface i
Definition: client.h:101
int numODs
Definition: q_shared.h:518
invDef_t ids[MAX_INVDEFS]
Definition: q_shared.h:524
int numItems[MAX_OBJDEFS]
Definition: inv_shared.h:608
byte numItemsLoose[MAX_OBJDEFS]
Definition: inv_shared.h:609
int removedTime
Definition: chr_shared.h:375
const implantDef_t * def
Definition: chr_shared.h:373
int installedTime
Definition: chr_shared.h:374
const char * id
Definition: inv_shared.h:102
char name[MAX_VAR]
Definition: inv_shared.h:372
void * data
Definition: list.h:31
Defines all attributes of objects used in the inventory.
Definition: inv_shared.h:264
const char * id
Definition: inv_shared.h:268
char id[MAX_VAR]
Definition: chr_shared.h:309
const BodyData * bodyTemplate
Definition: chr_shared.h:350
int treatmentLevel[BODYPART_MAXTYPE]
Definition: chr_shared.h:363
void UI_ResetData(int dataId)
Reset a shared data. Type became NONE and value became nullptr.
Definition: ui_data.cpp:212
@ TEXT_STANDARD
Definition: ui_dataids.h:30
void UI_ExecuteConfunc(const char *fmt,...)
Executes confunc - just to identify those confuncs in the code - in this frame.
Definition: ui_main.cpp:110
Inventory * ui_inventory
void UI_ContainerNodeUpdateEquipment(Inventory *inv, const equipDef_t *ed)
Fills the ground container of the ui_inventory with unused items from a given equipment definition.
void UI_Popup(const char *title, const char *text)
Popup on geoscape.
Definition: ui_popup.cpp:47
xmlNode_t * XML_GetNextNode(xmlNode_t *current, xmlNode_t *parent, const char *name)
Get next Node of the XML tree by name.
Definition: xml.cpp:499
void XML_AddString(xmlNode_t *parent, const char *name, const char *value)
add a String attribute to the XML Node
Definition: xml.cpp:36
void XML_AddIntValue(xmlNode_t *parent, const char *name, int value)
add a non-zero Int attribute to the XML Node
Definition: xml.cpp:195
int XML_GetInt(xmlNode_t *parent, const char *name, const int defaultval)
retrieve an Int attribute from an XML Node
Definition: xml.cpp:308
const char * XML_GetString(xmlNode_t *parent, const char *name)
retrieve a String attribute from an XML Node
Definition: xml.cpp:350
xmlNode_t * XML_Parse(const char *buffer)
Definition: xml.cpp:531
xmlNode_t * XML_AddNode(xmlNode_t *parent, const char *name)
add a new node to the XML tree
Definition: xml.cpp:277
void XML_AddInt(xmlNode_t *parent, const char *name, int value)
add an Int attribute to the XML Node
Definition: xml.cpp:183
xmlNode_t * XML_GetNode(xmlNode_t *parent, const char *name)
Get first Node of the XML tree by name.
Definition: xml.cpp:487
#define xmlNode_t
Definition: xml.h:24