Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added getobjects to retrieve GID of objects on a map #11

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions doc/script_commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3197,6 +3197,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
BL_*. 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
Expand Down
95 changes: 95 additions & 0 deletions src/custom/script.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
2 changes: 2 additions & 0 deletions src/custom/script_def.inc
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@
**/

//BUILDIN_DEF(example,""),

BUILDIN_DEF(getobjects, "ii?????"), // [Cydh]
1 change: 1 addition & 0 deletions src/map/script_constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7270,6 +7270,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 */
Expand Down