From aef0d1c1268ab7d4bc18996c9c6b4da16a40aadc Mon Sep 17 00:00:00 2001 From: navewindre Date: Mon, 4 Dec 2023 18:06:10 +0100 Subject: bbbbbbbbwaaaaaaaaaaa --- sourcemod/scripting/gokz-measure/commands.sp | 49 +++++ sourcemod/scripting/gokz-measure/measure_menu.sp | 82 ++++++++ sourcemod/scripting/gokz-measure/measurer.sp | 231 +++++++++++++++++++++++ 3 files changed, 362 insertions(+) create mode 100644 sourcemod/scripting/gokz-measure/commands.sp create mode 100644 sourcemod/scripting/gokz-measure/measure_menu.sp create mode 100644 sourcemod/scripting/gokz-measure/measurer.sp (limited to 'sourcemod/scripting/gokz-measure') diff --git a/sourcemod/scripting/gokz-measure/commands.sp b/sourcemod/scripting/gokz-measure/commands.sp new file mode 100644 index 0000000..5fe3028 --- /dev/null +++ b/sourcemod/scripting/gokz-measure/commands.sp @@ -0,0 +1,49 @@ +void RegisterCommands() +{ + RegConsoleCmd("+measure", CommandMeasureStart, "[KZ] Set the measure origin."); + RegConsoleCmd("-measure", CommandMeasureEnd, "[KZ] Set the measure origin."); + RegConsoleCmd("sm_measure", CommandMeasureMenu, "[KZ] Open the measurement menu."); + RegConsoleCmd("sm_measuremenu", CommandMeasureMenu, "[KZ] Open the measurement menu."); + RegConsoleCmd("sm_measureblock", CommandMeasureBlock, "[KZ] Measure the block distance."); +} + +public Action CommandMeasureMenu(int client, int args) +{ + DisplayMeasureMenu(client); + return Plugin_Handled; +} + +public Action CommandMeasureStart(int client, int args) +{ + if (!IsValidClient(client)) + { + return Plugin_Handled; + } + gB_Measuring[client] = true; + MeasureGetPos(client, 0); + return Plugin_Handled; +} + +public Action CommandMeasureEnd(int client, int args) +{ + if (!IsValidClient(client)) + { + return Plugin_Handled; + } + gB_Measuring[client] = false; + MeasureGetPos(client, 1); + MeasureDistance(client, MEASURE_MIN_DIST); + CreateTimer(4.9, Timer_DeletePoints, GetClientUserId(client)); + return Plugin_Handled; +} + +public Action CommandMeasureBlock(int client, int args) +{ + if (!IsValidClient(client)) + { + return Plugin_Handled; + } + MeasureBlock(client); + CreateTimer(4.9, Timer_DeletePoints, GetClientUserId(client)); + return Plugin_Handled; +} \ No newline at end of file diff --git a/sourcemod/scripting/gokz-measure/measure_menu.sp b/sourcemod/scripting/gokz-measure/measure_menu.sp new file mode 100644 index 0000000..cf9deb3 --- /dev/null +++ b/sourcemod/scripting/gokz-measure/measure_menu.sp @@ -0,0 +1,82 @@ +#define ITEM_INFO_POINT_A "a" +#define ITEM_INFO_POINT_B "b" +#define ITEM_INFO_GET_DISTANCE "get" +#define ITEM_INFO_GET_BLOCK_DISTANCE "block" + +// =====[ PUBLIC ]===== + +void DisplayMeasureMenu(int client, bool reset = true) +{ + if (reset) + { + MeasureResetPos(client); + } + + Menu menu = new Menu(MenuHandler_Measure); + menu.SetTitle("%T", "Measure Menu - Title", client); + MeasureMenuAddItems(client, menu); + menu.Display(client, MENU_TIME_FOREVER); +} + + + +// =====[ EVENTS ]===== + +public int MenuHandler_Measure(Menu menu, MenuAction action, int param1, int param2) +{ + if (action == MenuAction_Select) + { + char info[16]; + menu.GetItem(param2, info, sizeof(info)); + + if (StrEqual(info, ITEM_INFO_POINT_A, false)) + { + MeasureGetPos(param1, 0); + } + else if (StrEqual(info, ITEM_INFO_POINT_B, false)) + { + MeasureGetPos(param1, 1); + } + else if (StrEqual(info, ITEM_INFO_GET_DISTANCE, false)) + { + MeasureDistance(param1); + } + else if (StrEqual(info, ITEM_INFO_GET_BLOCK_DISTANCE, false)) + { + if (!MeasureBlock(param1)) + { + DisplayMeasureMenu(param1, false); + } + } + + DisplayMeasureMenu(param1, false); + } + else if (action == MenuAction_Cancel) + { + MeasureResetPos(param1); + } + else if (action == MenuAction_End) + { + delete menu; + } + return 0; +} + + + +// =====[ PRIVATE ]===== + +static void MeasureMenuAddItems(int client, Menu menu) +{ + char display[32]; + + FormatEx(display, sizeof(display), "%T", "Measure Menu - Point A", client); + menu.AddItem(ITEM_INFO_POINT_A, display); + FormatEx(display, sizeof(display), "%T", "Measure Menu - Point B", client); + menu.AddItem(ITEM_INFO_POINT_B, display); + FormatEx(display, sizeof(display), "%T\n ", "Measure Menu - Get Distance", client); + menu.AddItem(ITEM_INFO_GET_DISTANCE, display); + FormatEx(display, sizeof(display), "%T", "Measure Menu - Get Block Distance", client); + menu.AddItem(ITEM_INFO_GET_BLOCK_DISTANCE, display); +} + 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 -- cgit v1.2.3