summaryrefslogtreecommitdiff
path: root/sourcemod/scripting/gokz-measure/measurer.sp
diff options
context:
space:
mode:
authornavewindre <nw@moneybot.cc>2023-12-04 18:06:10 +0100
committernavewindre <nw@moneybot.cc>2023-12-04 18:06:10 +0100
commitaef0d1c1268ab7d4bc18996c9c6b4da16a40aadc (patch)
tree43e766b51704f4ab8b383583bdc1871eeeb9c698 /sourcemod/scripting/gokz-measure/measurer.sp
parent38f1140c11724da05a23a10385061200b907cf6e (diff)
bbbbbbbbwaaaaaaaaaaa
Diffstat (limited to 'sourcemod/scripting/gokz-measure/measurer.sp')
-rw-r--r--sourcemod/scripting/gokz-measure/measurer.sp231
1 files changed, 231 insertions, 0 deletions
diff --git a/sourcemod/scripting/gokz-measure/measurer.sp b/sourcemod/scripting/gokz-measure/measurer.sp
new file mode 100644
index 0000000..f88e79c
--- /dev/null
+++ b/sourcemod/scripting/gokz-measure/measurer.sp
@@ -0,0 +1,231 @@
+// =====[ PUBLIC ]=====
+
+void MeasureGetPos(int client, int arg)
+{
+ float origin[3];
+ float angles[3];
+
+ GetClientEyePosition(client, origin);
+ GetClientEyeAngles(client, angles);
+
+ MeasureGetPosEx(client, arg, origin, angles);
+}
+
+void MeasureResetPos(int client)
+{
+ delete gH_P2PRed[client];
+ delete gH_P2PGreen[client];
+
+ gB_MeasurePosSet[client][0] = false;
+ gB_MeasurePosSet[client][1] = false;
+
+ gF_MeasurePos[client][0][0] = 0.0; // This is stupid.
+ gF_MeasurePos[client][0][1] = 0.0;
+ gF_MeasurePos[client][0][2] = 0.0;
+ gF_MeasurePos[client][1][0] = 0.0;
+ gF_MeasurePos[client][1][1] = 0.0;
+ gF_MeasurePos[client][1][2] = 0.0;
+}
+
+bool MeasureBlock(int client)
+{
+ float angles[3];
+ MeasureGetPos(client, 0);
+ GetVectorAngles(gF_MeasureNormal[client][0], angles);
+ MeasureGetPosEx(client, 1, gF_MeasurePos[client][0], angles);
+ AddVectors(gF_MeasureNormal[client][0], gF_MeasureNormal[client][1], angles);
+ if (GetVectorLength(angles, true) > EPSILON ||
+ FloatAbs(gF_MeasureNormal[client][0][2]) > EPSILON ||
+ FloatAbs(gF_MeasureNormal[client][1][2]) > EPSILON)
+ {
+ GOKZ_PrintToChat(client, true, "%t", "Measure Failure (Blocks not aligned)");
+ GOKZ_PlayErrorSound(client);
+ return false;
+ }
+ GOKZ_PrintToChat(client, true, "%t", "Block Measure Result", RoundFloat(GetVectorHorizontalDistance(gF_MeasurePos[client][0], gF_MeasurePos[client][1])));
+ MeasureBeam(client, gF_MeasurePos[client][0], gF_MeasurePos[client][1], 5.0, 0.2, 200, 200, 200);
+ return true;
+}
+
+bool MeasureDistance(int client, float minDistToMeasureBlock = -1.0)
+{
+ // Find Distance
+ if (gB_MeasurePosSet[client][0] && gB_MeasurePosSet[client][1])
+ {
+ float horizontalDist = GetVectorHorizontalDistance(gF_MeasurePos[client][0], gF_MeasurePos[client][1]);
+ float effectiveDist = CalcEffectiveDistance(gF_MeasurePos[client][0], gF_MeasurePos[client][1]);
+ float verticalDist = gF_MeasurePos[client][1][2] - gF_MeasurePos[client][0][2];
+ if (minDistToMeasureBlock >= 0.0 && (horizontalDist <= minDistToMeasureBlock && verticalDist <= minDistToMeasureBlock))
+ {
+ return MeasureBlock(client);
+ }
+ else
+ {
+ GOKZ_PrintToChat(client, true, "%t", "Measure Result", horizontalDist, effectiveDist, verticalDist);
+ MeasureBeam(client, gF_MeasurePos[client][0], gF_MeasurePos[client][1], 5.0, 0.2, 200, 200, 200);
+ }
+ return true;
+ }
+ else
+ {
+ GOKZ_PrintToChat(client, true, "%t", "Measure Failure (Points Not Set)");
+ GOKZ_PlayErrorSound(client);
+ return false;
+ }
+}
+
+// =====[ TIMERS ]=====
+
+public Action Timer_P2PRed(Handle timer, int userid)
+{
+ int client = GetClientOfUserId(userid);
+ if (IsValidClient(client))
+ {
+ P2PXBeam(client, 0);
+ }
+ return Plugin_Continue;
+}
+
+public Action Timer_P2PGreen(Handle timer, int userid)
+{
+ int client = GetClientOfUserId(userid);
+ if (IsValidClient(client))
+ {
+ P2PXBeam(client, 1);
+ }
+ return Plugin_Continue;
+}
+
+public Action Timer_DeletePoints(Handle timer, int userid)
+{
+ int client = GetClientOfUserId(userid);
+ if (!gB_Measuring[client])
+ {
+ MeasureResetPos(client);
+ }
+ return Plugin_Continue;
+}
+
+
+// =====[ PRIVATES ]=====
+static void P2PXBeam(int client, int arg)
+{
+ float Origin0[3];
+ float Origin1[3];
+ float Origin2[3];
+ float Origin3[3];
+
+ Origin0[0] = (gF_MeasurePos[client][arg][0] + 8.0);
+ Origin0[1] = (gF_MeasurePos[client][arg][1] + 8.0);
+ Origin0[2] = gF_MeasurePos[client][arg][2];
+
+ Origin1[0] = (gF_MeasurePos[client][arg][0] - 8.0);
+ Origin1[1] = (gF_MeasurePos[client][arg][1] - 8.0);
+ Origin1[2] = gF_MeasurePos[client][arg][2];
+
+ Origin2[0] = (gF_MeasurePos[client][arg][0] + 8.0);
+ Origin2[1] = (gF_MeasurePos[client][arg][1] - 8.0);
+ Origin2[2] = gF_MeasurePos[client][arg][2];
+
+ Origin3[0] = (gF_MeasurePos[client][arg][0] - 8.0);
+ Origin3[1] = (gF_MeasurePos[client][arg][1] + 8.0);
+ Origin3[2] = gF_MeasurePos[client][arg][2];
+
+ if (arg == 0)
+ {
+ MeasureBeam(client, Origin0, Origin1, 0.97, 0.2, 0, 255, 0);
+ MeasureBeam(client, Origin2, Origin3, 0.97, 0.2, 0, 255, 0);
+ }
+ else
+ {
+ MeasureBeam(client, Origin0, Origin1, 0.97, 0.2, 255, 0, 0);
+ MeasureBeam(client, Origin2, Origin3, 0.97, 0.2, 255, 0, 0);
+ }
+}
+
+static void MeasureGetPosEx(int client, int arg, float origin[3], float angles[3])
+{
+ Handle trace = TR_TraceRayFilterEx(origin, angles, MASK_PLAYERSOLID, RayType_Infinite, TraceEntityFilterPlayers, client);
+
+ if (!TR_DidHit(trace))
+ {
+ delete trace;
+ GOKZ_PrintToChat(client, true, "%t", "Measure Failure (Not Aiming at Solid)");
+ GOKZ_PlayErrorSound(client);
+ return;
+ }
+
+ TR_GetEndPosition(gF_MeasurePos[client][arg], trace);
+ TR_GetPlaneNormal(trace, gF_MeasureNormal[client][arg]);
+ delete trace;
+
+ if (arg == 0)
+ {
+ delete gH_P2PRed[client];
+ gB_MeasurePosSet[client][0] = true;
+ gH_P2PRed[client] = CreateTimer(1.0, Timer_P2PRed, GetClientUserId(client), TIMER_REPEAT);
+ P2PXBeam(client, 0);
+ }
+ else
+ {
+ delete gH_P2PGreen[client];
+ gH_P2PGreen[client] = null;
+ gB_MeasurePosSet[client][1] = true;
+ P2PXBeam(client, 1);
+ gH_P2PGreen[client] = CreateTimer(1.0, Timer_P2PGreen, GetClientUserId(client), TIMER_REPEAT);
+ }
+}
+
+static void MeasureBeam(int client, float vecStart[3], float vecEnd[3], float life, float width, int r, int g, int b)
+{
+ TE_Start("BeamPoints");
+ TE_WriteNum("m_nModelIndex", gI_BeamModel);
+ TE_WriteNum("m_nHaloIndex", 0);
+ TE_WriteNum("m_nStartFrame", 0);
+ TE_WriteNum("m_nFrameRate", 0);
+ TE_WriteFloat("m_fLife", life);
+ TE_WriteFloat("m_fWidth", width);
+ TE_WriteFloat("m_fEndWidth", width);
+ TE_WriteNum("m_nFadeLength", 0);
+ TE_WriteFloat("m_fAmplitude", 0.0);
+ TE_WriteNum("m_nSpeed", 0);
+ TE_WriteNum("r", r);
+ TE_WriteNum("g", g);
+ TE_WriteNum("b", b);
+ TE_WriteNum("a", 255);
+ TE_WriteNum("m_nFlags", 0);
+ TE_WriteVector("m_vecStartPoint", vecStart);
+ TE_WriteVector("m_vecEndPoint", vecEnd);
+ TE_SendToClient(client);
+}
+
+// Calculates the minimum equivalent jumpstat distance to go between the two points
+static float CalcEffectiveDistance(const float pointA[3], const float pointB[3])
+{
+ float Ax = FloatMin(pointA[0], pointB[0]);
+ float Bx = FloatMax(pointA[0], pointB[0]);
+ float Ay = FloatMin(pointA[1], pointB[1]);
+ float By = FloatMax(pointA[1], pointB[1]);
+
+ if (Bx - Ax < 32.0)
+ {
+ Ax = Bx;
+ }
+ else
+ {
+ Ax = Ax + 16.0;
+ Bx = Bx - 16.0;
+ }
+
+ if (By - Ay < 32.0)
+ {
+ Ay = By;
+ }
+ else
+ {
+ Ay = Ay + 16.0;
+ By = By - 16.0;
+ }
+
+ return SquareRoot(Pow(Ax - Bx, 2.0) + Pow(Ay - By, 2.0)) + 32.0;
+} \ No newline at end of file