From cd0c44af603d0ba00f9a66b1fb24ff61f3dfc965 Mon Sep 17 00:00:00 2001 From: Lemongrass3110 Date: Tue, 26 Dec 2023 23:52:37 +0100 Subject: [PATCH] Refactored script command rand (#8040) Fixes #8041 Added support for int64, so the range of the random numbers that can be generated is much wider now. Changed the logic to be more restrictive: (1) The range version is intended for positive numbers only. (2) If minimum and maximum are equal and no random value can be calculated. Triggering the more restrictive behavior will trigger the script source (file) to be reported in the map-server. Co-authored-by: Atemo --- src/map/script.cpp | 62 ++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/src/map/script.cpp b/src/map/script.cpp index a9e632dd1b..8db855f8e5 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -5566,33 +5566,51 @@ BUILDIN_FUNC(return) return SCRIPT_CMD_SUCCESS; } -/// Returns a random number from 0 to -1. -/// Or returns a random number from to . -/// If is greater than , their numbers are switched. -/// rand() -> -/// rand(,) -> +/// Returns a random number. +/// rand() -> in the mathematical range [0, ] +/// rand(,) -> in the mathematical range [, ] BUILDIN_FUNC(rand) { - int range; - int min; + int64 minimum; + int64 maximum; - if( script_hasdata(st,3) ) - {// min,max - int max = script_getnum(st,3); - min = script_getnum(st,2); - if( max < min ) - SWAP(min, max); - range = max; + // min,max + if( script_hasdata( st, 3 ) ){ + minimum = script_getnum64( st, 2 ); + maximum = script_getnum64( st, 3 ); + + if( minimum > maximum ){ + ShowWarning( "buildin_rand: minimum (%" PRId64 ") is bigger than maximum (%" PRId64 ").\n", minimum, maximum ); + // rnd_value already fixes this by swapping minimum and maximum automatically + } + // range + }else{ + minimum = 0; + maximum = script_getnum64( st, 2 ); + + if( maximum < 0 ){ + ShowError( "buildin_rand: range (%" PRId64 ") is negative.\n", maximum ); + st->state = END; + return SCRIPT_CMD_FAILURE; + } + + // The range version is exclusive maximum + maximum -= 1; + + if( maximum < 1 ){ + ShowError( "buildin_rand: range (%" PRId64 ") is too small. No randomness possible.\n", maximum ); + st->state = END; + return SCRIPT_CMD_FAILURE; + } } - else - {// range - min = 0; - range = script_getnum( st, 2 ) - 1; + + if( minimum == maximum ){ + ShowError( "buildin_rand: minimum (%" PRId64 ") and maximum (%" PRId64 ") are equal. No randomness possible.\n", minimum, maximum ); + st->state = END; + return SCRIPT_CMD_FAILURE; } - if( range <= 1 ) - script_pushint(st, min); - else - script_pushint( st, rnd_value( min, range ) ); + + script_pushint64( st, rnd_value( minimum, maximum ) ); return SCRIPT_CMD_SUCCESS; }