1 /**
2 * @file
3 */
4
5 /*
6 Copyright (C) 2002-2013 UFO: Alien Invasion.
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12
13 This program 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.
16
17 See the GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24 #include "../../cl_shared.h"
25 #include "cp_campaign.h"
26 #include "cp_capacity.h"
27 #include "cp_aircraft.h"
28 #include "cp_missions.h"
29 #include "cp_geoscape.h"
30 #include "cp_popup.h"
31 #include "cp_time.h"
32 #include "cp_ufo.h"
33
34 /**
35 * @brief Remove exceeding antimatter if an antimatter tank has been destroyed.
36 * @param[in] base Pointer to the base.
37 */
CAP_RemoveAntimatterExceedingCapacity(base_t * base)38 void CAP_RemoveAntimatterExceedingCapacity (base_t* base)
39 {
40 const int amount = CAP_GetCurrent(base, CAP_ANTIMATTER) - CAP_GetMax(base, CAP_ANTIMATTER);
41 if (amount <= 0)
42 return;
43
44 B_ManageAntimatter(base, amount, false);
45 }
46
47 /**
48 * @brief Update Storage Capacity.
49 * @param[in] base Pointer to the base
50 * @sa B_ResetAllStatusAndCapacities_f
51 */
CAP_UpdateStorageCap(base_t * base)52 void CAP_UpdateStorageCap (base_t* base)
53 {
54 int i;
55
56 CAP_SetCurrent(base, CAP_ITEMS, 0);
57
58 for (i = 0; i < cgi->csi->numODs; i++) {
59 const objDef_t* obj = INVSH_GetItemByIDX(i);
60
61 if (!B_ItemIsStoredInBaseStorage(obj))
62 continue;
63
64 CAP_AddCurrent(base, CAP_ITEMS, B_ItemInBase(obj, base) * obj->size);
65 }
66
67 /* UGV takes room in storage capacity */
68 CAP_AddCurrent(base, CAP_ITEMS, UGV_SIZE * E_CountHired(base, EMPL_ROBOT));
69 }
70
71 /**
72 * @brief Sets the maximal capacity on a base
73 * @param[in,out] base The base to set capacity at
74 * @param[in] capacity Capacity type
75 * @param[in] value New maximal capacity value
76 */
CAP_SetMax(base_t * base,baseCapacities_t capacity,int value)77 void CAP_SetMax (base_t* base, baseCapacities_t capacity, int value)
78 {
79 base->capacities[capacity].max = std::max(0, value);
80 }
81
82 /**
83 * @brief Changes the maximal capacity on a base
84 * @param[in,out] base The base to set capacity at
85 * @param[in] capacity Capacity type
86 * @param[in] value Capacity to add to the maximal capacity value (negative to decrease)
87 */
CAP_AddMax(base_t * base,baseCapacities_t capacity,int value)88 void CAP_AddMax (base_t* base, baseCapacities_t capacity, int value)
89 {
90 base->capacities[capacity].max = std::max(0, base->capacities[capacity].max + value);
91 }
92
93 /**
94 * @brief Sets the current (used) capacity on a base
95 * @param[in,out] base The base to set capacity at
96 * @param[in] capacity Capacity type
97 * @param[in] value New current (used) capacity value
98 */
CAP_SetCurrent(base_t * base,baseCapacities_t capacity,int value)99 void CAP_SetCurrent (base_t* base, baseCapacities_t capacity, int value)
100 {
101 base->capacities[capacity].cur = std::max(0, value);
102 }
103
104 /**
105 * @brief Changes the current (used) capacity on a base
106 * @param[in,out] base The base to set capacity at
107 * @param[in] capacity Capacity type
108 * @param[in] value Capacity to add to the current (used) capacity value (negative to decrease)
109 */
CAP_AddCurrent(base_t * base,baseCapacities_t capacity,int value)110 void CAP_AddCurrent (base_t* base, baseCapacities_t capacity, int value)
111 {
112 base->capacities[capacity].cur = std::max(0, base->capacities[capacity].cur + value);
113 }
114
115 /**
116 * @brief Returns the free capacity of a type
117 * @param[in] base Pointer to the base to check
118 * @param[in] capacityType Capacity type
119 * @sa baseCapacities_t
120 */
CAP_GetFreeCapacity(const base_t * base,baseCapacities_t capacityType)121 int CAP_GetFreeCapacity (const base_t* base, baseCapacities_t capacityType)
122 {
123 const capacities_t* cap = CAP_Get(base, capacityType);
124 return cap->max - cap->cur;
125 }
126
127 /**
128 * @brief Checks capacity overflows on bases
129 * @sa CP_CampaignRun
130 */
CAP_CheckOverflow(void)131 void CAP_CheckOverflow (void)
132 {
133 base_t* base = nullptr;
134
135 while ((base = B_GetNext(base)) != nullptr) {
136 int i;
137
138 for (i = CAP_ALIENS; i < MAX_CAP; i++) {
139 baseCapacities_t capacityType = (baseCapacities_t)i;
140 capacities_t* cap = CAP_Get(base, capacityType);
141
142 if (cap->cur <= cap->max)
143 continue;
144
145 switch (capacityType) {
146 case CAP_ANTIMATTER:
147 CAP_RemoveAntimatterExceedingCapacity(base);
148 break;
149 case CAP_WORKSPACE:
150 PR_UpdateProductionCap(base);
151 break;
152 case CAP_LABSPACE:
153 RS_RemoveScientistsExceedingCapacity(base);
154 break;
155 case CAP_AIRCRAFT_SMALL:
156 case CAP_AIRCRAFT_BIG:
157 case CAP_ALIENS:
158 case CAP_EMPLOYEES:
159 case CAP_ITEMS:
160 if (base->baseStatus != BASE_DESTROYED) {
161 const buildingType_t bldgType = B_GetBuildingTypeByCapacity((baseCapacities_t)i);
162 const building_t* bldg = B_GetBuildingTemplateByType(bldgType);
163 CP_GameTimeStop();
164 cgi->Cmd_ExecuteString("ui_push popup_cap_overload base %d \"%s\" \"%s\" %d %d",
165 base->idx, base->name, _(bldg->name), cap->max - cap->cur, cap->max);
166 }
167 break;
168 default:
169 /* nothing to do */
170 break;
171 }
172 }
173 }
174 }
175