From 26d40553b2800f8d2dbd41eccc54d5a7d593e6a3 Mon Sep 17 00:00:00 2001 From: niffiwan Date: Sun, 8 Nov 2015 12:33:02 +1000 Subject: [PATCH 1/3] Allow countermeasure kill-distance to be moddable Trivial efficiency improvement by calculating a pointer once & reusing it. Add more countermeasure nprintf messages Add to weapons tbl/tbm $Countermeasure: +Missile Detonation Radius: 40 --- code/cmeasure/cmeasure.cpp | 1 + code/cmeasure/cmeasure.h | 1 + code/weapon/weapon.h | 1 + code/weapon/weapons.cpp | 23 ++++++++++++++++------- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/code/cmeasure/cmeasure.cpp b/code/cmeasure/cmeasure.cpp index b31c64ea245..6316443fef1 100644 --- a/code/cmeasure/cmeasure.cpp +++ b/code/cmeasure/cmeasure.cpp @@ -21,6 +21,7 @@ int Cmeasures_homing_check = 0; int Countermeasures_enabled = 1; // Debug, set to 0 means no one can fire countermeasures. +const int CMEASURE_DETONATE_DISTANCE = 40.0f; //Used to set a countermeasure velocity after being launched from a ship as a countermeasure //ie not as a primary or secondary. diff --git a/code/cmeasure/cmeasure.h b/code/cmeasure/cmeasure.h index eaad7c384b5..01dc81569ee 100644 --- a/code/cmeasure/cmeasure.h +++ b/code/cmeasure/cmeasure.h @@ -22,6 +22,7 @@ class object; // Maximum distance at which a countermeasure can be tracked // If this value is too large, missiles will always be tracking countermeasures. #define MAX_CMEASURE_TRACK_DIST 300.0f +extern const int CMEASURE_DETONATE_DISTANCE; extern int Cmeasures_homing_check; extern int Countermeasures_enabled; diff --git a/code/weapon/weapon.h b/code/weapon/weapon.h index a10e966e25f..39629627b5e 100644 --- a/code/weapon/weapon.h +++ b/code/weapon/weapon.h @@ -501,6 +501,7 @@ typedef struct weapon_info { float cm_aspect_effectiveness; float cm_heat_effectiveness; float cm_effective_rad; + float cm_detonation_rad; // * diff --git a/code/weapon/weapons.cpp b/code/weapon/weapons.cpp index 57752d1cb62..80e567527df 100755 --- a/code/weapon/weapons.cpp +++ b/code/weapon/weapons.cpp @@ -1015,6 +1015,7 @@ void init_weapon_entry(int weap_info_index) wip->cm_aspect_effectiveness = 1.0f; wip->cm_heat_effectiveness = 1.0f; wip->cm_effective_rad = MAX_CMEASURE_TRACK_DIST; + wip->cm_detonation_rad = CMEASURE_DETONATE_DISTANCE; wip->b_info.beam_type = -1; wip->b_info.beam_life = -1.0f; @@ -2191,6 +2192,9 @@ int parse_weapon(int subtype, bool replace, const char *filename) if (optional_string("+Effective Radius:")) stuff_float(&wip->cm_effective_rad); + + if (optional_string("+Missile Detonation Radius:")) + stuff_float(&wip->cm_detonation_rad); } // beam weapon optional stuff @@ -3885,7 +3889,6 @@ void weapon_maybe_play_warning(weapon *wp) } } -#define CMEASURE_DETONATE_DISTANCE 40.0f /** * Detonate all missiles near this countermeasure. @@ -3909,8 +3912,11 @@ void detonate_nearby_missiles(object *killer_objp) if (iff_x_attacks_y(Weapons[killer_objp->instance].team, wp->team)) { if ( Missiontime - wp->creation_time > F1_0/2) { - if (vm_vec_dist_quick(&killer_objp->pos, &objp->pos) < CMEASURE_DETONATE_DISTANCE) { + if (vm_vec_dist_quick(&killer_objp->pos, &objp->pos) < Weapon_info[Weapons[killer_objp->instance].weapon_info_index].cm_detonation_rad) { if (wp->lifeleft > 0.2f) { + nprintf(("Countermeasures", "Countermeasure (%s-%i) detonated missile (%s-%i) Frame: %i\n", + Weapon_info[Weapons[killer_objp->instance].weapon_info_index].name, killer_objp->signature, + Weapon_info[Weapons[objp->instance].weapon_info_index].name, objp->signature, Framecount)); wp->lifeleft = 0.2f; } } @@ -4280,6 +4286,9 @@ void weapon_home(object *obj, int num, float frame_time) return; } + // if we've got this far, this should be valid + weapon_info* hobj_infop = &Weapon_info[Weapons[hobjp->instance].weapon_info_index]; + if (wip->acceleration_time > 0.0f) { if (Missiontime - wp->creation_time < fl2f(wip->acceleration_time)) { float t; @@ -4369,14 +4378,14 @@ void weapon_home(object *obj, int num, float frame_time) case OBJ_WEAPON: { bool home_on_cmeasure = The_mission.ai_profile->flags2 & AIPF2_ASPECT_LOCK_COUNTERMEASURE - || Weapon_info[Weapons[hobjp->instance].weapon_info_index].wi_flags3 & WIF3_CMEASURE_ASPECT_HOME_ON; + || hobj_infop->wi_flags3 & WIF3_CMEASURE_ASPECT_HOME_ON; // don't home on countermeasures or non-bombs, that's handled elsewhere - if (((Weapon_info[Weapons[hobjp->instance].weapon_info_index].wi_flags & WIF_CMEASURE) && !home_on_cmeasure)) + if (((hobj_infop->wi_flags & WIF_CMEASURE) && !home_on_cmeasure)) { break; } - else if (!(Weapon_info[Weapons[hobjp->instance].weapon_info_index].wi_flags & WIF_BOMB)) + else if (!(hobj_infop->wi_flags & WIF_BOMB)) { break; } @@ -4433,9 +4442,9 @@ void weapon_home(object *obj, int num, float frame_time) float dist; dist = vm_vec_dist_quick(&obj->pos, &hobjp->pos); - if (hobjp->type == OBJ_WEAPON && (Weapon_info[Weapons[hobjp->instance].weapon_info_index].wi_flags & WIF_CMEASURE)) + if (hobjp->type == OBJ_WEAPON && (hobj_infop->wi_flags & WIF_CMEASURE)) { - if (dist < CMEASURE_DETONATE_DISTANCE) + if (dist < hobj_infop->cm_detonation_rad) { // Make this missile detonate soon. Not right away, not sure why. Seems better. if (iff_x_attacks_y(Weapons[hobjp->instance].team, wp->team)) { From aff81fe471b90f6d62b2759edefbe4bc895c148b Mon Sep 17 00:00:00 2001 From: niffiwan Date: Sun, 8 Nov 2015 14:38:05 +1000 Subject: [PATCH 2/3] Countermeasures can detonate a single missile As opposed to detonating all missiles within a radius. Is more efficient than previous code that traversed the entire missile object list to find all the missiles to detonate Add to weapons tbl/tbm $Countermeasure: +Single Missile Kill: False --- code/weapon/weapon.h | 1 + code/weapon/weapons.cpp | 33 +++++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/code/weapon/weapon.h b/code/weapon/weapon.h index 39629627b5e..8cf2c9c784d 100644 --- a/code/weapon/weapon.h +++ b/code/weapon/weapon.h @@ -502,6 +502,7 @@ typedef struct weapon_info { float cm_heat_effectiveness; float cm_effective_rad; float cm_detonation_rad; + bool cm_kill_single; // should the countermeasure kill just the single decoyed missile within CMEASURE_DETONATE_DISTANCE? // * diff --git a/code/weapon/weapons.cpp b/code/weapon/weapons.cpp index 80e567527df..0cbec0217a6 100755 --- a/code/weapon/weapons.cpp +++ b/code/weapon/weapons.cpp @@ -1016,6 +1016,7 @@ void init_weapon_entry(int weap_info_index) wip->cm_heat_effectiveness = 1.0f; wip->cm_effective_rad = MAX_CMEASURE_TRACK_DIST; wip->cm_detonation_rad = CMEASURE_DETONATE_DISTANCE; + wip->cm_kill_single = false; wip->b_info.beam_type = -1; wip->b_info.beam_life = -1.0f; @@ -2195,6 +2196,9 @@ int parse_weapon(int subtype, bool replace, const char *filename) if (optional_string("+Missile Detonation Radius:")) stuff_float(&wip->cm_detonation_rad); + + if (optional_string("+Single Missile Kill:")) + stuff_boolean(&wip->cm_kill_single); } // beam weapon optional stuff @@ -3893,22 +3897,31 @@ void weapon_maybe_play_warning(weapon *wp) /** * Detonate all missiles near this countermeasure. */ -void detonate_nearby_missiles(object *killer_objp) +void detonate_nearby_missiles(object* killer_objp, object* missile_objp) { - if(killer_objp->type != OBJ_WEAPON) { + if(killer_objp->type != OBJ_WEAPON || missile_objp->type != OBJ_WEAPON) { Int3(); return; } - missile_obj *mop; + weapon_info* killer_infop = &Weapon_info[Weapons[killer_objp->instance].weapon_info_index]; - mop = GET_FIRST(&Missile_obj_list); - while(mop != END_OF_LIST(&Missile_obj_list)) { - object *objp; - weapon *wp; + if (killer_infop->cm_kill_single) { + weapon* wp = &Weapons[missile_objp->instance]; + if (wp->lifeleft > 0.2f) { + nprintf(("Countermeasures", "Countermeasure (%s-%i) detonated missile (%s-%i) Frame: %i\n", + killer_infop->name, killer_objp->signature, + Weapon_info[Weapons[missile_objp->instance].weapon_info_index].name, missile_objp->signature, Framecount)); + wp->lifeleft = 0.2f; + } + return; + } - objp = &Objects[mop->objnum]; - wp = &Weapons[objp->instance]; + missile_obj* mop = GET_FIRST(&Missile_obj_list); + + while(mop != END_OF_LIST(&Missile_obj_list)) { + object* objp = &Objects[mop->objnum]; + weapon* wp = &Weapons[objp->instance]; if (iff_x_attacks_y(Weapons[killer_objp->instance].team, wp->team)) { if ( Missiontime - wp->creation_time > F1_0/2) { @@ -4448,7 +4461,7 @@ void weapon_home(object *obj, int num, float frame_time) { // Make this missile detonate soon. Not right away, not sure why. Seems better. if (iff_x_attacks_y(Weapons[hobjp->instance].team, wp->team)) { - detonate_nearby_missiles(hobjp); + detonate_nearby_missiles(hobjp, obj); return; } } From 4849f443aa49d2a9d78ef87cdb945742a9834ff2 Mon Sep 17 00:00:00 2001 From: niffiwan Date: Sun, 8 Nov 2015 14:51:04 +1000 Subject: [PATCH 3/3] Missed two places to use killer_infop --- code/weapon/weapons.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/weapon/weapons.cpp b/code/weapon/weapons.cpp index 0cbec0217a6..3cb9c9e3926 100755 --- a/code/weapon/weapons.cpp +++ b/code/weapon/weapons.cpp @@ -3925,10 +3925,10 @@ void detonate_nearby_missiles(object* killer_objp, object* missile_objp) if (iff_x_attacks_y(Weapons[killer_objp->instance].team, wp->team)) { if ( Missiontime - wp->creation_time > F1_0/2) { - if (vm_vec_dist_quick(&killer_objp->pos, &objp->pos) < Weapon_info[Weapons[killer_objp->instance].weapon_info_index].cm_detonation_rad) { + if (vm_vec_dist_quick(&killer_objp->pos, &objp->pos) < killer_infop->cm_detonation_rad) { if (wp->lifeleft > 0.2f) { nprintf(("Countermeasures", "Countermeasure (%s-%i) detonated missile (%s-%i) Frame: %i\n", - Weapon_info[Weapons[killer_objp->instance].weapon_info_index].name, killer_objp->signature, + killer_infop->name, killer_objp->signature, Weapon_info[Weapons[objp->instance].weapon_info_index].name, objp->signature, Framecount)); wp->lifeleft = 0.2f; }