Code:
#include <amxmodx>
/*
Measures the actual time (even if the server is frozen due to working) for up to almost 25d.
new hTimer = TimerStart();
// ...
TimerStop(hTimer);
*/
#define TimerStart() tickcount()
#define TimerMid(%0) ( tickcount() - %0 )
#define TimerStop(%0) ( %0 = tickcount() - %0 )
#define TimerDays(%0) ( %0 / 86400000 )
#define TimerHours(%0) ( %0 % 86400000 / 3600000 )
#define TimerMinutes(%0) ( %0 % 3600000 / 60000 )
#define TimerSeconds(%0) ( %0 % 60000 / 1000 )
#define TimerMilliseconds(%0) ( %0 % 1000 )
/* TimerFormat(hTimer, output[], maxlen, mode = 1, bool:full = 0)
* Formats the result of a timer handle into a string.
*
* Parameters:
*
* hTimer
* Timer Handle
*
* output[]
* The output string
*
* maxlen
* Maximum size of the output string
*
* mode
* 1: 00:00:00:00.000
* 2: 0d 0h 0m 0s 0ms
*
* bool:full
* If full is set to true it will print all fields, even those which contains no value.
* If full is set to false and mode is set to 1, it will print the first field that contains a value and everything after that point. For example: 03:00:00.295
* If full is set to false and mode is set to 2, it will print only the fields that contains a value. For example: 3h 295ms
*/
stock TimerFormat(hTimer, output[], maxlen, mode = 1, bool:full = false) {
new len;
if ( full || TimerDays(hTimer) )
len = formatex(output, maxlen, mode == 1 ? "%02d:" : "%dd ", TimerDays(hTimer));
if ( full || ( len && mode == 1 ) || TimerHours(hTimer) )
len += formatex(output[len], maxlen - len, mode == 1 ? "%02d:" : "%dh ", TimerHours(hTimer));
if ( full || ( len && mode == 1 ) || TimerMinutes(hTimer) )
len += formatex(output[len], maxlen - len, mode == 1 ? "%02d:" : "%dm ", TimerMinutes(hTimer));
if ( full || ( len && mode == 1 ) || TimerSeconds(hTimer) )
len += formatex(output[len], maxlen - len, mode == 1 ? "%02d." : "%ds ", TimerSeconds(hTimer));
if ( full || ! len || mode == 1 || TimerMilliseconds(hTimer) )
len += formatex(output[len], maxlen - len, mode == 1 ? "%03d" : "%dms", TimerMilliseconds(hTimer));
}
public plugin_init() {
register_plugin("Test Plugin 2", "1.0", "[ --{-@ ]");
new cyc = 1000000
test(5, cyc, 1);
test(50, cyc, 1);
test(500, cyc, 1);
test(5000, cyc, 1);
test(5, cyc, 2);
test(50, cyc, 2);
test(500, cyc, 2);
test(5000, cyc, 2);
}
test(range, cycles, method) {
new test[2];
new hTimer;
if ( method == 1 ) {
hTimer = TimerStart();
for ( new i ; i < cycles ; i++ ) {
random_coord1(test, range);
}
TimerStop(hTimer);
}
else {
hTimer = TimerStart();
for ( new i ; i < cycles ; i++ ) {
random_coord2(test, range);
}
TimerStop(hTimer);
}
new output[32];
TimerFormat(hTimer, output, charsmax(output), 2);
server_print("Testing %dM cycles of method %d. Time: %s", cycles/1000000, method, output)
}
stock random_coord1(coord[2], range) {
new newCoord[3], tempCoord[3];
tempCoord[0] = coord[0];
tempCoord[1] = coord[1];
do {
newCoord[0] = tempCoord[0] + random_num(-range, range);
newCoord[1] = tempCoord[1] + random_num(-range, range);
}
while ( get_distance(newCoord, tempCoord) > range )
}
stock random_coord2(Origin[2], range){
new Float:rand_coord[2]
new Float:theta
new Float:r
new Float:rand[2]
rand[0] = random_float(0.0, 1.0); //randomize the smaller radius
rand[1] = random_float(0.0, 1.0); //randomize the angle multiplication factor
r = range * rand[0]
theta = rand[1] * 6 // i use 6 instead of 2*PI , don't judge me (dont really need extra accuracy)
rand_coord[0] = r*floatcos(theta, radian)
rand_coord[1] = r*floatsin(theta, radian)
Origin[0] += rand_coord[0];
Origin[1] += rand_coord[1];
}