Skip to content
Permalink
Browse files
Added getobjects to retrieve GID of objects on a map
* Detailed info please read the changes on doc/script_commands.txt
  • Loading branch information
cydh committed Jul 9, 2018
1 parent b2c026d commit 65df844d6815866c5649322df67b6b77b5cfc71f
Showing with 165 additions and 0 deletions.
  1. +56 −0 doc/script_commands.txt
  2. +95 −0 src/custom/script.inc
  3. +2 −0 src/custom/script_def.inc
  4. +12 −0 src/map/script_constants.hpp
@@ -3196,6 +3196,62 @@ within the specified area - an x1/y1-x2/y2 square on the specified map.
This is useful for maps that are split into many buildings, such as all the
"*_in" maps, due to all the shops and houses.

---------------------------------------

*getobjects(<type>,<data>{,"<map name>"{,<x1>,<y1>,<x2>,<y2>}})

Get object GIDs on specified location based on specified 'type'. The returned
value is number of all objects found. The GIDs is stored in temporary NPC
variables.

<type> can be combined value as bitwise of
BL_PC - Character object
BL_MOB - Monster object
BL_PET - Pet object
BL_HOM - Homunculus object
BL_NPC - NPC object
BL_MER - Mercenary object
BL_ELEM - Elemental object

'data' values are bitmask of
0x1 - GID (default)
0x2 - Name
0x4 - Char ID (only for BL_PC)
0x8 - Class (Job ID for BL_PC, Sprite ID for BL_NPC, and Class
for other types)

Default 'map name' for look up is invoker location or NPC if no invoker found.

Object GID found will be saved in these arrays, while 'type' is value of
UNITTYPE_*. Use getd for good practice.

.@obj_type_id[]
.@obj_type_name$[]
.@obj_type_cid[]
.@obj_type_class[]

Example 1:

getobjects(BL_PC,0x1);
.@n = getarraysize(getd(".@obj_"+BL_PC+"_id"));
for (.@i = 0; .@i < .@n; .@i++) {
getitem 607,1,getd(".@obj_"+BL_PC+"_id["+.@i+"]");
}

Example 2:

getobjects(BL_PC|BL_NPC,0x1|0x2);
// For players
.@pc = getarraysize(getd(".@obj_"+BL_PC+"_id"));
for (.@i = 0; .@i < .@pc; .@i++) {
getitem 501,1,getd(".@obj_"+BL_PC+"_id["+.@i+"]");
}
// For NPCs
.@npc = getarraysize(getd(".@obj_"+BL_NPC+"_id"));
for (.@i = 0; .@i < .@npc; .@i++) {
npctalk "My number is "+(.@i+1)+"",getd(".@obj_"+BL_NPC+"_name$["+.@i+"]");
}

---------------------------------------
\\
2,2.- Guild-related commands
@@ -17,3 +17,98 @@
// script_pushint(st,1);
// return 0;
//}

static int getobjects_count[11]; /// Store number of object found by getobjects command

/**
* Get object's data requested by getobjects
* @author [Cydh]
*/
static int buildin_getobjects_sub(struct block_list *bl, va_list ap) {
struct script_state *st;
int get_what, type;
char varname[23];

if (!bl)
return 0;

get_what = va_arg(ap, int);
st = va_arg(ap, struct script_state *);
type = (int)(log((int)bl->type)/log(2));

memset(varname, '\0', sizeof(varname));
sprintf(varname, ".@obj_%d_id", bl->type);
setd_sub(st, NULL, varname, getobjects_count[type], (void*)__64BPRTSIZE(bl->id), NULL);
if (get_what & 0x2) {
memset(varname, '\0', sizeof(varname));
sprintf(varname, ".@obj_%d_name$", bl->type);
setd_sub(st, NULL, varname, getobjects_count[type], (void*)status_get_name(bl), NULL);
}
if (get_what & 0x4 && bl->type == BL_PC) {
memset(varname, '\0', sizeof(varname));
sprintf(varname, ".@obj_%d_cid", bl->type);
setd_sub(st, NULL, varname, getobjects_count[type], (void*)__64BPRTSIZE((BL_CAST(BL_PC, bl))->status.char_id), NULL);
}
if (get_what & 0x8) {
memset(varname, '\0', sizeof(varname));
sprintf(varname, ".@obj_%d_class", bl->type);
setd_sub(st, NULL, varname, getobjects_count[type], (void*)__64BPRTSIZE(status_get_class(bl)), NULL);
}

getobjects_count[type]++;
return 1;
}

/**
* getobjects(<type>,<data>{,"<map name>"{,<x1>,<y1>,<x2>,<y2>}})
* @param type See enum bl_type
* @param data 0x1:GID, 0x2:Name, 0x4:Char ID (BL_PC), 0x8:Class
* @author [Cydh]
*/
BUILDIN_FUNC(getobjects) {
int type = script_getnum(st, 2);
int get_what = script_getnum(st, 3);
int m = -1, x1 = 0, y1 = 0, x2 = 0, y2 = 0;

if (script_hasdata(st, 4)) {
int mapindex = 0;
const char *str = script_getstr(st, 4);
mapindex = mapindex_name2id(str);
if (!mapindex) {
ShowError("buildin_getobjects: Map '%s' if not found.\n", str);
script_pushint(st, 0);
return SCRIPT_CMD_FAILURE;
}
m = map_mapindex2mapid(mapindex);
}
else {
struct block_list *bl = map_id2bl(st->rid ? st->rid : st->oid);
if (!bl) {
ShowError("buildin_getobjects: Script is not attached, cannot get map!\n");
script_pushint(st, 0);
return SCRIPT_CMD_FAILURE;
}
m = bl->m;
}
if (m < 0) {
ShowError("buildin_getobjects: Script is not on map!\n");
script_pushint(st, 0);
return SCRIPT_CMD_FAILURE;
}

memset(&getobjects_count, 0, sizeof(getobjects_count));
FETCH(5, x1);
FETCH(6, y1);
FETCH(7, x2);
FETCH(8, y2);

if (x1 && y1 && x2 && y2) {
map_foreachinarea(buildin_getobjects_sub, m, x1, y1, x2, y2, type, get_what, st);
}
else {
map_foreachinmap(buildin_getobjects_sub, m, type, get_what, st);
}

script_pushint(st, 1);
return SCRIPT_CMD_SUCCESS;
}
@@ -9,3 +9,5 @@
**/

//BUILDIN_DEF(example,""),

BUILDIN_DEF(getobjects, "ii?????"), // [Cydh]
@@ -7244,6 +7244,18 @@
export_constant(GSTORAGE_NO_STORAGE);
export_constant(GSTORAGE_NO_PERMISSION);

//export_constant(BL_NUL);
export_constant(BL_PC);
export_constant(BL_MOB);
export_constant(BL_PET);
export_constant(BL_HOM);
export_constant(BL_MER);
//export_constant(BL_ITEM);
//export_constant(BL_SKILL);
export_constant(BL_NPC);
//export_constant(BL_CHAT);
export_constant(BL_ELEM);

#undef export_constant
#undef export_constant2
#undef export_parameter

0 comments on commit 65df844

Please sign in to comment.