#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <xs>
#include <engine>
new beampoint
public plugin_precache() {
beampoint = precache_model("sprites/laserbeam.spr")
}
public client_PreThink(player) {
if(is_user_bot(player))
return
shoot_laser(player)
}
public shoot_laser(player)
{
new tr = 0
new Float: vecSrc[3], Float: vecEnd[3]
new Float: v_angle[3]
pev(player, pev_v_angle, v_angle)
engfunc(EngFunc_MakeVectors, v_angle)
ExecuteHam(Ham_Player_GetGunPosition, player, vecSrc)
new Float: gpGlobals__v_forward[3]
global_get(glb_v_forward, gpGlobals__v_forward)
const Float: KNIFE_SWING_DISTANCE = 48.0
vecEnd[0] = vecSrc[0] + gpGlobals__v_forward[0] * KNIFE_SWING_DISTANCE
vecEnd[1] = vecSrc[1] + gpGlobals__v_forward[1] * KNIFE_SWING_DISTANCE
vecEnd[2] = vecSrc[2] + gpGlobals__v_forward[2] * KNIFE_SWING_DISTANCE
engfunc(EngFunc_TraceLine, vecSrc, vecEnd, DONT_IGNORE_MONSTERS, player, tr)
new Float: fraction
get_tr2(tr, TR_flFraction, fraction)
if (fraction >= 1.0) {
const head_hull = 3;
engfunc(EngFunc_TraceHull, vecSrc, vecEnd, DONT_IGNORE_MONSTERS, head_hull, player, tr)
get_tr2(tr, TR_flFraction, fraction)
if (fraction < 1.0) {
// Calculate the point of intersection of the line (or hull) and the object we hit
// This is and approximation of the "best" intersection
new pHit = get_tr2(tr, TR_pHit)
if (!pHit || (pHit > -1 && ExecuteHam(Ham_IsBSPModel, pHit))) {
#define VEC_DUCK_HULL_MIN Float: { -16.0, -16.0, -18.0 }
#define VEC_DUCK_HULL_MAX Float: { 16.0, 16.0, 32.0 }
FindHullIntersection(vecSrc, tr, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX, player)
}
// This is the point on the actual surface (the hull could have hit space)
new Float: vecEnd_old[3]
xs_vec_copy(vecEnd, vecEnd_old)
get_tr2(tr, TR_vecEndPos, vecEnd)
new Float: dist = vector_distance(vecEnd_old, vecEnd)
if(dist > 0.0) {
pHit = get_tr2(tr, TR_pHit)
client_print(player, print_chat, "FindHullIntersection() changes diff: %.1f (pHit: %i)}", dist, pHit) // watch this .............
}
}
}
draw_laser(vecSrc, vecEnd, 1)
}
stock FindHullIntersection(const Float: vecSrc[3], &iTrace, const Float: vecMins[3], const Float: vecMaxs[3], const iEntity) {
new iTempTrace;
new Float: flFraction;
new Float: flThisDistance;
new Float: vecEnd[3];
new Float: vecEndPos[3];
new Float: vecHullEnd[3];
new Float: vecMinMaxs[2][3];
new Float: flDistance = 999999.0;
xs_vec_copy(vecMins, vecMinMaxs[0]);
xs_vec_copy(vecMaxs, vecMinMaxs[1]);
get_tr2(iTrace, TR_vecEndPos, vecHullEnd);
xs_vec_sub(vecHullEnd, vecSrc, vecHullEnd);
xs_vec_mul_scalar(vecHullEnd, 2.0, vecHullEnd);
xs_vec_add(vecHullEnd, vecSrc, vecHullEnd);
engfunc(EngFunc_TraceLine, vecSrc, vecHullEnd, DONT_IGNORE_MONSTERS, iEntity, (iTempTrace = create_tr2()));
get_tr2(iTempTrace, TR_flFraction, flFraction);
if (flFraction < 1.0)
{
free_tr2(iTrace);
iTrace = iTempTrace;
return;
}
for (new j, k, i = 0; i < 2; i++)
{
for (j = 0; j < 2; j++)
{
for (k = 0; k < 2; k++)
{
vecEnd[0] = vecHullEnd[0] + vecMinMaxs[i][0];
vecEnd[1] = vecHullEnd[1] + vecMinMaxs[j][1];
vecEnd[2] = vecHullEnd[2] + vecMinMaxs[k][2];
engfunc(EngFunc_TraceLine, vecSrc, vecEnd, DONT_IGNORE_MONSTERS, iEntity, iTempTrace);
get_tr2(iTempTrace, TR_flFraction, flFraction);
if (flFraction < 1.0)
{
get_tr2(iTempTrace, TR_vecEndPos, vecEndPos);
xs_vec_sub(vecEndPos, vecSrc, vecEndPos);
if ((flThisDistance = xs_vec_len(vecEndPos)) < flDistance)
{
free_tr2(iTrace);
iTrace = iTempTrace;
flDistance = flThisDistance;
}
}
}
}
}
}
stock draw_laser(Float: start[3], Float: end[3], staytime = 1) {
message_begin(MSG_ALL, SVC_TEMPENTITY)
write_byte(TE_BEAMPOINTS)
engfunc(EngFunc_WriteCoord, start[0])
engfunc(EngFunc_WriteCoord, start[1])
engfunc(EngFunc_WriteCoord, start[2])
engfunc(EngFunc_WriteCoord, end[0])
engfunc(EngFunc_WriteCoord, end[1])
engfunc(EngFunc_WriteCoord, end[2])
write_short(beampoint)
write_byte(0)
write_byte(0)
write_byte(staytime) // In tenths of a second.
write_byte(10)
write_byte(1)
write_byte(255) // Red
write_byte(0) // Green
write_byte(0) // Blue
write_byte(127)
write_byte(1)
message_end()
}