diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 289362e7b5..8f6d1efcef 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -7613,6 +7613,29 @@ Example: --------------------------------------- +*min({,,...}) +*minimum({,,...}) +*max({,,...}) +*maximum({,,...}) + +Returns the smallest (or biggest) from the set of given parameters. +These parameters have to be either numbers or number arrays. + +Example: + .@minimum = min( 1, -6, -2, 8, 2 ); // .@minimum will be equal to -6 + .@maximum = max( 0, 5, 10, 4 ); // .@maximum will be equal to 10 + .@level = min( BaseLevel, 70 ); // .@level will be the character's base level, capped to 70 + + setarray .@testarray, 4, 5, 12, 6, 7, 3, 8, 9, 10; + + .@minimum = min( .@testarray ); // .@minimum will be equal to 3 + .@maximum = max( .@testarray ); // .@maximum will be equal to 12 + + .@minimum = min( -6, 1, 2, 3, .@testarray ); // .@minimum will be equal to -6 + .@maximum = max( -6, 1, 2, 3, .@testarray ); // .@minimum will be equal to 12 + +--------------------------------------- + *md5("") Returns the md5 checksum of a number or string. diff --git a/src/map/script.c b/src/map/script.c index 0bfa82c236..e9e4ca7d97 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -21167,6 +21167,117 @@ BUILDIN_FUNC(adopt) return SCRIPT_CMD_FAILURE; } +/** + * Returns the minimum or maximum of all the given parameters for integer variables. + * + * min( {,value or array 2,...} ); + * minimum( {,value or array 2,...} ); + * max( {,value or array 2,...} ); + * maximum( {,value or array 2,...} ); +*/ +BUILDIN_FUNC(minmax){ + char *functionname; + unsigned int i; + int value; + // Function pointer for our comparison function (either min or max at the moment) + int32 (*func)(int32, int32); + + // Get the real function name + functionname = script_getfuncname(st); + + // Our data should start at offset 2 + i = 2; + + if( !script_hasdata( st, i ) ){ + ShowError( "buildin_%s: no arguments given!\n", functionname ); + st->state = END; + return SCRIPT_CMD_FAILURE; + } + + if( strnicmp( functionname, "min", strlen( "min" ) ) == 0 ){ + value = INT_MAX; + func = i32min; + }else if( strnicmp( functionname, "max", strlen( "max" ) ) == 0 ){ + value = INT_MIN; + func = i32max; + }else{ + ShowError( "buildin_%s: Unknown call case for min/max!\n", functionname ); + st->state = END; + return SCRIPT_CMD_FAILURE; + } + + // As long as we have data on our script stack + while( script_hasdata(st,i) ){ + struct script_data *data; + + // Get the next piece of data from the script stack + data = script_getdata( st, i ); + + // Is the current parameter a single integer? + if( data_isint( data ) ){ + value = func( value, script_getnum( st, i ) ); + // Is the current parameter an array variable? + }else if( data_isreference( data ) ){ + const char *name; + struct map_session_data* sd; + unsigned int start, end; + + // Get the name of the variable + name = reference_getname(data); + + // Check if it's a string variable + if( is_string_variable( name ) ){ + ShowError( "buildin_%s: illegal type, need integer!\n", functionname ); + script_reportdata( data ); + st->state = END; + return SCRIPT_CMD_FAILURE; + } + + // Get the session data, if a player is attached + sd = st->rid ? map_id2sd(st->rid) : NULL; + + // Try to find the array's source pointer + if( !script_array_src( st, sd, name, reference_getref( data ) ) ){ + ShowError( "buildin_%s: not a array!\n", functionname ); + script_reportdata( data ); + st->state = END; + return SCRIPT_CMD_FAILURE; + } + + // Get the start and end indices of the array + start = reference_getindex( data ); + end = script_array_highest_key( st, sd, name, reference_getref( data ) ); + + // Skip empty arrays + if( start < end ){ + int id; + + // For getting the values we need the id of the array + id = reference_getid( data ); + + // Loop through each value stored in the array + for( ; start < end; start++ ){ + value = func( value, (int32)get_val2( st, reference_uid( id, start ), reference_getref( data ) ) ); + + script_removetop( st, -1, 0 ); + } + } + }else{ + ShowError( "buildin_%s: not a supported data type!\n", functionname ); + script_reportdata( data ); + st->state = END; + return SCRIPT_CMD_FAILURE; + } + + // Continue with the next stack entry + i++; + } + + script_pushint( st, value ); + + return SCRIPT_CMD_SUCCESS; +} + /** * Safety Base/Job EXP addition than using `set BaseExp,n;` or `set JobExp,n;` * Unlike `getexp` that affected by some adjustments. @@ -21566,6 +21677,10 @@ struct script_function buildin_func[] = { BUILDIN_DEF(sqrt,"i"), BUILDIN_DEF(pow,"ii"), BUILDIN_DEF(distance,"iiii"), + BUILDIN_DEF2(minmax,"min", "*"), + BUILDIN_DEF2(minmax,"minimum", "*"), + BUILDIN_DEF2(minmax,"max", "*"), + BUILDIN_DEF2(minmax,"maximum", "*"), // <--- [zBuffer] List of mathematics commands BUILDIN_DEF(md5,"s"), // [zBuffer] List of dynamic var commands --->