mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 18:31:26 -10:00
* add new conditions * don't worry about it * implement new conditions * bugfixing * handle pokethrough differently * clang for the clang god * appeasement * to the last i grapple with thee * from hell's heart etc * bugfixing * support hits while dying * fix shield math, cleanup * fix memory error
200 lines
8.0 KiB
C++
200 lines
8.0 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/global_hooks.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 );
|
|
|
|
if (reject_due_collision_groups(pdebris, weapon_obj))
|
|
return 0;
|
|
|
|
// 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;
|
|
|
|
bool weapon_override = false, debris_override = false;
|
|
|
|
if (scripting::hooks::OnDebrisCollision->isActive()) {
|
|
weapon_override = scripting::hooks::OnDebrisCollision->isOverride(scripting::hooks::CollisionConditions{ {weapon_obj, pdebris} },
|
|
scripting::hook_param_list(scripting::hook_param("Self", 'o', weapon_obj),
|
|
scripting::hook_param("Object", 'o', pdebris),
|
|
scripting::hook_param("Weapon", 'o', weapon_obj),
|
|
scripting::hook_param("Debris", 'o', pdebris),
|
|
scripting::hook_param("Hitpos", 'o', hitpos)));
|
|
}
|
|
if (scripting::hooks::OnWeaponCollision->isActive()) {
|
|
debris_override = scripting::hooks::OnWeaponCollision->isOverride(scripting::hooks::CollisionConditions{ {weapon_obj, pdebris} },
|
|
scripting::hook_param_list(scripting::hook_param("Self", 'o', pdebris),
|
|
scripting::hook_param("Object", 'o', weapon_obj),
|
|
scripting::hook_param("Weapon", 'o', weapon_obj),
|
|
scripting::hook_param("Debris", 'o', pdebris),
|
|
scripting::hook_param("Hitpos", 'o', hitpos)));
|
|
}
|
|
|
|
if(!weapon_override && !debris_override)
|
|
{
|
|
vec3d force = weapon_obj->phys_info.vel * Weapon_info[Weapons[weapon_obj->instance].weapon_info_index].mass;
|
|
bool armed = weapon_hit( weapon_obj, pdebris, &hitpos, -1 );
|
|
float damage = Weapon_info[Weapons[weapon_obj->instance].weapon_info_index].damage;
|
|
std::array<std::optional<ConditionData>, NumHitTypes> impact_data = {};
|
|
impact_data[static_cast<std::underlying_type_t<HitType>>(HitType::HULL)] = ConditionData {
|
|
SpecialImpactCondition::DEBRIS,
|
|
HitType::HULL,
|
|
damage,
|
|
pdebris->hull_strength,
|
|
Debris[pdebris->instance].max_hull,
|
|
};
|
|
maybe_play_conditional_impacts(impact_data, weapon_obj, pdebris, armed, -1, &hitpos, nullptr, &hitnormal);
|
|
debris_hit( pdebris, weapon_obj, &hitpos, damage , &force);
|
|
}
|
|
|
|
if (scripting::hooks::OnDebrisCollision->isActive() && !(debris_override && !weapon_override))
|
|
{
|
|
scripting::hooks::OnDebrisCollision->run(scripting::hooks::CollisionConditions{ {weapon_obj, pdebris} },
|
|
scripting::hook_param_list(scripting::hook_param("Self", 'o', weapon_obj),
|
|
scripting::hook_param("Object", 'o', pdebris),
|
|
scripting::hook_param("Weapon", 'o', weapon_obj),
|
|
scripting::hook_param("Debris", 'o', pdebris),
|
|
scripting::hook_param("Hitpos", 'o', hitpos)));
|
|
}
|
|
|
|
if (scripting::hooks::OnWeaponCollision->isActive() && ((debris_override && !weapon_override) || (!debris_override && !weapon_override)))
|
|
{
|
|
scripting::hooks::OnWeaponCollision->run(scripting::hooks::CollisionConditions{ {weapon_obj, pdebris} },
|
|
scripting::hook_param_list(scripting::hook_param("Self", 'o', pdebris),
|
|
scripting::hook_param("Object", 'o', weapon_obj),
|
|
scripting::hook_param("Weapon", 'o', weapon_obj),
|
|
scripting::hook_param("Debris", 'o', pdebris),
|
|
scripting::hook_param("Hitpos", 'o', 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;
|
|
|
|
bool weapon_override = false, asteroid_override = false;
|
|
|
|
if (scripting::hooks::OnAsteroidCollision->isActive()) {
|
|
weapon_override = scripting::hooks::OnAsteroidCollision->isOverride(scripting::hooks::CollisionConditions{ {weapon_obj, pasteroid} },
|
|
scripting::hook_param_list(scripting::hook_param("Self", 'o', weapon_obj),
|
|
scripting::hook_param("Object", 'o', pasteroid),
|
|
scripting::hook_param("Weapon", 'o', weapon_obj),
|
|
scripting::hook_param("Asteroid", 'o', pasteroid),
|
|
scripting::hook_param("Hitpos", 'o', hitpos)));
|
|
}
|
|
if (scripting::hooks::OnWeaponCollision->isActive()) {
|
|
asteroid_override = scripting::hooks::OnWeaponCollision->isOverride(scripting::hooks::CollisionConditions{ {weapon_obj, pasteroid} },
|
|
scripting::hook_param_list(scripting::hook_param("Self", 'o', pasteroid),
|
|
scripting::hook_param("Object", 'o', weapon_obj),
|
|
scripting::hook_param("Weapon", 'o', weapon_obj),
|
|
scripting::hook_param("Asteroid", 'o', pasteroid),
|
|
scripting::hook_param("Hitpos", 'o', hitpos)));
|
|
}
|
|
|
|
if(!weapon_override && !asteroid_override)
|
|
{
|
|
vec3d force = weapon_obj->phys_info.vel * Weapon_info[Weapons[weapon_obj->instance].weapon_info_index].mass;
|
|
bool armed = weapon_hit( weapon_obj, pasteroid, &hitpos, -1);
|
|
float damage = Weapon_info[Weapons[weapon_obj->instance].weapon_info_index].damage;
|
|
std::array<std::optional<ConditionData>, NumHitTypes> impact_data = {};
|
|
impact_data[static_cast<std::underlying_type_t<HitType>>(HitType::HULL)] = ConditionData {
|
|
SpecialImpactCondition::DEBRIS,
|
|
HitType::HULL,
|
|
damage,
|
|
pasteroid->hull_strength,
|
|
Asteroid_info[Asteroids[pasteroid->instance].asteroid_type].initial_asteroid_strength,
|
|
};
|
|
maybe_play_conditional_impacts(impact_data, weapon_obj, pasteroid, armed, -1, &hitpos, nullptr, &hitnormal);
|
|
asteroid_hit( pasteroid, weapon_obj, &hitpos, damage, &force );
|
|
}
|
|
|
|
if (scripting::hooks::OnAsteroidCollision->isActive() && !(asteroid_override && !weapon_override))
|
|
{
|
|
scripting::hooks::OnAsteroidCollision->run(scripting::hooks::CollisionConditions{ {weapon_obj, pasteroid} },
|
|
scripting::hook_param_list(scripting::hook_param("Self", 'o', weapon_obj),
|
|
scripting::hook_param("Object", 'o', pasteroid),
|
|
scripting::hook_param("Weapon", 'o', weapon_obj),
|
|
scripting::hook_param("Asteroid", 'o', pasteroid),
|
|
scripting::hook_param("Hitpos", 'o', hitpos)));
|
|
}
|
|
|
|
if (scripting::hooks::OnWeaponCollision->isActive() && ((asteroid_override && !weapon_override) || (!asteroid_override && !weapon_override)))
|
|
{
|
|
scripting::hooks::OnWeaponCollision->run(scripting::hooks::CollisionConditions{ {weapon_obj, pasteroid} },
|
|
scripting::hook_param_list(scripting::hook_param("Self", 'o', pasteroid),
|
|
scripting::hook_param("Object", 'o', weapon_obj),
|
|
scripting::hook_param("Weapon", 'o', weapon_obj),
|
|
scripting::hook_param("Asteroid", 'o', pasteroid),
|
|
scripting::hook_param("Hitpos", 'o', hitpos)));
|
|
}
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
return weapon_will_never_hit( weapon_obj, pasteroid, pair );
|
|
}
|
|
}
|