27 #include "../../cl_shared.h"
34 #include "../../sound/s_main.h"
37 #define AIRCRAFT_INVALID -1
72 if (!weaponSlot->
ammo) {
73 cgi->Com_Printf(
"AIRFIGHT_AddProjectile: Error - no ammo assigned\n");
77 assert(weaponSlot->
item);
84 }
else if (attackingInstallation) {
86 VectorSet(projectile->
pos[0], attackingInstallation->
pos[0], attackingInstallation->
pos[1], 0);
102 projectile->
time = 0;
103 projectile->
angle = 0.0f;
117 sound =
"geoscape/combat-gun";
118 }
else if (projectile->
beam) {
119 sound =
"geoscape/combat-airlaser";
120 }
else if (projectile->
rocket) {
121 sound =
"geoscape/combat-rocket";
126 if (sound !=
nullptr)
127 cgi->S_StartLocalSample(sound, 1.0
f);
137 static void AIRFIGHT_ProjectileList_f (
void)
145 cgi->Com_Printf(
"... base is shooting, or shooting aircraft is destroyed\n");
149 cgi->Com_Printf(
"... aiming idle target at (%.02f, %.02f)\n",
181 offset = (distance / 3) * (
frand() - 0.5f);
183 if (abs(offset) < 0.1f)
186 newTarget[0] = newTarget[0] +
offset;
187 newTarget[1] = newTarget[1] +
offset;
237 float distance0 = 99999.9f;
241 for (
int i = 0;
i < maxSlot;
i++) {
247 if (weaponStatus > slotIdx)
253 distance0 = distance;
274 float probability = 0.0f;
277 cgi->Com_Printf(
"AIRFIGHT_ProbabilityToHit: no weapon assigned to attacking aircraft\n");
282 cgi->Com_Printf(
"AIRFIGHT_ProbabilityToHit: no ammo in weapon of attacking aircraft\n");
288 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ProbabilityToHit: Base probability: %f\n", probability);
294 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ProbabilityToHit: Probability after accounting items of attacker: %f\n", probability);
300 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ProbabilityToHit: Probability after accounting ECM of target: %f\n", probability);
304 if (shooter->
pilot) {
312 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ProbabilityToHit: Probability after accounting targeting skill of shooter: %f\n",
327 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ProbabilityToHit: Probability after accounting evasion skill of target: %f\n",
333 probability = std::min(probability, 0.95
f);
335 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ProbabilityToHit: Probability to hit: %f\n", probability);
364 const float probability =
frand();
365 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ExecuteActions: %s - Random probability to hit: %f\n", shooter->
name, probability);
369 cgi->Com_DPrintf(
DEBUG_CLIENT,
"AIRFIGHT_ExecuteActions: %s - Calculated probability to hit: %f\n", shooter->
name, calculatedProbability);
371 if (probability > calculatedProbability)
401 MS_AddNewMessage(
_(
"Notice"),
_(
"Our aircraft has no more ammo left - returning to home base now."));
446 if (attacker == aircraft)
487 MS_AddNewMessage(
_(
"Interception"),
_(
"UFO interception successful -- UFO lost to sea."));
521 bool pilotSurvived =
false;
523 pilotSurvived =
true;
561 if (distance < movement)
625 assert(target->
damage > 0);
627 if (target->
damage <= 0) {
630 cgi->S_StartLocalSample(
"geoscape/combat-explosion", 1.0
f);
633 cgi->S_StartLocalSample(
"geoscape/combat-rocket-exp", 1.0
f);
648 vec3_t startPoint, finalVectorPoint;
666 *angle =
GEO_AngleOfPath(originalPoint, targetPoint,
nullptr, orthogonalVector);
683 projectile->
time += dt;
697 vec3_t ortogonalVector, finalPoint, projectedPoint;
709 projectile->
angle = angle;
724 for (
int i = 0;
i < maxWeapons;
i++) {
778 for (
int i = 0;
i < maxWeapons;
i++) {
833 while ((base =
B_GetNext(base)) !=
nullptr) {
848 for (idx = 0; idx < base->
numLasers; idx++) {
869 if (installation->installationTemplate->maxBatteries <= 0)
872 for (
int idx = 0; idx < installation->installationTemplate->maxBatteries; idx++) {
951 cgi->Com_Printf(
"AIR_Load: Could not get technology of projectile %i\n", i);
1000 cgi->Cmd_AddCommand(
"debug_listprojectile", AIRFIGHT_ProjectileList_f,
"Print Projectiles information to game console");
#define AIRFIGHT_WEAPON_CAN_SHOOT
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.
static bool AIRFIGHT_ProjectileReachedTarget(const aircraftProjectile_t *projectile, float movement)
Check if some projectiles on geoscape reached their destination.
#define VectorCopy(src, dest)
#define AIRFIGHT_WEAPON_CAN_NEVER_SHOOT
bool AIR_IsAircraftInBase(const aircraft_t *aircraft)
Checks whether given aircraft is in its homebase.
#define VectorSet(v, x, y, z)
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...
XML tag constants for savegame.
const objDef_t * INVSH_GetItemByID(const char *id)
Returns the item that belongs to the given id or nullptr if it wasn't found.
A installation with all it's data.
bool B_GetBuildingStatus(const base_t *const base, const buildingType_t buildingType)
Get the status associated to a building.
#define SAVE_AIRFIGHT_POS
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...
bool AIR_SendAircraftPursuingUFO(aircraft_t *aircraft, aircraft_t *ufo)
Make the specified aircraft purchasing a UFO.
int AIRFIGHT_CheckWeapon(const aircraftSlot_t *slot, float distance)
Check if the selected weapon can shoot.
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...
void VecToPolar(const vec3_t v, vec2_t a)
Converts vector coordinates into polar coordinates.
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.
bool UFO_IsUFOSeenOnGeoscape(const aircraft_t *ufo)
Check if an aircraft should be seen on geoscape.
#define B_IsUnderAttack(base)
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.
#define SAVE_AIRFIGHT_PROJECTILE
#define SAVE_AIRFIGHT_IDLETARGET
#define SAVE_AIRFIGHT_ATTACKINGAIRCRAFT
static float AIRFIGHT_ProbabilityToHit(const aircraft_t *shooter, const aircraft_t *target, const aircraftSlot_t *slot)
Calculate the probability to hit the enemy.
#define REMOVE_ELEM_ADJUST_IDX(array, index, n)
bool AII_InstallationCanShoot(const installation_t *installation)
Check if the installation has a weapon and ammo.
xmlNode_t *IMPORT * XML_GetPos3(xmlNode_t *parent, const char *name, vec3_t pos)
void AIRFIGHT_InitStartup(void)
aircraft_t * AIR_AircraftGetFromIDX(int aircraftIdx)
Returns aircraft for a given global index.
void RotatePointAroundVector(vec3_t dst, const vec3_t dir, const vec3_t point, float degrees)
Rotate a point around a given vector.
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...
void CP_SpawnCrashSiteMission(aircraft_t *ufo)
Spawn a new crash site after a UFO has been destroyed.
#define SAVE_AIRFIGHT_ANGLE
float stats[AIR_STATS_MAX]
#define SAVE_AIRFIGHT_TIME
bool AIRFIGHT_SaveXML(xmlNode_t *parent)
Save callback for savegames in XML Format.
Defines all attributes of objects used in the inventory.
void AIRFIGHT_ExecuteActions(const campaign_t *campaign, aircraft_t *shooter, aircraft_t *target)
Decide what an attacking aircraft can do.
bool RADAR_CheckRadarSensored(const vec2_t pos)
Check if the specified position is within base radar range.
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.
#define SAVE_AIRFIGHT_ISUFO
A base with all it's data.
int numInterpolationPoints
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.
bool UFO_SendPursuingAircraft(aircraft_t *ufo, aircraft_t *aircraft)
Make the specified UFO pursue a phalanx aircraft.
#define SAVE_AIRFIGHT_AIMEDAIRCRAFT
#define AIRFIGHT_WEAPON_CAN_NOT_SHOOT_AT_THE_MOMENT
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.
#define UFO_GetGeoscapeIDX(ufo)
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...
void AIR_AircraftReturnToBase(aircraft_t *aircraft)
Calculates the way back to homebase for given aircraft and returns it.
#define SAVE_AIRFIGHT_ATTACKERPOS
Campaign missions headers.
bool AIRFIGHT_LoadXML(xmlNode_t *parent)
Load callback for savegames in XML Format.
base_t * B_GetNext(base_t *lastBase)
Iterates through founded bases.
#define MAX_MULTIPLE_PROJECTILES
void PolarToVec(const vec2_t a, vec3_t v)
Converts longitude and latitude to a 3D vector in Euclidean coordinates.
void AIRFIGHT_CampaignRunBaseDefence(int dt)
Run base defences.
const cgame_import_t * cgi
void UFO_NotifyPhalanxAircraftRemoved(const aircraft_t *const aircraft)
Notify to UFOs that a Phalanx aircraft has been destroyed.
#define MAX_PROJECTILESONGEOSCAPE
static void AIRFIGHT_UpdateProjectileForDestroyedAircraft(const aircraft_t *aircraft)
Set all projectile attackingAircraft pointers to nullptr.
struct aircraft_s * aircraftTarget
This is the technology parsed from research.ufo.
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)...
#define SAVE_AIRFIGHT_AIRCRAFTIDX
aircraftSlot_t weapons[MAX_AIRCRAFTSLOT]
Header for Geoscape management.
static void AIRFIGHT_MissTarget(aircraftProjectile_t *projectile)
Change destination of projectile to an idle point of the map, close to its former target...
const objDef_t * aircraftItem
void CP_MissionIsOverByUFO(aircraft_t *ufocraft)
Mission is finished because Phalanx team ended it.
baseWeapon_t batteries[MAX_BASE_SLOT]
void AIR_DestroyAircraft(aircraft_t *aircraft, bool killPilot)
Removes an aircraft from its base and the game.
void CP_SpawnRescueMission(aircraft_t *aircraft, aircraft_t *ufo)
Spawn a new rescue mission for a crashed (phalanx) aircraft.
aircraft_t * UFO_GetByIDX(const int idx)
returns the UFO on the geoscape with a certain index
xmlNode_t *IMPORT * XML_GetPos2(xmlNode_t *parent, const char *name, vec2_t pos)
aircraft_t * attackingAircraft
float frand(void)
Return random values between 0 and 1.
aircraftProjectile_t projectiles[MAX_PROJECTILESONGEOSCAPE]
#define AIR_IsUFO(aircraft)
void RADAR_AddDetectedUFOToEveryRadar(const aircraft_t *ufo)
Adds detected UFO to any radar in range (if not already detected).
xmlNode_t *IMPORT * XML_GetNextNode(xmlNode_t *current, xmlNode_t *parent, const char *name)
vec3_t projectedPos[MAX_MULTIPLE_PROJECTILES]
Header for slot management related stuff.
#define SAVE_AIRFIGHT_ITEMID
static int AIRFIGHT_GetDamage(const objDef_t *od, const aircraft_t *target)
Calculates the damage value for the airfight.
void UFO_DetectNewUFO(aircraft_t *ufocraft)
Perform actions when a new UFO is detected.
#define MapIsWater(color)
Header file for single player campaign control.
void AIRFIGHT_ActionsAfterAirfight(const campaign_t *campaign, aircraft_t *shooter, aircraft_t *aircraft, bool phalanxWon)
Actions to execute when a fight is done.
#define SAVE_AIRFIGHT_BULLET
xmlNode_t *IMPORT * XML_AddNode(xmlNode_t *parent, const char *name)
baseWeapon_t lasers[MAX_BASE_SLOT]
technology_t * RS_GetTechByProvided(const char *idProvided)
returns a pointer to the item tech (as listed in "provides")
int AII_BaseCanShoot(const base_t *base)
Check if the base has weapon and ammo.
#define SAVE_AIRFIGHT_BEAM
aircraft_t * aimedAircraft
projectile used during fight between two or more aircraft
An aircraft with all it's data.
vec3_t pos[MAX_MULTIPLE_PROJECTILES]
static void AIRFIGHT_ProjectileHits(const campaign_t *campaign, aircraftProjectile_t *projectile)
Solve the result of one projectile hitting an aircraft.
xmlNode_t *IMPORT * XML_GetNextPos2(xmlNode_t *actual, xmlNode_t *parent, const char *name, vec2_t pos)
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_RemoveProjectile(aircraftProjectile_t *projectile)
Remove a projectile from ccs.projectiles.
int skills[SKILL_NUM_TYPES]
void AIRFIGHT_CampaignRunProjectiles(const campaign_t *campaign, int dt)
Update values of projectiles.
const char *IMPORT * XML_GetString(xmlNode_t *parent, const char *name)
xmlNode_t *IMPORT * XML_GetNode(xmlNode_t *parent, const char *name)
void AIRFIGHT_RemoveProjectileAimingAircraft(const aircraft_t *aircraft)
Set all projectile aiming a given aircraft to an idle destination.
void UFO_CheckShootBack(const campaign_t *campaign, aircraft_t *ufo, aircraft_t *phalanxAircraft)
Check if the ufo can shoot back at phalanx aircraft.
bool AII_ReloadWeapon(aircraftSlot_t *slot)
Reloads an aircraft/defence-system weapon.
double GetDistanceOnGlobe(const vec2_t pos1, const vec2_t pos2)
Calculate distance on the geoscape.
const char * getTerrainName(const byte *const color) const
Translate color value to terrain type.