Compare commits
7 Commits
master
...
feature/ar
Author | SHA1 | Date | |
---|---|---|---|
![]() |
726f7ac07b | ||
![]() |
15c6201d99 | ||
![]() |
e815efb565 | ||
![]() |
22debbe86b | ||
![]() |
0bf92ab14f | ||
![]() |
9231262787 | ||
![]() |
12d5d99a4d |
@ -2406,6 +2406,34 @@ For more details, see the sample in 'doc/sample/inarray.txt'.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*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
|
||||
|
||||
setarray .@text$, "Lemongrass", "Atemo", "Jey", "Lighta", "Nova", "MasterOfMuppets", "Aleos", "Cydh", "Playtester", "Stolao", "Nanakiwurtz", "Akkarin", "Secret";
|
||||
sortarray(.@text$);
|
||||
for(.@i = 0; .@i < getarraysize(.@text$); .@i++) {
|
||||
.@msg$ = .@msg$ + .@text$[.@i] + " ";
|
||||
}
|
||||
debugmes(.@msg$);
|
||||
|
||||
Output: Akkarin Aleos Atemo Cydh Jey Lemongrass Lighta MasterOfMuppets Nanakiwurtz Nova Playtester Secret Stolao
|
||||
|
||||
---------------------------------------
|
||||
|
||||
======================================
|
||||
|2.- Information-retrieving commands.|
|
||||
======================================
|
||||
|
18
npc/test/ci/2796.txt
Normal file
18
npc/test/ci/2796.txt
Normal file
@ -0,0 +1,18 @@
|
||||
- script PullRequest2796 -1,{
|
||||
OnInit:
|
||||
setarray .@actual, 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( .@actual );
|
||||
setarray .@expected, 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;
|
||||
|
||||
for( .@i = 0; .@i < getarraysize( .@expected ); .@i++ ){
|
||||
AssertEquals( .@expected[.@i], .@actual[.@i], "Index " + .@i );
|
||||
}
|
||||
|
||||
setarray .@actual$, "Lemongrass", "Atemo", "Jey", "Lighta", "Nova", "MasterOfMuppets", "Aleos", "Cydh", "Playtester", "Stolao", "Nanakiwurtz", "Akkarin", "Secret";
|
||||
sortarray( .@actual$ );
|
||||
setarray .@expected$, "Akkarin", "Aleos", "Atemo", "Cydh", "Jey", "Lemongrass", "Lighta", "MasterOfMuppets", "Nanakiwurtz", "Nova", "Playtester", "Secret", "Stolao";
|
||||
|
||||
for( .@i = 0; .@i < getarraysize( .@expected$ ); .@i++ ){
|
||||
AssertEquals( .@expected$[.@i], .@actual$[.@i], "Index " + .@i );
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
#include <cmath>
|
||||
#include <csetjmp>
|
||||
#include <cstdlib> // atoi, strtol, strtoll, exit
|
||||
#include <stack>
|
||||
|
||||
#ifdef PCRE_SUPPORT
|
||||
#include <pcre.h> // preg_match
|
||||
@ -27263,6 +27264,178 @@ BUILDIN_FUNC(setdialogpospercent){
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partition a string array to be used in quick sort with Hoare's partitioning
|
||||
* This function does not guarantee that the string 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 string array to be partitioned
|
||||
* @param start Starting index
|
||||
* @param end Ending index
|
||||
*/
|
||||
int32 partition_array_str(script_state *st, map_session_data *sd, script_data *array_, int32 start, int32 end) {
|
||||
struct reg_db* ref = reference_getref(array_);
|
||||
int32 id = reference_getid(array_);
|
||||
const char* name = reference_getname(array_);
|
||||
int32 i = start, j = end;
|
||||
int32 pivotidx = rnd() % (end - start);
|
||||
const char* pivot = get_val2_str(st, reference_uid(id, start + pivotidx), ref);
|
||||
|
||||
while (i < j) {
|
||||
const char* tmp_i;
|
||||
int64 uid_i;
|
||||
|
||||
while (true) {
|
||||
uid_i = reference_uid(id, i);
|
||||
tmp_i = get_val2_str(st, uid_i, ref);
|
||||
|
||||
if (strcmp( tmp_i, pivot) >= 0)
|
||||
break;
|
||||
|
||||
// Pop tmp_i
|
||||
script_removetop(st, -1, 0);
|
||||
i++;
|
||||
}
|
||||
|
||||
const char* tmp_j;
|
||||
int64 uid_j;
|
||||
|
||||
while (true) {
|
||||
uid_j = reference_uid(id, j);
|
||||
tmp_j = get_val2_str(st, uid_j, ref);
|
||||
|
||||
if (strcmp( tmp_j, pivot) <= 0)
|
||||
break;
|
||||
|
||||
// Pop tmp_j
|
||||
script_removetop(st, -1, 0);
|
||||
j--;
|
||||
}
|
||||
|
||||
// Swap
|
||||
set_reg_str( st, sd, uid_j, name, tmp_i, ref );
|
||||
set_reg_str( st, sd, uid_i, name, tmp_j, ref );
|
||||
|
||||
// Pop tmp_i and tmp_j
|
||||
script_removetop(st, -2, 0);
|
||||
}
|
||||
|
||||
// Pop pivot
|
||||
script_removetop(st, -1, 0);
|
||||
return j;
|
||||
}
|
||||
|
||||
/**
|
||||
* Partition an integer array to be used in quick sort with Hoare's partitioning
|
||||
* This function does not guarantee that the integer 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 integer array to be partitioned
|
||||
* @param start Starting index
|
||||
* @param end Ending index
|
||||
*/
|
||||
int32 partition_array_num(script_state *st, map_session_data *sd, script_data *array_, int32 start, int32 end) {
|
||||
struct reg_db* ref = reference_getref(array_);
|
||||
int32 id = reference_getid(array_);
|
||||
const char* name = reference_getname(array_);
|
||||
int32 i = start, j = end;
|
||||
int32 pivotidx = rnd() % (end - start);
|
||||
int64 pivot = get_val2_num(st, reference_uid(id, start + pivotidx), ref);
|
||||
|
||||
while (i < j) {
|
||||
int64 tmp_i;
|
||||
int64 uid_i;
|
||||
|
||||
while (true) {
|
||||
uid_i = reference_uid(id, i);
|
||||
tmp_i = get_val2_num(st, uid_i, ref);
|
||||
|
||||
if (tmp_i >= pivot)
|
||||
break;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
int64 tmp_j;
|
||||
int64 uid_j;
|
||||
|
||||
while (true) {
|
||||
uid_j = reference_uid(id, j);
|
||||
tmp_j = get_val2_num(st, uid_j, ref);
|
||||
|
||||
if (tmp_j <= pivot)
|
||||
break;
|
||||
|
||||
j--;
|
||||
}
|
||||
|
||||
// Swap
|
||||
set_reg_num( st, sd, uid_j, name, tmp_i, ref );
|
||||
set_reg_num( st, sd, uid_i, name, tmp_j, ref );
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort an array
|
||||
* sortarray(<array>);
|
||||
*/
|
||||
BUILDIN_FUNC(sortarray) {
|
||||
map_session_data *sd = nullptr;
|
||||
script_data *array_ = script_getdata(st, 2);
|
||||
|
||||
if (!data_isreference(array_)) {
|
||||
ShowError("buildin_sortarray: Not a variable!\n");
|
||||
script_reportdata(array_);
|
||||
st->state = END;
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
char* name = reference_getname(array_);
|
||||
reg_db* ref = reference_getref(array_);
|
||||
|
||||
if( not_server_variable( name[0] ) && !script_rid2sd( sd ) ){
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
bool is_string = is_string_variable(name);
|
||||
|
||||
std::stack<int32> stack;
|
||||
int32 size = script_array_highest_key(st, sd, name, ref);
|
||||
|
||||
// Push initial indices
|
||||
stack.push(0);
|
||||
stack.push(size - 1);
|
||||
|
||||
while (!stack.empty()) {
|
||||
int32 end = stack.top();
|
||||
stack.pop();
|
||||
int32 start = stack.top();
|
||||
stack.pop();
|
||||
|
||||
int32 p;
|
||||
|
||||
if( is_string ){
|
||||
p = partition_array_str(st, sd, array_, start, end);
|
||||
}else{
|
||||
p = partition_array_num(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>
|
||||
|
||||
// declarations that were supposed to be exported from npc_chat.cpp
|
||||
@ -28027,6 +28200,7 @@ struct script_function buildin_func[] = {
|
||||
BUILDIN_DEF(setdialogsize, "ii"),
|
||||
BUILDIN_DEF(setdialogpos, "ii"),
|
||||
BUILDIN_DEF(setdialogpospercent, "ii"),
|
||||
BUILDIN_DEF(sortarray, "r"),
|
||||
|
||||
#include <custom/script_def.inc>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user