1 /**
2  * @file
3  * @brief Header for base management related stuff.
4  */
5 
6 /*
7 Copyright (C) 2002-2013 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 #pragma once
26 
27 #include "cp_capacity.h"
28 #include "cp_aliencont.h"
29 #include "cp_produce.h"
30 #include "cp_building.h"
31 
32 #define MAX_BASES 8
33 
34 #define MAX_BUILDINGS		32
35 #define MAX_BASETEMPLATES	5
36 
37 #define MAX_BATTERY_DAMAGE	50
38 #define MAX_BASE_DAMAGE		100
39 #define MAX_BASE_SLOT		4
40 
41 /** @todo take the values from scriptfile */
42 #define BASEMAP_SIZE_X		778.0
43 #define BASEMAP_SIZE_Y		672.0
44 
45 /* see MAX_TILESTRINGS */
46 #define BASE_SIZE		5
47 #define MAX_BASEBUILDINGS	BASE_SIZE * BASE_SIZE
48 
49 #define MAX_EMPLOYEES_IN_BUILDING 64
50 
51 #define MAX_BLOCKEDFIELDS	4
52 #define MIN_BLOCKEDFIELDS	1
53 
54 /** basetiles are 16 units in each direction
55  * 512 / UNIT_SIZE = 16
56  * 512 is the size in the mapeditor and the worldplane for a
57  * single base map tile */
58 #define BASE_TILE_SIZE 512
59 #define BASE_TILE_UNITS (BASE_TILE_SIZE / UNIT_SIZE)
60 
61 #define BASE_INITIALINTEREST 1.0
62 
63 #define B_IsUnderAttack(base) ((base)->baseStatus == BASE_UNDER_ATTACK)
64 
65 #define B_AtLeastOneExists() (B_GetNext(nullptr) != nullptr)
66 
67 /**
68  * @brief Possible base states
69  * @note: Don't change the order or you have to change the basemenu scriptfiles, too
70  */
71 typedef enum {
72 	BASE_NOT_USED,
73 	BASE_UNDER_ATTACK,	/**< base is under attack */
74 	BASE_WORKING,		/**< nothing special */
75 	BASE_DESTROYED		/**< the base is being destroyed (prevent double destroy attempt) */
76 } baseStatus_t;
77 
78 /** @brief All possible base actions */
79 typedef enum {
80 	BA_NONE,
81 	BA_NEWBUILDING,		/**< hovering the needed base tiles for this building */
82 
83 	BA_MAX
84 } baseAction_t;
85 
86 typedef struct baseBuildingTile_s {
87 	building_t* building;	/**< nullptr if free spot */
88 	bool	blocked;		/**< true if the tile is usable for buildings otherwise it's false (blocked somehow). */
89 	/* These are only used for baseTemplates: */
90 	int posX;				/**< The x screen coordinate for the building on the basemap. */
91 	int posY;				/**< The y screen coordinate for the building on the basemap. */
92 } baseBuildingTile_t;
93 
94 typedef struct baseWeapon_s {
95 	/* int idx; */
96 	aircraftSlot_t slot;	/**< Weapon. */
97 	aircraft_t* target;		/**< Aimed target for the weapon. */
98 	bool autofire;			/**< If it should automatically open fire on ufos */
99 } baseWeapon_t;
100 
101 /** @brief A base with all it's data */
102 typedef struct base_s {
103 	int idx;					/**< Self link. Index in the global base-list. */
104 	char name[MAX_VAR];			/**< Name of the base */
105 	baseBuildingTile_t map[BASE_SIZE][BASE_SIZE];	/**< The base maps (holds building pointers)
106 													 * @todo  maybe integrate BASE_INVALID_SPACE and BASE_FREE_SPACE here? */
107 
108 	bool founded;	/**< already founded? */
109 	vec3_t pos;		/**< pos on geoscape */
110 
111 	/**
112 	 * @note These bools does not say whether there is such building in the
113 	 * base or there is not. They are true only if such buildings are operational
114 	 * (for example, in some cases, if they are provided with power).
115 	 */
116 	bool hasBuilding[MAX_BUILDING_TYPE];
117 
118 	aircraft_t* aircraftCurrent;	/**< Currently selected aircraft in _this base_. (i.e. an entry in base_t->aircraft). */
119 
120 	baseStatus_t baseStatus; 		/**< the current base status */
121 
122 	float alienInterest;			/**< How much aliens know this base (and may attack it) */
123 
124 	struct radar_s radar;
125 
126 	class AlienContainment* alienContainment;	/**< alien containment data */
127 
128 	capacities_t capacities[MAX_CAP];			/**< Capacities. */
129 
130 	equipDef_t storage;							/**< weapons, etc. stored in base */
131 
132 	Inventory bEquipment;						/**< The equipment of the base; needn't be saved */
133 
134 	baseWeapon_t batteries[MAX_BASE_SLOT];		/**< Missile batteries assigned to base. */
135 	int numBatteries;
136 	int numActiveBatteries;
137 	baseWeapon_t lasers[MAX_BASE_SLOT];			/**< Laser batteries assigned to base. */
138 	int numLasers;
139 	int numActiveLasers;
140 
141 	/* we will allow only one active production at the same time for each base */
142 	production_queue_t productions;
143 
144 	bool selected;		/**< the current selected base */
145 	building_t* buildingCurrent; /**< needn't be saved */
146 } base_t;
147 
148 /** @brief template for creating a base */
149 typedef struct baseTemplate_s {
150 	char* id;			/**< ID of the base template */
151 	baseBuildingTile_t buildings[MAX_BASEBUILDINGS]; /**< the buildings to be built for this template. */
152 	int numBuildings;		/**< Number of buildings in this template. */
153 } baseTemplate_t;
154 
155 void B_UpdateBaseData(void);
156 float B_GetMaxBuildingLevel(const base_t* base, const buildingType_t type);
157 void B_ParseBaseTemplate(const char* name, const char** text);
158 void B_BaseResetStatus(base_t* const base);
159 const building_t* B_GetBuildingInBaseByType(const base_t* base, buildingType_t type, bool onlyWorking);
160 const baseTemplate_t* B_GetBaseTemplate(const char* baseTemplateName);
161 
162 void B_InitStartup(void);
163 
164 /* base functions */
165 base_t* B_Build(const struct campaign_s* campaign, const vec2_t pos, const char* name);
166 void B_SetUpFirstBase(const struct campaign_s* campaign, base_t* base);
167 base_t* B_GetNext(base_t* lastBase);
168 base_t* B_GetBaseByIDX(int baseIdx);
169 base_t* B_GetFoundedBaseByIDX(int baseIdx);
170 int B_GetCount(void);
171 void B_SelectBase(const base_t* base);
172 void B_Destroy(base_t* base);
173 void B_SetName(base_t* base, const char* name);
174 
175 base_t* B_GetFirstUnfoundedBase(void);
176 base_t* B_GetCurrentSelectedBase(void);
177 void B_SetCurrentSelectedBase(const base_t* base);
178 
179 bool B_AssembleMap(char* maps, size_t mapsLength, char* coords, size_t coordsLength, const base_t* base);
180 
181 /* building functions */
182 #define B_IsTileBlocked(base, x, y) (base)->map[(int)(y)][(int)(x)].blocked
183 #define B_GetBuildingAt(base, x, y) (base)->map[(int)(y)][(int)(x)].building
184 
185 buildingType_t B_GetBuildingTypeByCapacity(baseCapacities_t cap);
186 
187 building_t* B_GetNextBuilding(const base_t* base, building_t* lastBuilding);
188 building_t* B_GetNextBuildingByType(const base_t* base, building_t* lastBuilding, buildingType_t buildingType);
189 void B_BuildingStatus(const building_t* building);
190 bool B_CheckBuildingTypeStatus(const base_t* const base, buildingType_t type, buildingStatus_t status, int* cnt);
191 bool B_GetBuildingStatus(const base_t* const base, const buildingType_t type);
192 void B_SetBuildingStatus(base_t* const base, const buildingType_t type, bool newStatus);
193 
194 bool B_MapIsCellFree(const base_t* base, int col, int row);
195 building_t* B_SetBuildingByClick(base_t* base, const building_t* buildingTemplate, int row, int col);
196 bool B_IsBuildingDestroyable(const building_t* building);
197 bool B_BuildingDestroy(building_t* building);
198 
199 building_t* B_GetFreeBuildingType(buildingType_t type);
200 int B_GetNumberOfBuildingsInBaseByTemplate(const base_t* base, const building_t* type);
201 int B_GetNumberOfBuildingsInBaseByBuildingType(const base_t* base, const buildingType_t type);
202 
203 void B_BuildingOpenAfterClick(const building_t* building);
204 void B_ResetBuildingCurrent(base_t* base);
205 
206 /* storage functions */
207 bool B_ItemIsStoredInBaseStorage(const objDef_t* obj);
208 bool B_BaseHasItem(const base_t* base, const objDef_t* item);
209 int B_ItemInBase(const objDef_t* item, const base_t* base);
210 
211 int B_AddToStorage(base_t* base, const objDef_t* obj, int amount);
212 
213 /* aircraft functions */
214 void B_AircraftReturnedToHomeBase(aircraft_t* aircraft);
215 void B_DumpAircraftToHomeBase(aircraft_t* aircraft);
216 
217 /* capacity functions */
218 void B_UpdateBaseCapacities(baseCapacities_t cap, base_t* base);
219 baseCapacities_t B_GetCapacityFromBuildingType(buildingType_t type);
220 void B_ResetAllStatusAndCapacities(base_t* base, bool firstEnable);
221 
222 /* menu functions */
223 void B_BaseMenuInit(const base_t* base);
224 void B_DrawBuilding(const building_t* building);
225 
226 /* antimatter */
227 int B_AntimatterInBase(const base_t* base);
228 void B_ManageAntimatter(base_t* base, int amount, bool add);
229 
230 /* savesystem */
231 void B_SaveBaseSlotsXML(const baseWeapon_t* weapons, const int numWeapons, xmlNode_t* p);
232 int B_LoadBaseSlotsXML(baseWeapon_t* weapons, int numWeapons, xmlNode_t* p);
233 bool B_SaveStorageXML(xmlNode_t* parent, const equipDef_t &equip);
234 bool B_LoadStorageXML(xmlNode_t* parent, equipDef_t* equip);
235 
236 /* other */
237 int B_GetInstallationLimit(void);
238 
239 /* functions that checks whether the buttons in the base menu are useable */
240 bool BS_BuySellAllowed(const base_t* base);
241 bool AIR_AircraftAllowed(const base_t* base);
242 bool RS_ResearchAllowed(const base_t* base);
243 bool PR_ProductionAllowed(const base_t* base);
244 bool E_HireAllowed(const base_t* base);
245 bool AC_ContainmentAllowed(const base_t* base);
246 bool HOS_HospitalAllowed(const base_t* base);
247