Skip to content

Commit 3056bce

Browse files
Merge pull request #3319 from jasonch35/getmobdrops-refactor
`getmobdrops` refactor
2 parents 84da0df + e0fa6d8 commit 3056bce

File tree

2 files changed

+78
-56
lines changed

2 files changed

+78
-56
lines changed

doc/script_commands.txt

+9-38
Original file line numberDiff line numberDiff line change
@@ -4364,54 +4364,25 @@ Example:
43644364

43654365
---------------------------------------
43664366

4367-
*getmobdrops(<mob id>)
4367+
*getmobdrops(<mob_id>, <item_id_array>{, <drop_rate_array>});
43684368

4369-
This command will find all drops of the specified mob and return the item
4370-
IDs and drop percentages into arrays of temporary global variables.
4371-
getmobdrops() returns true if successful and false if the mob ID doesn't
4372-
exist.
4373-
4374-
Upon executing this,
4375-
4376-
$@MobDrop_item[] is a global temporary number array which contains the
4377-
item IDs of the monster's drops.
4378-
4379-
$@MobDrop_rate[] is a global temporary number array which contains the
4380-
drop percentages of each item. (1 = .01%)
4381-
4382-
$@MobDrop_count is the number of item drops found.
4383-
4384-
Be sure to use $@MobDrop_count to go through the arrays, and not
4385-
'getarraysize', because the temporary global arrays are not cleared
4386-
between runs of 'getmobdrops'. If a mob with 7 item drops is looked up,
4387-
the arrays would have 7 elements. But if another mob is looked up and it
4388-
only has 5 item drops, the server will not clear the arrays for you,
4389-
overwriting the values instead. So in addition to returning the 5 item
4390-
drops, the 6th and 7th elements from the last call remain, and you will
4391-
get 5+2 item drops, of which the last 2 don't belong to the new mob.
4392-
$@MobDrop_count will always contain the correct number (5), unlike
4393-
getarraysize() which would return 7 in this case.
4369+
This command will find drops information of the specified <mob_id>, copy the
4370+
item ids on to <item_id_array> and drop rate on to <drop_rate_array> if provided.
4371+
Returns the number of items found. Will return 0 if <mob_id> is invalid.
43944372

43954373
Example:
4396-
43974374
// get a Mob ID from the user
43984375
input(.@mob_id);
43994376

