From ea7ffafd881944295ff94501cd1ddfd644ed695b Mon Sep 17 00:00:00 2001 From: IgnacioDM Date: Sat, 26 Jan 2019 09:41:45 -0300 Subject: [PATCH] Add square distance functions to xs.inc --- plugins/include/xs.inc | 379 ++++++++++++++++++++++------------------- 1 file changed, 205 insertions(+), 174 deletions(-) diff --git a/plugins/include/xs.inc b/plugins/include/xs.inc index 9a297577..2d85f721 100755 --- a/plugins/include/xs.inc +++ b/plugins/include/xs.inc @@ -11,7 +11,7 @@ /** * XS Library * Version 0.1 - * + * * MACROS THAT YOU CAN DEFINE BEFORE INCLUDING XS.INC: * XS_FLEQ_TOLERANCE: * Tolerance that is used for XS_FLEQ float nearly-equal comparisions @@ -34,7 +34,7 @@ * DEFAULT: 2048 * XS_REPLACEBUF_SIZE * DEFAULT: 3072 - * + * * NOTES: * On AMX, VexdUM is required for some math functions * xs__ / XS__ (2 underscores) stuff is meant to be intern @@ -89,7 +89,7 @@ enum xs_logtypes xs_error, xs_fatalerror, xs__assertionfailed, - + // must come last xs_logtypes_count } @@ -100,18 +100,18 @@ stock const xs__logtypenames[xs_logtypes_count][] = {"DEBUG", "", "WARNING", "ER stock xs_log(xs_logtypes:logtype, any:...) { // WARNING: Don't try to use assert in here; it uses this func - + // Don't log debug if not in debug mode #if !XS_DEBUG if (logtype == xs_debug) return; #endif - + new buffer[XS_LOGBUFFER_SIZE+1]; buffer[XS_LOGBUFFER_SIZE]=0; format_args(buffer, XS_LOGBUFFER_SIZE, 1 /* go from SECOND argument*/); new bool:addLogTypeName = strlen(xs__logtypenames[logtype]) ? true : false; - + // Use AMXX's logging system log_amx("%s%s%s", addLogTypeName ? xs__logtypenames[logtype] : "", addLogTypeName ? ": " : "", buffer); @@ -124,12 +124,12 @@ stock xs_assertfunc(any:exp, const desc[]) // Check exp if (exp) return 1; // ok - + // not ok - + // print info xs_log(xs__assertionfailed, "%s", desc); - + return 0; } #define xs_assert(%1,%2) if (!xs_assertfunc(%1,%2)) xs__global_null /= xs__global_null @@ -151,9 +151,9 @@ new xs__global_null = 0; /** * Gets the sign of a value. - * + * * @param num Number to get the sign from. - * + * * @return -1 if the number is negative, * 0 if the number is equal to 0, * 1 if the number is positive. @@ -165,9 +165,9 @@ stock xs_sign(num) /** * Gets the sign of a float value. - * + * * @param num Number to get the sign from. - * + * * @return -1 if the number is negative, * 0 if the number is equal to 0, * 1 if the number is positive. @@ -179,9 +179,9 @@ stock xs_fsign(Float:num) /** * Gets the absolute value of a number. - * + * * @param num Number to get the absolute value from. - * + * * @return Absolute value of the input number. */ stock xs_abs(num) @@ -191,9 +191,9 @@ stock xs_abs(num) /** * Checks if the number is a power of 2. - * + * * @param x Number to check. - * + * * @return 1 if it is a power of 2, 0 otherwise. */ stock xs_is_2power(x) @@ -203,9 +203,9 @@ stock xs_is_2power(x) /** * Converts degrees to radians. - * + * * @param x Input degrees. - * + * * @return Degrees converted to radians. */ stock Float:xs_deg2rad(Float:x) @@ -215,9 +215,9 @@ stock Float:xs_deg2rad(Float:x) /** * Converts radians to degrees. - * + * * @param x Input radians. - * + * * @return Radians converted to degrees. */ stock Float:xs_rad2deg(Float:x) @@ -227,9 +227,9 @@ stock Float:xs_rad2deg(Float:x) /** * Converts gradians to radians. - * + * * @param x Input gradians. - * + * * @return Gradians converted to radians. */ stock Float:xs_gra2rad(Float:x) @@ -239,9 +239,9 @@ stock Float:xs_gra2rad(Float:x) /** * Converts radians to gradians. - * + * * @param x Input radians. - * + * * @return Radians converted to gradians. */ stock Float:xs_rad2gra(Float:x) @@ -251,19 +251,19 @@ stock Float:xs_rad2gra(Float:x) /** * Checks if two floating point values are nearly equal. - * + * * @param %1 The first value to compare. * @param %2 The second value to compare. - * + * * @return 1 if they are nearly equal, 0 otherwise. */ #define XS_FLEQ(%1,%2) (((%1) <= ((%2) + XS_FLEQ_TOLERANCE)) && ((%1) >= ((%2) - XS_FLEQ_TOLERANCE))) /** * Calculates the reciprocal of the square root of the input value. - * + * * @param x The input value. - * + * * @return The reciprocal of the square root of the input value. */ stock Float:xs_rsqrt(Float:x) @@ -273,11 +273,11 @@ stock Float:xs_rsqrt(Float:x) /** * Calculates the square root of the input value. - * + * * @note This is an alias for floatsqroot(). - * + * * @param x The input value. - * + * * @return The square root of the input value. */ stock Float:xs_sqrt(Float:x) @@ -362,9 +362,9 @@ stock xs__internalseed=0x546875; /** * Sets the seed for the random number generation. - * + * * @param x The seed to set. - * + * * @noreturn */ stock xs_seed(seed) @@ -374,14 +374,14 @@ stock xs_seed(seed) /** * Retrieves a random integer. - * + * * @return A random integer. */ stock xs_irand() { new lo, hi, ll, lh, hh, hl; new result; - + lo = xs__internalseed & 0xffff; hi = xs__internalseed >> 16; xs__internalseed = xs__internalseed * XS__IL_RMULT + 12345; @@ -395,7 +395,7 @@ stock xs_irand() /** * Retrieves a random float. - * + * * @return A random float. */ stock Float:xs_frand() @@ -405,12 +405,12 @@ stock Float:xs_frand() /** * Retrieves a random integer between the specified values. - * + * * @note @pmax has to be greater than @pmin! - * + * * @param pmin The minimum value. * @param pmax The maximum value. - * + * * @return A random integer. */ stock xs_irand_range(pmin, pmax) @@ -428,12 +428,12 @@ stock xs_irand_range(pmin, pmax) /** * Sets vector's components to specified values. - * + * * @param vec The vector to set values to. * @param x The X component to be set. * @param y The Y component to be set. * @param z The Z component to be set. - * + * * @noreturn */ stock xs_vec_set(Float:vec[], Float:x, Float:y, Float:z) @@ -445,11 +445,11 @@ stock xs_vec_set(Float:vec[], Float:x, Float:y, Float:z) /** * Adds two vectors. - * + * * @param in1 The first vector to add. * @param in2 The second vector to add. * @param out The output vector. Can be one of the input vectors. - * + * * @noreturn */ stock xs_vec_add(const Float:in1[], const Float:in2[], Float:out[]) @@ -461,11 +461,11 @@ stock xs_vec_add(const Float:in1[], const Float:in2[], Float:out[]) /** * Subtracts one vector from another one. - * + * * @param in1 Vector to subtract from. * @param in2 Vector to subtract from the first one. * @param out The output vector. Can be one of the input vectors. - * + * * @noreturn */ stock xs_vec_sub(const Float:in1[], const Float:in2[], Float:out[]) @@ -477,12 +477,12 @@ stock xs_vec_sub(const Float:in1[], const Float:in2[], Float:out[]) /** * Adds the second vector scaled by a scalar to the first. - * + * * @param in1 Vector to add to. * @param in2 Vector to scale and add. * @param scalar Scalar to scale the second vector with. * @param out The output vector. Can be one of the input vectors. - * + * * @noreturn */ stock xs_vec_add_scaled(const Float:in1[], const Float:in2[], Float:scalar, Float:out[]) @@ -494,12 +494,12 @@ stock xs_vec_add_scaled(const Float:in1[], const Float:in2[], Float:scalar, Floa /** * Subtracts the second vector scaled by a scalar from the first one. - * + * * @param in1 Vector to subtract from. * @param in2 Vector to scale and subtract. * @param scalar Scalar to scale the second vector with. * @param out The output vector. Can be one of the input vectors. - * + * * @noreturn */ stock xs_vec_sub_scaled(const Float:in1[], const Float:in2[], Float:scalar, Float:out[]) @@ -511,13 +511,13 @@ stock xs_vec_sub_scaled(const Float:in1[], const Float:in2[], Float:scalar, Floa /** * Checks if two vectors are equal. - * + * * @note If you need to check if two vectors are nearly equal, * take a look at xs_vec_nearlyequal(). - * + * * @param vec1 The first input vector to check. * @param vec2 The second input vector to check. - * + * * @return 1 if vectors are equal, 0 otherwise. */ stock bool:xs_vec_equal(const Float:vec1[], const Float:vec2[]) @@ -527,13 +527,13 @@ stock bool:xs_vec_equal(const Float:vec1[], const Float:vec2[]) /** * Checks if two vectors are nearly equal. - * + * * @note If you need to check if two vectors are exactly equal, * take a look at xs_vec_equal(). - * + * * @param vec1 The first input vector to check. * @param vec2 The second input vector to check. - * + * * @return 1 if vectors are equal, 0 otherwise. */ stock bool:xs_vec_nearlyequal(const Float:vec1[], const Float:vec2[]) @@ -543,11 +543,11 @@ stock bool:xs_vec_nearlyequal(const Float:vec1[], const Float:vec2[]) /** * Multiply a vector by a scalar value. - * + * * @param vec The vector to be multiplied. * @param scalar The scalar value to multiply the vector with. * @param out The output vector. Can be the same as the input vector. - * + * * @noreturn */ stock xs_vec_mul_scalar(const Float:vec[], Float:scalar, Float:out[]) @@ -559,11 +559,11 @@ stock xs_vec_mul_scalar(const Float:vec[], Float:scalar, Float:out[]) /** * Divide a vector by a scalar value. - * + * * @param vec The vector to be divided. * @param scalar The scalar value to divide the vector with. * @param out The output vector. Can be the same as the input vector. - * + * * @noreturn */ stock xs_vec_div_scalar(const Float:vec[], Float:scalar, Float:out[]) @@ -576,9 +576,9 @@ stock xs_vec_div_scalar(const Float:vec[], Float:scalar, Float:out[]) /** * Computes the length of a vector. - * + * * @param vec The vector to compute the length of. - * + * * @return The length of the input vector. */ stock Float:xs_vec_len(const Float:vec[]) @@ -588,9 +588,9 @@ stock Float:xs_vec_len(const Float:vec[]) /** * Computes the length of a 2D vector. - * + * * @param vec The vector to compute the length of. - * + * * @return The length of the input vector. */ stock Float:xs_vec_len_2d(const Float:vec[]) @@ -600,10 +600,10 @@ stock Float:xs_vec_len_2d(const Float:vec[]) /** * Computes the distance between two vectors (points). - * + * * @param vec1 First vector. * @param vec2 Second vector. - * + * * @return The distance between two vectors. */ stock Float:xs_vec_distance(const Float:vec1[], const Float:vec2[]) @@ -615,10 +615,10 @@ stock Float:xs_vec_distance(const Float:vec1[], const Float:vec2[]) /** * Computes the distance between two 2D vectors (points). - * + * * @param vec1 First vector. * @param vec2 Second vector. - * + * * @return The distance between two vectors. */ stock Float:xs_vec_distance_2d(const Float:vec1[], const Float:vec2[]) @@ -627,13 +627,44 @@ stock Float:xs_vec_distance_2d(const Float:vec1[], const Float:vec2[]) (vec1[1]-vec2[1]) * (vec1[1]-vec2[1])); } +/** + * Computes the square of the distance between two vectors (points). + * This is faster than the distance. + * + * @param vec1 First vector. + * @param vec2 Second vector. + * + * @return The square of the distance between two vectors. + */ +stock Float:xs_vec_sqdistance(const Float:vec1[], const Float:vec2[]) +{ + return (vec1[0]-vec2[0]) * (vec1[0]-vec2[0]) + + (vec1[1]-vec2[1]) * (vec1[1]-vec2[1]) + + (vec1[2]-vec2[2]) * (vec1[2]-vec2[2]); +} + +/** + * Computes the square of the distance between two 2D vectors (points). + * This is faster than the distance. + * + * @param vec1 First vector. + * @param vec2 Second vector. + * + * @return The square of the distance between two vectors. + */ +stock Float:xs_vec_sqdistance_2d(const Float:vec1[], const Float:vec2[]) +{ + return (vec1[0]-vec2[0]) * (vec1[0]-vec2[0]) + + (vec1[1]-vec2[1]) * (vec1[1]-vec2[1]); +} + /** * Normalizes a vector. Normalized vector is a vector with the length of 1 unit, * but with the same direction as the original vector. - * + * * @param vec The vector to be normalized. * @param out The output vector. Can be the same as the input vector. - * + * * @noreturn */ stock xs_vec_normalize(const Float:vec[], Float:out[]) @@ -646,11 +677,11 @@ stock xs_vec_normalize(const Float:vec[], Float:out[]) /** * Computes the cross product of two vectors. - * + * * @param vec1 The first vector operand of the cross operation. * @param vec2 The second vector operand of the cross operation. * @param out The output vector. *Can't* be one of the input vectors. - * + * * @noreturn */ stock xs_vec_cross(const Float:vec1[], const Float:vec2[], Float:out[]) @@ -662,10 +693,10 @@ stock xs_vec_cross(const Float:vec1[], const Float:vec2[], Float:out[]) /** * Computes the dot product of two vectors. - * + * * @param vec1 The first vector operand of the dot operation. * @param vec2 The second vector operand of the dot operation. - * + * * @return The dot product of two input vectors. */ stock Float:xs_vec_dot(const Float:vec1[], const Float:vec2[]) @@ -675,10 +706,10 @@ stock Float:xs_vec_dot(const Float:vec1[], const Float:vec2[]) /** * Negates a vector. - * + * * @param vec The vector to negate. * @param out The output vector. Can be the same as the input vector. - * + * * @noreturn */ stock xs_vec_neg(const Float:vec[], Float:out[]) @@ -690,10 +721,10 @@ stock xs_vec_neg(const Float:vec[], Float:out[]) /** * Copies a vector into another one. - * + * * @param vecIn The vector to copy. * @param vecOut The output vector where to copy the input vector. - * + * * @noreturn */ stock xs_vec_copy(const Float:vecIn[], Float:vecOut[]) @@ -705,10 +736,10 @@ stock xs_vec_copy(const Float:vecIn[], Float:vecOut[]) /** * Computes the angle between two vectors. - * + * * @param vec1 The first vector. * @param vec2 The second vector. - * + * * @return The angle between two input vectors in degrees. */ stock Float:xs_vec_angle(const Float:vec1[], const Float:vec2[]) @@ -718,41 +749,41 @@ stock Float:xs_vec_angle(const Float:vec1[], const Float:vec2[]) /** * Reflects a vector about a normal. - * + * * @param vec The vector to be reflected. * @param normal The normal vector about which to reflect. * @param out The output reflected vector. - * + * * @noreturn */ stock xs_vec_reflect(const Float:vec[], const Float:normal[], Float:out[]) { // normalize(vec) - (normal * 2.0 * (tmp . normal)) * length(vec) - + new Float:tmp1[3]; xs_vec_normalize(vec, tmp1); - + // tmp1 - (normal * 2.0 * (tmp . normal)) * length(vec) - + new Float:tmp2[3]; xs_vec_mul_scalar(normal, 2.0, tmp2); xs_vec_mul_scalar(tmp2, xs_vec_dot(tmp1, normal), tmp2); - + // tmp1 - tmp2 * length(vec) xs_vec_mul_scalar(tmp2, xs_vec_len(vec), tmp2); - + // tmp1 - tmp2 xs_vec_sub(tmp1, tmp2, out); } /** * Turns a 3D vector into a 2D vector. - * + * * @note This function just ignores the Z (3rd) component of a 3D vector. - * + * * @param vec A 3D vector to turn into a 2D vector. * @param out The output 2D vector. - * + * * @noreturn */ stock xs_vec_make2d(const Float:vec[3], Float:out[2]) @@ -773,13 +804,13 @@ stock xs_vec_make2d(const Float:vec[3], Float:out[2]) /** * Sets a plane to the specified values. - * + * * @param plane The plane to set the values to. It's a 4D vector. * @param a The first component of a plane to be set. * @param b The second component of a plane to be set. * @param c The third component of a plane to be set. * @param d The fouth component of a plane to be set. - * + * * @noreturn */ stock xs_plane_set(Float:plane[], Float:a, Float:b, Float:c, Float:d) @@ -792,39 +823,39 @@ stock xs_plane_set(Float:plane[], Float:a, Float:b, Float:c, Float:d) /** * Constructs a plane out of 4 points in space. - * + * * @param plane The output plane to store the newly created plane. * @param p1 The first point of a plane. * @param p2 The second point of a plane. * @param p3 The third point of a plane. - * + * * @noreturn */ stock xs_plane_3p(Float:plane[], const Float:p1[], const Float:p2[], const Float:p3[]) { new Float:normalA[3], Float:normalB[3]; - + // normalA = Normalize(p3 - p1); normalA[0] = p3[0] - p1[0]; normalA[1] = p3[1] - p1[1]; normalA[2] = p3[2] - p1[2]; xs_vec_normalize(normalA, normalA); - + // normalB = Normalize(p3 - p2); normalB[0] = p3[0] - p2[0]; normalB[1] = p3[1] - p2[1]; normalB[2] = p3[2] - p2[2]; xs_vec_normalize(normalB, normalB); - + // plane normal = Normalize(normalA cross normalB) xs_vec_cross(normalA, normalB, plane); xs_vec_normalize(plane, plane); - + // plane shift distance = (-p1) dot plane normal new Float:__tmp[3]; xs_vec_neg(plane, __tmp); plane[XS_PLANE_D] = xs_vec_dot(__tmp, p1); - + } /** @@ -832,10 +863,10 @@ stock xs_plane_3p(Float:plane[], const Float:p1[], const Float:p2[], const Float * * @note If you have to check if two planes are just nearly equal, * take a look at xs_plane_nearlyequal(). - * + * * @param plane1 The first plane to check. * @param plane2 The second plane to check. - * + * * @return 1 if planes are equal, 0 otherwise. */ stock bool:xs_plane_equal(const Float:plane1[], const Float:plane2[]) @@ -853,10 +884,10 @@ stock bool:xs_plane_equal(const Float:plane1[], const Float:plane2[]) * * @note If you have to check if two planes are exactly equal, * take a look at xs_plane_equal(). - * + * * @param plane1 The first plane to check. * @param plane2 The second plane to check. - * + * * @return 1 if planes are nearly equal, 0 otherwise. */ stock bool:xs_plane_nearlyequal(const Float:plane1[], const Float:plane2[]) @@ -871,10 +902,10 @@ stock bool:xs_plane_nearlyequal(const Float:plane1[], const Float:plane2[]) /** * Computes the distance between a plane and a point. - * + * * @param plane The plane to check the distance from. * @param point The point to check the distance to. - * + * * @return The distance between the input plane and point. */ stock Float:xs_plane_dst2point(const Float:plane[], const Float:point[]) @@ -887,21 +918,21 @@ stock Float:xs_plane_dst2point(const Float:plane[], const Float:point[]) * Checks whether a plane intersects with the ray starting at @rayStart and * going to @rayDir direction. * If it does intersect, outputs the intersection point in @out. - * + * * @param plane The plane to check intersection with. * @param rayStart The starting point of the ray. * @param rayDir Direction in which the ray is going. * @param out The vector to copy the intersection point to, if it exists. - * + * * @return true if they intersect, false otherwise. */ stock bool:xs_plane_rayintersect(const Float:plane[], const Float:rayStart[], const Float:rayDir[], Float:out[]) { new Float:a = xs_vec_dot(plane, rayDir); - + if (a == 0.0) return false; // ray is parallel to plane - + // if (distance plane<->(rayStart + rayDir) > distance plane<->rayStart) and both have the same sign, the ray // goes away from the plane new Float:rsplusrd[3]; @@ -910,23 +941,23 @@ stock bool:xs_plane_rayintersect(const Float:plane[], const Float:rayStart[], co new Float:dst2 = xs_plane_dst2point(plane, rayStart); if (xs_fabs(dst1) > xs_fabs(dst2) && xs_fsign(dst1) == xs_fsign(dst2)) return false; - - + + // out = rayStart - rayDir * ((distance plane<->rayStart) / a) new Float:__tmp[3]; xs_vec_mul_scalar(rayDir, xs_plane_dst2point(plane, rayStart) / a, __tmp); // out = rayStart - tmp xs_vec_sub(rayStart, __tmp, out); - + return true; } /** * Checks if a point is on a specified plane. - * + * * @param plane The plane to check. * @param point The point to check. - * + * * @return true if the point is on the plane, false otherwise. */ stock bool:xs_point_onplane(const Float:plane[], const Float:point[]) @@ -936,11 +967,11 @@ stock bool:xs_point_onplane(const Float:plane[], const Float:point[]) /** * Projects a point on the plane. Stores the projected point in @out. - * + * * @param plane The plane to project the point onto. * @param point The point to project onto the plane. * @param out The vector to copy the projected point into. - * + * * @noreturn */ stock xs_projpoint_onplane(const Float:plane[], const Float:point[], Float:out[]) @@ -954,10 +985,10 @@ stock xs_projpoint_onplane(const Float:plane[], const Float:point[], Float:out[] /** * Copies a plane. - * + * * @param planeIn The plane to copy. * @param planeOut The plane to store the copy into. - * + * * @noreturn */ stock xs_plane_copy(const Float:planeIn[], Float:planeOut[]) @@ -977,34 +1008,34 @@ stock xs_plane_copy(const Float:planeIn[], Float:planeOut[]) /** * Computes forward, right and up vectors from given angles. - * + * * @param angles Angles to compute vectors from. * @param fwd The vector to store the forward vector into. * @param right The vector to store the right vector into. * @param up The vector to store the up vector into. - * + * * @noreturn */ stock xs_anglevectors(const Float:angles[3], Float:fwd[3], Float:right[3], Float:up[3]) { // sin (s) and cos (c) for yaw (y), pitch (p) and roll (r) new Float:sr, Float:sp, Float:sy, Float:cr, Float:cp, Float:cy; - + sy = xs_sin(angles[XS_YAW], degrees); cy = xs_cos(angles[XS_YAW], degrees); sp = xs_sin(angles[XS_PITCH], degrees); cp = xs_cos(angles[XS_PITCH], degrees); sr = xs_sin(angles[XS_ROLL], degrees); cr = xs_cos(angles[XS_ROLL], degrees); - + fwd[0] = cp*cy; fwd[1] = cp*sy; fwd[2] = -sp; - + right[0] = (-1*sr*sp*cy + -1*cr*-sy); right[1] = (-1*sr*sp*sy + -1*cr*cy); right[2] = -1*sr*cp; - + up[0] = (cr*sp*cy + -sr*-sy); up[1] = (cr*sp*sy + -sr*cy); up[2] = cr*cp; @@ -1013,10 +1044,10 @@ stock xs_anglevectors(const Float:angles[3], Float:fwd[3], Float:right[3], Float /** * Finds a character in a string and returns its position in the string. - * + * * @param str The string to search in. * @param chr The character to search for in the string. - * + * * @return The character position if found, -1 otherwise. */ stock xs_strchr(const str[], chr) @@ -1032,19 +1063,19 @@ stock xs_strchr(const str[], chr) /** * Remove @charstotrim number of characters from @stringtotrim, * either from the beginning or the end of the string. - * + * * @param stringtotrim The string to be trimmed. * @param charstostrim The number of characters to trim. * @param fromleft If set to true, the string will be trimmer from the left. * If false, it will be trimmed from the right. - * + * * @noreturn */ stock xs_strtrim(stringtotrim[], charstotrim, bool:fromleft = true) { if (charstotrim <= 0) return; - + if (fromleft) { new maxlen = strlen(stringtotrim); @@ -1068,7 +1099,7 @@ stock xs_strtrim(stringtotrim[], charstotrim, bool:fromleft = true) /** * Copies characters from @oldmsg to @newmsg, starting at @start and ending * at @end (includes the end character). - * + * * @param oldmsg The string to copy from. * @param newmsg The string to copy to. * @param start Starting position of the @oldmsg string to copy from. @@ -1076,38 +1107,38 @@ stock xs_strtrim(stringtotrim[], charstotrim, bool:fromleft = true) * @param outlen If positive, specifies the maximum number of characters * to be copied. Otherwise, the function assumes that * newmsg is at least @end - @start + 1 characters long. - * + * * @noreturn */ stock xs_strmid(const oldmsg[], newmsg[], start, end, outlen=-1) { new len = strlen(oldmsg); - + if(start < 0) start = 0; - + ++end; // Include end - + if(end <= start || end > len) end = len; new j = 0, i = start; for(; (i < end) && (outlen--);) newmsg[j++] = oldmsg[i++]; - + newmsg[j] = 0; } /** * "Explodes" a string, breaking it at the @delimeter character and putting * each exploded part into the @output array. - * + * * @param input The input string to be exploded. * @param output The output array of string where exploded string will be stored. * @param delimeter The character to break the string at. * @param maxelems Maximum amount of elements in @output. * @param elemsize Maximum size of each string in the @output array. - * + * * @return The number of strings successfully exploded. */ stock xs_explode(const input[], output[][], delimiter, maxelems, elemsize) @@ -1131,7 +1162,7 @@ stock xs_explode(const input[], output[][], delimiter, maxelems, elemsize) copied += found; } } - + nLen += copied + 1; // +1: skip delimiter } return nIdx; @@ -1140,13 +1171,13 @@ stock xs_explode(const input[], output[][], delimiter, maxelems, elemsize) /** * The opposite of xs_explode(). Takes an array of strings and puts them together * in a single string, delimeted by the @delimeter character. - * + * * @param output The string to store the impoded string into. * @param outsize The size of the output buffer. * @param delimeter The character to put between imploded strings. * @param input The array of strings to implode. * @param elemsnum The number of strings in the input array. - * + * * @return The number of characters in the final output buffer. */ stock xs_implode(output[], outsize, delimiter, const input[][], elemsnum) @@ -1166,7 +1197,7 @@ stock xs_implode(output[], outsize, delimiter, const input[][], elemsnum) if (pos >= outsize) return outsize; } - + output[--pos] = 0; // The last char would be delimiter, so skip it. return pos; } @@ -1176,12 +1207,12 @@ stock xs__replace_buf[XS_REPLACEBUF_SIZE]; /** * Replaces all occurencies of @what in @text with @with. - * + * * @param text The text to search in. * @param len The maximum size of the @text buffer. * @param what What to search for. * @param with What to replace occurencies with. - * + * * @return Returns the number of replaced items. */ stock xs_replace(text[], len, const what[], const with[]) @@ -1224,12 +1255,12 @@ stock xs_replace(text[], len, const what[], const with[]) /** * Replaces all occurencies of @what character in @text with @with character. - * + * * @param text The text to search in. * @param len The maximum size of the @text buffer. * @param what What character to search for. * @param with What charactear to replace occurencies with. - * + * * @return The number of replaced characters. */ stock xs_replace_char(text[], len, what, with) @@ -1240,7 +1271,7 @@ stock xs_replace_char(text[], len, what, with) arr[1] = 0; arr[2] = with; arr[3] = 0; - + return xs_replace(text, len, arr[0], arr[2]); } @@ -1248,11 +1279,11 @@ stock xs_replace_char(text[], len, what, with) /** * Retrieves the name of a command identified by its ID. - * + * * @param cid The command ID. * @param namestr The buffer where to store command's name. * @param namelen The maximum size of the output buffer. - * + * * @noreturn */ stock xs_concmd_name(cid, namestr[], namelen) @@ -1264,17 +1295,17 @@ stock xs_concmd_name(cid, namestr[], namelen) /** * Checks whether there are at least @num free visible slots. - * + * * @param num The number of slots to check. - * + * * @return true if there are at least that many free, false otherwise. */ stock bool:xs_freevisibleslots(num) -{ +{ new maxplayers = get_cvar_num("sv_visiblemaxplayers"); if (maxplayers <= 0) maxplayers = MaxClients; - + return (get_playersnum(1) <= maxplayers-num) ? true : false; } @@ -1282,7 +1313,7 @@ stock xs__maxnum = 0; /** * Returns the biggest possible positive number. - * + * * @return The biggest possible positive number. */ stock xs_get_maxnum() @@ -1302,7 +1333,7 @@ stock xs_get_maxnum() /** * Returns the smallest possible negative number. - * + * * @return The smallest possible negative number. */ stock xs_get_minnum() @@ -1322,11 +1353,11 @@ stock xs_get_minnum() stock xs_get_maxmessages() { new name[2]; - + for (new i = XS__MAX_ENGINE_MESSAGES + 1; i <= XS__MAX_POSSIBLE_MESSAGES; i++) if (!get_user_msgname(i, name, 1)) return i - 1; - + return XS__MAX_POSSIBLE_MESSAGES; } @@ -1335,10 +1366,10 @@ stock bool:xs_is_msg_valid(msgid) { new name[2]; new retval = get_user_msgname(msgid, name, 1); - + if (msgid < 1 || (msgid > XS__MAX_ENGINE_MESSAGES && !retval)) return false; - + return true; } @@ -1396,16 +1427,16 @@ stock xs__ITaskId; stock xs_task_begin(Float:interval, const func[], id = 0, const flags[] = "", repeat = 0) { xs_assert(xs__TaskInterval == 0.0, "New xs_task_begin called before xs_task_end"); - + xs__TaskInterval = interval; if (xs__TaskInterval < 0.1) xs__TaskInterval = 0.1; - + copy(xs__TaskFunc, 47, func); xs__TaskId = id; copy(xs__TaskFlags, 4, flags); xs__TaskRepeat = repeat; - + xs__TaskParamCount = 0; } @@ -1415,10 +1446,10 @@ stock xs_task_pushint(value, bool:__isfl=false /*internal use only*/) xs_assert(xs__TaskInterval, "xs_task_push* called without xs_task_begin"); if (xs__TaskParamCount >= XS_TASK_MAXPARAMS) return 0; - + xs__TaskParamType[xs__TaskParamCount] = __isfl ? xs_float : xs_int; xs__TaskParamValue[xs__TaskParamCount] = value; - + ++xs__TaskParamCount; return 1; } @@ -1435,7 +1466,7 @@ stock xs_task_pushstr(const value[]) xs_assert(xs__TaskInterval, "xs_task_push* called without xs_task_begin"); if (xs__TaskParamCount >= XS_TASK_MAXPARAMS) return 0; - + xs__TaskParamType[xs__TaskParamCount] = xs_string; strpack(xs__TaskParamValue[xs__TaskParamCount], value); ++xs__TaskParamCount; @@ -1446,7 +1477,7 @@ stock xs_task_pushstr(const value[]) stock xs_task_end() { xs_assert(xs__TaskInterval, "xs_task_end called without xs_task_begin"); - + // find a task id if needed if (xs__TaskId == -1) { @@ -1458,12 +1489,12 @@ stock xs_task_end() return -1; } } - - set_task(xs__TaskInterval, xs__TaskFunc, xs__TaskId, xs__TaskParam, + + set_task(xs__TaskInterval, xs__TaskFunc, xs__TaskId, xs__TaskParam, 1 + xs__TaskParamCount * (XS_TASK_MAXPARAMSIZE char), xs__TaskFlags, xs__TaskRepeat); - + xs__TaskInterval = 0.0; - + return xs__TaskId; } @@ -1498,7 +1529,7 @@ stock xs_paramtypes:xs_task_paramtype(paramid) { if (paramid < 0 || paramid >= xs__ITaskParamCount) return xs_invalid; - + return xs_paramtypes:xs__ITaskParamType[paramid]; } @@ -1509,7 +1540,7 @@ stock xs_task_paramint(paramid) return 0; if (xs__ITaskParamType[paramid] != _:xs_int) return 0; - + return xs__ITaskParamValue[paramid]; } @@ -1520,7 +1551,7 @@ stock Float:xs_task_paramfl(paramid) return 0.0; if (xs__ITaskParamType[paramid] != _:xs_float) return 0.0; - + return Float:xs__ITaskParamValue[paramid]; } @@ -1528,12 +1559,12 @@ stock Float:xs_task_paramfl(paramid) stock xs_task_paramstr(paramid, out[], maxlen) { #pragma unused maxlen - + if (paramid < 0 || paramid >= xs__ITaskParamCount) return 0; if (xs__ITaskParamType[paramid] != _:xs_string) return 0; - + strunpack(out, xs__ITaskParamValue[paramid]); return 1; }