diff options
Diffstat (limited to 'sourcemod/scripting/include/gamechaos')
| -rw-r--r-- | sourcemod/scripting/include/gamechaos/arrays.inc | 52 | ||||
| -rw-r--r-- | sourcemod/scripting/include/gamechaos/client.inc | 300 | ||||
| -rw-r--r-- | sourcemod/scripting/include/gamechaos/debug.inc | 19 | ||||
| -rw-r--r-- | sourcemod/scripting/include/gamechaos/isvalidclient.inc | 16 | ||||
| -rw-r--r-- | sourcemod/scripting/include/gamechaos/kreedzclimbing.inc | 226 | ||||
| -rw-r--r-- | sourcemod/scripting/include/gamechaos/maths.inc | 362 | ||||
| -rw-r--r-- | sourcemod/scripting/include/gamechaos/misc.inc | 245 | ||||
| -rw-r--r-- | sourcemod/scripting/include/gamechaos/strings.inc | 367 | ||||
| -rw-r--r-- | sourcemod/scripting/include/gamechaos/tempents.inc | 62 | ||||
| -rw-r--r-- | sourcemod/scripting/include/gamechaos/tracing.inc | 242 | ||||
| -rw-r--r-- | sourcemod/scripting/include/gamechaos/vectors.inc | 66 |
11 files changed, 1957 insertions, 0 deletions
diff --git a/sourcemod/scripting/include/gamechaos/arrays.inc b/sourcemod/scripting/include/gamechaos/arrays.inc new file mode 100644 index 0000000..eba62bb --- /dev/null +++ b/sourcemod/scripting/include/gamechaos/arrays.inc @@ -0,0 +1,52 @@ + +#if defined _gamechaos_stocks_arrays_included + #endinput +#endif +#define _gamechaos_stocks_arrays_included + +#define GC_ARRAYS_VERSION 0x01_00_00 +#define GC_ARRAYS_VERSION_STRING "1.0.0" + +/** + * Copies an array into an arraylist. + * + * @param array Arraylist Handle. + * @param index Index in the arraylist. + * @param values Array to copy. + * @param size Size of the array to copy. + * @param offset Arraylist offset to set. + * @return Number of cells copied. + * @error Invalid Handle or invalid index. + */ +stock int GCSetArrayArrayIndexOffset(ArrayList array, int index, const any[] values, int size, int offset) +{ + int cells; + for (int i; i < size; i++) + { + array.Set(index, values[i], offset + i); + cells++; + } + return cells; +} + +/** + * Copies an arraylist's specified cells to an array. + * + * @param array Arraylist Handle. + * @param index Index in the arraylist. + * @param result Array to copy to. + * @param size Size of the array to copy to. + * @param offset Arraylist offset. + * @return Number of cells copied. + * @error Invalid Handle or invalid index. + */ +stock int GCCopyArrayArrayIndex(const ArrayList array, int index, any[] result, int size, int offset) +{ + int cells; + for (int i = offset; i < (size + offset); i++) + { + result[i] = array.Get(index, i); + cells++; + } + return cells; +}
\ No newline at end of file diff --git a/sourcemod/scripting/include/gamechaos/client.inc b/sourcemod/scripting/include/gamechaos/client.inc new file mode 100644 index 0000000..cb2114a --- /dev/null +++ b/sourcemod/scripting/include/gamechaos/client.inc @@ -0,0 +1,300 @@ + +#if defined _gamechaos_stocks_client_included + #endinput +#endif +#define _gamechaos_stocks_client_included + +#define GC_CLIENT_VERSION 0x01_00_00 +#define GC_CLIENT_VERSION_STRING "1.0.0" + +/** + * Credit: Don't remember. + * Removes a player's weapon from the specified slot. + * + * @param client Client index. + * @param slot Weapon slot. + * @return True if removed, false otherwise. + */ +stock bool GCRemoveWeaponBySlot(int client, int slot) +{ + int entity = GetPlayerWeaponSlot(client, slot); + if (IsValidEdict(entity)) + { + RemovePlayerItem(client, entity); + AcceptEntityInput(entity, "kill"); + return true; + } + return false; +} + +/** + * Checks if a client is valid and not the server and optionally, whether he's alive. + * + * @param client Client index. + * @param alive Whether to check alive. + * @return True if valid, false otherwise. + */ +stock bool GCIsValidClient(int client, bool alive = false) +{ + return (client >= 1 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client) && !IsClientSourceTV(client) && (!alive || IsPlayerAlive(client))); +} + + + +/** + * Gets the value of m_flForwardMove. + * + * @param client Client index. + * @return Value of m_flForwardMove. + */ +stock float GCGetClientForwardMove(int client) +{ + return GetEntPropFloat(client, Prop_Data, "m_flForwardMove"); +} + +/** + * Gets the value of m_flSideMove. + * + * @param client Client index. + * @return Value of m_flSideMove. + */ +stock float GCGetClientSideMove(int client) +{ + return GetEntPropFloat(client, Prop_Data, "m_flSideMove"); +} + +/** + * Gets the client's abs origin. + * + * @param client Client index. + * @return result Player's origin. + */ +stock float[] GCGetClientAbsOriginRet(int client) +{ + float result[3] + GetClientAbsOrigin(client, result); + return result; +} + +/** + * Copies the client's velocity to a vector. + * + * @param client Client index. + * @param result Resultant vector. + */ +stock void GCGetClientVelocity(int client, float result[3]) +{ + GetEntPropVector(client, Prop_Data, "m_vecVelocity", result); +} + +/** + * Gets the client's velocity (m_vecVelocity). + * + * @param client Client index. + * @return result m_vecVelocity. + */ +stock float[] GCGetClientVelocityRet(int client) +{ + float result[3] + GetEntPropVector(client, Prop_Data, "m_vecVelocity", result); + return result +} + +/** + * Copies the client's basevelocity to a vector. + * + * @param client Client index. + * @param result Resultant vector. + */ +stock void GCGetClientBaseVelocity(int client, float result[3]) +{ + GetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", result); +} + +/** + * Gets the client's basevelocity (m_vecBaseVelocity). + * + * @param client Client index. + * @return result m_vecBaseVelocity. + */ +stock float[] GCGetClientBaseVelocityRet(int client) +{ + float result[3]; + GetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", result); + return result; +} + + +/** + * Gets the client's "m_flDuckSpeed" value. + * + * @param client Client index. + * @return "m_flDuckSpeed". + */ +stock float GCGetClientDuckSpeed(int client) +{ + return GetEntPropFloat(client, Prop_Send, "m_flDuckSpeed"); +} + +/** + * Gets the client's "m_flDuckAmount" value. + * + * @param client Client index. + * @return "m_flDuckAmount". + */ +stock float GCGetClientDuckAmount(int client) +{ + return GetEntPropFloat(client, Prop_Send, "m_flDuckAmount"); +} + +/** + * Gets the client's "m_bDucking" value. + * + * @param client Client index. + * @return "m_bDucking". + */ +stock int GCGetClientDucking(int client) +{ + return GetEntProp(client, Prop_Data, "m_bDucking"); +} + +/** + * Gets the client's "m_flMaxspeed" value. + * + * @param client Client index. + * @return "m_flMaxspeed". + */ +stock float GCGetClientMaxspeed(int client) +{ + return GetEntPropFloat(client, Prop_Send, "m_flMaxspeed"); +} + +/** + * Gets the client's "m_afButtonPressed" value. + * + * @param client Client index. + * @return "m_afButtonPressed". + */ +stock int GCGetClientButtonPressed(int client) +{ + return GetEntProp(client, Prop_Data, "m_afButtonPressed"); +} + +/** + * Gets the client's "m_afButtonReleased" value. + * + * @param client Client index. + * @return "m_afButtonReleased". + */ +stock int GCGetClientButtonReleased(int client) +{ + return GetEntProp(client, Prop_Data, "m_afButtonReleased"); +} + +/** + * Gets the client's "m_afButtonLast" value. + * + * @param client Client index. + * @return "m_afButtonLast". + */ +stock int GCGetClientButtonLast(int client) +{ + return GetEntProp(client, Prop_Data, "m_afButtonLast"); +} + +/** + * Gets the client's "m_afButtonForced" value. + * + * @param client Client index. + * @return "m_afButtonForced". + */ +stock int GCGetClientForcedButtons(int client) +{ + return GetEntProp(client, Prop_Data, "m_afButtonForced"); +} + +/** + * Gets the client's "m_flStamina" value. + * + * @param client Client index. + * @return "m_flStamina". + */ +stock float GCGetClientStamina(int client) +{ + return GetEntPropFloat(client, Prop_Send, "m_flStamina"); +} + + + +/** + * Sets the client's origin. + * + * @param client Client index. + * @param origin New origin. + */ +stock void GCSetClientAbsOrigin(int client, const float origin[3]) +{ + SetEntPropVector(client, Prop_Data, "m_vecAbsOrigin", origin); +} + +/** + * Sets the client's velocity. + * + * @param client Client index. + * @param velocity New velocity. + */ +stock void GCSetClientVelocity(int client, const float velocity[3]) +{ + SetEntPropVector(client, Prop_Data, "m_vecVelocity", velocity); +} + +/** + * Sets the client's "m_vecAbsVelocity". + * + * @param client Client index. + * @param velocity New "m_vecAbsVelocity". + */ +stock void GCSetClientAbsVelocity(int client, const float velocity[3]) +{ + SetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", velocity); +} + +/** + * Sets the client's eye angles. + * Ang has to be a 2 member array or more + * + * @param client Client index. + * @param ang New eyeangles. + */ +stock void GCSetClientEyeAngles(int client, const float[] ang) +{ + SetEntPropFloat(client, Prop_Send, "m_angEyeAngles[0]", ang[0]); + SetEntPropFloat(client, Prop_Send, "m_angEyeAngles[1]", ang[1]); +} + + +/** + * Sets the client's "m_flDuckSpeed". + * + * @param client Client index. + * @param value New "m_flDuckSpeed". + */ +stock void GCSetClientDuckSpeed(int client, float value) +{ + SetEntPropFloat(client, Prop_Send, "m_flDuckSpeed", value); +} + +stock void GCSetClientDuckAmount(int client, float value) +{ + SetEntPropFloat(client, Prop_Send, "m_flDuckAmount", value); +} + +stock void GCSetClientForcedButtons(int client, int buttons) +{ + SetEntProp(client, Prop_Data, "m_afButtonForced", buttons); +} + +stock void GCSetClientStamina(int client, float stamina) +{ + SetEntPropFloat(client, Prop_Send, "m_flStamina", stamina) +}
\ No newline at end of file diff --git a/sourcemod/scripting/include/gamechaos/debug.inc b/sourcemod/scripting/include/gamechaos/debug.inc new file mode 100644 index 0000000..4e5b7e7 --- /dev/null +++ b/sourcemod/scripting/include/gamechaos/debug.inc @@ -0,0 +1,19 @@ + +// gamechaos's debug stocks +// useful stocks for debugging + +#if defined _gamechaos_debug_included + #endinput +#endif +#define _gamechaos_debug_included + +#define GC_DEBUG_VERSION 0x1_00_00 +#define GC_DEBUG_VERSION_STRING "1.0.0" + +#if defined GC_DEBUG + #define GC_ASSERT(%1) if (!(%1))SetFailState("Assertion failed: \""...#%1..."\"") + #define GC_DEBUGPRINT(%1) PrintToChatAll(%1) +#else + #define GC_ASSERT(%1)%2; + #define GC_DEBUGPRINT(%1)%2; +#endif diff --git a/sourcemod/scripting/include/gamechaos/isvalidclient.inc b/sourcemod/scripting/include/gamechaos/isvalidclient.inc new file mode 100644 index 0000000..bf80246 --- /dev/null +++ b/sourcemod/scripting/include/gamechaos/isvalidclient.inc @@ -0,0 +1,16 @@ + +#if defined _gamechaos_isvalidclient_client_included + #endinput +#endif +#define _gamechaos_isvalidclient_client_included + +/** + * Checks if a client is valid. + * + * @param client Client index. + * @return True if valid, false otherwise. + */ +stock bool IsValidClient(int client) +{ + return (client >= 0 && client <= MaxClients && IsValidEntity(client) && IsClientConnected(client) && IsClientInGame(client)); +}
\ No newline at end of file diff --git a/sourcemod/scripting/include/gamechaos/kreedzclimbing.inc b/sourcemod/scripting/include/gamechaos/kreedzclimbing.inc new file mode 100644 index 0000000..0cbb828 --- /dev/null +++ b/sourcemod/scripting/include/gamechaos/kreedzclimbing.inc @@ -0,0 +1,226 @@ +// +// Useful things for making plugins for Kreedz Climbing +// + +#if defined _gamechaos_kreedzclimbing_included + #endinput +#endif +#define _gamechaos_kreedzclimbing_included + +#define GC_KREEDZCLIMBING_VERSION 0x01_00_00 +#define GC_KREEDZCLIMBING_VERSION_STRING "1.0.0" + + +#define MAX_COURSE_SIZE 128 // Reasonable maximum characters a course name can have +#define COURSE_CVAR_COUNT 20 // the amount of Course<int> cvars + +// Kreedz Climbing Client Commands: +// These may be executed by a player via the console, with / in chat, or via binds. + +// specmode - Cycles spectator mode (F3 by default). +// kz_pause - Pauses the timer. +// flare - Fires a flare. +// gototimer | start - Returns to the last pressed start timer. +// spectate | spec - Enters spectator mode. +// forcespectator - Becomes a spectator no matter what (force respawns a dead player as well). +// stoptimer - Instantly stops the player's timer. +// climb | ct - Respawns at the map spawnpoint. +// InvalidateTimer - Invalidates the player's timer. An invalid timer can't earn rewards for completing the course. InvalidateTimer 1 displays the message, without the 1 it does not. + +// Kreedz Climbing Constants + +// Timer state (player->m_Local->Timer_Active) +#define TIMER_STATE_INVISIBLE 0 +#define TIMER_STATE_ACTIVE 1 +#define TIMER_STATE_INACTIVE 2 +#define TIMER_STATE_PAUSED 3 + +// Timer flags (player_manager->m_iTimerFlags[32]) +// These are replicated flags for player's timer (most timer data is local to it's own player). +// Note that these flags are mirrors of data local to the player - they are set to the player's +// state every frame and cannot be changed. + +#define TIMER_FLAG_INVALID (1 << 0) +#define TIMER_FLAG_ACTIVE (1 << 1) // We need to broadcast this because Timer_State is local only. +#define TIMER_FLAG_PAUSED (1 << 2) // A paused timer cannot be active and vice versa. + +// Environmental Attributes (player->m_iEnvironmentalAttributes) +#define PLAYER_ENV_ATTRIBUTES_BHOP (1 << 0) +#define PLAYER_ENV_ATTRIBUTES_SURF (1 << 1) +#define PLAYER_ENV_ATTRIBUTES_AUTOBHOP (1 << 2) +#define PLAYER_ENV_ATTRIBUTES_CSGOMOVEMENT (1 << 3) +#define PLAYER_ENV_ATTRIBUTES_CSGODUCKHULL (1 << 4) + +// Movement restriction flags (player->m_iMovementRestrictions) (new version of Environmental Restrictions below) +#define PLAYER_MOVEMENT_RESTRICTION_NOJUMP (1 << 0) +#define PLAYER_MOVEMENT_RESTRICTION_NOBHOP (1 << 1) +#define PLAYER_MOVEMENT_RESTRICTION_NODOUBLEDUCK (1 << 2) + +// OBSOLETE: ONLY IN OLD MAPS: Environmental Restrictions (player->m_iEnvironmentalRestrictions), note not flags, complete integer. +#define PLAYER_ENV_RESTRICTION_NOJUMP 1 +#define PLAYER_ENV_RESTRICTION_NOBHOP 2 +#define PLAYER_ENV_RESTRICTION_BOTH 3 + +// Cooperative status (player->m_Local.m_multiplayercoursedata.Player1Status, Player2Status etc) +#define COOPERATIVE_STATUS_NONE 0 +#define COOPERATIVE_STATUS_WAITING 1 +#define COOPERATIVE_STATUS_READY 2 +#define COOPERATIVE_STATUS_TIMER_ACTIVE 3 +#define COOPERATIVE_STATUS_TIMER_COMPLETE 4 +#define COOPERATIVE_STATUS_PLAYER_DISCONNECTED 5 // Player disconnected from server, waiting for them to reconnect. +#define COOPERATIVE_STATUS_TIMER_PAUSED 6 + +// Kreedz Climbing Button Constants +#define IN_CHECKPOINT (1 << 25) +#define IN_TELEPORT (1 << 26) +#define IN_SPECTATE (1 << 27) +//#define IN_AVAILABLE (1 << 28) // Unused +#define IN_HOOK (1 << 29) + +// converts the course id from the obsolete "player_starttimer" event into the course name +stock void GCCourseidToString(int courseid, char[] course, int size) +{ + char szCourseid[16]; + if (courseid < 1 || courseid > COURSE_CVAR_COUNT) + { + return; + } + FormatEx(szCourseid, sizeof(szCourseid), "Course%i", courseid); + FindConVar(szCourseid).GetString(course, size); +} + +stock void GCGetCurrentMapCourses(ArrayList &array) +{ + if (array == null) + { + // 1 for endurance bool + array = new ArrayList(ByteCountToCells(MAX_COURSE_SIZE) + 1); + } + else + { + array.Clear(); + } + + char course[MAX_COURSE_SIZE]; + + int ent; + while((ent = FindEntityByClassname(ent, "func_stoptimer")) != -1) + { + int courseid = GetEntProp(ent, Prop_Data, "CourseID"); + GCCourseidToString(courseid, course, sizeof(course)); + array.PushString(course); + + bool endurance = GCIsCourseEndurance(course, ent); + array.Set(array.Length - 1, endurance, ByteCountToCells(MAX_COURSE_SIZE)); + } + + int courseStringtableCount; + int courseNamesIdx = FindStringTable("CourseNames"); + courseStringtableCount = GetStringTableNumStrings(courseNamesIdx); + + for (int i; i < courseStringtableCount; i++) + { + ReadStringTable(courseNamesIdx, i, course, sizeof(course)); + array.PushString(course); + + bool endurance = GCIsCourseEndurance(course, ent); + array.Set(array.Length - 1, endurance, ByteCountToCells(MAX_COURSE_SIZE)); + } +} + +stock int GCGetTimerState(int client) +{ + return GetEntProp(client, Prop_Send, "Timer_Active"); +} + +stock void GCSetTimerState(int client, int timerstate) +{ + SetEntProp(client, Prop_Send, "Timer_Active", timerstate); +} + +stock int GCGetPlayerEnvAttributes(int client) +{ + return GetEntProp(client, Prop_Send, "m_iEnvironmentalAttributes"); +} + +stock void GCSetPlayerEnvAttributes(int client, int attributes) +{ + SetEntProp(client, Prop_Send, "m_iEnvironmentalAttributes", attributes); +} + +stock int GCGetPlayerMovementRestrictions(int client) +{ + return GetEntProp(client, Prop_Send, "m_iMovementRestrictions"); +} + +stock void GCSetPlayerMovementRestrictions(int client, int restrictions) +{ + SetEntProp(client, Prop_Send, "m_iMovementRestrictions", restrictions); +} + +stock void GCSetActiveCourse(int client, int course) +{ + int ent = FindEntityByClassname(0, "player_manager"); + int courseOffset = FindSendPropInfo("CPlayerResource", "m_iActiveCourse"); + SetEntData(ent, courseOffset + (client * 4), course); +} + +stock int GCGetTimerFlags(int client) +{ + int ent = FindEntityByClassname(0, "player_manager"); + int courseOffset = FindSendPropInfo("CPlayerResource", "m_iTimerFlags"); + return GetEntData(ent, courseOffset + (client * 4)); +} + +stock bool GCInvalidateTimer(int client) +{ + if (~GCGetTimerFlags(client) & TIMER_FLAG_INVALID) + { + FakeClientCommand(client, "InvalidateTimer 1"); + return true; + } + + return false; +} + +stock bool GCIsCourseEndurance(char[] course, int ent = -1) +{ + if (ent != -1) + { + if (IsValidEntity(ent)) + { + return !!(GetEntProp(ent, Prop_Data, "m_bEnduranceCourse")); + } + } + + while ((ent = FindEntityByClassname(ent, "point_climbtimer")) != -1) + { + if (IsValidEntity(ent)) + { + char buffer[MAX_COURSE_SIZE]; + GetEntPropString(ent, Prop_Data, "m_strCourseName", buffer, sizeof(buffer)); + + if (StrEqual(buffer, course)) + { + return !!(GetEntProp(ent, Prop_Data, "m_bEnduranceCourse")); + } + } + } + + while ((ent = FindEntityByClassname(ent, "func_stoptimer")) != -1) + { + if (IsValidEntity(ent)) + { + char buffer[MAX_COURSE_SIZE]; + int courseid = GetEntProp(ent, Prop_Data, "CourseID"); + GCCourseidToString(courseid, buffer, sizeof(buffer)); + + if (StrEqual(buffer, course)) + { + return !!(GetEntProp(ent, Prop_Data, "m_bEnduranceCourse")); + } + } + } + + return false; +}
\ No newline at end of file diff --git a/sourcemod/scripting/include/gamechaos/maths.inc b/sourcemod/scripting/include/gamechaos/maths.inc new file mode 100644 index 0000000..f3c94af --- /dev/null +++ b/sourcemod/scripting/include/gamechaos/maths.inc @@ -0,0 +1,362 @@ + +#if defined _gamechaos_stocks_maths_included + #endinput +#endif +#define _gamechaos_stocks_maths_included + +#define GC_MATHS_VERSION 0x02_00_00 +#define GC_MATHS_VERSION_STRING "2.0.0" + +#include <gamechaos/vectors> + +#define GC_PI 3.14159265359 + +#define GC_DEGREES(%1) ((%1) * 180.0 / GC_PI) // convert radians to degrees +#define GC_RADIANS(%1) ((%1) * GC_PI / 180.0) // convert degrees to radians + +#define GC_FLOAT_NAN view_as<float>(0xffffffff) +#define GC_FLOAT_INFINITY view_as<float>(0x7f800000) +#define GC_FLOAT_NEGATIVE_INFINITY view_as<float>(0xff800000) + +#define GC_FLOAT_LARGEST_POSITIVE view_as<float>(0x7f7fffff) +#define GC_FLOAT_SMALLEST_NEGATIVE view_as<float>(0xff7fffff) + +#define GC_FLOAT_SMALLEST_POSITIVE view_as<float>(0x00000001) +#define GC_FLOAT_LARGEST_NEGATIVE view_as<float>(0x80000001) + +#define GC_INT_MAX 0x7fffffff +#define GC_INT_MIN 0xffffffff + + +/** + * Credit: https://stackoverflow.com/questions/5666222/3d-line-plane-intersection + * Determines the point of intersection between a plane defined by a point and a normal vector and a line defined by a point and a direction vector. + * + * @param planePoint A point on the plane. + * @param planeNormal Normal vector of the plane. + * @param linePoint A point on the line. + * @param lineDirection Direction vector of the line. + * @param result Resultant vector. + */ +stock void GCLineIntersection(const float planePoint[3], const float planeNormal[3], const float linePoint[3], const float lineDirection[3], float result[3]) +{ + if (GetVectorDotProduct(planeNormal, lineDirection) == 0) + { + return; + } + + float t = (GetVectorDotProduct(planeNormal, planePoint) + - GetVectorDotProduct(planeNormal, linePoint)) + / GetVectorDotProduct(planeNormal, lineDirection); + + float lineDir[3]; + lineDir = lineDirection; + NormalizeVector(lineDir, lineDir); + + ScaleVector(lineDir, t); + + AddVectors(linePoint, lineDir, result); +} + +/** + * Calculates a point according to angles supplied that is a certain distance away. + * + * @param client Client index. + * @param result Resultant vector. + * @param distance Maximum distance to trace. + * @return True on success, false otherwise. + */ +stock void GCCalcPointAngleDistance(const float start[3], const float angle[3], float distance, float result[3]) +{ + float zsine = Sine(DegToRad(-angle[0])); + float zcos = Cosine(DegToRad(-angle[0])); + + result[0] = Cosine(DegToRad(angle[1])) * zcos; + result[1] = Sine(DegToRad(angle[1])) * zcos; + result[2] = zsine; + + ScaleVector(result, distance); + AddVectors(start, result, result); +} + +/** + * Compares how close 2 floats are. + * + * @param z1 Float 1 + * @param z2 Float 2 + * @param tolerance How close the floats have to be to return true. + * @return True on success, false otherwise. + */ +stock bool GCIsRoughlyEqual(float z1, float z2, float tolerance) +{ + return FloatAbs(z1 - z2) < tolerance; +} + +/** + * Checks if a float is within a range + * + * @param number Float to check. + * @param min Minimum range. + * @param max Maximum range. + * @return True on success, false otherwise. + */ +stock bool GCIsFloatInRange(float number, float min, float max) +{ + return number >= min && number <= max; +} + +/** + * Keeps the yaw angle within the range of -180 to 180. + * + * @param angle Angle. + * @return Normalised angle. + */ +stock float GCNormaliseYaw(float angle) +{ + if (angle <= -180.0) + { + angle += 360.0; + } + + if (angle > 180.0) + { + angle -= 360.0; + } + + return angle; +} + +/** + * Keeps the yaw angle within the range of -180 to 180. + * + * @param angle Angle. + * @return Normalised angle. + */ +stock float GCNormaliseYawRad(float angle) +{ + if (angle <= -FLOAT_PI) + { + angle += FLOAT_PI * 2; + } + + if (angle > FLOAT_PI) + { + angle -= FLOAT_PI * 2; + } + + return angle; +} + +/** + * Linearly interpolates between 2 values. + * + * @param f1 Float 1. + * @param f2 Float 2. + * @param fraction Amount to interpolate. + * @return Interpolated value. + */ +stock float GCInterpLinear(float f1, float f2, float fraction) +{ + float diff = f2 - f1; + + return diff * fraction + f1; +} + +/** + * Calculates the linear fraction from a value that was interpolated and 2 values it was interpolated from. + * + * @param f1 Float 1. + * @param f2 Float 2. + * @param fraction Interpolated value. + * @return Fraction. + */ +stock float GCCalcLerpFraction(float f1, float f2, float lerped) +{ + float diff = f2 - f1; + + float fraction = lerped - f1 / diff; + return fraction; +} + +/** + * Calculate absolute value of an integer. + * + * @param x Integer. + * @return Absolute value of integer. + */ +stock int GCIntAbs(int x) +{ + return x >= 0 ? x : -x; +} + +/** + * Get the maximum of 2 integers. + * + * @param n1 Integer. + * @param n2 Integer. + * @return The biggest of n1 and n2. + */ +stock int GCIntMax(int n1, int n2) +{ + return n1 > n2 ? n1 : n2; +} + +/** + * Get the minimum of 2 integers. + * + * @param n1 Integer. + * @param n2 Integer. + * @return The smallest of n1 and n2. + */ +stock int GCIntMin(int n1, int n2) +{ + return n1 < n2 ? n1 : n2; +} + +/** + * Checks if an integer is within a range + * + * @param number Integer to check. + * @param min Minimum range. + * @param max Maximum range. + * @return True on success, false otherwise. + */ +stock bool GCIsIntInRange(int number, int min, int max) +{ + return number >= min && number <= max; +} + +/** + * Calculates a float percentage from a common fraction. + * + * @param numerator Numerator. + * @param denominator Denominator. + * @return Float percentage. -1.0 on failure. + */ +stock float GCCalcIntPercentage(int numerator, int denominator) +{ + return float(numerator) / float(denominator) * 100.0; +} + +/** + * Integer power. + * Returns the base raised to the power of the exponent. + * Returns 0 if exponent is negative. + * + * @param base Base to be raised. + * @param exponent Value to raise the base. + * @return Value to the power of exponent. + */ +stock int GCIntPow(int base, int exponent) +{ + if (exponent < 0) + { + return 0; + } + + int result = 1; + for (;;) + { + if (exponent & 1) + { + result *= base + } + + exponent >>= 1; + + if (!exponent) + { + break; + } + + base *= base; + } + return result; +} + +/** + * Swaps the values of 2 variables. + * + * @param cell1 Cell 1. + * @param cell2 Cell 2. + */ +stock void GCSwapCells(any &cell1, any &cell2) +{ + any temp = cell1; + cell1 = cell2; + cell2 = temp; +} + +/** + * Clamps an int between min and max. + * + * @param value Float to clamp. + * @param min Minimum range. + * @param max Maximum range. + * @return Clamped value. + */ +stock int GCIntClamp(int value, int min, int max) +{ + if (value < min) + { + return min; + } + if (value > max) + { + return max; + } + return value; +} + +/** + * Returns the biggest of 2 values. + * + * @param num1 Number 1. + * @param num2 Number 2. + * @return Biggest number. + */ +stock float GCFloatMax(float num1, float num2) +{ + if (num1 > num2) + { + return num1; + } + return num2; +} + +/** + * Returns the smallest of 2 values. + * + * @param num1 Number 1. + * @param num2 Number 2. + * @return Smallest number. + */ +stock float GCFloatMin(float num1, float num2) +{ + if (num1 < num2) + { + return num1; + } + return num2; +} + +/** + * Clamps a float between min and max. + * + * @param value Float to clamp. + * @param min Minimum range. + * @param max Maximum range. + * @return Clamped value. + */ +stock float GCFloatClamp(float value, float min, float max) +{ + if (value < min) + { + return min; + } + if (value > max) + { + return max; + } + return value; +} diff --git a/sourcemod/scripting/include/gamechaos/misc.inc b/sourcemod/scripting/include/gamechaos/misc.inc new file mode 100644 index 0000000..f964862 --- /dev/null +++ b/sourcemod/scripting/include/gamechaos/misc.inc @@ -0,0 +1,245 @@ + +#if defined _gamechaos_stocks_misc_included + #endinput +#endif +#define _gamechaos_stocks_misc_included + +#define GC_MISC_VERSION 0x01_00_00 +#define GC_MISC_VERSION_STRING "1.0.0" + +/** + * Check if player is overlapping their MOVERIGHT and MOVELEFT buttons. + * + * @param x Buttons; + * @return True if overlapping, false otherwise. + */ +stock bool GCIsOverlapping(int buttons) +{ + return buttons & IN_MOVERIGHT && buttons & IN_MOVELEFT +} + +/** + * Checks if player gained speed. + * + * @param speed Current player speed. + * @param lastspeed Player speed from previous tick. + * @return True if player gained speed, false otherwise. + */ +stock bool GCIsStrafeSynced(float speed, float lastspeed) +{ + return speed > lastspeed; +} + +/** + * Checks if the player is not holding down their MOVERIGHT and MOVELEFT buttons. + * + * @param x Buttons. + * @return True if they're not holding either, false otherwise. + */ +stock bool GCIsDeadAirtime(int buttons) +{ + return !(buttons & IN_MOVERIGHT) && !(buttons & IN_MOVELEFT); +} + +/** +* Source: https://forums.alliedmods.net/showthread.php?p=2535972 +* Runs a single line of vscript code. +* NOTE: Dont use the "script" console command, it startes a new instance and leaks memory. Use this instead! +* +* @param code The code to run. +* @noreturn +*/ +stock void GCRunScriptCode(const char[] code, any ...) +{ + static int scriptLogic = INVALID_ENT_REFERENCE; + + if (scriptLogic == INVALID_ENT_REFERENCE || !IsValidEntity(scriptLogic)) + { + scriptLogic = EntIndexToEntRef(CreateEntityByName("logic_script")); + if (scriptLogic == INVALID_ENT_REFERENCE || !IsValidEntity(scriptLogic)) + { + SetFailState("Could not create a 'logic_script' entity."); + } + + DispatchSpawn(scriptLogic); + } + + char buffer[512]; + VFormat(buffer, sizeof(buffer), code, 2); + + SetVariantString(buffer); + AcceptEntityInput(scriptLogic, "RunScriptCode"); +} + +stock void GCTE_SendBeamBox(int client, + const float origin[3], + const float mins[3], + const float maxs[3], + int ModelIndex, + int HaloIndex = 0, + float Life = 3.0, + float Width = 2.0, + const int Colour[4] = { 255, 255, 255, 255 }, + float EndWidth = 2.0, + int StartFrame = 0, + int FrameRate = 0, + int FadeLength = 0, + float Amplitude = 0.0, + int Speed = 0) +{ + // credit to some bhop timer by shavit? thanks + int pairs[8][3] = { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0, 1, 1 } }; + int edges[12][2] = { { 0, 1 }, { 0, 3 }, { 0, 4 }, { 2, 1 }, { 2, 3 }, { 2, 6 }, { 5, 4 }, { 5, 6 }, { 5, 1 }, { 7, 4 }, { 7, 6 }, { 7, 3 } }; + + float corners[8][3]; + float corner[2][3]; + + AddVectors(origin, mins, corner[0]); + AddVectors(origin, maxs, corner[1]); + + for (int i = 0; i < 8; i++) + { + corners[i][0] = corner[pairs[i][0]][0]; + corners[i][1] = corner[pairs[i][1]][1]; + corners[i][2] = corner[pairs[i][2]][2]; + } + + for (int i = 0; i < 12; i++) + { + TE_SetupBeamPoints(corners[edges[i][0]], + corners[edges[i][1]], + ModelIndex, + HaloIndex, + StartFrame, + FrameRate, + Life, + Width, + EndWidth, + FadeLength, + Amplitude, + Colour, + Speed); + TE_SendToClient(client); + } +} + +stock void GCTE_SendBeamCross(int client, + const float origin[3], + int ModelIndex, + int HaloIndex = 0, + float Life = 3.0, + float Width = 2.0, + const int Colour[4] = { 255, 255, 255, 255 }, + float EndWidth = 2.0, + int StartFrame = 0, + int FrameRate = 0, + int FadeLength = 0, + float Amplitude = 0.0, + int Speed = 0) +{ + float points[4][3]; + + for (int i; i < 4; i++) + { + points[i][2] = origin[2]; + } + + // -x; -y + points[0][0] = origin[0] - 8.0; + points[0][1] = origin[1] - 8.0; + + // +x; -y + points[1][0] = origin[0] + 8.0; + points[1][1] = origin[1] - 8.0; + + // +x; +y + points[2][0] = origin[0] + 8.0; + points[2][1] = origin[1] + 8.0; + + // -x; +y + points[3][0] = origin[0] - 8.0; + points[3][1] = origin[1] + 8.0; + + //draw cross + for (int corner; corner < 4; corner++) + { + TE_SetupBeamPoints(origin, points[corner], ModelIndex, HaloIndex, StartFrame, FrameRate, Life, Width, EndWidth, FadeLength, Amplitude, Colour, Speed); + TE_SendToClient(client); + } +} + +stock void GCTE_SendBeamRectangle(int client, + const float origin[3], + const float mins[3], + const float maxs[3], + int modelIndex, + int haloIndex = 0, + float life = 3.0, + float width = 2.0, + const int colour[4] = { 255, 255, 255, 255 }, + float endWidth = 2.0, + int startFrame = 0, + int frameRate = 0, + int fadeLength = 0, + float amplitude = 0.0, + int speed = 0) +{ + float vertices[4][3]; + GCRectangleVerticesFromPoint(vertices, origin, mins, maxs); + + // send the square + for (int i; i < 4; i++) + { + int j = (i == 3) ? (0) : (i + 1); + TE_SetupBeamPoints(vertices[i], + vertices[j], + modelIndex, + haloIndex, + startFrame, + frameRate, + life, + width, + endWidth, + fadeLength, + amplitude, + colour, + speed); + TE_SendToClient(client); + } +} + +/** + * Calculates vertices for a rectangle from a point, mins and maxs. + * + * @param result Vertex array result. + * @param origin Origin to offset mins and maxs by. + * @param mins Minimum size of the rectangle. + * @param maxs Maximum size of the rectangle. + * @return True if overlapping, false otherwise. + */ +stock void GCRectangleVerticesFromPoint(float result[4][3], const float origin[3], const float mins[3], const float maxs[3]) +{ + // Vertices are set clockwise starting from top left (-x; -y) + + // -x; -y + result[0][0] = origin[0] + mins[0]; + result[0][1] = origin[1] + mins[1]; + + // +x; -y + result[1][0] = origin[0] + maxs[0]; + result[1][1] = origin[1] + mins[1]; + + // +x; +y + result[2][0] = origin[0] + maxs[0]; + result[2][1] = origin[1] + maxs[1]; + + // -x; +y + result[3][0] = origin[0] + mins[0]; + result[3][1] = origin[1] + maxs[1]; + + // z is the same for every vertex + for (int vertex; vertex < 4; vertex++) + { + result[vertex][2] = origin[2]; + } +}
\ No newline at end of file diff --git a/sourcemod/scripting/include/gamechaos/strings.inc b/sourcemod/scripting/include/gamechaos/strings.inc new file mode 100644 index 0000000..8ffcb60 --- /dev/null +++ b/sourcemod/scripting/include/gamechaos/strings.inc @@ -0,0 +1,367 @@ + +#if defined _gamechaos_stocks_strings_included + #endinput +#endif +#define _gamechaos_stocks_strings_included + +// these are used for functions that return strings. +// you can change these if they're too small/big. +#define GC_FIXED_BUFFER_SIZE_SMALL 64 +#define GC_FIXED_BUFFER_SIZE_LARGE 4096 + +/** + * Puts the values from a string of integers into an array + * + * @param string + * @param separator + * @param array + * @param arraysize + */ +stock void GCSeparateIntsFromString(const char[] string, const char[] separator, int[] array, int arraysize) +{ + char[][] explodedbuffer = new char[arraysize][32]; + + ExplodeString(string, separator, explodedbuffer, arraysize, 32); + + for (int i; i < arraysize; i++) + { + array[i] = StringToInt(explodedbuffer[i]); + } +} + +/** + * Prints a message to all admins in the chat area. + * + * @param format Formatting rules. + * @param ... Variable number of format parameters. + */ +stock void GCPrintToChatAdmins(const char[] format, any ...) +{ + char buffer[256]; + + for (int i = 1; i <= MaxClients; i++) + { + if (GCIsValidClient(i)) + { + AdminId id = GetUserAdmin(i); + if (!GetAdminFlag(id, Admin_Generic)) + { + continue; + } + SetGlobalTransTarget(i); + VFormat(buffer, sizeof(buffer), format, 2); + PrintToChat(i, "%s", buffer); + } + } +} + +/** + * Removes trailings zeroes from a string. Also removes the decimal point if it can. + * + * @param buffer Buffer to trim. + * @return Whether anything was removed. + */ +stock bool GCRemoveTrailing0s(char[] buffer) +{ + bool removed; + int maxlen = strlen(buffer); + + if (maxlen == 0) + { + return removed; + } + + for (int i = maxlen - 1; i > 0 && (buffer[i] == '0' || buffer[i] == '.' || buffer[i] == 0); i--) + { + if (buffer[i] == 0) + { + continue; + } + if (buffer[i] == '.') + { + buffer[i] = 0; + removed = true; + break; + } + buffer[i] = 0; + removed = true; + } + return removed; +} + +/** + * Formats time by HHMMSS. Uses ticks for the time. + * + * @param timeInTicks Time in ticks. + * @param tickRate Tickrate. + * @param formattedTime String to use for formatting. + * @param size String size. + */ +stock void GCFormatTickTimeHHMMSS(int timeInTicks, float tickRate, char[] formattedTime, int size) +{ + if (timeInTicks <= 0) + { + FormatEx(formattedTime, size, "-00:00:00"); + return; + } + + int time = RoundFloat(float(timeInTicks) / tickRate * 100.0); // centiseconds + int iHours = time / 360000; + int iMinutes = time / 6000 - iHours * 6000; + int iSeconds = (time - iHours * 360000 - iMinutes * 6000) / 100; + int iCentiSeconds = time % 100; + + if (iHours != 0) + { + FormatEx(formattedTime, size, "%02i:", iHours); + } + if (iMinutes != 0) + { + Format(formattedTime, size, "%s%02i:", formattedTime, iMinutes); + } + + Format(formattedTime, size, "%s%02i.%02i", formattedTime, iSeconds, iCentiSeconds); +} + +/** + * Formats time by HHMMSS. Uses seconds. + * + * @param seconds Time in seconds. + * @param formattedTime String to use for formatting. + * @param size String size. + * @param decimals Amount of decimals to use for the fractional part. + */ +stock void GCFormatTimeHHMMSS(float seconds, char[] formattedTime, int size, int decimals) +{ + int iFlooredTime = RoundToFloor(seconds); + int iHours = iFlooredTime / 3600; + int iMinutes = iFlooredTime / 60 - iHours * 60; + int iSeconds = iFlooredTime - iHours * 3600 - iMinutes * 60; + int iFraction = RoundToFloor(FloatFraction(seconds) * Pow(10.0, float(decimals))); + + if (iHours != 0) + { + FormatEx(formattedTime, size, "%02i:", iHours); + } + if (iMinutes != 0) + { + Format(formattedTime, size, "%s%02i:", formattedTime, iMinutes); + } + char szFraction[32]; + FormatEx(szFraction, sizeof(szFraction), "%i", iFraction); + + int iTest = strlen(szFraction); + for (int i; i < decimals - iTest; i++) + { + Format(szFraction, sizeof(szFraction), "%s%s", "0", szFraction); + } + + Format(formattedTime, size, "%s%02i.%s", formattedTime, iSeconds, szFraction); +} + +/** + * Encodes and appends a number onto the end of a UTF-8 string. + * + * @param string String to append to. + * @param strsize String size. + * @param number Unicode codepoint to encode. + */ +stock void GCEncodeUtf8(char[] string, char strsize, int number) +{ + // UTF-8 octet sequence (only change digits marked with x) + /* + Char. number range | UTF-8 octet sequence + (hexadecimal) | (binary) + --------------------+--------------------------------------------- + 0000 0000-0000 007F | 0xxxxxxx + 0000 0080-0000 07FF | 110xxxxx 10xxxxxx + 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx + 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + // byte 4 | byte 3 | byte 2 | byte 1*/ + + //char encodedChar = 0b_11110000_10000000_10000000_10000000; + + int zeropos = strlen(string); + + if (zeropos >= strsize - 1) // need one byte for null terminator + { + return; + } + + if (number < 0) + { + //PrintToServer("ERROR: Encode() - Can't encode negative numbers"); + return; + } + + if (number >= 0x110_000) + { + //PrintToServer("ERROR: Encode() - Number is too big to encode"); + return; + } + + // 1 byte + if (number < 0x80) + { + string[zeropos] = number; + string[zeropos + 1] = '\0'; + } + // 2 bytes + else if (number < 0x800) + { + // can't encode if we don't have enough room + if (zeropos + 2 >= strsize) + { + return; + } + + string[zeropos] = 0b_1100_0000 | (number >> 6); // don't need to mask out bits over 0x7FF + string[zeropos + 1] = 0b_1000_0000 | (number & 0b_0011_1111); + + string[zeropos + 2] = '\0'; + } + // 3 bytes + else if (number < 0x10_000) + { + // can't encode if we don't have enough room + if (zeropos + 3 >= strsize) + { + return; + } + + string[zeropos] = 0b_1110_0000 | (number >> 12); // don't need to mask out bits over 0xFFFF + string[zeropos + 1] = 0b_1000_0000 | ((number >> 6) & 0b_0011_1111); + string[zeropos + 2] = 0b_1000_0000 | (number & 0b_0011_1111); + + string[zeropos + 3] = '\0'; + } + // 4 bytes + else if (number < 0x110_000) + { + // can't encode if we don't have enough room + if (zeropos + 4 >= strsize) + { + return; + } + + string[zeropos] = 0b_1111_0000 | (number >> 18); // don't need to mask out bits over 0x10FFFF + string[zeropos + 1] = 0b_1000_0000 | ((number >> 12) & 0b_0011_1111); + string[zeropos + 2] = 0b_1000_0000 | ((number >> 6) & 0b_0011_1111); + string[zeropos + 3] = 0b_1000_0000 | (number & 0b_0011_1111); + + string[zeropos + 4] = '\0'; + } +} + +// decode a UTF-8 string into an array of unicode codepoints +/** + * Decodes a UTF-8 string into an array of unicode codepoints. + * + * @param string String to decode. + * @param strsize String size. + * @param codepoints Array to use to store the codepoints. + * @param cplength Array length. + */ +stock void GCDecodeUtf8(char[] string, int strsize, int[] codepoints, int cplength) +{ + int charindex; + int cpindex; + + while (charindex < strsize && cpindex < cplength) + { + if (string[charindex] == '\0') + { + break; + } + + int bytes = GetCharBytes(string[charindex]); + + switch (bytes) + { + case 1: + { + codepoints[cpindex] = string[charindex]; + } + case 2: + { + codepoints[cpindex] = (string[charindex++] & 0b_0001_1111) << 6; // byte 2 + codepoints[cpindex] |= string[charindex] & 0b_0011_1111; // byte 1 + } + case 3: + { + codepoints[cpindex] = (string[charindex++] & 0b_0000_1111) << 12; // byte 3 + codepoints[cpindex] |= (string[charindex++] & 0b_0011_1111) << 6; // byte 2 + codepoints[cpindex] |= string[charindex] & 0b_0011_1111; // byte 1 + } + case 4: + { + codepoints[cpindex] = (string[charindex++] & 0b_0000_0111) << 18; // byte 4 + codepoints[cpindex] |= (string[charindex++] & 0b_0011_1111) << 12; // byte 3 + codepoints[cpindex] |= (string[charindex++] & 0b_0011_1111) << 6; // byte 2 + codepoints[cpindex] |= string[charindex] & 0b_0011_1111; // byte 1 + } + } + + charindex++; + cpindex++; + } +} + +/** + * Converts an integer to a string. + * Same as IntToString, but it returns the string. + * + * @param num Integer to convert. + * @return String of the number. + */ +stock char[] GCIntToStringRet(int num) +{ + char string[GC_FIXED_BUFFER_SIZE_SMALL]; + IntToString(num, string, sizeof string); + return string; +} + + /** + * Converts a floating point number to a string. + * Same as FloatToString, but it returns the string. + * + * @param num Floating point number to convert. + * @return String of the number. + */ +stock char[] GCFloatToStringRet(float num) +{ + char string[GC_FIXED_BUFFER_SIZE_SMALL]; + FloatToString(num, string, sizeof string); + return string; +} + +/** + * Formats a string according to the SourceMod format rules (see documentation). + * Same as Format, except it returns the formatted string. + * + * @param format Formatting rules. + * @param ... Variable number of format parameters. + * @return Formatted string. + */ +stock char[] GCFormatReturn(const char[] format, any ...) +{ + char string[GC_FIXED_BUFFER_SIZE_LARGE]; + VFormat(string, sizeof string, format, 2); + return string; +} + +/** + * Removes whitespace characters from the beginning and end of a string. + * Same as TrimString, except it returns the formatted string and + * it doesn't modify the passed string. + * + * @param str The string to trim. + * @return Number of bytes written (UTF-8 safe). + */ +stock char[] GCTrimStringReturn(char[] str) +{ + char string[GC_FIXED_BUFFER_SIZE_LARGE]; + strcopy(string, sizeof string, str); + TrimString(string); + return string; +}
\ No newline at end of file diff --git a/sourcemod/scripting/include/gamechaos/tempents.inc b/sourcemod/scripting/include/gamechaos/tempents.inc new file mode 100644 index 0000000..7ec9b5a --- /dev/null +++ b/sourcemod/scripting/include/gamechaos/tempents.inc @@ -0,0 +1,62 @@ + +#if defined _gamechaos_stocks_tempents_included + #endinput +#endif +#define _gamechaos_stocks_tempents_included + +// improved api of some tempents + +#define GC_TEMPENTS_VERSION 0x01_00_00 +#define GC_TEMPENTS_VERSION_STRING "1.0.0" + +#include <sdktools_tempents> + +/** + * Sets up a point to point beam effect. + * + * @param start Start position of the beam. + * @param end End position of the beam. + * @param modelIndex Precached model index. + * @param life Time duration of the beam. + * @param width Initial beam width. + * @param endWidth Final beam width. + * @param colour Color array (r, g, b, a). + * @param haloIndex Precached model index. + * @param amplitude Beam amplitude. + * @param speed Speed of the beam. + * @param fadeLength Beam fade time duration. + * @param frameRate Beam frame rate. + * @param startFrame Initial frame to render. + */ +stock void GCTE_SetupBeamPoints(const float start[3], + const float end[3], + int modelIndex, + float life = 2.0, + float width = 2.0, + float endWidth = 2.0, + const int colour[4] = {255, 255, 255, 255}, + int haloIndex = 0, + float amplitude = 0.0, + int speed = 0, + int fadeLength = 0, + int frameRate = 0, + int startFrame = 0) +{ + TE_Start("BeamPoints"); + TE_WriteVector("m_vecStartPoint", start); + TE_WriteVector("m_vecEndPoint", end); + TE_WriteNum("m_nModelIndex", modelIndex); + TE_WriteNum("m_nHaloIndex", haloIndex); + TE_WriteNum("m_nStartFrame", startFrame); + TE_WriteNum("m_nFrameRate", frameRate); + TE_WriteFloat("m_fLife", life); + TE_WriteFloat("m_fWidth", width); + TE_WriteFloat("m_fEndWidth", endWidth); + TE_WriteFloat("m_fAmplitude", amplitude); + TE_WriteNum("r", colour[0]); + TE_WriteNum("g", colour[1]); + TE_WriteNum("b", colour[2]); + TE_WriteNum("a", colour[3]); + TE_WriteNum("m_nSpeed", speed); + TE_WriteNum("m_nFadeLength", fadeLength); +}
\ No newline at end of file diff --git a/sourcemod/scripting/include/gamechaos/tracing.inc b/sourcemod/scripting/include/gamechaos/tracing.inc new file mode 100644 index 0000000..65d54a8 --- /dev/null +++ b/sourcemod/scripting/include/gamechaos/tracing.inc @@ -0,0 +1,242 @@ + +#if defined _gamechaos_stocks_tracing_included + #endinput +#endif +#define _gamechaos_stocks_tracing_included + +#include <sdktools_trace> + +#define GC_TRACING_VERSION 0x01_00_00 +#define GC_TRACING_VERSION_STRING "1.0.0" + +/** + * Trace ray filter that filters players from being traced. + * + * @param entity Entity. + * @param data Data. + * @return True on success, false otherwise. + */ +stock bool GCTraceEntityFilterPlayer(int entity, any data) +{ + return entity > MAXPLAYERS; +} + +/** + * Traces the player hull beneath the player in the direction of + * the player's velocity. This should be used on the tick when the player lands + * + * @param client Player's index. + * @param pos Player's position vector. + * @param velocity Player's velocity vector. This shuold have the current tick's x and y velocities, but the previous tick's z velocity, since when you're on ground, your z velocity is 0. + * @param result Trace endpoint on success, player's position on failure. + * @param bugged Whether to add gravity to the player's velocity or not. + * @return True on success, false otherwise. + */ +stock bool GCTraceLandPos(int client, const float pos[3], const float velocity[3], float result[3], float fGravity, bool bugged = false) +{ + float newVel[3]; + newVel = velocity; + + if (bugged) + { + // add 0.5 gravity + newVel[2] -= fGravity * GetTickInterval() * 0.5; + } + else + { + // add 1.5 gravity + newVel[2] -= fGravity * GetTickInterval() * 1.5; + } + + ScaleVector(newVel, GetTickInterval() * 2.0); + float pos2[3]; + AddVectors(pos, newVel, pos2); + + float mins[3]; + float maxs[3]; + GetClientMins(client, mins); + GetClientMaxs(client, maxs); + + Handle trace = TR_TraceHullFilterEx(pos, pos2, mins, maxs, MASK_PLAYERSOLID, GCTraceEntityFilterPlayer); + + if (!TR_DidHit(trace)) + { + result = pos; + CloseHandle(trace); + return false; + } + + TR_GetEndPosition(result, trace); + CloseHandle(trace); + + return true; +} + +/** + * Traces the player hull 2 units straight down beneath the player. + * + * @param client Player's index. + * @param pos Player's position vector. + * @param result Trace endpoint on success, player's position on failure. + * @return True on success, false otherwise. + */ +stock bool GCTraceGround(int client, const float pos[3], float result[3]) +{ + float mins[3]; + float maxs[3]; + + GetClientMins(client, mins); + GetClientMaxs(client, maxs); + + float startpos[3]; + float endpos[3]; + + startpos = pos; + endpos = pos; + + endpos[2] -= 2.0; + + TR_TraceHullFilter(startpos, endpos, mins, maxs, MASK_PLAYERSOLID, GCTraceEntityFilterPlayer); + + if (TR_DidHit()) + { + TR_GetEndPosition(result); + return true; + } + else + { + result = endpos; + return false; + } +} + +/** + * Traces a hull between 2 positions. + * + * @param pos1 Position 1. + * @param pos2 Position 2 + * @param result Trace endpoint on success, player's position on failure. + * @return True on success, false otherwise. + */ +stock bool GCTraceBlock(const float pos1[3], const float pos2[3], float result[3]) +{ + float mins[3] = {-16.0, -16.0, -1.0}; + float maxs[3] = { 16.0, 16.0, 0.0}; + + TR_TraceHullFilter(pos1, pos2, mins, maxs, MASK_PLAYERSOLID, GCTraceEntityFilterPlayer); + + if (TR_DidHit()) + { + TR_GetEndPosition(result); + return true; + } + else + { + return false; + } +} + +/** + * Traces from player eye position in the direction of where the player is looking. + * + * @param client Client index. + * @param result Resultant vector. + * @return True on success, false otherwise. + */ +stock bool GCGetEyeRayPosition(int client, float result[3], TraceEntityFilter filter, any data = 0, int flags = MASK_PLAYERSOLID) +{ + float start[3]; + float angle[3]; + + GetClientEyePosition(client, start); + GetClientEyeAngles(client, angle); + + TR_TraceRayFilter(start, angle, flags, RayType_Infinite, filter, data); + + if (TR_DidHit(INVALID_HANDLE)) + { + TR_GetEndPosition(result, INVALID_HANDLE); + return true; + } + return false; +} + +/** + * Traces from player eye position in the direction of where the player is looking, up to a certain distance. + * + * @param client Client index. + * @param result Resultant vector. + * @param distance Maximum distance to trace. + * @return True on success, false otherwise. + */ +stock bool GCTraceEyeRayPositionDistance(int client, float result[3], float distance) +{ + float start[3]; + float angle[3]; + + GetClientEyePosition(client, start); + GetClientEyeAngles(client, angle); + + float endpoint[3]; + float zsine = Sine(DegToRad(-angle[0])); + float zcos = Cosine(DegToRad(-angle[0])); + + endpoint[0] = Cosine(DegToRad(angle[1])) * zcos; + endpoint[1] = Sine(DegToRad(angle[1])) * zcos; + endpoint[2] = zsine; + + ScaleVector(endpoint, distance); + AddVectors(start, endpoint, endpoint); + + TR_TraceRayFilter(start, endpoint, MASK_PLAYERSOLID, RayType_EndPoint, GCTraceEntityFilterPlayer, client); + + if (TR_DidHit()) + { + TR_GetEndPosition(result); + return true; + } + + result = endpoint; + return false; +} + +/** + * Traces a hull in a certain direction and distance. + * + * @param origin Position to trace from. + * @param direction Trace direction. + * @param mins Minimum size of the hull. + * @param maxs Maximum size of the hull. + * @param result Resultant vector. + * @return True on success, false otherwise. + */ +stock bool GCTraceHullDirection(const float origin[3], + const float direction[3], + const float mins[3], + const float maxs[3], + float result[3], + float distance, + TraceEntityFilter filter, + any data = 0, + int flags = MASK_PLAYERSOLID) +{ + float pos2[3]; + float zsine = Sine(DegToRad(-direction[0])); + float zcos = Cosine(DegToRad(-direction[0])); + + pos2[0] = Cosine(DegToRad(direction[1])) * zcos; + pos2[1] = Sine(DegToRad(direction[1])) * zcos; + pos2[2] = zsine; + + ScaleVector(pos2, distance); + AddVectors(origin, pos2, pos2); + + TR_TraceHullFilter(origin, pos2, mins, maxs, flags, filter, data); + if (TR_DidHit()) + { + TR_GetEndPosition(result); + return true; + } + result = pos2; + return false; +}
\ No newline at end of file diff --git a/sourcemod/scripting/include/gamechaos/vectors.inc b/sourcemod/scripting/include/gamechaos/vectors.inc new file mode 100644 index 0000000..79d5e8f --- /dev/null +++ b/sourcemod/scripting/include/gamechaos/vectors.inc @@ -0,0 +1,66 @@ + +#if defined _gamechaos_stocks_vectors_included + #endinput +#endif +#define _gamechaos_stocks_vectors_included + +#define GC_VECTORS_VERSION 0x01_00_01 +#define GC_VECTORS_VERSION_STRING "1.0.1" + +/** + * Calculates the horizontal (x, y) length of a vector. + * + * @param vec Vector. + * @return Vector length (magnitude). + */ +stock float GCGetVectorLength2D(const float vec[3]) +{ + float tempVec[3]; + tempVec = vec; + tempVec[2] = 0.0; + + return GetVectorLength(tempVec); +} + +/** + * Calculates the horizontal (x, y) distance between 2 vectors. + * + * @param x Vector 1. + * @param y Vector 2. + * @param tolerance How close the floats have to be to return true. + * @return True on success, false otherwise. + */ +stock float GCGetVectorDistance2D(const float x[3], const float y[3]) +{ + float x2[3]; + float y2[3]; + + x2 = x; + y2 = y; + + x2[2] = 0.0; + y2[2] = 0.0; + + return GetVectorDistance(x2, y2); +} + +/** + * Checks if 2 vectors are exactly equal. + * + * @param a Vector 1. + * @param b Vector 2. + * @return True on success, false otherwise. + */ +stock bool GCVectorsEqual(const float a[3], const float b[3]) +{ + bool result = true; + for (int i = 0; i < 3; i++) + { + if (a[i] != b[i]) + { + result = false; + break; + } + } + return result; +}
\ No newline at end of file |
