inarray script commands (#3071)
Thanks to @anacondaqq, @Lemongrass3110, @Jeybla, @secretdataz, @aleos89, @Atemo and @hurtsky for reviewing and testing.
This commit is contained in:
parent
a12c79f782
commit
151c8476af
115
doc/sample/inarray.txt
Normal file
115
doc/sample/inarray.txt
Normal file
@ -0,0 +1,115 @@
|
||||
//===== rAthena Script =======================================
|
||||
//= Sample: inarray
|
||||
//===== By: ==================================================
|
||||
//= rAthena Dev Team
|
||||
//===== Last Updated: ========================================
|
||||
//= 20180424
|
||||
//===== Description: =========================================
|
||||
//= Demonstrates the 'inarray' and 'countinarray' commands.
|
||||
//============================================================
|
||||
|
||||
prontera,160,190,3 script inarray sample 847,{
|
||||
switch(select("inarray:countinarray")){
|
||||
case 1: //inarray command test
|
||||
mes "[inarray Test]";
|
||||
setarray .@array1[0],100,200,300,400,500,600,700;
|
||||
setarray .@array2$[0],"One Hundred","Two Hundred","Three Hundred","Four Hundred","Five Hundred","Six Hundred","Seven Hundred";
|
||||
|
||||
mes .@array2$[inarray(.@array1,100)]; //return One Hundred
|
||||
mes .@array2$[inarray(.@array1,300)]; //return Three Hundred
|
||||
|
||||
//mes .@array2$[inarray(.@array1,800)]; //this will return with an error
|
||||
//800 is not an element of the array .@array1
|
||||
|
||||
mes "" + inarray(.@array1,800); //this return -1
|
||||
//800 is not an element of the array .@array1
|
||||
|
||||
close;
|
||||
case 2: //countinarray command test
|
||||
switch(select("Basic:Advanced")){
|
||||
case 1:
|
||||
mes "[countinarray Basic Test]";
|
||||
setarray .@array$[0],"rathena","ragnarok","poring","script";
|
||||
mes "the array elements: ";
|
||||
for(.@i=0;.@i<getarraysize(.@array$);.@i++)
|
||||
mes .@array$[.@i];
|
||||
|
||||
input .@element$;
|
||||
clear;
|
||||
|
||||
//also in this example we are using normal variable instead of an array
|
||||
//arrays are variables but with more than one index
|
||||
//so you can use array or variable
|
||||
|
||||
//using countinarray command
|
||||
mes "[countinarray Basic Test]";
|
||||
if(countinarray(.@array$[0], .@element$) == 1)
|
||||
mes "we found " + .@element$ + " inside the array";
|
||||
else
|
||||
mes .@element$ + " is not an element of the array";
|
||||
/*
|
||||
without using countinarray command
|
||||
------------------------------------------
|
||||
for(.@i=0;.@i<getarraysize(.@array$);.@i++){
|
||||
if(.@array$[.@i] == .@element$){
|
||||
.@count ++;
|
||||
}
|
||||
}
|
||||
if(.@count == 1)
|
||||
mes "we found " + .@element$ + " inside the array";
|
||||
else
|
||||
mes .@element$ + " is not an element of the array";
|
||||
------------------------------------------
|
||||
*/
|
||||
close;
|
||||
|
||||
case 2:
|
||||
mes "[countinarray Advanced Test]";
|
||||
setarray .@array[0],50,40,80,90,70,500,60,400,700,1,2,2,2,2;
|
||||
mes "open the script and read to know what's going on";
|
||||
mes " ";
|
||||
|
||||
//50 and 70 are elements of the array
|
||||
//we make new array that have the values 50 and 70
|
||||
//you will see this all over the sample
|
||||
setarray .@array2[0],50,70;
|
||||
//2 cases true, so the command returns 2
|
||||
mes "searching for 50 and 70";
|
||||
mes "return " + countinarray(.@array[0], .@array2[0]);
|
||||
mes " ";
|
||||
|
||||
//50 is an element of the array
|
||||
//100 is not an element of the array
|
||||
setarray .@array3[0],50,100;
|
||||
//1 case true, so the command returns 1
|
||||
mes "searching for 50 and 100";
|
||||
mes "return " + countinarray(.@array[0], .@array3[0]);
|
||||
mes " ";
|
||||
|
||||
//586 and 100 are not elements of the array
|
||||
setarray .@array4[0],586,100;
|
||||
//0 case true, so the command returns 0
|
||||
mes "searching for 586 and 100";
|
||||
mes "return " + countinarray(.@array[0], .@array4[0]);
|
||||
mes " ";
|
||||
|
||||
//1 and 1 are elements of the array
|
||||
setarray .@array5[0],1,1;
|
||||
//2 cases true, so the command returns 2
|
||||
mes "searching for 1 and 1";
|
||||
mes "return " + countinarray(.@array[0], .@array5[0]);
|
||||
mes " ";
|
||||
|
||||
//2 is an element of the array, but it's in four indexes
|
||||
//the command will return the number valid cases
|
||||
//so here the command returns 4
|
||||
//this can be used to know the count of an element inside an array
|
||||
.@variable = 2;
|
||||
|
||||
mes "searching for 2";
|
||||
mes "return " + countinarray(.@array[0], .@variable);
|
||||
|
||||
close;
|
||||
}
|
||||
}
|
||||
}
|
@ -2260,6 +2260,62 @@ array, shifting all the elements beyond this towards the beginning.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*inarray <array name>,<value>;
|
||||
|
||||
This command returns the index of the first matching value found in the array.
|
||||
It will return -1 if the value is not found.
|
||||
|
||||
setarray .@array[0], 100, 200, 300, 400, 500, 600, 100;
|
||||
|
||||
inarray(.@array[0], 200);
|
||||
//return 1 because 200 is in index 1
|
||||
//another way to say it that .@array[1] == 200
|
||||
|
||||
.@index = inarray(.@array[0], 600);
|
||||
//.@index is now 5 because .@array[5] == 600
|
||||
|
||||
inarray(.@array[0], 100);
|
||||
//while index 6 is also 100, the command will return the first instance it finds
|
||||
//return 0 because .@array[0] == 100
|
||||
|
||||
inarray(.@array[0], 800);
|
||||
//return -1 because 800 is not an element of the array .@array
|
||||
|
||||
For more details, see the sample in 'doc/sample/inarray.txt'.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*countinarray <array name>{[<start index>]},<array name>{[<start index>]};
|
||||
|
||||
This command will check for matches between the array values and return the number of matches.
|
||||
While being optional, if [<start index>] is supplied, the search will begin from the given index value.
|
||||
|
||||
setarray .@array[0], 100, 200, 300, 400, 500, 600;
|
||||
|
||||
.@variable = 100;
|
||||
if(countinarray(.@array[0], .@variable))
|
||||
mes "The number 100 was found in the array @array";
|
||||
|
||||
countinarray(.@array[0], .@variable);
|
||||
//return 1 because the number 100 is an element of the array .@array
|
||||
|
||||
setarray .@array2[0],100,500;
|
||||
countinarray(.@array[0], .@array2[0]);
|
||||
//return 2 because the numbers 100 and 500 are elements of the array .@array
|
||||
|
||||
setarray .@array3[0],100,700;
|
||||
countinarray(.@array[0], .@array3[0]);
|
||||
//return 1 because the number 100 is an element of the array .@array
|
||||
//but the number 700 is not an element of the array .@array
|
||||
|
||||
//also you can change the position between the arrays in the command
|
||||
if(countinarray(.@array[0], .@array3[0]) == countinarray(.@array3[0], .@array[0]))
|
||||
//This is true
|
||||
|
||||
For more details, see the sample in 'doc/sample/inarray.txt'.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
======================================
|
||||
|2.- Information-retrieving commands.|
|
||||
======================================
|
||||
|
@ -6659,6 +6659,189 @@ BUILDIN_FUNC(getelementofarray)
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/// Return the index number of the first matching value in an array.
|
||||
/// ex: inarray arr,1;
|
||||
///
|
||||
/// inarray <array variable>,<value>;
|
||||
BUILDIN_FUNC(inarray)
|
||||
{
|
||||
struct script_data *data;
|
||||
const char* name;
|
||||
int id, i, array_size;
|
||||
struct map_session_data* sd = NULL;
|
||||
struct reg_db *ref = NULL;
|
||||
data = script_getdata(st, 2);
|
||||
|
||||
if (!data_isreference(data))
|
||||
{
|
||||
ShowError("buildin_inarray: not a variable\n");
|
||||
script_reportdata(data);
|
||||
st->state = END;
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
name = reference_getname(data);
|
||||
ref = reference_getref(data);
|
||||
|
||||
if (not_server_variable(*name) && !script_rid2sd(sd))
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
|
||||
array_size = script_array_highest_key(st, sd, name, ref) - 1;
|
||||
|
||||
if (array_size > SCRIPT_MAX_ARRAYSIZE)
|
||||
{
|
||||
ShowError("buildin_inarray: The array is too large.\n");
|
||||
script_reportdata(data);
|
||||
st->state = END;
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
id = reference_getid(data);
|
||||
if (is_string_variable(name))
|
||||
{
|
||||
const char* temp;
|
||||
const char* value;
|
||||
value = script_getstr(st, 3);
|
||||
for (i = 0; i <= array_size; ++i)
|
||||
{
|
||||
temp = (char*)get_val2(st, reference_uid(id, i), ref);
|
||||
script_removetop(st, -1, 0);
|
||||
if (!strcmp(temp, value))
|
||||
{
|
||||
script_pushint(st, i);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int temp, value;
|
||||
value = script_getnum(st, 3);
|
||||
for (i = 0; i <= array_size; ++i)
|
||||
{
|
||||
temp = (int32)__64BPRTSIZE(get_val2(st, reference_uid(id, i), ref));
|
||||
script_removetop(st, -1, 0);
|
||||
if (temp == value)
|
||||
{
|
||||
script_pushint(st, i);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
script_pushint(st, -1);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/// Return the number of matches in two arrays.
|
||||
/// ex: countinarray arr[0],arr1[0];
|
||||
///
|
||||
/// countinarray <array variable>,<array variable>;
|
||||
BUILDIN_FUNC(countinarray)
|
||||
{
|
||||
struct script_data *data1 , *data2;
|
||||
const char* name1;
|
||||
const char* name2;
|
||||
int id1, id2, i, j, array_size1, array_size2, case_count = 0;
|
||||
struct map_session_data* sd = NULL;
|
||||
struct reg_db *ref1 = NULL, *ref2 = NULL;
|
||||
data1 = script_getdata(st, 2);
|
||||
data2 = script_getdata(st, 3);
|
||||
|
||||
if (!data_isreference(data1) || !data_isreference(data2))
|
||||
{
|
||||
ShowError("buildin_countinarray: not a variable\n");
|
||||
script_reportdata(data1);
|
||||
script_reportdata(data2);
|
||||
st->state = END;
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
name1 = reference_getname(data1);
|
||||
name2 = reference_getname(data2);
|
||||
ref1 = reference_getref(data1);
|
||||
ref2 = reference_getref(data2);
|
||||
|
||||
if (not_server_variable(*name1) && not_server_variable(*name2) && !script_rid2sd(sd))
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
|
||||
array_size1 = script_array_highest_key(st, sd, name1, ref1) - 1;
|
||||
array_size2 = script_array_highest_key(st, sd, name2, ref2) - 1;
|
||||
|
||||
if (array_size1 > SCRIPT_MAX_ARRAYSIZE || array_size2 > SCRIPT_MAX_ARRAYSIZE)
|
||||
{
|
||||
ShowError("buildin_countinarray: The array is too large.\n");
|
||||
script_reportdata(data1);
|
||||
script_reportdata(data2);
|
||||
st->state = END;
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
i = reference_getindex(data1);
|
||||
j = reference_getindex(data2);
|
||||
if (array_size1 < i || array_size2 < j)
|
||||
{ //To prevent unintended behavior
|
||||
ShowError("buildin_countinarray: The given index of the array is higher than the array size.\n");
|
||||
script_reportdata(data1);
|
||||
script_reportdata(data2);
|
||||
st->state = END;
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
id1 = reference_getid(data1);
|
||||
id2 = reference_getid(data2);
|
||||
if (is_string_variable(name1) && is_string_variable(name2))
|
||||
{
|
||||
const char* temp1;
|
||||
const char* temp2;
|
||||
for (; i <= array_size1; ++i)
|
||||
{
|
||||
temp1 = (char*)get_val2(st, reference_uid(id1, i), ref1);
|
||||
for (j = reference_getindex(data2); j <= array_size2; j++)
|
||||
{
|
||||
temp2 = (char*)get_val2(st, reference_uid(id2, j), ref2);
|
||||
if (!strcmp(temp1, temp2))
|
||||
{
|
||||
case_count++;
|
||||
}
|
||||
script_removetop(st, -1, 0);
|
||||
}
|
||||
script_removetop(st, -1, 0);
|
||||
}
|
||||
}
|
||||
else if (!is_string_variable(name1) && !is_string_variable(name2))
|
||||
{
|
||||
int temp1, temp2;
|
||||
for (; i <= array_size1; ++i)
|
||||
{
|
||||
temp1 = (int32)__64BPRTSIZE(get_val2(st, reference_uid(id1, i), ref1));
|
||||
for (j = reference_getindex(data2); j <= array_size2; j++)
|
||||
{
|
||||
temp2 = (int32)__64BPRTSIZE(get_val2(st, reference_uid(id2, j), ref2));
|
||||
if (temp1 == temp2)
|
||||
{
|
||||
case_count++;
|
||||
}
|
||||
script_removetop(st, -1, 0);
|
||||
}
|
||||
script_removetop(st, -1, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowError("buildin_countinarray: Arrays does not match , You can't compare int array to string array.\n");
|
||||
script_reportdata(data1);
|
||||
script_reportdata(data2);
|
||||
st->state = END;
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
script_pushint(st, case_count);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/// ...
|
||||
///
|
||||
@ -24141,6 +24324,8 @@ struct script_function buildin_func[] = {
|
||||
BUILDIN_DEF(getarraysize,"r"),
|
||||
BUILDIN_DEF(deletearray,"r?"),
|
||||
BUILDIN_DEF(getelementofarray,"ri"),
|
||||
BUILDIN_DEF(inarray,"rv"),
|
||||
BUILDIN_DEF(countinarray,"rr"),
|
||||
BUILDIN_DEF(getitem,"vi?"),
|
||||
BUILDIN_DEF(rentitem,"vi?"),
|
||||
BUILDIN_DEF(rentitem2,"viiiiiiii?"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user