Implemented array sorting utility script command
This commit is contained in:
parent
48d79cef43
commit
12d5d99a4d
@ -2244,6 +2244,25 @@ array, shifting all the elements beyond this towards the beginning.
|
|||||||
|
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
*sortarray(<array name>);
|
||||||
|
|
||||||
|
This command will do an in-place sort on an array specified in <array name>.
|
||||||
|
Original ordering of the array before execution of this command will be lost.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
setarray .@a,31, 44, 14, 18, 24, 42, 39, 47, 30, 17, 36, 45, 34, 21, 38, 41, 23, 25, 13, 20, 8, 5, 22, 9, 2, 12, 19, 35, 48, 37;
|
||||||
|
sortarray(.@a);
|
||||||
|
.@size = getarraysize(.@a);
|
||||||
|
for(.@i = 0; .@size; .@i++) {
|
||||||
|
.@msg$ = .@msg$ + .@a[.@i] + " ";
|
||||||
|
}
|
||||||
|
debugmes(.@msg$);
|
||||||
|
|
||||||
|
Output: 2 5 8 9 12 13 14 17 18 19 20 21 22 23 24 25 30 31 34 35 36 37 38 39 41 42 44 45 47 48
|
||||||
|
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
======================================
|
======================================
|
||||||
|2.- Information-retrieving commands.|
|
|2.- Information-retrieving commands.|
|
||||||
======================================
|
======================================
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#include "script.hpp"
|
#include "script.hpp"
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h> // atoi, strtol, strtoll, exit
|
#include <stdlib.h> // atoi, strtol, strtoll, exit
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
@ -23728,6 +23730,124 @@ BUILDIN_FUNC(getequiptradability) {
|
|||||||
return SCRIPT_CMD_SUCCESS;
|
return SCRIPT_CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swaps position of two array elements.
|
||||||
|
* This function does not guarantee that the array is accessible, so the burden fall to the caller.
|
||||||
|
* @param st Current script state
|
||||||
|
* @param sd The player owning the variable, can be nullptr
|
||||||
|
* @param array_ The array containing elements to be swapped
|
||||||
|
* @param idx1 index of first element
|
||||||
|
* @param idx2 index of second element
|
||||||
|
*/
|
||||||
|
void swap_array_element(script_state *st, map_session_data *sd, script_data* array_, int idx1, int idx2) {
|
||||||
|
void *v1, *v2;
|
||||||
|
auto id = reference_getid(array_);
|
||||||
|
auto name = reference_getname(array_);
|
||||||
|
auto ref = reference_getref(array_);
|
||||||
|
|
||||||
|
v1 = get_val2(st, reference_uid(id, idx1), ref);
|
||||||
|
v2 = get_val2(st, reference_uid(id, idx2), ref);
|
||||||
|
set_reg(st, sd, reference_uid(id, idx2), name, v1, ref);
|
||||||
|
set_reg(st, sd, reference_uid(id, idx1), name, v2, ref);
|
||||||
|
script_removetop(st, -2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Partition an array to be used in quick sort with Hoare's partitioning
|
||||||
|
* This function does not guarantee that the array is accessible, so the burden fall to the caller.
|
||||||
|
* @param st Current script state
|
||||||
|
* @param sd The player owning the variable, can be nullptr
|
||||||
|
* @param array_ The array to be partitioned
|
||||||
|
* @param start Starting index
|
||||||
|
* @param end Ending index
|
||||||
|
*/
|
||||||
|
int partition_array(script_state *st, map_session_data *sd, script_data *array_, int start, int end) {
|
||||||
|
auto ref = reference_getref(array_);
|
||||||
|
auto id = reference_getid(array_);
|
||||||
|
int i = start, j = end;
|
||||||
|
int pivotidx = rnd() % (end - start);
|
||||||
|
int pivot = reinterpret_cast<int>(__64BPRTSIZE(get_val2(st, reference_uid(id, start + pivotidx), ref)));
|
||||||
|
script_removetop(st, -1, 0);
|
||||||
|
|
||||||
|
while (i < j) {
|
||||||
|
while (true) {
|
||||||
|
int tmp = reinterpret_cast<int>(__64BPRTSIZE(get_val2(st, reference_uid(id, i), ref)));
|
||||||
|
script_removetop(st, -1, 0);
|
||||||
|
if (tmp >= pivot)
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int tmp = reinterpret_cast<int>(__64BPRTSIZE(get_val2(st, reference_uid(id, j), ref)));
|
||||||
|
script_removetop(st, -1, 0);
|
||||||
|
if (tmp <= pivot)
|
||||||
|
break;
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
|
||||||
|
swap_array_element(st, sd, array_, i, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort an array
|
||||||
|
* sortarray(<array>);
|
||||||
|
*/
|
||||||
|
BUILDIN_FUNC(sortarray) {
|
||||||
|
map_session_data *sd = nullptr;
|
||||||
|
script_data *array_ = script_getdata(st, 2);
|
||||||
|
reg_db *ref;
|
||||||
|
char* name;
|
||||||
|
|
||||||
|
if (!data_isreference(array_)) {
|
||||||
|
ShowError("buildin_sortarray: Not a variable!\n");
|
||||||
|
script_reportdata(array_);
|
||||||
|
st->state = END;
|
||||||
|
return SCRIPT_CMD_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = reference_getname(array_);
|
||||||
|
ref = reference_getref(array_);
|
||||||
|
|
||||||
|
if (not_server_variable(name[0])) {
|
||||||
|
if (!script_rid2sd(sd))
|
||||||
|
return SCRIPT_CMD_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stack<int> stack;
|
||||||
|
auto size = script_array_highest_key(st, sd, name, ref);
|
||||||
|
|
||||||
|
// Push initial indices
|
||||||
|
stack.push(0);
|
||||||
|
stack.push(size - 1);
|
||||||
|
|
||||||
|
while (!stack.empty()) {
|
||||||
|
int end, start, p;
|
||||||
|
|
||||||
|
end = stack.top();
|
||||||
|
stack.pop();
|
||||||
|
start = stack.top();
|
||||||
|
stack.pop();
|
||||||
|
|
||||||
|
p = partition_array(st, sd, array_, start, end);
|
||||||
|
|
||||||
|
if(p - 1 > start) {
|
||||||
|
stack.push(start);
|
||||||
|
stack.push(p - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(p + 1 < end) {
|
||||||
|
stack.push(p + 1);
|
||||||
|
stack.push(end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SCRIPT_CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
#include "../custom/script.inc"
|
#include "../custom/script.inc"
|
||||||
|
|
||||||
// declarations that were supposed to be exported from npc_chat.c
|
// declarations that were supposed to be exported from npc_chat.c
|
||||||
@ -24376,6 +24496,7 @@ struct script_function buildin_func[] = {
|
|||||||
BUILDIN_DEF2(round, "ceil", "i"),
|
BUILDIN_DEF2(round, "ceil", "i"),
|
||||||
BUILDIN_DEF2(round, "floor", "i"),
|
BUILDIN_DEF2(round, "floor", "i"),
|
||||||
BUILDIN_DEF(getequiptradability, "i?"),
|
BUILDIN_DEF(getequiptradability, "i?"),
|
||||||
|
BUILDIN_DEF(sortarray, "r"),
|
||||||
#include "../custom/script_def.inc"
|
#include "../custom/script_def.inc"
|
||||||
|
|
||||||
{NULL,NULL,NULL},
|
{NULL,NULL,NULL},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user