2626#include " weapon/muzzleflash.h"
2727#include " weapon/swarm.h"
2828#include " weapon/weapon.h"
29+ #include " utils/modular_curves.h"
2930
3031#include < climits>
3132
@@ -1549,22 +1550,26 @@ bool turret_should_pick_new_target(ship_subsys *turret)
15491550/* *
15501551 * Set the next fire timestamp for a turret, based on weapon type and ai class
15511552 */
1552- void turret_set_next_fire_timestamp (int weapon_num, const weapon_info *wip, ship_subsys *turret, const ai_info *aip)
1553+ void turret_set_next_fire_timestamp (int weapon_num, const weapon_info *wip, ship_subsys *turret, const ai_info *aip, const WeaponLaunchCurveData& launch_curve_data )
15531554{
15541555 Assert (weapon_num < MAX_SHIP_WEAPONS);
15551556 float wait = 1000 .0f ;
15561557 // should subtract 1 from firepoints to match behavior of wip->burst_shots
15571558 int burst_shots = (wip->burst_flags [Weapon::Burst_Flags::Num_firepoints_burst_shots] ? turret->system_info ->turret_num_firing_points - 1 : wip->burst_shots );
1559+ burst_shots = fl2i (i2fl (burst_shots) * wip->weapon_launch_curves .get_output (weapon_info::WeaponLaunchCurveOutputs::BURST_SHOTS_MULT, launch_curve_data));
15581560
15591561 if (burst_shots > turret->weapons .burst_counter [weapon_num]) {
15601562 wait *= wip->burst_delay ;
1563+ wait *= wip->weapon_launch_curves .get_output (weapon_info::WeaponLaunchCurveOutputs::BURST_DELAY_MULT, launch_curve_data);
15611564 turret->weapons .burst_counter [weapon_num]++;
15621565 } else {
15631566 // Random fire delay (DahBlount) used in ship_fire_primary(), added here by wookieejedi to correct oversight
15641567 if (wip->max_delay != 0 .0f && wip->min_delay != 0 .0f ) {
15651568 wait *= frand_range (wip->min_delay , wip->max_delay );
1569+ wait *= wip->weapon_launch_curves .get_output (weapon_info::WeaponLaunchCurveOutputs::FIRE_WAIT_MULT, launch_curve_data);
15661570 } else {
15671571 wait *= wip->fire_wait ;
1572+ wait *= wip->weapon_launch_curves .get_output (weapon_info::WeaponLaunchCurveOutputs::FIRE_WAIT_MULT, launch_curve_data);
15681573 }
15691574 if ((burst_shots > 0 ) && (wip->burst_flags [Weapon::Burst_Flags::Random_length])) {
15701575 turret->weapons .burst_counter [weapon_num] = Random::next (burst_shots);
@@ -1690,7 +1695,15 @@ void turret_update_enemy_in_range(ship_subsys *turret, float seconds)
16901695/* *
16911696 * Fire a weapon from a turret
16921697 */
1693- bool turret_fire_weapon (int weapon_num, ship_subsys *turret, int parent_objnum, const vec3d *orig_firing_pos, const vec3d *orig_firing_vec, const vec3d *predicted_pos = nullptr , float flak_range_override = 100 .0f , bool play_sound = true )
1698+ bool turret_fire_weapon (int weapon_num,
1699+ ship_subsys *turret,
1700+ int parent_objnum,
1701+ const WeaponLaunchCurveData& launch_curve_data,
1702+ const vec3d *orig_firing_pos,
1703+ const vec3d *orig_firing_vec,
1704+ const vec3d *predicted_pos = nullptr ,
1705+ float flak_range_override = 100 .0f ,
1706+ bool play_sound = true )
16941707{
16951708 matrix firing_orient;
16961709 int weapon_objnum;
@@ -1790,7 +1803,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
17901803
17911804 // set next fire timestamp for the turret
17921805 if (last_shot_in_salvo)
1793- turret_set_next_fire_timestamp (weapon_num, wip, turret, parent_aip);
1806+ turret_set_next_fire_timestamp (weapon_num, wip, turret, parent_aip, launch_curve_data );
17941807
17951808 // if this weapon is a beam weapon, handle it specially
17961809 if (wip->wi_flags [Weapon::Info_Flags::Beam]) {
@@ -1875,7 +1888,8 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
18751888 }
18761889 // now do anything else
18771890 else {
1878- for (int i = 0 ; i < wip->shots ; i++) {
1891+ int shots = fl2i (i2fl (wip->shots ) * wip->weapon_launch_curves .get_output (weapon_info::WeaponLaunchCurveOutputs::SHOTS_MULT, launch_curve_data));
1892+ for (int i = 0 ; i < shots; i++) {
18791893 if (!in_lab && turret->system_info ->flags [Model::Subsystem_Flags::Turret_use_ammo]) {
18801894 int bank_to_fire, num_slots = turret->system_info ->turret_num_firing_points ;
18811895 if (wip->subtype == WP_LASER) {
@@ -1971,7 +1985,7 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
19711985 // so we need to get the position info separately for each shot
19721986 ship_get_global_turret_gun_info (&Objects[parent_objnum], turret, &firing_pos_buf, false , nullptr , true , nullptr );
19731987
1974- weapon_objnum = weapon_create (firing_pos, &firing_orient, turret_weapon_class, parent_objnum, -1 , 1 , 0 , 0 .0f , turret);
1988+ weapon_objnum = weapon_create (firing_pos, &firing_orient, turret_weapon_class, parent_objnum, -1 , true , false , 0 .0f , turret, launch_curve_data );
19751989 weapon_set_tracking_info (weapon_objnum, parent_objnum, turret->turret_enemy_objnum , 1 , turret->targeted_subsys );
19761990
19771991 // nprintf(("AI", "Turret_time_enemy_in_range = %7.3f\n", ss->turret_time_enemy_in_range));
@@ -2033,9 +2047,9 @@ bool turret_fire_weapon(int weapon_num, ship_subsys *turret, int parent_objnum,
20332047 subsys_index = ship_get_subsys_index (turret);
20342048 Assert ( subsys_index != -1 );
20352049 if (wip->wi_flags [Weapon::Info_Flags::Flak]){
2036- send_flak_fired_packet ( parent_objnum, subsys_index, weapon_objnum, flak_range );
2050+ send_flak_fired_packet ( parent_objnum, subsys_index, weapon_objnum, flak_range, launch_curve_data. distance_to_target );
20372051 } else {
2038- send_turret_fired_packet ( parent_objnum, subsys_index, weapon_objnum );
2052+ send_turret_fired_packet ( parent_objnum, subsys_index, weapon_objnum, launch_curve_data. distance_to_target );
20392053 }
20402054 }
20412055
@@ -2105,8 +2119,13 @@ void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
21052119 // make firing_orient from turret_fvec -- turret->turret_last_fire_direction
21062120 vm_vector_2_matrix_norm (&firing_orient, &turret_fvec, nullptr , nullptr );
21072121
2122+ auto launch_curve_data = WeaponLaunchCurveData {
2123+ tsi->turret ->system_info ->turret_num_firing_points ,
2124+ 0 .f ,
2125+ };
2126+
21082127 // create weapon and homing info
2109- weapon_objnum = weapon_create (&turret_pos, &firing_orient, tsi->weapon_class , tsi->parent_objnum , -1 , 1 , 0 , 0 .0f , tsi->turret );
2128+ weapon_objnum = weapon_create (&turret_pos, &firing_orient, tsi->weapon_class , tsi->parent_objnum , -1 , true , false , 0 .0f , tsi->turret , launch_curve_data );
21102129 weapon_set_tracking_info (weapon_objnum, tsi->parent_objnum , tsi->target_objnum , 1 , tsi->target_subsys );
21112130
21122131 // do other cool stuff if weapon is created.
@@ -2157,7 +2176,7 @@ void turret_swarm_fire_from_turret(turret_swarm_info *tsi)
21572176
21582177 subsys_index = ship_get_subsys_index (tsi->turret );
21592178 Assert ( subsys_index != -1 );
2160- send_turret_fired_packet ( tsi->parent_objnum , subsys_index, weapon_objnum );
2179+ send_turret_fired_packet ( tsi->parent_objnum , subsys_index, weapon_objnum, 0 . f );
21612180 }
21622181 }
21632182}
@@ -2325,6 +2344,12 @@ void ai_turret_execute_behavior(const ship *shipp, ship_subsys *ss)
23252344
23262345 float turret_barrel_length = -1 .0f ;
23272346
2347+ // grab the data for the launch curve inputs
2348+ auto launch_curve_data = WeaponLaunchCurveData {
2349+ ss->system_info ->turret_num_firing_points ,
2350+ dist_to_enemy,
2351+ };
2352+
23282353 // WMC - go through all valid weapons. Fire spawns if there are any.
23292354 int valid_weapons[MAX_SHIP_WEAPONS];
23302355 int num_valid = 0 ;
@@ -2356,7 +2381,7 @@ void ai_turret_execute_behavior(const ship *shipp, ship_subsys *ss)
23562381 if (!in_lab && (wip->wi_flags [Weapon::Info_Flags::Spawn]) && !(wip->wi_flags [Weapon::Info_Flags::Smart_spawn]) )
23572382 {
23582383 if (( num_ships_nearby >= 3 ) || ((num_ships_nearby >= 2 ) && (frand () < 0 .1f ))) {
2359- turret_fire_weapon (i, ss, parent_objnum, &global_gun_pos, &ss->turret_last_fire_direction );
2384+ turret_fire_weapon (i, ss, parent_objnum, launch_curve_data, &global_gun_pos, &ss->turret_last_fire_direction );
23602385 } else {
23612386 // Regardless of firing rate, don't check whether should fire for awhile.
23622387 if (tp->flags [Model::Subsystem_Flags::Use_multiple_guns])
@@ -2809,7 +2834,7 @@ void ai_turret_execute_behavior(const ship *shipp, ship_subsys *ss)
28092834 flak_jitter_aim (&shoot_vector, dist_to_enemy, ship_get_subsystem_strength (shipp, SUBSYSTEM_WEAPONS), wip);
28102835 }
28112836
2812- turret_fire_weapon (valid_weapons[valid_index], ss, parent_objnum, &global_gun_pos, &shoot_vector, &predicted_enemy_pos, 100 .0f , play_sound);
2837+ turret_fire_weapon (valid_weapons[valid_index], ss, parent_objnum, launch_curve_data, &global_gun_pos, &shoot_vector, &predicted_enemy_pos, 100 .0f , play_sound);
28132838 }
28142839 else
28152840 {
@@ -2822,7 +2847,7 @@ void ai_turret_execute_behavior(const ship *shipp, ship_subsys *ss)
28222847 // make sure salvo fire mode does not turn into autofire
28232848 if ((tp->flags [Model::Subsystem_Flags::Turret_salvo]) && ((i + 1 ) == number_of_firings)) {
28242849 ai_info *parent_aip = &Ai_info[shipp->ai_index ];
2825- turret_set_next_fire_timestamp (valid_weapons[valid_index], wip, ss, parent_aip);
2850+ turret_set_next_fire_timestamp (valid_weapons[valid_index], wip, ss, parent_aip, launch_curve_data );
28262851 }
28272852 }
28282853
0 commit comments