UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
itemcargo.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.
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 #include "itemcargo.h"
26 
27 #define SAVE_ITEMCARGO_ITEM "item"
28 #define SAVE_ITEMCARGO_ITEMID "itemid"
29 #define SAVE_ITEMCARGO_AMOUNT "amount"
30 #define SAVE_ITEMCARGO_LOOSEAMOUNT "looseamount"
31 
39 bool ItemCargo::add(const objDef_t* od, int amount, int looseAmount = 0)
40 {
41  if (!od)
42  return false;
43  if (amount == 0 && looseAmount == 0)
44  return true;
45 
46  LIST_Foreach(this->cargo, itemCargo_t, item) {
47  if (item->objDef != od)
48  continue;
49 
50  if (amount + item->amount < 0)
51  return false;
52  if (looseAmount + item->looseAmount < 0)
53  return false;
54 
55  item->amount += amount;
56  item->looseAmount += looseAmount;
57  if (od->ammo > 0 && item->looseAmount >= od->ammo) {
58  const int magazine = item->looseAmount / od->ammo;
59  this->add(od, magazine, -magazine * od->ammo);
60  }
61 
62  if (item->amount == 0 && item->looseAmount == 0)
63  cgi->LIST_Remove(&this->cargo, (void*)item);
64 
65  return true;
66  }
67 
68  if (amount < 0 || looseAmount < 0)
69  return false;
70 
71  itemCargo_t cargoItem = { od, amount, looseAmount };
72 
73  if (cgi->LIST_Add(&this->cargo, (const void*)&cargoItem, sizeof(cargoItem))) {
74  return true;
75  }
76 
77  return false;
78 }
79 
86 bool ItemCargo::add(const char* objDefId, int amount, int looseAmount = 0)
87 {
88  if (!objDefId)
89  return false;
90  const objDef_t* od = INVSH_GetItemByIDSilent(objDefId);
91  if (!od)
92  return false;
93  return this->add(od, amount, looseAmount);
94 }
95 
99 void ItemCargo::empty (void)
100 {
101  cgi->LIST_Delete(&(this->cargo));
102 }
103 
107 bool ItemCargo::isEmpty (void) const
108 {
109  return (this->cargo == nullptr);
110 }
111 
118 {
119  LIST_Foreach(this->cargo, itemCargo_t, item) {
120  if (item->objDef == od)
121  return item;
122  }
123  return nullptr;
124 }
125 
131 int ItemCargo::getAmount(const objDef_t* od) const
132 {
133  const itemCargo_t* const item = this->get(od);
134  if (item == nullptr)
135  return 0;
136  return item->amount;
137 }
138 
145 {
146  const itemCargo_t* const item = this->get(od);
147  if (item == nullptr)
148  return 0;
149  return item->looseAmount;
150 }
151 
157 {
158  linkedList_t* listing = nullptr;
159 
160  LIST_Foreach(this->cargo, itemCargo_t, item) {
161  if (!cgi->LIST_Add(&listing, (void*)item, sizeof(*item))) {
162  cgi->LIST_Delete(&listing);
163  return nullptr;
164  }
165  }
166  return listing;
167 }
168 
172 int ItemCargo::count(void) const
173 {
174  int count = 0;
175  LIST_Foreach(this->cargo, itemCargo_t, item) {
176  count += item->amount;
177  }
178  return count;
179 }
180 
184 int ItemCargo::size(void) const
185 {
186  int size = 0;
187  LIST_Foreach(this->cargo, itemCargo_t, item) {
188  size += item->amount * item->objDef->size;
189  }
190  return size;
191 }
192 
198 {
199  if (!root)
200  return false;
201 
202  for (xmlNode_t* itemNode = cgi->XML_GetNode(root, SAVE_ITEMCARGO_ITEM); itemNode;
203  itemNode = cgi->XML_GetNextNode(itemNode, root, SAVE_ITEMCARGO_ITEM))
204  {
205  const char* objDefId = cgi->XML_GetString(itemNode, SAVE_ITEMCARGO_ITEMID);
206  const int amount = cgi->XML_GetInt(itemNode, SAVE_ITEMCARGO_AMOUNT, 0);
207  const int looseAmount = cgi->XML_GetInt(itemNode, SAVE_ITEMCARGO_LOOSEAMOUNT, 0);
208  if (!add(objDefId, amount, looseAmount))
209  cgi->Com_Printf("ItemCargo::load: Could add items to cargo: %s, %d, %d\n", objDefId, amount, looseAmount);
210  }
211  return true;
212 }
213 
218 bool ItemCargo::save(xmlNode_t* root) const
219 {
220  if (!root)
221  return false;
222  LIST_Foreach(this->cargo, itemCargo_t, item) {
223  xmlNode_t* itemNode = cgi->XML_AddNode(root, SAVE_ITEMCARGO_ITEM);
224  if (!itemNode)
225  return false;
226  cgi->XML_AddString(itemNode, SAVE_ITEMCARGO_ITEMID, item->objDef->id);
227  cgi->XML_AddIntValue(itemNode, SAVE_ITEMCARGO_AMOUNT, item->amount);
228  cgi->XML_AddIntValue(itemNode, SAVE_ITEMCARGO_LOOSEAMOUNT, item->looseAmount);
229  }
230  return true;
231 }
232 
237 {
238 }
239 
245 {
246  linkedList_t* list = itemCargo.list();
247 
248  LIST_Foreach(list, itemCargo_t, cargoItem) {
249  cgi->LIST_Add(&this->cargo, (void*)cargoItem, sizeof(*cargoItem));
250  }
251  cgi->LIST_Delete(&list);
252 }
253 
258 {
259  cgi->LIST_Delete(&this->cargo);
260 }
const objDef_t * INVSH_GetItemByIDSilent(const char *id)
Returns the item that belongs to the given id or nullptr if it wasn't found.
Definition: inv_shared.cpp:249
virtual bool add(const objDef_t *od, int amount, int looseAmount)
Add items to the cargo.
Definition: itemcargo.cpp:39
int getLooseAmount(const objDef_t *od) const
Returns amount of loose item in the cargo.
Definition: itemcargo.cpp:144
int looseAmount
Definition: itemcargo.h:35
#define SAVE_ITEMCARGO_AMOUNT
Definition: itemcargo.cpp:29
#define SAVE_ITEMCARGO_LOOSEAMOUNT
Definition: itemcargo.cpp:30
#define SAVE_ITEMCARGO_ITEMID
Definition: itemcargo.cpp:28
itemCargo_t * get(const objDef_t *od) const
Returns a cargo item by its object definition.
Definition: itemcargo.cpp:117
void empty(void)
Empties the cargo.
Definition: itemcargo.cpp:99
#define nullptr
Definition: cxx.h:53
bool load(xmlNode_t *root)
Load item cargo from xml savegame.
Definition: itemcargo.cpp:197
Item cargo class header.
Defines all attributes of objects used in the inventory.
Definition: inv_shared.h:264
#define SAVE_ITEMCARGO_ITEM
Definition: itemcargo.cpp:27
#define xmlNode_t
Definition: xml.h:24
GLsizei size
Definition: r_gl.h:152
int size(void) const
Calculate size of all items in the cargo.
Definition: itemcargo.cpp:184
Item cargo class.
Definition: itemcargo.h:41
const cgame_import_t * cgi
linkedList_t * cargo
Definition: itemcargo.h:43
bool isEmpty(void) const
Checks if the cargo is empty.
Definition: itemcargo.cpp:107
ItemCargo(void)
Creates and initializes ItemCargo object.
Definition: itemcargo.cpp:236
virtual ~ItemCargo(void)
Destroys ItemCargo with it's internal data.
Definition: itemcargo.cpp:257
int count(void) const
Count all items in the cargo.
Definition: itemcargo.cpp:172
int amount
Definition: itemcargo.h:34
xmlNode_t *IMPORT * XML_GetNextNode(xmlNode_t *current, xmlNode_t *parent, const char *name)
bool save(xmlNode_t *root) const
Save item cargo to xml savegame.
Definition: itemcargo.cpp:218
int ammo
Definition: inv_shared.h:293
#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
xmlNode_t *IMPORT * XML_AddNode(xmlNode_t *parent, const char *name)
linkedList_t * list(void) const
Returns a copy of the cargo list.
Definition: itemcargo.cpp:156
linkedList_t *IMPORT * LIST_Add(linkedList_t **list, void const *data, size_t length)
item cargo entry
Definition: itemcargo.h:32
const char *IMPORT * XML_GetString(xmlNode_t *parent, const char *name)
xmlNode_t *IMPORT * XML_GetNode(xmlNode_t *parent, const char *name)
int getAmount(const objDef_t *od) const
Returns amount of an item in the cargo.
Definition: itemcargo.cpp:131