UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
cp_team.cpp
Go to the documentation of this file.
1 
6 /*
7 Copyright (C) 2002-2020 UFO: Alien Invasion.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.m
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 
24 */
25 
26 #include "../../cl_shared.h"
27 #include "../../cl_team.h"
28 #include "cp_campaign.h"
29 #include "cp_team.h"
30 
38 void CP_AddWeaponAmmo (equipDef_t* ed, Item* item)
39 {
40  const objDef_t* type = item->def();
41 
42  assert(ed->numItems[type->idx] > 0);
43  --ed->numItems[type->idx];
44  if (type->isArmour())
45  return;
46 
47  if (type->weapons[0]) {
48  /* The given item is ammo or self-contained weapon (i.e. It has firedefinitions. */
49  if (!type->isAmmo()) {
50  /* "Recharge" the oneshot weapon. */
51  item->setAmmoLeft(type->ammo);
52  item->setAmmoDef(item->def()); /* Just in case this hasn't been done yet. */
53  cgi->Com_DPrintf(DEBUG_CLIENT, "CL_AddWeaponAmmo: oneshot weapon '%s'.\n", type->id);
54  return;
55  } else {
56  /* No change, nothing needs to be done to this item. */
57  return;
58  }
59  } else if (item->getAmmoLeft()) {
60  assert(item->ammoDef());
61  /* The item is a weapon and it was reloaded one time. */
62  if (item->getAmmoLeft() == type->ammo) {
63  /* Fully loaded, no need to reload, but mark the ammo as used. */
64  if (ed->numItems[item->ammoDef()->idx] > 0) {
65  --ed->numItems[item->ammoDef()->idx];
66  } else {
67  /* Your clip has been sold; give it back. */
68  item->setAmmoLeft(NONE_AMMO);
69  }
70  return;
71  }
72  }
73 
74  /* Check for complete clips of the same kind */
75  if (item->ammoDef() && ed->numItems[item->ammoDef()->idx] > 0) {
76  --ed->numItems[item->ammoDef()->idx];
77  item->setAmmoLeft(type->ammo);
78  return;
79  }
80 
81  /* Search for any complete clips. */
83  for (int i = 0; i < cgi->csi->numODs; i++) {
84  const objDef_t* od = INVSH_GetItemByIDX(i);
85  if (od->isLoadableInWeapon(type)) {
86  if (ed->numItems[i] > 0) {
87  --ed->numItems[i];
88  item->setAmmoLeft(type->ammo);
89  item->setAmmoDef(od);
90  return;
91  }
92  }
93  }
94 
101  /* Failed to find a complete clip - see if there's any loose ammo
102  * of the same kind; if so, gather it all in this weapon. */
103  if (item->ammoDef() && ed->numItemsLoose[item->ammoDef()->idx] > 0) {
104  item->setAmmoLeft(ed->numItemsLoose[item->ammoDef()->idx]);
105  ed->numItemsLoose[item->ammoDef()->idx] = 0;
106  return;
107  }
108 
109  /* See if there's any loose ammo */
111  item->setAmmoLeft(NONE_AMMO);
112  for (int i = 0; i < cgi->csi->numODs; i++) {
113  const objDef_t* od = INVSH_GetItemByIDX(i);
114  if (od->isLoadableInWeapon(type) && ed->numItemsLoose[i] > item->getAmmoLeft()) {
115  if (item->getAmmoLeft() > 0) {
116  /* We previously found some ammo, but we've now found other
117  * loose ammo of a different (but appropriate) type with
118  * more bullets. Put the previously found ammo back, so
119  * we'll take the new type. */
120  assert(item->ammoDef());
121  ed->numItemsLoose[item->ammoDef()->idx] = item->getAmmoLeft();
122  /* We don't have to accumulate loose ammo into clips
123  * because we did it previously and we create no new ammo */
124  }
125  /* Found some loose ammo to load the weapon with */
126  item->setAmmoLeft(ed->numItemsLoose[i]);
127  ed->numItemsLoose[i] = 0;
128  item->setAmmoDef(od);
129  }
130  }
131 }
132 
138 {
139  /* get the inventory the UI uses for all the work */
140  Inventory* uiInv = *cgi->ui_inventory;
141  /* if it was not already set to our character's inventory ... */
142  if (uiInv && uiInv != &chr->inv) {
143  /* ...use the UI equip cont for our character's equipment container */
145  /* set 'old' CID_EQUIP to nullptr */
146  uiInv->resetContainer(CID_EQUIP);
147  }
148  /* set the UI inventory to our char's (including the equip container we preserved.) */
149  *cgi->ui_inventory = &chr->inv;
150 }
151 
156 {
157  Item* ic, *next;
158 
159  for (ic = chr->inv.getContainer2(container); ic; ic = next) {
160  next = ic->getNext();
161  if (ed->numItems[ic->def()->idx] > 0) {
162  CP_AddWeaponAmmo(ed, ic);
163  } else {
164  /* Drop ammo used for reloading and sold carried weapons. */
165  if (!cgi->INV_RemoveFromInventory(&chr->inv, chr->inv.getContainer(container).def(), ic))
166  cgi->Com_Error(ERR_DROP, "Could not remove item from inventory");
167  }
168  }
169 }
170 
186 {
187  assert(base);
188 
189  /* Auto-assign weapons to UGVs/Robots if they have no weapon yet. */
190  E_Foreach(EMPL_ROBOT, employee) {
191  if (!employee->isHiredInBase(base))
192  continue;
193  if (employee->transfer)
194  continue;
195 
196  character_t* chr = &employee->chr;
197 
198  /* This is an UGV */
199  if (employee->getUGV()) {
200  /* Check if there is a weapon and add it if there isn't. */
201  Item* rightH = chr->inv.getRightHandContainer();
202  if (!rightH || !rightH->def())
203  cgi->INV_EquipActor(chr, nullptr, INVSH_GetItemByID(employee->getUGV()->weapon),
204  cgi->GAME_GetChrMaxLoad(chr));
205  }
206  }
207 
208  for (containerIndex_t container = 0; container < CID_MAX; container++) {
209  E_Foreach(EMPL_SOLDIER, employee) {
210  if (!employee->isHiredInBase(base))
211  continue;
212  if (employee->transfer)
213  continue;
214 
215  character_t* chr = &employee->chr;
216 #if 0
217  /* ignore items linked from any temp container */
218  if (INVDEF(container)->temp)
219  continue;
220 #endif
221  CP_CleanupContainerWeapons(ed, container, chr);
222  }
223  }
224 }
225 
241 {
242  assert(aircraft);
243 
244  for (containerIndex_t container = 0; container < CID_MAX; container++) {
245  LIST_Foreach(aircraft->acTeam, Employee, employee) {
246  character_t* chr = &employee->chr;
247 
248  /* Auto-assign weapons to UGVs/Robots if they have no weapon yet. */
249  if (employee->getUGV()) {
250  /* Check if there is a weapon and add it if there isn't. */
251  Item* rightH = chr->inv.getRightHandContainer();
252  if (!rightH || !rightH->def())
253  cgi->INV_EquipActor(chr, nullptr, INVSH_GetItemByID(employee->getUGV()->weapon),
254  cgi->GAME_GetChrMaxLoad(chr));
255  continue;
256  }
257 
258 #if 0
259  /* ignore items linked from any temp container */
260  if (INVDEF(container)->temp)
261  continue;
262 #endif
263  CP_CleanupContainerWeapons(ed, container, chr);
264  }
265  }
266 }
267 
274 {
275  E_Foreach(EMPL_SOLDIER, employee) {
276  employee->chr.inv.resetTempContainers();
277  }
278 
279  E_Foreach(EMPL_ROBOT, employee) {
280  employee->chr.inv.resetTempContainers();
281  }
282 
283  if (!base)
284  return;
285 
286  cgi->INV_DestroyInventory(&base->bEquipment);
287 }
288 
297 {
298  int numOnAircraft;
299  const Employee* pilot = AIR_GetPilot(aircraft);
300 
301  assert(aircraft);
302 
303  numOnAircraft = AIR_GetTeamSize(aircraft);
304  cgi->Cvar_Set("mn_hired", _("%i of %i"), numOnAircraft, aircraft->maxTeamSize);
305  cgi->Cvar_Set("mn_hirable_count", "%i", aircraft->maxTeamSize - numOnAircraft);
306  cgi->Cvar_Set("mn_hired_count", "%i", numOnAircraft);
307 
308  if (pilot) {
309  cgi->Cvar_Set("mn_pilotassigned", "1");
310  cgi->Cvar_Set("mn_pilot_name", "%s", pilot->chr.name);
311  cgi->Cvar_Set("mn_pilot_body", "%s", CHRSH_CharGetBody(&pilot->chr));
312  cgi->Cvar_Set("mn_pilot_head", "%s", CHRSH_CharGetHead(&pilot->chr));
313  cgi->Cvar_Set("mn_pilot_body_skin", "%i", pilot->chr.bodySkin);
314  cgi->Cvar_Set("mn_pilot_head_skin", "%i", pilot->chr.headSkin);
315  } else {
316  cgi->Cvar_Set("mn_pilotassigned", "0");
317  cgi->Cvar_Set("mn_pilot_name", "");
318  cgi->Cvar_Set("mn_pilot_body", "");
319  cgi->Cvar_Set("mn_pilot_head", "");
320  cgi->Cvar_Set("mn_pilot_body_skin", "");
321  cgi->Cvar_Set("mn_pilot_head_skin", "");
322  }
323 }
#define CID_EQUIP
Definition: inv_shared.h:56
void setAmmoLeft(int value)
Definition: inv_shared.h:441
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
QGL_EXTERN GLint GLenum type
Definition: r_gl.h:94
int getAmmoLeft() const
Definition: inv_shared.h:466
#define E_Foreach(employeeType, var)
Definition: cp_employee.h:122
void resetContainer(const containerIndex_t idx)
Definition: inv_shared.h:554
#define _(String)
Definition: cl_shared.h:43
Item * getContainer2(const containerIndex_t idx) const
Definition: inv_shared.h:546
int maxTeamSize
Definition: cp_aircraft.h:138
csi_t * csi
Definition: cgame.h:100
character_t chr
Definition: cp_employee.h:119
const objDef_t * def(void) const
Definition: inv_shared.h:469
Inventory ** ui_inventory
Definition: cgame.h:101
int numODs
Definition: q_shared.h:518
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:296
Item * getNext() const
Definition: inv_shared.h:451
linkedList_t * acTeam
Definition: cp_aircraft.h:139
Defines all attributes of objects used in the inventory.
Definition: inv_shared.h:264
void CP_UpdateActorAircraftVar(aircraft_t *aircraft, employeeType_t employeeType)
Updates data about teams in aircraft.
Definition: cp_team.cpp:296
A base with all it's data.
Definition: cp_base.h:84
item instance data, with linked list capability
Definition: inv_shared.h:402
cvar_t *IMPORT * Cvar_Set(const char *varName, const char *value,...) __attribute__((format(__printf__
inventory definition with all its containers
Definition: inv_shared.h:525
#define ERR_DROP
Definition: common.h:211
#define DEBUG_CLIENT
Definition: defines.h:59
Item * getRightHandContainer() const
Definition: inv_shared.cpp:955
const cgame_import_t * cgi
bool isAmmo() const
Definition: inv_shared.h:343
employeeType_t
The types of employees.
Definition: cp_employee.h:30
Employee * AIR_GetPilot(const aircraft_t *aircraft)
Get pilot of an aircraft.
const invDef_t * def() const
Definition: inv_shared.cpp:667
#define INVDEF(containerID)
Definition: cl_shared.h:47
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:318
const Container & getContainer(const containerIndex_t idx) const
Definition: inv_shared.h:537
int32_t containerIndex_t
Definition: inv_shared.h:46
bool isLoadableInWeapon(const objDef_s *weapon) const
Checks if an item can be used to reload a weapon.
Definition: inv_shared.cpp:356
static void CP_CleanupContainerWeapons(equipDef_t *ed, containerIndex_t container, character_t *chr)
Reload or remove weapons in container.
Definition: cp_team.cpp:155
void CP_AddWeaponAmmo(equipDef_t *ed, Item *item)
Updates status of weapon (sets pointers, reloads, etc).
Definition: cp_team.cpp:38
QGL_EXTERN GLint i
Definition: r_gl.h:113
void CP_CleanupTeam(base_t *base, equipDef_t *ed)
Reloads weapons, removes not assigned and resets defaults.
Definition: cp_team.cpp:185
int AIR_GetTeamSize(const aircraft_t *aircraft)
Counts the number of soldiers in given aircraft.
int numItems[MAX_OBJDEFS]
Definition: inv_shared.h:608
void setAmmoDef(const objDef_t *od)
Definition: inv_shared.h:435
int ammo
Definition: inv_shared.h:293
#define CID_MAX
Definition: inv_shared.h:57
bool isArmour() const
Definition: inv_shared.h:346
#define NONE_AMMO
Definition: defines.h:69
const objDef_t * ammoDef(void) const
Definition: inv_shared.h:460
#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
Header file for single player campaign control.
byte numItemsLoose[MAX_OBJDEFS]
Definition: inv_shared.h:609
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
Inventory inv
Definition: chr_shared.h:392
char name[MAX_VAR]
Definition: chr_shared.h:371
void CP_CleanTempInventory(base_t *base)
Clears all containers that are temp containers (see script definition).
Definition: cp_team.cpp:273
Inventory bEquipment
Definition: cp_base.h:114
An aircraft with all it's data.
Definition: cp_aircraft.h:114
Team management for the campaign gametype headers.
void setContainer(const containerIndex_t idx, Item *cont)
Definition: inv_shared.h:550
const char * id
Definition: inv_shared.h:268
const struct objDef_s * weapons[MAX_WEAPONS_PER_OBJDEF]
Definition: inv_shared.h:311
void CP_SetEquipContainer(character_t *chr)
Set up equip (floor) container for soldiers.
Definition: cp_team.cpp:137
void CP_CleanupAircraftTeam(aircraft_t *aircraft, equipDef_t *ed)
Reloads weapons, removes not assigned and resets defaults.
Definition: cp_team.cpp:240
Describes a character with all its attributes.
Definition: chr_shared.h:369