diff options
Diffstat (limited to 'npc/functions')
-rw-r--r-- | npc/functions/array.txt | 48 | ||||
-rw-r--r-- | npc/functions/util.txt | 1 |
2 files changed, 49 insertions, 0 deletions
diff --git a/npc/functions/array.txt b/npc/functions/array.txt index ca2d7fbd6..1bc54610d 100644 --- a/npc/functions/array.txt +++ b/npc/functions/array.txt @@ -447,3 +447,51 @@ function script array_highest { return .@idx; } +// relative_array_random(<array: 0, {[value, probability]..}>) +// returns a random entry from the array, by relative probability +// the first key of the array should be 0 and every entries are a tuple +// of [value, probability] + +function script relative_array_random { + .@is_str = getdatatype(getarg(0)) & DATATYPE_STR; + .@total_prob = getelementofarray(getarg(0), 0); + .@initial_index = getarrayindex(getarg(0)); + .@initial_index = .@initial_index ? .@initial_index : 1; + freeloop(true); + + if (.@total_prob < 1 || getarg(1, false)) + { + // first calculation, or forced re-calculation + .@total_prob = 0; + .@size = getarraysize(getarg(0)); + + for (.@i = .@initial_index + 1; .@i < .@size; .@i += 2) { + if (.@is_str) { + .@total_prob += max(1, atoi(getelementofarray(getarg(0), .@i))); + } else { + .@total_prob += max(1, getelementofarray(getarg(0), .@i)); + } + } + + // we cache on the first key + set(getelementofarray(getarg(0), 0), .@total_prob); + } + + .@target_sum = rand(0, .@total_prob); + + for (.@i = .@initial_index; .@sum < .@target_sum; .@i += 2) { + if (.@is_str) { + .@sum += atoi(getelementofarray(getarg(0), .@i + 1)); + } else { + .@sum += getelementofarray(getarg(0), .@i + 1); + } + + if (.@sum >= .@target_sum) { + break; + } + } + + freeloop(false); + return getelementofarray(getarg(0), .@i); +} + diff --git a/npc/functions/util.txt b/npc/functions/util.txt index d829c4524..b87bc89b1 100644 --- a/npc/functions/util.txt +++ b/npc/functions/util.txt @@ -934,3 +934,4 @@ function script NewcomerEXPDROPUP { return .@BONUS; } + |