4400-
if (getmobdrops(.@mob_id)) { // getmobdrops() returns true on success
4401-
// immediately copy global temporary variables into scope
4402-
// variables, since we don't know when getmobdrops() will get
4403-
// called again for another mob, overwriting your global temporary
4404-
// variables.
4405-
.@count = $@MobDrop_count;
4406-
copyarray(.@item[0], $@MobDrop_item[0], .@count);
4407-
copyarray(.@rate[0], $@MobDrop_rate[0], .@count);
4408-
4377+
.@count = getmobdrops(.@mob_id, .@item, .@rate);
4378+
4379+
if (.@count == 0) {
4380+
mes("No drops found.");
4381+
} else {
44094382
mes(getmonsterinfo(.@mob_id, MOB_NAME) + " - " + .@count + " drops found:");
44104383
for (.@i = 0; .@i < .@count; ++.@i) {
44114384
mes(.@item[.@i] + " (" + getitemname(.@item[.@i]) + ") " + .@rate[.@i]/100 + ((.@rate[.@i]%100 < 10) ? ".0":".") + .@rate[.@i]%100 + "%");
44124385
}
4413-
} else {
4414-
mes("Unknown monster ID.");
44154386
}
44164387
close();
44174388

src/map/script.c

+69-18
Original file line numberDiff line numberDiff line change
@@ -12284,36 +12284,87 @@ static BUILDIN(monster)
1228412284
*------------------------------------------*/
1228512285
static BUILDIN(getmobdrops)
1228612286
{
12287-
int class_ = script_getnum(st,2);
12288-
int i, j = 0;
12289-
struct mob_db *monster;
12287+
struct map_session_data *sd = NULL;
12288+
int mob_id = script_getnum(st, 2);
12289+
struct mob_db *monster = NULL;
12290+
struct script_data *data1 = script_getdata(st, 3);
12291+
struct script_data *data2 = NULL;
12292+
const char *varname1 = NULL;
12293+
const char *varname2 = NULL;
12294+
int varid1 = 0;
12295+
int varid2 = 0;
12296+
int num = 0;
1229012297

12291-
if( !mob->db_checkid(class_) )
12292-
{
12298+
if (!data_isreference(data1) || reference_toconstant(data1)) {
12299+
ShowError("buildin_getmobdrops: Target argument must be a variable\n");
12300+
script->reportdata(data1);
12301+
st->state = END;
12302+
return false;
12303+
}
12304+
12305+
varname1 = reference_getname(data1);
12306+
varid1 = reference_getid(data1);
12307+
12308+
if (!is_int_variable(varname1)) {
12309+
ShowError("buildin_getmobdrops: Target argument must be an integer variable\n");
12310+
script->reportdata(data1);
12311+
st->state = END;
12312+
return false;
12313+
}
12314+
12315+
if (script_hasdata(st, 4)) {
12316+
data2 = script_getdata(st, 4);
12317+
12318+
if (!data_isreference(data2) || reference_toconstant(data2)) {
12319+
ShowError("buildin_getmobdrops: Target argument must be a variable\n");
12320+
script->reportdata(data1);
12321+
st->state = END;
12322+
return false;
12323+
}
12324+
12325+
varname2 = reference_getname(data2);
12326+
varid2 = reference_getid(data2);
12327+
12328+
if (data2 == NULL || !is_int_variable(varname2)) {
12329+
ShowError("buildin_getmobdrops: 2nd target argument must be an integer variable\n");
12330+
script->reportdata(data2);
12331+
st->state = END;
12332+
return false;
12333+
}
12334+
}
12335+
12336+
if (not_server_variable(*varname1) || (data2 != NULL && not_server_variable(*varname2))) {
12337+
sd = script->rid2sd(st);
12338+
if (sd == NULL) {
12339+
script_pushint(st, 0);
12340+
return true; // player variable but no player attached
12341+
}
12342+
}
12343+
12344+
monster = mob->db(mob_id);
12345+
12346+
if (!mob->db_checkid(mob_id) || monster == NULL) {
1229312347
script_pushint(st, 0);
1229412348
return true;
1229512349
}
1229612350

12297-
monster = mob->db(class_);
12298-
12299-
for( i = 0; i < MAX_MOB_DROP; i++ )
12300-
{
12301-
if( monster->dropitem[i].nameid < 1 )
12351+
for (int i = 0; i < MAX_MOB_DROP; i++) {
12352+
if (monster->dropitem[i].nameid < 1)
1230212353
continue;
12303-
if( itemdb->exists(monster->dropitem[i].nameid) == NULL )
12354+
if (itemdb->exists(monster->dropitem[i].nameid) == NULL)
1230412355
continue;
1230512356

12306-
mapreg->setreg(reference_uid(script->add_variable("$@MobDrop_item"), j), monster->dropitem[i].nameid);
12307-
mapreg->setreg(reference_uid(script->add_variable("$@MobDrop_rate"), j), monster->dropitem[i].p);
12308-
12309-
j++;
12357+
script->set_reg(st, sd, reference_uid(varid1, num), varname1, (const void *)h64BPTRSIZE(monster->dropitem[i].nameid), reference_getref(data1));
12358+
if (data2 != NULL)
12359+
script->set_reg(st, sd, reference_uid(varid2, num), varname2, (const void *)h64BPTRSIZE(monster->dropitem[i].p), reference_getref(data2));
12360+
num++;
1231012361
}
1231112362

12312-
mapreg->setreg(script->add_variable("$@MobDrop_count"), j);
12313-
script_pushint(st, 1);
12363+
script_pushint(st, num);
1231412364

1231512365
return true;
1231612366
}
12367+
1231712368
/*==========================================
1231812369
* Same as monster but randomize location in x0,x1,y0,y1 area
1231912370
*------------------------------------------*/
@@ -29110,7 +29161,7 @@ static void script_parse_builtin(void)
2911029161
BUILDIN_DEF(produce,"i"),
2911129162
BUILDIN_DEF(cooking,"i"),
2911229163
BUILDIN_DEF(monster,"siisii???"),
29113-
BUILDIN_DEF(getmobdrops,"i"),
29164+
BUILDIN_DEF(getmobdrops,"ii?"),
2911429165
BUILDIN_DEF(areamonster,"siiiisii???"),
2911529166
BUILDIN_DEF(killmonster,"ss?"),
2911629167
BUILDIN_DEF(killmonsterall,"s?"),

0 commit comments

Comments
 (0)