I had to make a number of changes to the script, otherwise it didn't work correctly.
src/map/map.cpp
Change
@@ -2829,6 +2835,27 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
if (map_getmapflag(m, MF_MOBITEMADDER)) {
for (const auto& it : mapdata->mobitemadder_droplist)
{
if (it.mob_id == md->mob_id) {
struct s_mob_drop mobdrop;
drop_rate = it.item_per;
mobdrop.nameid = it.item_id;
if (rand() % 10000 > drop_rate)
continue;
- if (!ditem || !itemdb_exists(it.item_id))
+ if (!itemdb_exists(it.item_id))
continue;
ditem = mob_setdropitem(&mobdrop, 1, it.mob_id);
mob_item_drop(md, dlist, ditem, 0, it.item_per, homkillonly);
}
}
}
src/map/npc.cpp
new code
case MF_MOBITEMADDER:
{
if (state) {
// Copy the string so as not to modify the original string
char* droplist = strdup(w4);
if (droplist) {
char* checkdroplist = strtok(droplist, ", ");
if (checkdroplist) {
union u_mapflag_args args = {};
args.mobitemadder.mob_id = atoi(checkdroplist);
// Clearing the current item data of a mob before adding new ones
map_setmapflag(m, MF_MOBITEMADDER, false);
// Create a temporary array to store added items
int added_items[50]; // Assume no more than 50 items per monster
int num_added_items = 0; // Number of items added
// Process the string and add the items
while ((checkdroplist = strtok(NULL, ", "))) {
args.mobitemadder.item_id = atoi(checkdroplist);
if ((checkdroplist = strtok(NULL, ", "))) {
args.mobitemadder.item_per = atoi(checkdroplist);
// Check to see if the mob already has the item.
bool already_added = false;
for (int i = 0; i < num_added_items; ++i) {
if (added_items[i] == args.mobitemadder.item_id) {
already_added = true;
break;
}
}
// If the item is not already present on the mob, add it
if (!already_added) {
map_setmapflag_sub(m, MF_MOBITEMADDER, true, &args);
added_items[num_added_items++] = args.mobitemadder.item_id;
}
}
}
}
free(droplist); // Freeing the allocated memory
}
} else {
map_setmapflag(m, MF_MOBITEMADDER, false);
}
break;
}
The only problem I have not been able to solve is the duplicate drop if @reloadscript is produced on the server
That is, if you did reloadscript 10 times, the drop will drop in 10 instances.