diff --git a/doc/sample/inarray.txt b/doc/sample/inarray.txt new file mode 100644 index 00000000000..8b1443d3b37 --- /dev/null +++ b/doc/sample/inarray.txt @@ -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,; + +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 {[]},{[]}; + +This command will check for matches between the array values and return the number of matches. +While being optional, if [] 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.| ====================================== diff --git a/src/map/script.cpp b/src/map/script.cpp index 34532088034..f10d154acfa 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -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 ,; +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 ,; +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?"),