From 9ccfe9d9e3d64e6a314195ccfbd9014dd25a4927 Mon Sep 17 00:00:00 2001 From: wookieejedi Date: Mon, 3 Aug 2026 23:03:35 -0400 Subject: [PATCH 1/8] Add weapon launch curve input 'Target Forward Speed' Following style of 'target radius' and other useful weapon launch curve inputs, this PR adds 'Target Forward Speed' which can be useful to use as an input and then use FoF as an output to do things like make turrets have a tougher time having dynamic FoF depending on target speed. --- code/ai/aiturret.cpp | 7 +++++-- code/network/multimsgs.cpp | 8 ++++++-- code/network/multimsgs.h | 4 ++-- code/ship/ship.cpp | 6 ++++++ code/weapon/weapon.h | 4 +++- 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/code/ai/aiturret.cpp b/code/ai/aiturret.cpp index 974e37557f4..7836793ace1 100644 --- a/code/ai/aiturret.cpp +++ b/code/ai/aiturret.cpp @@ -2061,9 +2061,9 @@ bool turret_fire_weapon(int weapon_num, subsys_index = ship_get_subsys_index(turret); Assert( subsys_index != -1 ); if(wip->wi_flags[Weapon::Info_Flags::Flak]){ - send_flak_fired_packet( parent_objnum, subsys_index, weapon_objnum, flak_range, launch_curve_data.distance_to_target, launch_curve_data.target_radius ); + send_flak_fired_packet( parent_objnum, subsys_index, weapon_objnum, flak_range, launch_curve_data.distance_to_target, launch_curve_data.target_radius, launch_curve_data.target_forward_speed ); } else { - send_turret_fired_packet( parent_objnum, subsys_index, weapon_objnum, launch_curve_data.distance_to_target, launch_curve_data.target_radius ); + send_turret_fired_packet( parent_objnum, subsys_index, weapon_objnum, launch_curve_data.distance_to_target, launch_curve_data.target_radius, launch_curve_data.target_forward_speed ); } } @@ -2361,9 +2361,11 @@ void ai_turret_execute_behavior(const ship *shipp, ship_subsys *ss) float turret_barrel_length = -1.0f; float target_radius = 0.f; + float target_forward_speed = 0.f; if (lep != nullptr) { target_radius = lep->radius; + target_forward_speed = lep->phys_info.fspeed; } // grab the data for the launch curve inputs @@ -2371,6 +2373,7 @@ void ai_turret_execute_behavior(const ship *shipp, ship_subsys *ss) ss->system_info->turret_num_firing_points, base_dist_to_enemy, target_radius, + target_forward_speed, }; //WMC - go through all valid weapons. Fire spawns if there are any. diff --git a/code/network/multimsgs.cpp b/code/network/multimsgs.cpp index e7b5d9a677d..69bba473fa4 100644 --- a/code/network/multimsgs.cpp +++ b/code/network/multimsgs.cpp @@ -3317,7 +3317,7 @@ void process_countermeasure_fired_packet( ubyte *data, header *hinfo ) } // send a packet indicating that a turret has been fired -void send_turret_fired_packet( int ship_objnum, int subsys_index, int weapon_objnum, float dist_to_target, float target_radius ) +void send_turret_fired_packet( int ship_objnum, int subsys_index, int weapon_objnum, float dist_to_target, float target_radius, float target_forward_speed ) { int packet_size; ushort pnet_signature; @@ -3376,6 +3376,8 @@ void send_turret_fired_packet( int ship_objnum, int subsys_index, int weapon_obj ADD_FLOAT(dist_to_target); ADD_FLOAT(target_radius); + + ADD_FLOAT(target_forward_speed); multi_io_send_to_all(data, packet_size); @@ -8633,7 +8635,7 @@ void process_weapon_detonate_packet(ubyte *data, header *hinfo) } // flak fired packet -void send_flak_fired_packet(int ship_objnum, int subsys_index, int weapon_objnum, float flak_range, float dist_to_target, float target_radius) +void send_flak_fired_packet(int ship_objnum, int subsys_index, int weapon_objnum, float flak_range, float dist_to_target, float target_radius, float target_forward_speed) { int packet_size; ushort pnet_signature; @@ -8684,6 +8686,8 @@ void send_flak_fired_packet(int ship_objnum, int subsys_index, int weapon_objnum ADD_FLOAT( dist_to_target ); + ADD_FLOAT( target_forward_speed ); + ADD_FLOAT( target_radius ); multi_io_send_to_all(data, packet_size); diff --git a/code/network/multimsgs.h b/code/network/multimsgs.h index 91852e9b6a4..a878c8ff35c 100644 --- a/code/network/multimsgs.h +++ b/code/network/multimsgs.h @@ -528,11 +528,11 @@ void send_weapon_detonate_packet(object *objp); void process_weapon_detonate_packet(ubyte *data, header *hinfo); // turret fired packet -void send_turret_fired_packet( int objnum, int subsys_index, int weapon_objnum, float dist_to_target, float target_radius ); +void send_turret_fired_packet( int objnum, int subsys_index, int weapon_objnum, float dist_to_target, float target_radius, float target_forward_speed ); void process_turret_fired_packet( ubyte *data, header *hinfo ); // flak fired packet -void send_flak_fired_packet(int ship_objnum, int subsys_index, int weapon_objnum, float flak_range, float dist_to_target, float target_radius ); +void send_flak_fired_packet(int ship_objnum, int subsys_index, int weapon_objnum, float flak_range, float dist_to_target, float target_radius, float target_forward_speed ); void process_flak_fired_packet(ubyte *data, header *hinfo); // player pain packet diff --git a/code/ship/ship.cpp b/code/ship/ship.cpp index 799c8c09d45..c39e89fe930 100644 --- a/code/ship/ship.cpp +++ b/code/ship/ship.cpp @@ -12961,15 +12961,18 @@ int ship_fire_primary(object * obj, int force, bool rollback_shot) int num_slots = pm->gun_banks[bank_to_fire].num_slots; float target_radius = 0.f; + float target_forward_speed = 0.f; if (aip->target_objnum >= 0) { target_radius = Objects[aip->target_objnum].radius; + target_forward_speed = Objects[aip->target_objnum].phys_info.fspeed; } auto launch_curve_data = WeaponLaunchCurveData { num_slots, dist_to_target, target_radius, + target_forward_speed, }; // do timestamp stuff for next firing time @@ -14257,15 +14260,18 @@ int ship_fire_secondary( object *obj, int allow_swarm, bool rollback_shot ) num_slots = pm->missile_banks[bank].num_slots; float target_radius = 0.f; + float target_forward_speed = 0.f; if (tinfo.objnum >= 0) { target_radius = Objects[tinfo.objnum].radius; + target_forward_speed = Objects[tinfo.objnum].phys_info.fspeed; } auto launch_curve_data = WeaponLaunchCurveData { num_slots, dist_to_target, target_radius, + target_forward_speed, }; // determine if there is enough ammo left to fire weapons on this bank. As with primary diff --git a/code/weapon/weapon.h b/code/weapon/weapon.h index ed59726b94f..e4704dd4087 100644 --- a/code/weapon/weapon.h +++ b/code/weapon/weapon.h @@ -370,6 +370,7 @@ struct WeaponLaunchCurveData { int num_firepoints; float distance_to_target; float target_radius; + float target_forward_speed; }; struct weapon_info; @@ -748,7 +749,8 @@ struct weapon_info }, std::pair {"Num Firepoints", modular_curves_submember_input<&WeaponLaunchCurveData::num_firepoints>{}}, std::pair {"Distance to Target", modular_curves_submember_input<&WeaponLaunchCurveData::distance_to_target>{}}, - std::pair {"Target Radius", modular_curves_submember_input<&WeaponLaunchCurveData::target_radius>{}} + std::pair {"Target Radius", modular_curves_submember_input<&WeaponLaunchCurveData::target_radius>{}}, + std::pair {"Target Forward Speed", modular_curves_submember_input<&WeaponLaunchCurveData::target_forward_speed>{}} ); public: From 208cfdfed31b218bfee96c6a40bf486fe318db6d Mon Sep 17 00:00:00 2001 From: wookieejedi Date: Mon, 3 Aug 2026 23:18:03 -0400 Subject: [PATCH 2/8] clang --- code/weapon/weapon.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/weapon/weapon.h b/code/weapon/weapon.h index e4704dd4087..e5e718c3188 100644 --- a/code/weapon/weapon.h +++ b/code/weapon/weapon.h @@ -750,7 +750,7 @@ struct weapon_info std::pair {"Num Firepoints", modular_curves_submember_input<&WeaponLaunchCurveData::num_firepoints>{}}, std::pair {"Distance to Target", modular_curves_submember_input<&WeaponLaunchCurveData::distance_to_target>{}}, std::pair {"Target Radius", modular_curves_submember_input<&WeaponLaunchCurveData::target_radius>{}}, - std::pair {"Target Forward Speed", modular_curves_submember_input<&WeaponLaunchCurveData::target_forward_speed>{}} + std::pair {"Target Forward Speed", modular_curves_submember_input<&WeaponLaunchCurveData::target_forward_speed>{}}, ); public: @@ -1035,6 +1035,7 @@ int weapon_create( const vec3d *pos, const WeaponLaunchCurveData& launch_curve_data = WeaponLaunchCurveData { 0, 0.f, + 0.f, 0.f }); void weapon_set_tracking_info(int weapon_objnum, int parent_objnum, int target_objnum, int target_is_locked = 0, ship_subsys *target_subsys = NULL); From af7a2f37ed33147ada1bee775ba48f10f0acf752 Mon Sep 17 00:00:00 2001 From: wookieejedi Date: Tue, 4 Aug 2026 07:36:38 -0400 Subject: [PATCH 3/8] clang again --- code/weapon/weapon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/weapon/weapon.h b/code/weapon/weapon.h index e5e718c3188..814c9896ee2 100644 --- a/code/weapon/weapon.h +++ b/code/weapon/weapon.h @@ -750,7 +750,7 @@ struct weapon_info std::pair {"Num Firepoints", modular_curves_submember_input<&WeaponLaunchCurveData::num_firepoints>{}}, std::pair {"Distance to Target", modular_curves_submember_input<&WeaponLaunchCurveData::distance_to_target>{}}, std::pair {"Target Radius", modular_curves_submember_input<&WeaponLaunchCurveData::target_radius>{}}, - std::pair {"Target Forward Speed", modular_curves_submember_input<&WeaponLaunchCurveData::target_forward_speed>{}}, + std::pair {"Target Forward Speed", modular_curves_submember_input<&WeaponLaunchCurveData::target_forward_speed>{} ); public: From 61b7c9f3f10d4fd5bbcc16be08dad38a87b17f8c Mon Sep 17 00:00:00 2001 From: wookieejedi Date: Tue, 4 Aug 2026 07:56:44 -0400 Subject: [PATCH 4/8] clang auto format typo --- code/weapon/weapon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/weapon/weapon.h b/code/weapon/weapon.h index 814c9896ee2..578f846ed90 100644 --- a/code/weapon/weapon.h +++ b/code/weapon/weapon.h @@ -750,7 +750,7 @@ struct weapon_info std::pair {"Num Firepoints", modular_curves_submember_input<&WeaponLaunchCurveData::num_firepoints>{}}, std::pair {"Distance to Target", modular_curves_submember_input<&WeaponLaunchCurveData::distance_to_target>{}}, std::pair {"Target Radius", modular_curves_submember_input<&WeaponLaunchCurveData::target_radius>{}}, - std::pair {"Target Forward Speed", modular_curves_submember_input<&WeaponLaunchCurveData::target_forward_speed>{} + std::pair {"Target Forward Speed", modular_curves_submember_input<&WeaponLaunchCurveData::target_forward_speed>{}} ); public: From 4c4cc4431082a28fd312e1b6d5af6c1eff5e54bd Mon Sep 17 00:00:00 2001 From: wookieejedi Date: Tue, 4 Aug 2026 09:05:08 -0400 Subject: [PATCH 5/8] multi packets --- code/ai/aiturret.cpp | 1 + code/network/multimsgs.cpp | 6 ++++++ code/scripting/api/objs/subsystem.cpp | 1 + 3 files changed, 8 insertions(+) diff --git a/code/ai/aiturret.cpp b/code/ai/aiturret.cpp index 7836793ace1..175ed74895c 100644 --- a/code/ai/aiturret.cpp +++ b/code/ai/aiturret.cpp @@ -2137,6 +2137,7 @@ void turret_swarm_fire_from_turret(turret_swarm_info *tsi) tsi->turret->system_info->turret_num_firing_points, 0.f, 0.f, + 0.f, }; // create weapon and homing info diff --git a/code/network/multimsgs.cpp b/code/network/multimsgs.cpp index 69bba473fa4..13042956f21 100644 --- a/code/network/multimsgs.cpp +++ b/code/network/multimsgs.cpp @@ -3400,6 +3400,7 @@ void process_turret_fired_packet( ubyte *data, header *hinfo ) float angle1, angle2; float dist_to_target; float target_radius; + float target_forward_speed; // get the data for the turret fired packet offset = HEADER_LENGTH; @@ -3417,6 +3418,7 @@ void process_turret_fired_packet( ubyte *data, header *hinfo ) GET_FLOAT( angle2 ); GET_FLOAT( dist_to_target ); GET_FLOAT( target_radius ); + GET_FLOAT( target_forward_speed ); PACKET_SET_SIZE(); // move our counter forward the number of bytes we have read // if we don't have a valid weapon index then bail @@ -3465,6 +3467,7 @@ void process_turret_fired_packet( ubyte *data, header *hinfo ) ssp->system_info->turret_num_firing_points, dist_to_target, target_radius, + target_forward_speed, }; // create the weapon object @@ -8710,6 +8713,7 @@ void process_flak_fired_packet(ubyte *data, header *hinfo) float flak_range; float dist_to_target; float target_radius; + float target_forward_speed; // get the data for the turret fired packet offset = HEADER_LENGTH; @@ -8722,6 +8726,7 @@ void process_flak_fired_packet(ubyte *data, header *hinfo) GET_FLOAT( flak_range ); GET_FLOAT( dist_to_target ); GET_FLOAT( target_radius ); + GET_FLOAT( target_forward_speed ); PACKET_SET_SIZE(); // move our counter forward the number of bytes we have read // if we don't have a valid weapon index then bail @@ -8769,6 +8774,7 @@ void process_flak_fired_packet(ubyte *data, header *hinfo) ssp->system_info->turret_num_firing_points, dist_to_target, target_radius, + target_forward_speed, }; // create the weapon object diff --git a/code/scripting/api/objs/subsystem.cpp b/code/scripting/api/objs/subsystem.cpp index 02bacbe6083..8ca424a1bfb 100644 --- a/code/scripting/api/objs/subsystem.cpp +++ b/code/scripting/api/objs/subsystem.cpp @@ -946,6 +946,7 @@ ADE_FUNC(fireWeapon, l_Subsystem, "[number TurretWeaponIndex = 1, number FlakRan sso->ss->system_info->turret_num_firing_points, 0.f, 0.f, + 0.f, }; bool rtn = turret_fire_weapon(wnum, sso->ss, sso->objh.objnum, launch_curve_data, &gpos, &gvec, nullptr, flak_range); From acd868fa49251d5c62605a19c64c62a6430ee43f Mon Sep 17 00:00:00 2001 From: wookieejedi Date: Tue, 4 Aug 2026 09:56:21 -0400 Subject: [PATCH 6/8] one more multi clang --- code/ai/aiturret.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ai/aiturret.cpp b/code/ai/aiturret.cpp index 175ed74895c..b67db156eb1 100644 --- a/code/ai/aiturret.cpp +++ b/code/ai/aiturret.cpp @@ -2189,7 +2189,7 @@ void turret_swarm_fire_from_turret(turret_swarm_info *tsi) subsys_index = ship_get_subsys_index(tsi->turret); Assert( subsys_index != -1 ); - send_turret_fired_packet( tsi->parent_objnum, subsys_index, weapon_objnum, 0.f, 0.f); + send_turret_fired_packet( tsi->parent_objnum, subsys_index, weapon_objnum, 0.f, 0.f, 0.f); } } } From 08bb369e466ce29d1d583be604f0d8bb03cbeca5 Mon Sep 17 00:00:00 2001 From: wookieejedi Date: Tue, 4 Aug 2026 16:07:06 -0400 Subject: [PATCH 7/8] fix order and multi bump --- code/network/multi.h | 2 +- code/network/multimsgs.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/network/multi.h b/code/network/multi.h index 46a03e7e6b6..9833cc052ad 100644 --- a/code/network/multi.h +++ b/code/network/multi.h @@ -78,7 +78,7 @@ class player; // Version 62 - 5/26/2025 - Added some modular curve input data to turret firing packets; 5/31/2025 - Added another input // STANDALONE_ONLY -#define MULTI_FS_SERVER_VERSION 62 +#define MULTI_FS_SERVER_VERSION 63 #define MULTI_FS_SERVER_COMPATIBLE_VERSION MULTI_FS_SERVER_VERSION diff --git a/code/network/multimsgs.cpp b/code/network/multimsgs.cpp index 13042956f21..c05a848a60a 100644 --- a/code/network/multimsgs.cpp +++ b/code/network/multimsgs.cpp @@ -8689,9 +8689,9 @@ void send_flak_fired_packet(int ship_objnum, int subsys_index, int weapon_objnum ADD_FLOAT( dist_to_target ); - ADD_FLOAT( target_forward_speed ); - ADD_FLOAT( target_radius ); + + ADD_FLOAT( target_forward_speed ); multi_io_send_to_all(data, packet_size); From 2821eb8ccf713d6edf61a63fc2e1018d5c7e4608 Mon Sep 17 00:00:00 2001 From: wookieejedi Date: Tue, 4 Aug 2026 21:55:08 -0400 Subject: [PATCH 8/8] Update code/network/multi.h Co-authored-by: Goober5000 --- code/network/multi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/code/network/multi.h b/code/network/multi.h index 9833cc052ad..80e8608b4f5 100644 --- a/code/network/multi.h +++ b/code/network/multi.h @@ -76,6 +76,7 @@ class player; // Version 60 - 3/27/2023 - Added generic lua data packet // Version 61 - 4/17/2023 - Added compatibility for whackable asteroids (added force) // Version 62 - 5/26/2025 - Added some modular curve input data to turret firing packets; 5/31/2025 - Added another input +// Version 63 - 8/4/2026 - Added target forward speed to turret and flak fired packets // STANDALONE_ONLY #define MULTI_FS_SERVER_VERSION 63