Skip to content

Commit

Permalink
Merge pull request #3275 from lucasgolino/feat/getitemgroupitems_script
Browse files Browse the repository at this point in the history
Add script function to work with item_group
  • Loading branch information
MishimaHaruna authored Apr 30, 2024
2 parents 7a13f7f + b665c4c commit 9fc9d76
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 0 deletions.
20 changes: 20 additions & 0 deletions doc/script_commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11136,3 +11136,23 @@ When <played_time> is not provided, it defaults to -1, and the current played ti
If keeping the GoldPC mode between sessions is desired, you may use OnPCLoginEvent.

Check out some examples in `doc/sample/goldpc.txt`.


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

*getitemgroupitems(<item_id_array>, <item_group_id>)

Fills the array <item_id_array> with the IDs of the items from the <item_group_id> item group, without duplicates.

Returns the amount of items inserted into the array.

Note: The array will not be automatically cleared. It's recommended to use the returned value to loop over the array instead of relying on getarraysize.

The possible values for <item_group_id> can be found in `db/(pre-)re/item_group.conf`

Example:

.@count = getitemgroupitems(.@item_list[0], Old_Card_Album);
for (.@i = 0; .@i < .@count; ++.@i) {
mesf("^1E56BD\t%s^000000", getitemname(.@item_list[.@i]));
}
17 changes: 17 additions & 0 deletions src/map/itemdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,22 @@ static bool itemdb_in_group(struct item_group *group, int nameid)
return false;
}

/**
* Search for an item group.
*
* @param nameid item group id to search
* @return A pointer to the group
* @retval NULL if the group was not found
*/
static const struct item_group *itemdb_search_group(int nameid)
{
int i;
ARR_FIND(0, itemdb->group_count, i, itemdb->groups[i].id == nameid);
if (i != itemdb->group_count)
return &itemdb->groups[i];
return NULL;
}

/// Searches for the item_data.
/// Returns the item_data or NULL if it does not exist.
static struct item_data *itemdb_exists(int nameid)
Expand Down Expand Up @@ -3357,6 +3373,7 @@ void itemdb_defaults(void)
itemdb->option_exists = itemdb_option_exists;
itemdb->reform_exists = itemdb_reform_exists;
itemdb->in_group = itemdb_in_group;
itemdb->search_group = itemdb_search_group;
itemdb->group_item = itemdb_searchrandomid;
itemdb->chain_item = itemdb_chain_item;
itemdb->package_item = itemdb_package_item;
Expand Down
1 change: 1 addition & 0 deletions src/map/itemdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,7 @@ struct itemdb_interface {
struct itemdb_option* (*option_exists) (int idx);
struct item_reform* (*reform_exists) (int idx);
bool (*in_group) (struct item_group *group, int nameid);
const struct item_group *(*search_group) (int nameid);
int (*group_item) (struct item_group *group);
int (*chain_item) (unsigned short chain_id, int *rate);
void (*package_item) (struct map_session_data *sd, struct item_package *package);
Expand Down
69 changes: 69 additions & 0 deletions src/map/script.c
Original file line number Diff line number Diff line change
Expand Up @@ -9133,6 +9133,74 @@ static BUILDIN(grouprandomitem)
return true;
}

/*==========================================
* getitemgroupitems <reference array of item_id>, <item_group_id>;
*------------------------------------------*/
static BUILDIN(getitemgroupitems)
{
struct script_data* data = script_getdata(st, 2);

if (!data_isreference(data)) {
ShowError("buildin_getitemgroupitems: not a variable\n");
script->reportdata(data);
script_pushnil(st);
st->state = END;
return false;// not a variable
}

int32 idata = reference_getindex(data);
int32 dataid = reference_getid(data);
const char *data_name = reference_getname(data);

if (not_server_variable(*data_name)) {
if (script->rid2sd(st) == NULL) {
// no player attached
script_pushint(st, 0);
return false;
}
}

if (is_string_variable(data_name)) {
// string array
ShowError("buildin_getitemgroupitems: not an integer array reference\n");
script->reportdata(data);
st->state = END;
return false;
}

int nameid = script_getnum(st, 3);
struct item_data *item = itemdb->exists(nameid);
if (item == NULL) {
ShowError("buildin_getitemgroupitems: invalid item %d\n", nameid);
script_pushint(st, 0);
return false;
}

const struct item_group *group = itemdb->search_group(item->nameid);
if (group == NULL) {
ShowWarning("buildin_getitemgroupitems: item group not found\n");
script_pushint(st, 0);
return false;
}

int count = 0;
for (int i = 0; i < group->qty; i++) {
int id = group->nameid[i];
int j = 0;
ARR_FIND(0, i, j, group->nameid[i] == group->nameid[j]);
if (i != j) {
// Already encountered - skip duplicates
continue;
}
const void *v = (const void *)h64BPTRSIZE(id);
script->set_reg(st, NULL, reference_uid(dataid, idata + count), data_name, v, reference_getref(data));
count++;
}

script_pushint(st, count);
return true;
}

/*==========================================
* makeitem <item_id>, <amount>, "<map name>", <X>, <Y> {, <showdropeffect>}};
*------------------------------------------*/
Expand Down Expand Up @@ -28652,6 +28720,7 @@ static void script_parse_builtin(void)
BUILDIN_DEF(getitem2,"viiiiiiii?"),
BUILDIN_DEF(getnameditem,"vv"),
BUILDIN_DEF2(grouprandomitem,"groupranditem","i"),
BUILDIN_DEF(getitemgroupitems, "ri"),
BUILDIN_DEF(makeitem,"visii?"),
BUILDIN_DEF(makeitem2,"viiiiiiii?????"),
BUILDIN_DEF(delitem,"vi?"),
Expand Down

0 comments on commit 9fc9d76

Please sign in to comment.