Files
2025-04-15 22:27:20 -04:00

307 lines
8.0 KiB
SourcePawn

#pragma semicolon 1
#include <sourcemod>
#if defined INFO_INCLUDES
#include "../info/constants.sp"
#include "../info/enums.sp"
#include "../info/variables.sp"
#endif
/**
* Creates a beam line.
*
* @param iClient The client.
* @param fStart The start point.
* @param fEnd The end point.
* @param fDuration The duration it should appear (in seconds).
* @param iColors The colors.
* @noreturn
*/
stock void CreateBeamLine(int iClient, float fStart[3], float fEnd[3], float fDuration = 5.0, const int[] iColors = { 255, 0, 0, 255 } ) {
int iColors2[4];
iColors2[0] = iColors[0];
iColors2[1] = iColors[1];
iColors2[2] = iColors[2];
iColors2[3] = iColors[3];
TE_SetupBeamPoints(fStart, fEnd, g_iLaserMaterial, g_iHaloMaterial, 0, 0, fDuration + 0.1, 1.0, 1.0, 1, 0.0, iColors2, 0);
if (fDuration == 0.0) {
DataPack hPack = new DataPack();
CreateDataTimer(fDuration, Timer_CreateBeam, hPack);
hPack.WriteCell(iClient);
hPack.WriteFloat(fDuration);
hPack.WriteFloat(fStart[0]);
hPack.WriteFloat(fStart[1]);
hPack.WriteFloat(fStart[2]);
hPack.WriteFloat(fEnd[0]);
hPack.WriteFloat(fEnd[1]);
hPack.WriteFloat(fEnd[2]);
hPack.WriteCell(iColors[0]);
hPack.WriteCell(iColors[1]);
hPack.WriteCell(iColors[2]);
hPack.WriteCell(iColors[3]);
}
TE_SendToAll();
}
public Action Timer_CreateBeam(Handle hTimer, DataPack hPack) {
int iClient, iColors[4];
float fDuration, fStart[3], fEnd[3];
hPack.Reset();
iClient = hPack.ReadCell();
fDuration = hPack.ReadFloat();
fStart[0] = hPack.ReadFloat();
fStart[1] = hPack.ReadFloat();
fStart[2] = hPack.ReadFloat();
fEnd[0] = hPack.ReadFloat();
fEnd[1] = hPack.ReadFloat();
fEnd[2] = hPack.ReadFloat();
iColors[0] = hPack.ReadCell();
iColors[1] = hPack.ReadCell();
iColors[2] = hPack.ReadCell();
iColors[3] = hPack.ReadCell();
CreateBeamLine(iClient, fStart, fEnd, fDuration, iColors);
return Plugin_Stop;
}
/**
* Creates a beam box.
*
* @param iClient The client.
* @param fStart The start point.
* @param fEnd The end point.
* @param fDuration The duration it should appear (in seconds).
* @param iColors The colors.
* @noreturn
*/
stock void CreateBeamBox(int iClient, float fStart[3], float fEnd[3], float fDuration = 5.0, const int[] iColors = { 255, 0, 0, 255 } ) {
float fPoint[8][3];
CopyVector(fStart, fPoint[0]);
CopyVector(fEnd, fPoint[7]);
CreateZonePoints(fPoint);
for (int i = 0, i2 = 3; i2 >= 0; i += i2--) {
for (int j = 1; j <= 7; j += (j / 2) + 1) {
if (j != 7 - i) {
CreateBeamLine(iClient, fPoint[i], fPoint[j], fDuration, iColors);
}
}
}
}
/**
* Creates all 8 zone points by using start and end point.
*
* @param fPoint The array to store the points in.
* @noreturn
*/
stock void CreateZonePoints(float fPoint[8][3]) {
for (int i = 1; i < 7; i++) {
for (int j = 0; j < 3; j++) {
fPoint[i][j] = fPoint[((i >> (2 - j)) & 1) * 7][j];
}
}
}
/**
* Creates all an beam box around a client.
*
* @param iClient The client.
* @param fStart The start point.
* @param fEnd The end point.
* @param fDuration The duration it should appear (in seconds).
* @param iColors The colors.
* @noreturn
*/
stock void CreateBeamBoxAroundClient(int iClient, float fDistance, bool OnlyPlayerHeight = true, float fDuration = 5.0, const int[] iColors = { 255, 0, 0, 255 } ) {
if (!IsValidClient(iClient) || !IsClientConnected(iClient) || !IsClientInGame(iClient) || !IsPlayerAlive(iClient)) {
return;
}
float fLocation[3], fStart[3], fEnd[3];
GetClientAbsOrigin(iClient, fLocation);
if (OnlyPlayerHeight) {
fStart[0] = fLocation[0] - fDistance;
fStart[1] = fLocation[1] - fDistance;
fStart[2] = fLocation[2];
fEnd[0] = fLocation[0] + fDistance;
fEnd[1] = fLocation[1] + fDistance;
fEnd[2] = fLocation[2] + 83;
} else {
fStart[0] = fLocation[0] - fDistance;
fStart[1] = fLocation[1] - fDistance;
fStart[2] = fLocation[2] - fDistance;
fEnd[0] = fLocation[0] + fDistance;
fEnd[1] = fLocation[1] + fDistance;
fEnd[2] = fLocation[2] + 83 + fDistance;
}
CreateBeamBox(iClient, fStart, fEnd, fDuration, iColors);
float fPoint[8][3];
CopyVector(fStart, fPoint[0]);
CopyVector(fEnd, fPoint[7]);
CreateZonePoints(fPoint);
CopyZone(fPoint, g_fBeamPoints[iClient]);
}
/**
* Copies one float vector onto another one.
*
* @param fSource The vector to copy.
* @param fDestination The destination vector.
* @noreturn
*/
stock void CopyVector(float fSource[3], float fDestination[3]) {
for (int i = 0; i < sizeof(fSource); i++) {
fDestination[i] = fSource[i];
}
}
/**
* Copies one zone array onto another one.
*
* @param fSource The array to copy.
* @param fDestination The destination array.
* @noreturn
*/
stock void CopyZone(float fSource[8][3], float fDestination[8][3]) {
for (int i = 0; i < sizeof(fSource); i++) {
for (int j = 0; j < sizeof(fSource[]); j++) {
fDestination[i][j] = fSource[i][j];
}
}
}
/**
* Checkes if an entity is inside a zone.
*
* @param iClient The entity.
* @param fZone The zone array.
* @return True if inside, false otherwise.
*/
stock bool IsEntityInZone(int iEntity, float fZone[8][3], float fDifferenceZ) {
float fEntityPosition[3];
GetEntPropVector(iEntity, Prop_Send, "m_vecOrigin", fEntityPosition);
fEntityPosition[2] += fDifferenceZ;
return IsPointInZone(fEntityPosition, fZone);
}
/**
* Checkes if a client is inside a zone.
*
* @param iClient The client.
* @param fPoint The zone array.
* @return True if inside, false otherwise.
*/
stock bool IsClientInZone(int iClient, float fPoint[8][3]) {
float fPlayerPosition[3], fPlayerPoint[8][3];
GetEntPropVector(iClient, Prop_Send, "m_vecOrigin", fPlayerPosition);
fPlayerPosition[2] += 41.5;
fPlayerPoint[0][0] = fPlayerPosition[0] - 12.0;
fPlayerPoint[0][1] = fPlayerPosition[1] - 12.0;
fPlayerPoint[0][2] = fPlayerPosition[2] - 20.0;
fPlayerPoint[7][0] = fPlayerPosition[0] + 12.0;
fPlayerPoint[7][1] = fPlayerPosition[1] + 12.0;
fPlayerPoint[7][2] = fPlayerPosition[2] + 20.0;
CreateZonePoints(fPlayerPoint);
return Box3DIntersects(fPlayerPoint, fPoint);
}
/**
* Draws a bounding box around a client.
*
* @param iClient The client.
* @noreturn
*/
stock void DrawClientBoundingBox(int iClient) {
float fPlayerPosition[3], fPlayerPoint[8][3];
GetEntPropVector(iClient, Prop_Send, "m_vecOrigin", fPlayerPosition);
fPlayerPosition[2] += 41.5;
fPlayerPoint[0][0] = fPlayerPosition[0] - 12.0;
fPlayerPoint[0][1] = fPlayerPosition[1] - 12.0;
fPlayerPoint[0][2] = fPlayerPosition[2] - 20.0;
fPlayerPoint[7][0] = fPlayerPosition[0] + 12.0;
fPlayerPoint[7][1] = fPlayerPosition[1] + 12.0;
fPlayerPoint[7][2] = fPlayerPosition[2] + 20.0;
CreateZonePoints(fPlayerPoint);
CreateBeamBox(iClient, fPlayerPoint[0], fPlayerPoint[7]);
}
/**
* Checkes if a zone intersects with another zone.
*
* @param fCheck The 1st zone array.
* @param fSource The 2nd zone array.
* @return True if intersects, false otherwise.
*/
stock bool Box3DIntersects(float fCheck[8][3], float fSource[8][3]) {
if (fCheck[0][0] > fSource[4][0] || // fCheck is right of fSource
fCheck[4][0] < fSource[0][0] || // fCheck is left of fSource
fCheck[1][2] < fSource[0][2] || // fCheck is below fSource
fCheck[0][2] > fSource[1][2] || // fCheck is above fSource
fCheck[3][1] < fSource[1][1] || // fCheck is behind fSource
fCheck[1][1] > fSource[3][1]) { // fCheck is in front fSource
return false;
}
return true;
}
/**
* Checkes if a point is inside a zone.
*
* @param fPoint The point vector.
* @param fZone The zone array.
* @return True if inside, false otherwise.
*/
stock bool IsPointInZone(float fPoint[3], float fZone[8][3]) {
if (fPoint[0] > fZone[4][0] || // fPoint is right of fZone
fPoint[0] < fZone[0][0] || // fPoint is left of fZone
fPoint[2] < fZone[0][2] || // fPoint is below fZone
fPoint[2] > fZone[1][2] || // fPoint is above fZone
fPoint[1] < fZone[1][1] || // fPoint is behind fZone
fPoint[1] > fZone[3][1]) { // fPoint is in front fZone
return false;
}
return true;
}