@@ -36,7 +36,6 @@ using ship_weapon_collision_data = std::tuple<std::optional<mc_info>, int, bool,
3636
3737extern int Game_skill_level;
3838extern float ai_endangered_time (const object *ship_objp, const object *weapon_objp);
39- static int check_inside_radius_for_big_objects ( object *ship, object *weapon_obj, obj_pair *pair );
4039static std::tuple<bool , bool , ship_weapon_collision_data> check_inside_radius_for_big_ships ( object *ship, object *weapon_obj, obj_pair *pair );
4140extern float flFrametime;
4241
@@ -618,9 +617,7 @@ static void ship_weapon_process_collision(obj_pair* pair, const std::any& collis
618617 ship_weapon_process_collision (pair, std::any_cast<ship_weapon_collision_data>(collision_data));
619618}
620619
621-
622-
623- static int prop_weapon_check_collision (object* prop_objp, object* weapon_objp, float time_limit = 0 .0f , int * next_hit = nullptr )
620+ static std::tuple<bool , bool , ship_weapon_collision_data> prop_weapon_check_collision (object* prop_objp, object* weapon_objp, float time_limit = 0 .0f , int * next_hit = nullptr )
624621{
625622 weapon* wp;
626623 weapon_info* wip;
@@ -683,12 +680,24 @@ static int prop_weapon_check_collision(object* prop_objp, object* weapon_objp, f
683680 *next_hit = (int )(1000 .0f * (mc.hit_dist * (flFrametime + time_limit) - flFrametime));
684681 if (*next_hit > 0 )
685682 // if hit occurs outside of this frame, do not do damage
686- return 1 ;
683+ valid_hit_occurred = 1 ;
684+ bool postproc = true ;
685+ bool recheck = false ;
686+ // most of this data is irrevelant for props but let's match it to make it easy
687+ ship_weapon_collision_data cd{
688+ mc,
689+ -1 ,
690+ postproc,
691+ -1 ,
692+ -1 ,
693+ ZERO_VECTOR
694+ };
695+ return {postproc, recheck, cd};
687696 }
688697
689698 if (hit)
690699 {
691- wp->collisionInfo = new mc_info; // The weapon will free this memory later
700+ /* wp->collisionInfo = new mc_info; // The weapon will free this memory later
692701 *wp->collisionInfo = mc;
693702
694703 bool prop_override = false, weapon_override = false;
@@ -717,7 +726,7 @@ static int prop_weapon_check_collision(object* prop_objp, object* weapon_objp, f
717726 }
718727
719728 if (!prop_override && !weapon_override) {
720- weapon_hit (weapon_objp, prop_objp, &mc.hit_point_world , MISS_SHIELDS, &mc.hit_normal , &mc.hit_point , mc.hit_submodel );
729+ weapon_hit(weapon_objp, prop_objp, &mc.hit_point_world, MISS_SHIELDS); // , &mc.hit_normal, &mc.hit_point, mc.hit_submodel); This was changed by PR 6785 and the changes were not documented
721730 }
722731
723732 if (scripting::hooks::OnWeaponCollision->isActive() && !(weapon_override && !prop_override)) {
@@ -736,10 +745,87 @@ static int prop_weapon_check_collision(object* prop_objp, object* weapon_objp, f
736745 scripting::hook_param("Weapon", 'o', weapon_objp),
737746 scripting::hook_param("Hitpos", 'o', mc.hit_point_world),
738747 scripting::hook_param("PropSubmodel", 'o', scripting::api::l_Submodel.Set(smh), has_submodel)));
739- }
748+ }*/
749+ valid_hit_occurred = 1 ;
740750 }
741751
742- return valid_hit_occurred;
752+ bool postproc = (valid_hit_occurred != 0 );
753+ bool recheck = (valid_hit_occurred == 0 );
754+ // most of this data is irrevelant for props but let's match it to make it easy
755+ ship_weapon_collision_data cd{
756+ (valid_hit_occurred ? mc : mc_info{}),
757+ -1 ,
758+ postproc,
759+ -1 ,
760+ -1 ,
761+ ZERO_VECTOR
762+ };
763+
764+ return {postproc, recheck, cd};
765+ }
766+
767+ static void prop_weapon_process_collision (obj_pair* pair, const ship_weapon_collision_data& cd)
768+ {
769+ object* prop_objp = pair->a ;
770+ object* weapon_objp = pair->b ;
771+
772+ auto mc_opt = std::get<0 >(cd);
773+ if (!mc_opt) {
774+ return ;
775+ }
776+ const mc_info& mc = *mc_opt;
777+
778+ weapon* wp = &Weapons[weapon_objp->instance ];
779+ wp->collisionInfo = new mc_info (mc);
780+
781+ bool prop_override = false ;
782+ bool weapon_override = false ;
783+
784+ bool has_submodel = (mc.hit_submodel >= 0 );
785+ scripting::api::submodel_h smh (mc.model_num , mc.hit_submodel );
786+
787+ if (scripting::hooks::OnWeaponCollision->isActive ()) {
788+ prop_override = scripting::hooks::OnWeaponCollision->isOverride (
789+ scripting::hooks::CollisionConditions{{prop_objp, weapon_objp}},
790+ scripting::hook_param_list (scripting::hook_param (" Self" , ' o' , prop_objp),
791+ scripting::hook_param (" Object" , ' o' , weapon_objp),
792+ scripting::hook_param (" Prop" , ' o' , prop_objp),
793+ scripting::hook_param (" Weapon" , ' o' , weapon_objp),
794+ scripting::hook_param (" Hitpos" , ' o' , mc.hit_point_world )));
795+ }
796+
797+ if (scripting::hooks::OnPropCollision->isActive ()) {
798+ weapon_override = scripting::hooks::OnPropCollision->isOverride (
799+ scripting::hooks::CollisionConditions{{prop_objp, weapon_objp}},
800+ scripting::hook_param_list (scripting::hook_param (" Self" , ' o' , weapon_objp),
801+ scripting::hook_param (" Object" , ' o' , prop_objp),
802+ scripting::hook_param (" Prop" , ' o' , prop_objp),
803+ scripting::hook_param (" Weapon" , ' o' , weapon_objp),
804+ scripting::hook_param (" Hitpos" , ' o' , mc.hit_point_world ),
805+ scripting::hook_param (" PropSubmodel" , ' o' , scripting::api::l_Submodel.Set (smh), has_submodel)));
806+ }
807+
808+ if (!prop_override && !weapon_override) {
809+ weapon_hit (weapon_objp, prop_objp, &mc.hit_point_world , MISS_SHIELDS);
810+ }
811+
812+ if (scripting::hooks::OnWeaponCollision->isActive () && !(weapon_override && !prop_override)) {
813+ scripting::hooks::OnWeaponCollision->run (scripting::hooks::CollisionConditions{{prop_objp, weapon_objp}},
814+ scripting::hook_param_list (scripting::hook_param (" Self" , ' o' , prop_objp),
815+ scripting::hook_param (" Object" , ' o' , weapon_objp),
816+ scripting::hook_param (" Prop" , ' o' , prop_objp),
817+ scripting::hook_param (" Weapon" , ' o' , weapon_objp),
818+ scripting::hook_param (" Hitpos" , ' o' , mc.hit_point_world )));
819+ }
820+ if (scripting::hooks::OnPropCollision->isActive () && !prop_override) {
821+ scripting::hooks::OnPropCollision->run (scripting::hooks::CollisionConditions{{prop_objp, weapon_objp}},
822+ scripting::hook_param_list (scripting::hook_param (" Self" , ' o' , weapon_objp),
823+ scripting::hook_param (" Object" , ' o' , prop_objp),
824+ scripting::hook_param (" Prop" , ' o' , prop_objp),
825+ scripting::hook_param (" Weapon" , ' o' , weapon_objp),
826+ scripting::hook_param (" Hitpos" , ' o' , mc.hit_point_world ),
827+ scripting::hook_param (" PropSubmodel" , ' o' , scripting::api::l_Submodel.Set (smh), has_submodel)));
828+ }
743829}
744830
745831
@@ -857,7 +943,6 @@ collision_result collide_ship_weapon_check( obj_pair * pair )
857943 */
858944int collide_prop_weapon (obj_pair* pair)
859945{
860- int did_hit;
861946 object* prop = pair->a ;
862947 object* weapon_obj = pair->b ;
863948
@@ -883,13 +968,23 @@ int collide_prop_weapon(obj_pair* pair)
883968 // Note: culling ships with auto spread shields seems to waste more performance than it saves,
884969 // so we're not doing that here
885970 if (vm_vec_dist_squared (&prop->pos , &weapon_obj->pos ) < (1 .2f * prop->radius * prop->radius )) {
886- return check_inside_radius_for_big_objects (prop, weapon_obj, pair);
971+ auto [do_postproc, never_hits, collision_data] =
972+ check_inside_radius_for_big_ships (prop, weapon_obj, pair);
973+
974+ if (do_postproc) {
975+ prop_weapon_process_collision (pair, collision_data);
976+ }
977+ return never_hits;
887978 }
888979 }
889980
890- did_hit = prop_weapon_check_collision (prop, weapon_obj);
981+ auto [do_postproc, does_not_hit, collision_data] = prop_weapon_check_collision (prop, weapon_obj);
982+
983+ if (do_postproc) {
984+ prop_weapon_process_collision (pair, collision_data);
985+ }
891986
892- if (!did_hit ) {
987+ if (does_not_hit ) {
893988 // Since we didn't hit, check to see if we can disable all future collisions
894989 // between these two.
895990 return weapon_will_never_hit (weapon_obj, prop, pair);
@@ -929,7 +1024,7 @@ static float estimate_ship_speed_upper_limit( object *ship, float time )
9291024 * @return 1 if pair can be culled
9301025 * @return 0 if pair can not be culled
9311026 */
932- static std::tuple<bool , bool , ship_weapon_collision_data> check_inside_radius_for_big_ships ( object *ship , object *weapon_obj, obj_pair *pair )
1027+ static std::tuple<bool , bool , ship_weapon_collision_data> check_inside_radius_for_big_ships ( object *big_obj , object *weapon_obj, obj_pair *pair )
9331028{
9341029 vec3d error_vel; // vel perpendicular to laser
9351030 float error_vel_mag; // magnitude of error_vel
@@ -967,13 +1062,15 @@ static std::tuple<bool, bool, ship_weapon_collision_data> check_inside_radius_fo
9671062 // Note: when estimated hit time is less than 200 ms, look at every frame
9681063 int hit_time; // estimated time of hit in ms
9691064 // modify the collision check to do damage if hit_time is negative (ie, hit occurs in this frame)
970- bool hit = false ;
971- if (big_obj->type == OBJ_SHIP)
972- hit = ship_weapon_check_collision (big_obj, weapon_obj, limit_time, &hit_time);
973- else // OBJ_PROP
974- hit = prop_weapon_check_collision (big_obj, weapon_obj, limit_time, &hit_time);
1065+ bool do_postproc, does_not_hit;
1066+ ship_weapon_collision_data collision_data;
1067+
1068+ if (big_obj->type == OBJ_PROP) {
1069+ std::tie (do_postproc, does_not_hit, collision_data) = prop_weapon_check_collision (big_obj, weapon_obj, limit_time, &hit_time);
1070+ } else {
1071+ std::tie (do_postproc, does_not_hit, collision_data) = ship_weapon_check_collision (big_obj, weapon_obj, limit_time, &hit_time);
1072+ }
9751073
976- const auto & [do_postproc, does_not_hit, collision_data] = ship_weapon_check_collision ( ship, weapon_obj, limit_time, &hit_time );
9771074 // modify ship_weapon_check_collision to do damage if hit_time is negative (ie, hit occurs in this frame)
9781075 if ( !does_not_hit ) {
9791076 // hit occured in while in sphere
0 commit comments