1 /**
2  * @file
3  * @brief Header file for aircraft 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 
29 #define MAX_CARGO		32
30 #define MAX_AIRCRAFT	64
31 #define LINE_MAXSEG 64
32 #define LINE_MAXPTS (LINE_MAXSEG + 2)
33 #define LINE_DPHI	(M_PI / LINE_MAXSEG)
34 
35 /** Invalid aircraft index (global index). */
36 #define AIRCRAFT_INVALID -1
37 /** Invalid aircraft index in base-list of aircraft. */
38 #define AIRCRAFT_INBASE_INVALID -1
39 
40 /** factor to speed up refuelling */
41 #define AIRCRAFT_REFUEL_FACTOR 16
42 
43 #define AIR_IsUFO(aircraft) ((aircraft)->ufotype != UFO_MAX)
44 
45 /** @brief A path on the map described by 2D points */
46 typedef struct mapline_s {
47 	int numPoints;		/**< number of points that make up this path */
48 	float distance;		/**< the distance between two points of the path - total
49 						 * distance is then (distance * (numPoints - 1)) */
50 	vec2_t point[LINE_MAXPTS]; /**< array of 2D points that make up this path */
51 } mapline_t;
52 
53 /** @brief All different types of aircraft. */
54 typedef enum {
55 	AIRCRAFT_TRANSPORTER,
56 	AIRCRAFT_INTERCEPTOR,
57 	AIRCRAFT_UFO
58 } aircraftType_t;
59 
60 #define MAX_HUMAN_AIRCRAFT_TYPE AIRCRAFT_INTERCEPTOR
61 
62 /** @brief All different size of aircraft. */
63 typedef enum {
64 	AIRCRAFT_SMALL = 1,
65 	AIRCRAFT_LARGE = 2
66 } aircraftSize_t;
67 
68 /** @brief different weight for aircraft items
69  * @note values must go from the lightest to the heaviest item */
70 typedef enum {
71 	ITEM_LIGHT,
72 	ITEM_MEDIUM,
73 	ITEM_HEAVY
74 } itemWeight_t;
75 
76 /** @brief different positions for aircraft items */
77 typedef enum {
78 	AIR_NOSE_LEFT,
79 	AIR_NOSE_CENTER,
80 	AIR_NOSE_RIGHT,
81 	AIR_WING_LEFT,
82 	AIR_WING_RIGHT,
83 	AIR_REAR_LEFT,
84 	AIR_REAR_CENTER,
85 	AIR_REAR_RIGHT,
86 
87 	AIR_POSITIONS_MAX
88 } itemPos_t;
89 
90 /** @brief notification signals for aircraft events */
91 typedef enum {
92 	AIR_CANNOT_REFUEL,
93 
94 	MAX_AIR_NOTIFICATIONS
95 } aircraft_notifications_t;
96 
97 #define MAX_AIRCRAFTSLOT 8
98 
99 /** @brief slot of aircraft */
100 typedef struct aircraftSlot_s {
101 	int idx;					/**< self link */
102 	struct base_s* base;		/**< A link to the base. (if defined by aircraftItemType_t) */
103 	struct installation_s* installation;	/**< A link to the installation. (if defined by aircraftItemType_t) */
104 	struct aircraft_s* aircraft;	/**< A link to the aircraft (if defined by aircraftItemType_t). */
105 	aircraftItemType_t type;	/**< The type of item that can fit in this slot. */
106 
107 	const objDef_t* item;		/**< Item that is currently in the slot. nullptr if empty. */
108 	const objDef_t* ammo;		/**< Ammo that is currently in the slot. nullptr if empty. */
109 	itemWeight_t size;			/**< The maximum size (weight) of item that can fit in this slot. */
110 	int ammoLeft;				/**< The number of ammo left in this slot */
111 	int delayNextShot;			/**< The delay before the next projectile can be shot */
112 	int installationTime;		/**< The time (in hours) left before the item is finished to be installed or removed in/from slot
113 								  *	This is > 0 if the item is being installed, < 0 if the item is being removed, 0 if the item is in place */
114 	const objDef_t* nextItem;	/**< Next item to install when the current item in slot will be removed
115 								  *	(Should be used only if installationTime is different of 0) */
116 	const objDef_t* nextAmmo;	/**< Next ammo to install when the nextItem will be installed */
117 	itemPos_t pos;				/**< Position of the slot on the aircraft */
118 } aircraftSlot_t;
119 
120 
121 /** @brief A cargo of items collected after mission. */
122 typedef struct itemsTmp_s {
123 	const objDef_t* item;		/**< Collected item. */
124 	int amount;					/**< Amount of collected items. */
125 } itemsTmp_t;
126 
127 /** possible aircraft states */
128 typedef enum aircraftStatus_s {
129 	AIR_NONE,
130 	AIR_REFUEL,			/**< refill fuel */
131 	AIR_HOME,			/**< in homebase */
132 	AIR_IDLE,			/**< just sit there on geoscape */
133 	AIR_TRANSIT,		/**< moving */
134 	AIR_MISSION,		/**< moving to a mission */
135 	AIR_UFO,			/**< pursuing a UFO - also used for ufos that are pursuing an aircraft */
136 	AIR_DROP,			/**< ready to drop down */
137 	AIR_INTERCEPT,		/**< ready to intercept */
138 	AIR_TRANSFER,		/**< being transfered */
139 	AIR_CRASHED,		/**< crashed */
140 	AIR_RETURNING		/**< returning to homebase */
141 } aircraftStatus_t;
142 
143 /** @brief An aircraft with all it's data */
144 typedef struct aircraft_s {
145 	int idx;			/**< Global index of this aircraft. See also ccs.numAircraft and AIRCRAFT_INVALID
146 						 * this index is also updated when AIR_DeleteAircraft was called
147 						 * for all the other aircraft.
148 						 * For aircraftTemplates[] aircraft this is the index in that array.
149 						 * this should be references only with the variable name aircraftIdx
150 						 * to let us find references all over the code easier @sa AIR_DeleteAircraft  */
151 	struct aircraft_s* tpl;	/**< Self-link in aircraft_sample list (i.e. templates). */
152 	char* id;			/**< Internal id from script file. */
153 	char name[MAX_VAR];			/**< Aircraft name (user can change this). */
154 	char* defaultName;	/**< Translatable default name for aircraft. */
155 	char* image;		/**< Image on geoscape. */
156 	char* model;		/**< Model used on geoscape */
157 	aircraftType_t type;/**< Type of aircraft, see aircraftType_t. */
158 	ufoType_t ufotype;	/**< Type of UFO, see ufoType_t (UFO_MAX if craft is not a UFO). */
159 	aircraftStatus_t status;			/**< Status of this aircraft, see aircraftStatus_t. */
160 
161 	int price;			/**< Price of this aircraft type at game start, it's evolving on the market. */
162 	int productionCost;	/**< Production costs of this aircraft type. */
163 	int fuel;			/**< Current fuel amount. */
164 	int damage;			/**< Current Hit Point of the aircraft */
165 	int size;			/**< Size of the aircraft used in capacity calculations. */
166 	vec3_t pos;			/**< Current position on the geoscape. @todo change to vec2_t - this is long/lat */
167 	vec3_t direction;	/**< Direction in which the aircraft is going on 3D geoscape (used for smoothed rotation). */
168 	vec3_t projectedPos;	/**< Projected position of the aircraft (latitude and longitude). */
169 	mapline_t route;
170 	int point;			/**< Number of route points that has already been done when aircraft is moving */
171 	int time;			/**< Elapsed seconds since aircraft started it's new route */
172 
173 	int maxTeamSize;	/**< Max amount of soldiers onboard. */
174 	linkedList_t* acTeam;			/**< List of employees. i.e. current team for this aircraft */
175 
176 	Employee* pilot;			/**< Current Pilot assigned to the aircraft. */
177 
178 	aircraftSlot_t weapons[MAX_AIRCRAFTSLOT];	/**< Weapons assigned to aircraft */
179 	int maxWeapons;					/**< Total number of weapon slots aboard this aircraft (empty or not) */
180 	aircraftSlot_t shield;			/**< Armour assigned to aircraft (1 maximum) */
181 	aircraftSlot_t electronics[MAX_AIRCRAFTSLOT];		/**< Electronics assigned to aircraft */
182 	int maxElectronics;				/**< Total number of electronics slots aboard this aircraft  (empty or not) */
183 
184 	struct base_s* homebase;			/**< Pointer to homebase for faster access. */
185 	itemsTmp_t itemcargo[MAX_CARGO];	/**< Cargo of items. */
186 	int itemTypes;						/**< How many types of items we collected. */
187 
188 	const char* building;		/**< id of the building needed as hangar */
189 
190 	struct mission_s* mission;	/**< The mission the aircraft is moving to if this is a PHALANX aircraft
191 								 * The mission the UFO is involved if this is a UFO */
192 	char* missionID;			/**< aircraft loaded before missions, we need this temporary as reference
193 								 * AIR_PostLoadInitMissions resolves the pointers after game loaded and frees this */
194 	struct aircraft_s* aircraftTarget;		/**< Target of the aircraft (ufo or phalanx) */
195 	bool leader;				/**< try to follow this aircraft */
196 	struct radar_s radar;				/**< Radar to track ufos */
197 	int stats[AIR_STATS_MAX];	/**< aircraft parameters for speed, damage and so on
198 								 * @note As this is an int, wrange is multiplied by 1000 */
199 
200 	technology_t* tech;		/**< link to the aircraft tech */
201 
202 	bool notifySent[MAX_AIR_NOTIFICATIONS];	/* stores if a notification was already sent */
203 
204 	bool detected;		/**< Is the ufo detected by a radar? (note that a detected landed ufo has @c detected set to true
205 							 * and @c visible set to false: we can't see it on geoscape) */
206 	bool landed;		/**< Is ufo landed for a mission? This is used when a UFO lands (a UFO must have both
207 							 * @c detected and @c visible set to true to be actually seen on geoscape) */
208 	bool notOnGeoscape;	/**< don't let this aircraft appear ever on geoscape (e.g. ufo_carrier) */
209 	int ufoInterestOnGeoscape;	/**< interest level at which this ufo should be available on geoscape first */
210 	int detectionIdx;		/**< detected UFO number (for descriptions "UFO #4")*/
211 	date_t lastSpotted;		/**< date the UFO was detected last time */
212 
213 	class AlienCargo* alienCargo;	/**< Cargo of aliens. */
214 } aircraft_t;
215 
216 /* script functions */
217 
218 #ifdef DEBUG
219 void AIR_ListAircraft_f(void);
220 void AIR_ListAircraftSamples_f(void);
221 void AIR_ListCraftIndexes_f(void);
222 #endif
223 
224 #define AIR_IsAircraftOfBase(aircraft, base) ((aircraft)->homebase == (base) && (aircraft)->status != AIR_CRASHED)
225 #define AIR_Foreach(var) LIST_Foreach(ccs.aircraft, aircraft_t, var)
226 
227 aircraft_t* AIR_Add(struct base_s* base, const aircraft_t* aircraftTemplate);
228 bool AIR_Delete(struct base_s* base, const aircraft_t* aircraft);
229 
230 #define AIR_ForeachFromBase(var, base) \
231 	AIR_Foreach(var) \
232 		if (!AIR_IsAircraftOfBase(var, (base))) continue; else
233 
234 #define AIR_ForeachSorted(var, sorter, userdata, sortedlist) LIST_ForeachSorted(ccs.aircraft, aircraft_t, var, sorter, userdata, sortedlist)
235 
236 aircraft_t* AIR_GetFirstFromBase(const struct base_s* base);
237 
238 bool AIR_BaseHasAircraft(const struct base_s* base);
239 int AIR_BaseCountAircraft(const struct base_s* base);
240 aircraft_t* AIR_GetAircraftFromBaseByIDXSafe(const struct base_s* base, int index);
241 const char* AIR_AircraftStatusToName(const aircraft_t* aircraft);
242 bool AIR_IsAircraftInBase(const aircraft_t* aircraft);
243 bool AIR_IsAircraftOnGeoscape(const aircraft_t* aircraft);
244 
245 void AIR_DeleteAircraft(aircraft_t* aircraft);
246 void AIR_DestroyAircraft(aircraft_t* aircraft, bool killPilot = true);
247 
248 void AIR_ResetAircraftTeam(aircraft_t* aircraft);
249 bool AIR_AddToAircraftTeam(aircraft_t* aircraft, Employee* employee);
250 bool AIR_IsInAircraftTeam(const aircraft_t* aircraft, const Employee* employee);
251 int AIR_GetTeamSize(const aircraft_t* aircraft);
252 
253 void AIR_CampaignRun(const struct campaign_s* campaign, int dt, bool updateRadarOverlay);
254 const aircraft_t* AIR_GetAircraftSilent(const char* name);
255 const aircraft_t* AIR_GetAircraft(const char* name);
256 aircraft_t* AIR_AircraftGetFromIDX(int idx);
257 bool AIR_AircraftMakeMove(int dt, aircraft_t* aircraft);
258 void AIR_ParseAircraft(const char* name, const char** text, bool assignAircraftItems);
259 bool AIR_AircraftHasEnoughFuel(const aircraft_t* aircraft, const vec2_t destination);
260 bool AIR_AircraftHasEnoughFuelOneWay(const aircraft_t* aircraft, const vec2_t destination);
261 void AIR_AircraftReturnToBase(aircraft_t* aircraft);
262 bool AIR_SendAircraftToMission(aircraft_t* aircraft, struct mission_s* mission);
263 void AIR_GetDestinationWhilePursuing(const aircraft_t* shooter, const aircraft_t* target, vec2_t dest);
264 bool AIR_SendAircraftPursuingUFO(aircraft_t* aircraft, aircraft_t* ufo);
265 void AIR_AircraftsNotifyUFORemoved(const aircraft_t* const ufo, bool destroyed);
266 void AIR_AircraftsUFODisappear(const aircraft_t* const ufo);
267 bool AIR_ScriptSanityCheck(void);
268 int AIR_AircraftMenuStatsValues(const int value, const int stat);
269 int AIR_CountTypeInBase(const struct base_s* base, aircraftType_t aircraftType);
270 int AIR_CountInBaseByTemplate(const struct base_s* base, const aircraft_t* aircraftTemplate);
271 const char* AIR_GetAircraftString(aircraftType_t aircraftType);
272 
273 int AIR_GetAircraftWeaponRanges(const aircraftSlot_t* slot, int maxSlot, float* weaponRanges);
274 baseCapacities_t AIR_GetCapacityByAircraftWeight(const aircraft_t* aircraft);
275 
276 const char* AIR_CheckMoveIntoNewHomebase(const aircraft_t* aircraft, const struct base_s* base);
277 void AIR_MoveAircraftIntoNewHomebase(aircraft_t* aircraft, struct base_s* base);
278 
279 void AII_CollectItem(aircraft_t* aircraft, const objDef_t* item, int amount);
280 void AII_CollectingItems(aircraft_t* aircraft, int won);
281 
282 bool AIR_SetPilot(aircraft_t* aircraft, Employee* pilot);
283 Employee* AIR_GetPilot(const aircraft_t* aircraft);
284 
285 bool AIR_PilotSurvivedCrash(const aircraft_t* aircraft);
286 
287 void AIR_AutoAddPilotToAircraft(const struct base_s* base, Employee* pilot);
288 void AIR_RemovePilotFromAssignedAircraft(const struct base_s* base, const Employee* pilot);
289 void AIR_RemoveEmployees(aircraft_t &aircraft);
290 bool AIR_AddEmployee(Employee* employee, aircraft_t* aircraft);
291 bool AIR_RemoveEmployee(Employee* employee, aircraft_t* aircraft);
292 const aircraft_t* AIR_IsEmployeeInAircraft(const Employee* employee, const aircraft_t* aircraft);
293 void AIR_MoveEmployeeInventoryIntoStorage(const aircraft_t &aircraft, equipDef_t &equip);
294 
295 void AIR_AssignInitial(aircraft_t* aircraft);
296 
297 bool AIR_CanIntercept(const aircraft_t* aircraft);
298 
299 int AIR_GetOperationRange(const aircraft_t* aircraft);
300 int AIR_GetRemainingRange(const aircraft_t* aircraft);
301 
302 void AIR_InitStartup(void);
303 void AIR_Shutdown(void);
304