Skip to content

Commit 2d7e47f

Browse files
BaezonMjnMixael
authored andcommitted
prop collision support
1 parent 3b68971 commit 2d7e47f

14 files changed

+1341
-53
lines changed

code/object/collidedebrisship.cpp

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "scripting/api/objs/model.h"
2121
#include "scripting/api/objs/vecmath.h"
2222
#include "playerman/player.h"
23+
#include "prop/prop.h"
2324
#include "ship/ship.h"
2425
#include "ship/shiphit.h"
2526

@@ -413,3 +414,266 @@ int collide_asteroid_ship( obj_pair * pair )
413414
return 0;
414415
}
415416
}
417+
418+
/**
419+
* Checks debris-prop collisions.
420+
* @param pair obj_pair pointer to the two objects. pair->a is debris and pair->b is prop.
421+
* @return 1 if all future collisions between these can be ignored
422+
*/
423+
int collide_debris_prop(obj_pair* pair)
424+
{
425+
float dist;
426+
object* debris_objp = pair->a;
427+
object* prop_objp = pair->b;
428+
429+
Assert(debris_objp->type == OBJ_DEBRIS);
430+
Assert(prop_objp->type == OBJ_PROP);
431+
432+
if (reject_due_collision_groups(debris_objp, prop_objp))
433+
return 0;
434+
435+
dist = vm_vec_dist(&debris_objp->pos, &prop_objp->pos);
436+
if (dist < debris_objp->radius + prop_objp->radius) {
437+
int hit;
438+
vec3d hitpos;
439+
// create and initialize ship_ship_hit_info struct
440+
collision_info_struct debris_hit_info;
441+
init_collision_info_struct(&debris_hit_info);
442+
443+
if (debris_objp->radius > prop_objp->radius) {
444+
debris_hit_info.heavy = debris_objp;
445+
debris_hit_info.light = prop_objp;
446+
}
447+
else {
448+
debris_hit_info.heavy = prop_objp;
449+
debris_hit_info.light = debris_objp;
450+
}
451+
452+
hit = prop_check_collision(prop_objp, debris_objp, &hitpos, &debris_hit_info);
453+
if (hit)
454+
{
455+
bool ship_override = false, debris_override = false;
456+
457+
// get submodel handle if scripting needs it
458+
bool has_submodel = (debris_hit_info.heavy_submodel_num >= 0);
459+
scripting::api::submodel_h smh(debris_hit_info.heavy_model_num, debris_hit_info.heavy_submodel_num);
460+
461+
// TODO PROP
462+
/*
463+
if (scripting::hooks::OnDebrisCollision->isActive()) {
464+
ship_override = scripting::hooks::OnDebrisCollision->isOverride(scripting::hooks::CollisionConditions{ {ship_objp, debris_objp} },
465+
scripting::hook_param_list(scripting::hook_param("Self", 'o', ship_objp),
466+
scripting::hook_param("Object", 'o', debris_objp),
467+
scripting::hook_param("Ship", 'o', ship_objp),
468+
scripting::hook_param("Debris", 'o', debris_objp),
469+
scripting::hook_param("Hitpos", 'o', hitpos)));
470+
}
471+
472+
if (scripting::hooks::OnShipCollision->isActive()) {
473+
debris_override = scripting::hooks::OnShipCollision->isOverride(scripting::hooks::CollisionConditions{ {ship_objp, debris_objp} },
474+
scripting::hook_param_list(scripting::hook_param("Self", 'o', debris_objp),
475+
scripting::hook_param("Object", 'o', ship_objp),
476+
scripting::hook_param("Ship", 'o', ship_objp),
477+
scripting::hook_param("Debris", 'o', debris_objp),
478+
scripting::hook_param("Hitpos", 'o', hitpos),
479+
scripting::hook_param("ShipSubmodel", 'o', scripting::api::l_Submodel.Set(smh), has_submodel && (debris_hit_info.heavy == ship_objp))));
480+
}*/
481+
482+
if (!ship_override && !debris_override)
483+
{
484+
// do collision physics
485+
calculate_ship_ship_collision_physics(&debris_hit_info);
486+
487+
if (debris_hit_info.impulse < 0.5f)
488+
return 0;
489+
490+
float debris_damage = debris_hit_info.impulse / debris_objp->phys_info.mass; // ie, delta velocity of debris
491+
492+
// apply damage to debris
493+
// no need for force, already handled in calculate_ship_ship_collision_physics
494+
debris_hit(debris_objp, prop_objp, &hitpos, debris_damage, nullptr); // speed => damage
495+
496+
collide_ship_ship_do_sound(&hitpos, prop_objp, debris_objp,false );
497+
}
498+
499+
if (scripting::hooks::OnDebrisCollision->isActive() && !(debris_override && !ship_override)) {
500+
// TODO PROP
501+
/*
502+
scripting::hooks::OnDebrisCollision->run(scripting::hooks::CollisionConditions{ {ship_objp, debris_objp} },
503+
scripting::hook_param_list(scripting::hook_param("Self", 'o', ship_objp),
504+
scripting::hook_param("Object", 'o', debris_objp),
505+
scripting::hook_param("Ship", 'o', ship_objp),
506+
scripting::hook_param("Debris", 'o', debris_objp),
507+
scripting::hook_param("Hitpos", 'o', hitpos)));
508+
*/
509+
}
510+
if (scripting::hooks::OnShipCollision->isActive() && ((debris_override && !ship_override) || (!debris_override && !ship_override)))
511+
{
512+
// TODO PROP
513+
/*
514+
scripting::hooks::OnShipCollision->run(scripting::hooks::CollisionConditions{ {ship_objp, debris_objp} },
515+
scripting::hook_param_list(scripting::hook_param("Self", 'o', debris_objp),
516+
scripting::hook_param("Object", 'o', ship_objp),
517+
scripting::hook_param("Ship", 'o', ship_objp),
518+
scripting::hook_param("Debris", 'o', debris_objp),
519+
scripting::hook_param("Hitpos", 'o', hitpos),
520+
scripting::hook_param("ShipSubmodel", 'o', scripting::api::l_Submodel.Set(smh), has_submodel && (debris_hit_info.heavy == ship_objp))));
521+
*/
522+
}
523+
524+
return 0;
525+
}
526+
}
527+
else { // Bounding spheres don't intersect, set timestamp for next collision check.
528+
float debris_speed;
529+
float time;
530+
531+
debris_speed = debris_objp->phys_info.speed;
532+
533+
time = 1000.0f * (dist - prop_objp->radius - debris_objp->radius - 10.0f) / (debris_speed); // 10.0f is a safety factor
534+
time -= 200.0f; // allow one frame slow frame at ~5 fps
535+
536+
if (time > 100) {
537+
pair->next_check_time = timestamp(fl2i(time));
538+
}
539+
else {
540+
pair->next_check_time = timestamp(0); // check next time
541+
}
542+
}
543+
544+
return 0;
545+
}
546+
547+
/**
548+
* Checks asteroid-prop collisions.
549+
* @param pair obj_pair pointer to the two objects. pair->a is asteroid and pair->b is prop.
550+
* @return 1 if all future collisions between these can be ignored
551+
*/
552+
int collide_asteroid_prop(obj_pair* pair)
553+
{
554+
if (!Asteroids_enabled)
555+
return 0;
556+
557+
float dist;
558+
object* asteroid_objp = pair->a;
559+
object* prop_objp = pair->b;
560+
561+
if (asteroid_objp->hull_strength < 0.0f)
562+
return 0;
563+
564+
Assert(asteroid_objp->type == OBJ_ASTEROID);
565+
Assert(prop_objp->type == OBJ_PROP);
566+
567+
dist = vm_vec_dist(&asteroid_objp->pos, &prop_objp->pos);
568+
569+
if (dist < asteroid_objp->radius + prop_objp->radius) {
570+
int hit;
571+
vec3d hitpos;
572+
// create and initialize ship_ship_hit_info struct
573+
collision_info_struct asteroid_hit_info;
574+
init_collision_info_struct(&asteroid_hit_info);
575+
576+
if (asteroid_objp->radius > prop_objp->radius) {
577+
asteroid_hit_info.heavy = asteroid_objp;
578+
asteroid_hit_info.light = prop_objp;
579+
}
580+
else {
581+
asteroid_hit_info.heavy = prop_objp;
582+
asteroid_hit_info.light = asteroid_objp;
583+
}
584+
585+
hit = prop_check_collision(prop_objp, prop_objp, &hitpos, &asteroid_hit_info);
586+
if (hit)
587+
{
588+
bool ship_override = false, asteroid_override = false;
589+
590+
// get submodel handle if scripting needs it
591+
bool has_submodel = (asteroid_hit_info.heavy_submodel_num >= 0);
592+
scripting::api::submodel_h smh(asteroid_hit_info.heavy_model_num, asteroid_hit_info.heavy_submodel_num);
593+
594+
//Scripting support (WMC)
595+
// TODO PROP
596+
/*
597+
if (scripting::hooks::OnAsteroidCollision->isActive()) {
598+
ship_override = scripting::hooks::OnAsteroidCollision->isOverride(scripting::hooks::CollisionConditions{ {ship_objp, asteroid_objp} },
599+
scripting::hook_param_list(scripting::hook_param("Self", 'o', ship_objp),
600+
scripting::hook_param("Object", 'o', asteroid_objp),
601+
scripting::hook_param("Ship", 'o', ship_objp),
602+
scripting::hook_param("Asteroid", 'o', asteroid_objp),
603+
scripting::hook_param("Hitpos", 'o', hitpos)));
604+
}
605+
if (scripting::hooks::OnShipCollision->isActive()) {
606+
asteroid_override = scripting::hooks::OnShipCollision->isOverride(scripting::hooks::CollisionConditions{ {ship_objp, asteroid_objp} },
607+
scripting::hook_param_list(scripting::hook_param("Self", 'o', asteroid_objp),
608+
scripting::hook_param("Object", 'o', ship_objp),
609+
scripting::hook_param("Ship", 'o', ship_objp),
610+
scripting::hook_param("Asteroid", 'o', asteroid_objp),
611+
scripting::hook_param("Hitpos", 'o', hitpos),
612+
scripting::hook_param("ShipSubmodel", 'o', scripting::api::l_Submodel.Set(smh), has_submodel && (asteroid_hit_info.heavy == ship_objp))));
613+
}*/
614+
615+
if (!ship_override && !asteroid_override)
616+
{
617+
float asteroid_damage;
618+
619+
vec3d asteroid_vel = asteroid_objp->phys_info.vel;
620+
621+
// do collision physics
622+
calculate_ship_ship_collision_physics(&asteroid_hit_info);
623+
624+
if (asteroid_hit_info.impulse < 0.5f)
625+
return 0;
626+
627+
asteroid_damage = asteroid_hit_info.impulse / asteroid_objp->phys_info.mass; // ie, delta velocity of asteroid
628+
629+
// apply damage to asteroid
630+
asteroid_hit(asteroid_objp, prop_objp, &hitpos, asteroid_damage, nullptr); // speed => damage
631+
632+
collide_ship_ship_do_sound(&hitpos, prop_objp, asteroid_objp, false);
633+
}
634+
635+
// TODO PROP
636+
/*
637+
if (scripting::hooks::OnAsteroidCollision->isActive() && !(asteroid_override && !ship_override)) {
638+
scripting::hooks::OnAsteroidCollision->run(scripting::hooks::CollisionConditions{ {ship_objp, asteroid_objp} },
639+
scripting::hook_param_list(scripting::hook_param("Self", 'o', ship_objp),
640+
scripting::hook_param("Object", 'o', asteroid_objp),
641+
scripting::hook_param("Ship", 'o', ship_objp),
642+
scripting::hook_param("Asteroid", 'o', asteroid_objp),
643+
scripting::hook_param("Hitpos", 'o', hitpos)));
644+
}
645+
if (scripting::hooks::OnShipCollision->isActive() && ((asteroid_override && !ship_override) || (!asteroid_override && !ship_override)))
646+
{
647+
scripting::hooks::OnShipCollision->run(scripting::hooks::CollisionConditions{ {ship_objp, asteroid_objp} },
648+
scripting::hook_param_list(scripting::hook_param("Self", 'o', asteroid_objp),
649+
scripting::hook_param("Object", 'o', ship_objp),
650+
scripting::hook_param("Ship", 'o', ship_objp),
651+
scripting::hook_param("Asteroid", 'o', asteroid_objp),
652+
scripting::hook_param("Hitpos", 'o', hitpos),
653+
scripting::hook_param("ShipSubmodel", 'o', scripting::api::l_Submodel.Set(smh), has_submodel && (asteroid_hit_info.heavy == ship_objp))));
654+
}*/
655+
656+
return 0;
657+
}
658+
659+
return 0;
660+
}
661+
else {
662+
// estimate earliest time at which pair can hit
663+
float asteroid_max_speed, time;
664+
665+
asteroid_max_speed = vm_vec_mag(&asteroid_objp->phys_info.vel); // Asteroid... vel gets reset, not max vel.z
666+
asteroid_max_speed = MAX(asteroid_max_speed, 10.0f);
667+
668+
time = 1000.0f * (dist - prop_objp->radius - asteroid_objp->radius - 10.0f) / (asteroid_max_speed); // 10.0f is a safety factor
669+
time -= 200.0f; // allow one frame slow frame at ~5 fps
670+
671+
if (time > 100) {
672+
pair->next_check_time = timestamp(fl2i(time));
673+
}
674+
else {
675+
pair->next_check_time = timestamp(0); // check next time
676+
}
677+
return 0;
678+
}
679+
}

code/object/collidepropdebris.cpp

Lines changed: 0 additions & 1 deletion
This file was deleted.

code/object/collidepropship.cpp

Lines changed: 0 additions & 1 deletion
This file was deleted.

code/object/collidepropweapon.cpp

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)