38#define AIRCRAFT_INVALID -1
47 const ptrdiff_t num = (ptrdiff_t)(projectile -
ccs.projectiles);
71 projectile = &
ccs.projectiles[
ccs.numProjectiles];
73 if (!weaponSlot->
ammo) {
74 cgi->Com_Printf(
"AIRFIGHT_AddProjectile: Error - no ammo assigned\n");
78 assert(weaponSlot->
item);
85 }
else if (attackingInstallation) {
87 VectorSet(projectile->
pos[0], attackingInstallation->
pos[0], attackingInstallation->
pos[1], 0);
103 projectile->
time = 0;
104 projectile->
angle = 0.0f;
114 ccs.numProjectiles++;
118 sound =
"geoscape/combat-gun";
119 }
else if (projectile->
beam) {
120 sound =
"geoscape/combat-airlaser";
121 }
else if (projectile->
rocket) {
122 sound =
"geoscape/combat-rocket";
127 if (sound !=
nullptr)
128 cgi->S_StartLocalSample(sound, 1.0f);
138static void AIRFIGHT_ProjectileList_f (
void)
140 for (
int i = 0;
i <
ccs.numProjectiles;
i++) {
141 cgi->Com_Printf(
"%i. (idx: %i)\n",
i,
ccs.projectiles[
i].idx);
142 cgi->Com_Printf(
"... type '%s'\n",
ccs.projectiles[
i].aircraftItem->id);
143 if (
ccs.projectiles[
i].attackingAircraft)
144 cgi->Com_Printf(
"... shooting aircraft '%s'\n",
ccs.projectiles[
i].attackingAircraft->id);
146 cgi->Com_Printf(
"... base is shooting, or shooting aircraft is destroyed\n");
147 if (
ccs.projectiles[
i].aimedAircraft)
148 cgi->Com_Printf(
"... aiming aircraft '%s'\n",
ccs.projectiles[
i].aimedAircraft->id);
150 cgi->Com_Printf(
"... aiming idle target at (%.02f, %.02f)\n",
151 ccs.projectiles[
i].idleTarget[0],
ccs.projectiles[
i].idleTarget[1]);
187 newTarget[0] = newTarget[0] +
offset;
188 newTarget[1] = newTarget[1] +
offset;
238 float distance0 = 99999.9f;
242 for (
int i = 0;
i < maxSlot;
i++) {
248 if (weaponStatus > slotIdx)
254 distance0 = distance;
275 float probability = 0.0f;
278 cgi->Com_Printf(
"AIRFIGHT_ProbabilityToHit: no weapon assigned to attacking aircraft\n");
283 cgi->Com_Printf(
"AIRFIGHT_ProbabilityToHit: no ammo in weapon of attacking aircraft\n");
289 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ProbabilityToHit: Base probability: %f\n", probability);
295 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ProbabilityToHit: Probability after accounting items of attacker: %f\n", probability);
301 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ProbabilityToHit: Probability after accounting ECM of target: %f\n", probability);
305 if (shooter->
pilot) {
313 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ProbabilityToHit: Probability after accounting targeting skill of shooter: %f\n",
328 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ProbabilityToHit: Probability after accounting evasion skill of target: %f\n",
334 probability = std::min(probability, 0.95f);
336 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ProbabilityToHit: Probability to hit: %f\n", probability);
365 const float probability =
frand();
366 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ExecuteActions: %s - Random probability to hit: %f\n", shooter->
name, probability);
370 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ExecuteActions: %s - Calculated probability to hit: %f\n", shooter->
name, calculatedProbability);
372 if (probability > calculatedProbability)
402 MS_AddNewMessage(
_(
"Notice"),
_(
"Our aircraft has no more ammo left - returning to home base now."));
422 for (projectile =
ccs.projectiles; idx <
ccs.numProjectiles; projectile++, idx++) {
444 for (idx = 0, projectile =
ccs.projectiles; idx <
ccs.numProjectiles; projectile++, idx++) {
447 if (attacker == aircraft)
487 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ActionsAfterAirfight: zone: %s (%i:%i:%i)\n",
cgi->csi->terrainDefs.getTerrainName(color), color[0], color[1], color[2]);
488 MS_AddNewMessage(
_(
"Interception"),
_(
"UFO interception successful -- UFO lost to sea."));
522 bool pilotSurvived =
false;
524 pilotSurvived =
true;
562 if (distance < movement)
626 assert(target->
damage > 0);
628 if (target->
damage <= 0) {
631 cgi->S_StartLocalSample(
"geoscape/combat-explosion", 1.0f);
634 cgi->S_StartLocalSample(
"geoscape/combat-rocket-exp", 1.0f);
649 vec3_t startPoint, finalVectorPoint;
667 *angle =
GEO_AngleOfPath(originalPoint, targetPoint,
nullptr, orthogonalVector);
681 for (idx =
ccs.numProjectiles - 1; idx >= 0; idx--) {
684 projectile->
time += dt;
698 vec3_t ortogonalVector, finalPoint, projectedPoint;
710 projectile->
angle = angle;
725 for (
int i = 0;
i < maxWeapons;
i++) {
779 for (
int i = 0;
i < maxWeapons;
i++) {
834 while ((base =
B_GetNext(base)) !=
nullptr) {
849 for (idx = 0; idx < base->
numLasers; idx++) {
870 if (installation->installationTemplate->maxBatteries <= 0)
873 for (
int idx = 0; idx < installation->installationTemplate->maxBatteries; idx++) {
894 for (
int i = 0;
i <
ccs.numProjectiles;
i++) {
952 cgi->Com_Printf(
"AIR_Load: Could not get technology of projectile %i\n",
i);
990 ccs.numProjectiles =
i;
1001 cgi->Cmd_AddCommand(
"debug_listprojectile", AIRFIGHT_ProjectileList_f,
"Print Projectiles information to game console");
DateTime class definition.
Share stuff between the different cgame implementations.
static const short SECONDS_PER_HOUR
#define REMOVE_ELEM_ADJUST_IDX(array, index, n)
void AIR_AircraftReturnToBase(aircraft_t *aircraft)
Calculates the way back to homebase for given aircraft and returns it.
bool AIR_PilotSurvivedCrash(const aircraft_t *aircraft)
Determine if an aircraft's pilot survived a crash, based on his piloting skill (and a bit of randomne...
bool AIR_SendAircraftPursuingUFO(aircraft_t *aircraft, aircraft_t *ufo)
Make the specified aircraft purchasing a UFO.
void AIR_DestroyAircraft(aircraft_t *aircraft, bool killPilot)
Removes an aircraft from its base and the game.
bool AIR_IsAircraftInBase(const aircraft_t *aircraft)
Checks whether given aircraft is in its homebase.
aircraft_t * AIR_AircraftGetFromIDX(int aircraftIdx)
Returns aircraft for a given global index.
#define AIR_IsUFO(aircraft)
void AIRFIGHT_CampaignRunBaseDefence(int dt)
Run base defences.
void AIRFIGHT_ExecuteActions(const campaign_t *campaign, aircraft_t *shooter, aircraft_t *target)
Decide what an attacking aircraft can do.
static bool AIRFIGHT_ProjectileReachedTarget(const aircraftProjectile_t *projectile, float movement)
Check if some projectiles on geoscape reached their destination.
static bool AIRFIGHT_AddProjectile(const base_t *attackingBase, const installation_t *attackingInstallation, aircraft_t *attacker, aircraft_t *target, aircraftSlot_t *weaponSlot)
Add a projectile in ccs.projectiles.
static void AIRFIGHT_InstallationShoot(const installation_t *installation, baseWeapon_t *weapons, int maxWeapons)
Check if one type of battery (missile or laser) can shoot now.
int AIRFIGHT_ChooseWeapon(const aircraftSlot_t *slot, int maxSlot, const vec2_t pos, const vec2_t targetPos)
Choose the weapon an attacking aircraft will use to fire on a target.
static void AIRFIGHT_MissTarget(aircraftProjectile_t *projectile)
Change destination of projectile to an idle point of the map, close to its former target.
bool AIRFIGHT_SaveXML(xmlNode_t *parent)
Save callback for savegames in XML Format.
static float AIRFIGHT_ProbabilityToHit(const aircraft_t *shooter, const aircraft_t *target, const aircraftSlot_t *slot)
Calculate the probability to hit the enemy.
void AIRFIGHT_CampaignRunProjectiles(const campaign_t *campaign, int dt)
Update values of projectiles.
static void AIRFIGHT_RemoveProjectile(aircraftProjectile_t *projectile)
Remove a projectile from ccs.projectiles.
static void AIRFIGHT_GetNextPointInPath(const float *movement, const vec2_t originalPoint, const vec2_t targetPoint, float *angle, vec2_t finalPoint, vec3_t orthogonalVector)
Get the next point in the object path based on movement.
void AIRFIGHT_RemoveProjectileAimingAircraft(const aircraft_t *aircraft)
Set all projectile aiming a given aircraft to an idle destination.
static int AIRFIGHT_GetDamage(const objDef_t *od, const aircraft_t *target)
Calculates the damage value for the airfight.
static void AIRFIGHT_GetNextPointInPathFromVector(const float *movement, const vec2_t originalPoint, const vec3_t orthogonalVector, vec2_t finalPoint)
Get the next point in the object path based on movement converting the positions from polar coordinat...
static void AIRFIGHT_UpdateProjectileForDestroyedAircraft(const aircraft_t *aircraft)
Set all projectile attackingAircraft pointers to nullptr.
bool AIRFIGHT_LoadXML(xmlNode_t *parent)
Load callback for savegames in XML Format.
void AIRFIGHT_InitStartup(void)
static void AIRFIGHT_ProjectileHits(const campaign_t *campaign, aircraftProjectile_t *projectile)
Solve the result of one projectile hitting an aircraft.
int AIRFIGHT_CheckWeapon(const aircraftSlot_t *slot, float distance)
Check if the selected weapon can shoot.
static void AIRFIGHT_BaseShoot(const base_t *base, baseWeapon_t *weapons, int maxWeapons)
Check if one type of battery (missile or laser) can shoot now.
void AIRFIGHT_ActionsAfterAirfight(const campaign_t *campaign, aircraft_t *shooter, aircraft_t *aircraft, bool phalanxWon)
Actions to execute when a fight is done.
#define MAX_MULTIPLE_PROJECTILES
#define AIRFIGHT_WEAPON_CAN_NOT_SHOOT_AT_THE_MOMENT
#define AIRFIGHT_WEAPON_CAN_SHOOT
#define AIRFIGHT_WEAPON_CAN_NEVER_SHOOT
base_t * B_GetNext(base_t *lastBase)
Iterates through founded bases.
bool B_GetBuildingStatus(const base_t *const base, const buildingType_t buildingType)
Get the status associated to a building.
#define B_IsUnderAttack(base)
Header file for single player campaign control.
const cgame_import_t * cgi
#define MAX_PROJECTILESONGEOSCAPE
const byte * GEO_GetColor(const vec2_t pos, mapType_t type, bool *coast)
Returns the color value from geoscape of a certain mask (terrain, culture or population) at a given p...
float GEO_AngleOfPath(const vec2_t start, const vec2_t end, vec3_t direction, vec3_t ortVector)
Select which function should be used for calculating the direction of model on 2D or 3D geoscape.
Header for Geoscape management.
#define MapIsWater(color)
bool AII_ReloadWeapon(aircraftSlot_t *slot)
Reloads an aircraft/defence-system weapon.
int AII_BaseCanShoot(const base_t *base)
Check if the base has weapon and ammo.
bool AII_InstallationCanShoot(const installation_t *installation)
Check if the installation has a weapon and ammo.
Header for slot management related stuff.
uiMessageListNodeMessage_t * MSO_CheckAddNewMessage(const notify_t messagecategory, const char *title, const char *text, messageType_t type, technology_t *pedia, bool popup)
Adds a new message to message stack. It uses message settings to verify whether sound should be playe...
uiMessageListNodeMessage_t * MS_AddNewMessage(const char *title, const char *text, messageType_t type, technology_t *pedia, bool popup, bool playSound)
Adds a new message to message stack.
void CP_SpawnRescueMission(aircraft_t *aircraft, aircraft_t *ufo)
Spawn a new rescue mission for a crashed (phalanx) aircraft.
void CP_MissionIsOverByUFO(aircraft_t *ufocraft)
Mission is finished because Phalanx team ended it.
void CP_SpawnCrashSiteMission(aircraft_t *ufo)
Spawn a new crash site after a UFO has been destroyed.
void CP_UFOProceedMission(const campaign_t *campaign, aircraft_t *ufo)
Make UFO proceed with its mission when the fight with another aircraft is over (and UFO survived).
Campaign missions headers.
bool RADAR_CheckRadarSensored(const vec2_t pos)
Check if the specified position is within base radar range.
void RADAR_AddDetectedUFOToEveryRadar(const aircraft_t *ufo)
Adds detected UFO to any radar in range (if not already detected).
technology_t * RS_GetTechByProvided(const char *idProvided)
returns a pointer to the item tech (as listed in "provides")
void UFO_NotifyPhalanxAircraftRemoved(const aircraft_t *const aircraft)
Notify to UFOs that a Phalanx aircraft has been destroyed.
aircraft_t * UFO_GetByIDX(const int idx)
returns the UFO on the geoscape with a certain index
void UFO_CheckShootBack(const campaign_t *campaign, aircraft_t *ufo, aircraft_t *phalanxAircraft)
Check if the ufo can shoot back at phalanx aircraft.
void UFO_DetectNewUFO(aircraft_t *ufocraft)
Perform actions when a new UFO is detected.
bool UFO_IsUFOSeenOnGeoscape(const aircraft_t *ufo)
Check if an aircraft should be seen on geoscape.
bool UFO_SendPursuingAircraft(aircraft_t *ufo, aircraft_t *aircraft)
Make the specified UFO pursue a phalanx aircraft.
#define UFO_GetGeoscapeIDX(ufo)
const objDef_t * INVSH_GetItemByID(const char *id)
Returns the item that belongs to the given id or nullptr if it wasn't found.
void RotatePointAroundVector(vec3_t dst, const vec3_t dir, const vec3_t point, float degrees)
Rotate a point around a given vector.
void PolarToVec(const vec2_t a, vec3_t v)
Converts longitude and latitude to a 3D vector in Euclidean coordinates.
double GetDistanceOnGlobe(const vec2_t pos1, const vec2_t pos2)
Calculate distance on the geoscape.
void VecToPolar(const vec3_t v, vec2_t a)
Converts vector coordinates into polar coordinates.
float frand(void)
Return random values between 0 and 1.
XML tag constants for savegame.
#define SAVE_AIRFIGHT_IDLETARGET
#define SAVE_AIRFIGHT_ANGLE
#define SAVE_AIRFIGHT_ISUFO
#define SAVE_AIRFIGHT_POS
#define SAVE_AIRFIGHT_BEAM
#define SAVE_AIRFIGHT_ATTACKERPOS
#define SAVE_AIRFIGHT_AIMEDAIRCRAFT
#define SAVE_AIRFIGHT_PROJECTILE
#define SAVE_AIRFIGHT_AIRCRAFTIDX
#define SAVE_AIRFIGHT_BULLET
#define SAVE_AIRFIGHT_ITEMID
#define SAVE_AIRFIGHT_ATTACKINGAIRCRAFT
#define SAVE_AIRFIGHT_TIME
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
An aircraft with all it's data.
aircraftSlot_t weapons[MAX_AIRCRAFTSLOT]
struct aircraft_s * aircraftTarget
projectile used during fight between two or more aircraft
const objDef_t * aircraftItem
int numInterpolationPoints
aircraft_t * aimedAircraft
vec3_t projectedPos[MAX_MULTIPLE_PROJECTILES]
vec3_t pos[MAX_MULTIPLE_PROJECTILES]
aircraft_t * attackingAircraft
A base with all it's data.
baseWeapon_t batteries[MAX_BASE_SLOT]
baseWeapon_t lasers[MAX_BASE_SLOT]
int skills[SKILL_NUM_TYPES]
float stats[AIR_STATS_MAX]
A installation with all it's data.
Defines all attributes of objects used in the inventory.
This is the technology parsed from research.ufo.
#define VectorCopy(src, dest)
#define VectorSet(v, x, y, z)