// Evol Script // Author: Gumi // array_pad(, , ) // prepend or append until the array is of size // returns the amount added on success, or false (0) if nothing changed function script array_pad { .@index = getarrayindex(getarg(0)); // passed index .@count = getarraysize(getarg(0)) - .@index; // actual size .@size = getarg(1); // desired size .@absolute = (.@size >= 0 ? .@size : -(.@size)); // |size| .@delta = .@absolute - .@count; // amount to fill if (.@absolute <= .@count) { return false; // nothing to do } if (.@size < 0) { copyarray(getelementofarray(getarg(0), .@index + .@delta), getarg(0), .@count); // shift to the right cleararray(getarg(0), getarg(2), .@delta); // prepend } else { cleararray(getelementofarray(getarg(0), .@index + .@count), getarg(2), .@delta); // append } return .@delta; } // array_replace(, , {, }) // replace every occurence of with // returns the number of replaced elements function script array_replace { .@size = getarraysize(getarg(0)); .@neq = getarg(3, false); freeloop(true); for (.@i = getarrayindex(getarg(0)); .@i < .@size; ++.@i) { if ((.@neq && (getelementofarray(getarg(0), .@i) != getarg(1))) || (!(.@neq) && (getelementofarray(getarg(0), .@i) == getarg(1)))) { set(getelementofarray(getarg(0), .@i), getarg(2)); ++.@count; } } freeloop(false); return .@count; } // array_find(, {, }) // return the index of the first occurence of in // if not found it returns -1 function script array_find { .@size = getarraysize(getarg(0)); .@neq = getarg(2, false); freeloop(true); for (.@i = getarrayindex(getarg(0)); .@i < .@size; ++.@i) { if ((.@neq && (getelementofarray(getarg(0), .@i) != getarg(1))) || (!(.@neq) && (getelementofarray(getarg(0), .@i) == getarg(1)))) { freeloop(false); return .@i; } } freeloop(false); return -1; } // array_rfind(, {, }) // return the index of the last occurence of in // if not found it returns -1 function script array_rfind { .@min = getarrayindex(getarg(0)); .@neq = getarg(2, false); freeloop(true); for (.@i = (getarraysize(getarg(0)) - 1); .@i >= .@min; --.@i) { if ((.@neq && (getelementofarray(getarg(0), .@i) != getarg(1))) || (!(.@neq) && (getelementofarray(getarg(0), .@i) == getarg(1)))) { freeloop(false); return .@i; } } freeloop(false); return -1; } // array_exists(, {, }) // return true or false accordingly if is found in function script array_exists { return array_find(getarg(0), getarg(1), getarg(2, false)) > -1; } // array_count(, {, }) // counts the number of occurrence of in the function script array_count { .@size = getarraysize(getarg(0)); .@neq = getarg(2, false); freeloop(true); for (.@i = getarrayindex(getarg(0)); .@i < .@size; ++.@i) { if ((.@neq && (getelementofarray(getarg(0), .@i) != getarg(1))) || (!(.@neq) && (getelementofarray(getarg(0), .@i) == getarg(1)))) { ++.@count; } } freeloop(false); return .@count; } // array_entries() // returns the number of non-empty entries function script array_entries { if (isstr(getarg(0)) == 1) { return array_count(getarg(0), "", true); } return array_count(getarg(0), 0, true); } // array_remove(, {, }) // removes every occurrence of in the while shifting left function script array_remove { .@size = getarraysize(getarg(0)); .@neq = getarg(2, false); freeloop(true); for (.@i = getarrayindex(getarg(0)); .@i < .@size; ++.@i) { if ((.@neq && (getelementofarray(getarg(0), .@i) != getarg(1))) || (!(.@neq) && (getelementofarray(getarg(0), .@i) == getarg(1)))) { deletearray(getelementofarray(getarg(0), .@i), 1); // shift left ++.@count; // increase the counter --.@size; // reduce the size --.@i; // step back } } freeloop(false); return .@count; } // array_reverse() // reverses the array function script array_reverse { .@index = getarrayindex(getarg(0)); .@size = getarraysize(getarg(0)); freeloop(true); for (.@i = .@index; .@i < ((.@size + .@index) / 2); ++.@i) { swap(getelementofarray(getarg(0), .@i), getelementofarray(getarg(0), .@size + .@index - 1 - .@i)); // a <> b } freeloop(false); return true; } // array_sum() // return the sum of every element of the array function script array_sum { .@size = getarraysize(getarg(0)); freeloop(true); for (.@i = getarrayindex(getarg(0)); .@i < .@size; ++.@i) { .@sum += getelementofarray(getarg(0), .@i); } freeloop(false); return .@sum; } // array_difference() // return the difference of every element of the array function script array_difference { .@size = getarraysize(getarg(0)); freeloop(true); for (.@i = getarrayindex(getarg(0)); .@i < .@size; ++.@i) { .@diff -= getelementofarray(getarg(0), .@i); } freeloop(false); return .@diff; } // array_avg() // return the average of every element of the array function script array_avg { .@size = getarraysize(getarg(0)); .@suma = array_sum(getarg(0)); return .@suma / .@size; } // array_shift() // returns the first element of the array and removes it, while shifting left function script array_shift { if (isstr(getarg(0)) == 1) { .@val$ = getarg(0); } else { .@int = true; .@val = getarg(0); } deletearray(getarg(0), 1); // shift left return .@int ? .@val : .@val$; } // array_unshift(, ) // adds to the start of the array, while shifting right // returns the new size function script array_unshift { .@size = getarraysize(getarg(0)) + 1; array_pad(getarg(0), -(.@size - getarrayindex(getarg(0))), getarg(1)); return .@size; } // array_pop() // returns the last element of the array and removes it function script array_pop { .@last = getarraysize(getarg(0)) - 1; if (isstr(getelementofarray(getarg(0), .@last)) == 1) { .@val$ = getelementofarray(getarg(0), .@last); } else { .@int = true; .@val = getelementofarray(getarg(0), .@last); } deletearray(getelementofarray(getarg(0), .@last), 1); return .@int ? .@val : .@val$; } // TODO: Rename to array_append >.< // array_push(, ) // adds to the end of the array // returns the new size function script array_push { .@size = getarraysize(getarg(0)); set(getelementofarray(getarg(0), .@size), getarg(1)); return .@size + 1; } // array_shuffle() // shuffles the array function script array_shuffle { .@index = getarrayindex(getarg(0)); .@size = getarraysize(getarg(0)) - .@index; freeloop(true); if (isstr(getarg(0)) == 1) { copyarray(.@tmp$[0], getarg(0), .@size); for (; .@size >= 1; --.@size) { set(getelementofarray(getarg(0), .@index + .@size - 1), array_shift(.@tmp$[rand(.@size)])); } } else { copyarray(.@tmp[0], getarg(0), .@size); for (; .@size >= 1; --.@size) { set(getelementofarray(getarg(0), .@index + .@size - 1), array_shift(.@tmp[rand(.@size)])); } } freeloop(false); return true; } // array_unique({, }) // allows entries to appear up to in the array function script array_unique { .@size = getarraysize(getarg(0)); .@max = getarg(1, 1); freeloop(true); for (.@i = getarrayindex(getarg(0)); .@i < .@size; ++.@i) { .@count = 1; for (.@e = .@i + 1; .@e < .@size; ++.@e) { if (getelementofarray(getarg(0), .@i) == getelementofarray(getarg(0), .@e)) { if (++.@count >= .@max) { deletearray(getelementofarray(getarg(0), .@e), 1); ++.@removed; // increase counter --.@size; // reduce size --.@e; // step back } } } } freeloop(false); return .@removed; } // array_diff(, {, ...}, ) // compares array1 against one or more other arrays and fills the last array // with the values in array1 that are not present in any of the other arrays // returns the number of entries not matching function script array_diff { .@size = getarraysize(getarg(0)); .@index = getarrayindex(getarg(0)); freeloop(true); for (.@a = 1; .@a < (getargcount() - 1); ++.@a) { for (.@i = .@index; .@i < .@size; ++.@i) { if (!array_exists(getarg(.@a), getelementofarray(getarg(0), .@i))) { array_push(getarg(getargcount() - 1), getelementofarray(getarg(0), .@i)); ++.@count; } } } freeloop(false); return .@count; } // array_filter(, "") // filters the array using a callback function function script array_filter { .@size = getarraysize(getarg(0)); .@neq = getarg(2, false); freeloop(true); for (.@i = getarrayindex(getarg(0)); .@i < .@size; ++.@i) { .@eq = callfunc(getarg(1), getelementofarray(getarg(0), .@i)) != false; if ((.@neq && .@eq) || (!(.@neq) && !(.@eq))) { deletearray(getelementofarray(getarg(0), .@i), 1); // shift left ++.@count; // increase the counter --.@size; // reduce the size --.@i; // step back } } freeloop(false); return .@count; } // array_highest() // Returns the index of the highest value in // NOTE: Array must be an INT array! function script array_highest { .@size = getarraysize(getarg(0)); .@win=0; .@idx=0; .@dw=false; freeloop(true); for (.@i = getarrayindex(getarg(0)); .@i < .@size; ++.@i) { if (getelementofarray(getarg(0), .@i) > .@win) { .@win=getelementofarray(getarg(0), .@i); .@idx=.@i; if (.@dw) { deletearray .@draw; .@dw=false; } } else if (getelementofarray(getarg(0), .@i) == .@win) { if (!.@dw) array_push(.@draw, .@idx); array_push(.@draw, .@i); .@dw=true; } } // Will we return .@idx or do we need to draw a loot? freeloop(false); if (.@dw) return any_of(.@draw); else return .@idx; } // relative_array_random() // 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); }