From 10e7035bebdbc2ec25a392ee2cf14172ecf169e5 Mon Sep 17 00:00:00 2001 From: Sader Fawall Date: Wed, 10 Oct 2018 16:33:01 +0200 Subject: [PATCH] Added script command getunits (#3389) * Closes #3159. * Adds script commands getunits, getmapunits, and getareaunits. * Replacement for script commands getusers, getmapusers, getareausers. (In a future commit) Thanks to @sader1992, @Atemo, and @anacondaqq! --- doc/sample/npc_test_getunits.txt | 51 +++++++++++++++++++ doc/script_commands.txt | 66 +++++++++++++++++++++++- src/map/script.cpp | 87 ++++++++++++++++++++++++++++++++ src/map/script_constants.hpp | 1 + 4 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 doc/sample/npc_test_getunits.txt diff --git a/doc/sample/npc_test_getunits.txt b/doc/sample/npc_test_getunits.txt new file mode 100644 index 0000000000..b7155caed3 --- /dev/null +++ b/doc/sample/npc_test_getunits.txt @@ -0,0 +1,51 @@ +//===== rAthena Script ======================================= +//= Sample: getunits Test +//===== By: ================================================== +//= rAthena Dev Team +//===== Last Updated: ======================================== +//= 20180831 +//===== Description: ========================================= +//= An example of getunits command script +//============================================================ +prontera,145,177,0 script getunits Test 857,{ + mes "server information option will take a while if there is large amount of objects"; + switch(select("server information:map information")){ + case 1: + mes "server information"; + mes getunits(BL_PC,.@Character$[0]) + " Character Online."; + mes getunits(BL_MOB,.@Monster$[0]) + " Monster."; + mes getunits(BL_PET,.@Pet$[0]) + " Pet."; + mes getunits(BL_HOM,.@Homunculus$[0]) + " Homunculus."; + mes getunits(BL_MER,.@Mercenary$[0]) + " Mercenary."; + mes getunits(BL_NPC,.@NPC$[0]) + " NPC."; + break; + case 2: + clear; + mes "input the map name."; + input .@input$; + clear; + mes "map information : " + .@input$; + mes getmapunits(BL_PC,.@input$,.@Character$[0]) + " Character Online."; + mes getmapunits(BL_MOB,.@input$,.@Monster$[0]) + " Monster."; + mes getmapunits(BL_PET,.@input$,.@Pet$[0]) + " Pet."; + mes getmapunits(BL_HOM,.@input$,.@Homunculus$[0]) + " Homunculus."; + mes getmapunits(BL_MER,.@input$,.@Mercenary$[0]) + " Mercenary."; + mes getmapunits(BL_NPC,.@input$,.@NPC$[0]) + " NPC."; + } + mes "select for more info"; + setarray .@list$,"Character","Monster","Pet","Homunculus","Mercenary","NPC"; + .@s = select(implode(.@list$,":")) -1; + clear; + copyarray .@name$[0], getd(".@" + .@list$[.@s] + "$"), getarraysize(getd(".@" + .@list$[.@s] + "$")); + mes "count : " + getarraysize(.@name$); + freeloop(1); + for(.@i=0;.@i{,[]}) +*getmapunits(,<"map name">{,[]}) +*getareaunits(,<"map name">,,,,{,[]}) + +The 'getunits' command will return the number of objects active on the server. + +The 'getmapunits' command will return the number of objects active on the +specified <"map name">. + +The 'getareaunits' command will return the number of objects actively located +within the specified area where , , , form the area. + +Type is the type of object to search for: + + BL_PC - Character objects + BL_MOB - Monster objects + BL_PET - Pet objects + BL_HOM - Homunculus objects + BL_MER - Mercenary objects + BL_NPC - NPC objects + BL_ELEM - Elemental objects + +If is provided: + - An int variable will return the list of GID. + - A string variable will return the list of names. + +Example 1: + // getting the players count and building a string array of the names. + .@num = getunits(BL_PC,.@array$[0]); + + mes "the number of Users Connected to the server is " + .@num + " ."; + mes "list of Players names :"; + freeloop(1); // for if the list was too big. + for(.@i=0;.@i{,[]}) + * getmapunits(,<"map name">{,[]}) + * getareaunits(,<"map name">,,,,{,[]}) + *------------------------------------------*/ +BUILDIN_FUNC(getunits) +{ + struct block_list *bl = NULL; + struct map_session_data *sd = NULL; + struct script_data *data = NULL; + char *command = (char *)script_getfuncname(st); + const char *str; + const char *name; + int type = script_getnum(st, 2); + int size = 0; + int32 idx, id; + int16 m = 0, x0 = 0, y0 = 0, x1 = 0, y1 = 0; + struct s_mapiterator *iter = mapit_alloc(MAPIT_NORMAL, bl_type(type)); + + if (!strcmp(command, "getmapunits")) + { + str = script_getstr(st, 3); + if ((m = map_mapname2mapid(str)) < 0) { + script_pushint(st, -1); + st->state = END; + ShowWarning("buildin_%s: Unknown map '%s'.\n", command, str); + return SCRIPT_CMD_FAILURE; + } + if (script_hasdata(st, 4)) + data = script_getdata(st, 4); + } + else if (!strcmp(command, "getareaunits")) + { + str = script_getstr(st, 3); + if ((m = map_mapname2mapid(str)) < 0) { + script_pushint(st, -1); + st->state = END; + ShowWarning("buildin_%s: Unknown map '%s'.\n", command, str); + return SCRIPT_CMD_FAILURE; + } + x0 = script_getnum(st, 4); + y0 = script_getnum(st, 5); + x1 = script_getnum(st, 6); + y1 = script_getnum(st, 7); + + if (script_hasdata(st, 8)) + data = script_getdata(st, 8); + } + else + { + if (script_hasdata(st, 3)) + data = script_getdata(st, 3); + } + + if (data) + { + if (!data_isreference(data)) + { + ShowError("buildin_%s: not a variable\n", command); + script_reportdata(data); + st->state = END; + return SCRIPT_CMD_FAILURE; + } + id = reference_getid(data); + idx = reference_getindex(data); + name = reference_getname(data); + } + + for (bl = (struct block_list*)mapit_first(iter); mapit_exists(iter); bl = (struct block_list*)mapit_next(iter)) + { + if (!m || (m == bl->m && !x0 && !y0 && !x1 && !y1) || (bl->m == m && (bl->x >= x0 && bl->y <= y0) && (bl->x <= x1 && bl->y >= y1))) + { + if (data) + set_reg(st, sd, reference_uid(id, idx + size), name, (is_string_variable(name) ? (void*)status_get_name(bl) : (void*)__64BPRTSIZE(bl->id)), reference_getref(data)); + size++; + } + } + + mapit_free(iter); + + script_pushint(st, size); + return SCRIPT_CMD_SUCCESS; +} + /*========================================== *------------------------------------------*/ static int buildin_getareadropitem_sub(struct block_list *bl,va_list ap) @@ -24029,6 +24113,9 @@ struct script_function buildin_func[] = { BUILDIN_DEF(getmapguildusers,"si"), BUILDIN_DEF(getmapusers,"s"), BUILDIN_DEF(getareausers,"siiii"), + BUILDIN_DEF(getunits, "i?"), + BUILDIN_DEF2(getunits, "getmapunits", "is?"), + BUILDIN_DEF2(getunits, "getareaunits", "isiiii?"), BUILDIN_DEF(getareadropitem,"siiiiv"), BUILDIN_DEF(enablenpc,"s"), BUILDIN_DEF(disablenpc,"s"), diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index e7cf992c59..6d55e91261 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -7295,6 +7295,7 @@ export_constant(BL_PET); export_constant(BL_HOM); export_constant(BL_MER); + export_constant(BL_NPC); export_constant(BL_ELEM); /* skill damage mapflag types */