Files
fs2open.github.com/code/object/collidedebrisweapon.cpp
Goober5000 de0a9ca9c1 add Hitpos as a hook variable for all collision hooks
Also slightly optimizes some of the hooks because the adding/removing of hook variables should be guarded by the same if() block that controls execution.
2020-09-09 20:04:58 -04:00

148 lines
5.8 KiB
C++

/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
#include "asteroid/asteroid.h"
#include "debris/debris.h"
#include "math/fvi.h"
#include "object/objcollide.h"
#include "object/object.h"
#include "scripting/scripting.h"
#include "scripting/api/objs/vecmath.h"
#include "weapon/weapon.h"
/**
* Checks debris-weapon collisions.
* @param pair obj_pair pointer to the two objects. pair->a is debris and pair->b is weapon.
* @return 1 if all future collisions between these can be ignored
*/
int collide_debris_weapon( obj_pair * pair )
{
vec3d hitpos, hitnormal;
object *pdebris = pair->a;
object *weapon_obj = pair->b;
Assert( pdebris->type == OBJ_DEBRIS );
Assert( weapon_obj->type == OBJ_WEAPON );
// first check the bounding spheres of the two objects.
int hit = fvi_segment_sphere(&hitpos, &weapon_obj->last_pos, &weapon_obj->pos, &pdebris->pos, pdebris->radius);
if (hit) {
hit = debris_check_collision(pdebris, weapon_obj, &hitpos, nullptr, &hitnormal );
if ( !hit )
return 0;
Script_system.SetHookObjects(4, "Self", weapon_obj, "Object", pdebris, "Weapon", weapon_obj, "Debris", pdebris);
Script_system.SetHookVar("Hitpos", 'o', scripting::api::l_Vector.Set(hitpos));
bool weapon_override = Script_system.IsConditionOverride(CHA_COLLIDEDEBRIS, weapon_obj);
Script_system.RemHookVars({ "Self", "Object", "Weapon", "Debris", "Hitpos" });
Script_system.SetHookObjects(4, "Self", pdebris, "Object", weapon_obj, "Weapon", weapon_obj, "Debris", pdebris);
Script_system.SetHookVar("Hitpos", 'o', scripting::api::l_Vector.Set(hitpos));
bool debris_override = Script_system.IsConditionOverride(CHA_COLLIDEWEAPON, pdebris);
Script_system.RemHookVars({ "Self", "Object", "Weapon", "Debris", "Hitpos" });
if(!weapon_override && !debris_override)
{
weapon_hit( weapon_obj, pdebris, &hitpos, -1, &hitnormal );
debris_hit( pdebris, weapon_obj, &hitpos, Weapon_info[Weapons[weapon_obj->instance].weapon_info_index].damage );
}
if (!(debris_override && !weapon_override))
{
Script_system.SetHookObjects(4, "Self", weapon_obj, "Object", pdebris, "Weapon", weapon_obj, "Debris", pdebris);
Script_system.SetHookVar("Hitpos", 'o', scripting::api::l_Vector.Set(hitpos));
Script_system.RunCondition(CHA_COLLIDEDEBRIS, weapon_obj);
Script_system.RemHookVars({ "Self", "Object", "Weapon", "Debris", "Hitpos" });
}
if ((debris_override && !weapon_override) || (!debris_override && !weapon_override))
{
Script_system.SetHookObjects(4, "Self", pdebris, "Object", weapon_obj, "Weapon", weapon_obj, "Debris", pdebris);
Script_system.SetHookVar("Hitpos", 'o', scripting::api::l_Vector.Set(hitpos));
Script_system.RunCondition(CHA_COLLIDEWEAPON, pdebris, Weapons[weapon_obj->instance].weapon_info_index);
Script_system.RemHookVars({ "Self", "Object", "Weapon", "Debris", "Hitpos" });
}
return 0;
} else {
return weapon_will_never_hit( weapon_obj, pdebris, pair );
}
}
/**
* Checks debris-weapon collisions.
* @param pair obj_pair pointer to the two objects. pair->a is debris and pair->b is weapon.
* @return 1 if all future collisions between these can be ignored
*/
int collide_asteroid_weapon( obj_pair * pair )
{
if (!Asteroids_enabled)
return 0;
vec3d hitpos, hitnormal;
object *pasteroid = pair->a;
object *weapon_obj = pair->b;
Assert( pasteroid->type == OBJ_ASTEROID);
Assert( weapon_obj->type == OBJ_WEAPON );
// first check the bounding spheres of the two objects.
int hit = fvi_segment_sphere(&hitpos, &weapon_obj->last_pos, &weapon_obj->pos, &pasteroid->pos, pasteroid->radius);
if (hit) {
hit = asteroid_check_collision(pasteroid, weapon_obj, &hitpos, nullptr, &hitnormal);
if ( !hit )
return 0;
Script_system.SetHookObjects(4, "Self", weapon_obj, "Object", pasteroid, "Weapon", weapon_obj, "Asteroid", pasteroid);
Script_system.SetHookVar("Hitpos", 'o', scripting::api::l_Vector.Set(hitpos));
bool weapon_override = Script_system.IsConditionOverride(CHA_COLLIDEASTEROID, weapon_obj);
Script_system.RemHookVars({ "Self", "Object", "Weapon", "Asteroid", "Hitpos" });
Script_system.SetHookObjects(4, "Self", pasteroid, "Object", weapon_obj, "Weapon", weapon_obj, "Asteroid", pasteroid);
Script_system.SetHookVar("Hitpos", 'o', scripting::api::l_Vector.Set(hitpos));
bool asteroid_override = Script_system.IsConditionOverride(CHA_COLLIDEWEAPON, pasteroid);
Script_system.RemHookVars({ "Self", "Object", "Weapon", "Asteroid", "Hitpos" });
if(!weapon_override && !asteroid_override)
{
weapon_hit( weapon_obj, pasteroid, &hitpos, -1, &hitnormal);
asteroid_hit( pasteroid, weapon_obj, &hitpos, Weapon_info[Weapons[weapon_obj->instance].weapon_info_index].damage );
}
if (!(asteroid_override && !weapon_override))
{
Script_system.SetHookObjects(4, "Self", weapon_obj, "Object", pasteroid, "Weapon", weapon_obj, "Asteroid", pasteroid);
Script_system.SetHookVar("Hitpos", 'o', scripting::api::l_Vector.Set(hitpos));
Script_system.RunCondition(CHA_COLLIDEASTEROID, weapon_obj);
Script_system.RemHookVars({ "Self", "Object", "Weapon", "Asteroid", "Hitpos" });
}
if ((asteroid_override && !weapon_override) || (!asteroid_override && !weapon_override))
{
Script_system.SetHookObjects(4, "Self", pasteroid, "Object", weapon_obj, "Weapon", weapon_obj, "Asteroid", pasteroid);
Script_system.SetHookVar("Hitpos", 'o', scripting::api::l_Vector.Set(hitpos));
Script_system.RunCondition(CHA_COLLIDEWEAPON, pasteroid, Weapons[weapon_obj->instance].weapon_info_index);
Script_system.RemHookVars({ "Self", "Object", "Weapon", "Asteroid", "Hitpos" });
}
return 0;
} else {
return weapon_will_never_hit( weapon_obj, pasteroid, pair );
}
}