FatalEror's post in @mapmoblist/@ml (GM command) was marked as the answer
../src/map/atcommand.c
put this above atcommand_basecommands function
static int count_mob(struct block_list *bl, va_list ap) // [FE]
{
struct mob_data *md = (struct mob_data*)bl;
short id = va_arg(ap, short);
if (md->class_ == id)
return 1;
return 0;
}
ACMD_FUNC(mapmoblist) // [FE]
{
char temp[100];
bool mob_searched[MAX_MOB_DB];
bool mob_mvp[MAX_MOB_DB]; // Store mvp data..
struct s_mapiterator* it;
unsigned short count = 0, i, mapindex = 0;
int m = 0;
memset(mob_searched, 0, MAX_MOB_DB);
memset(mob_mvp, 0, MAX_MOB_DB);
if (message && *message) {
// Player input map name, search mob list for that map
mapindex = mapindex_name2id(message);
if (!mapindex) {
clif_displaymessage(fd, "Map not found");
return -1;
}
m = map_mapindex2mapid(mapindex);
} else {
// Player doesn't input map name, search mob list in player current map
mapindex = sd->mapindex;
m = sd->bl.m;
}
clif_displaymessage(fd, "--------Monster List--------");
sprintf(temp, "Mapname: %s", mapindex_id2name(mapindex));
clif_displaymessage(fd, temp);
clif_displaymessage(fd, "Monsters: ");
//Looping and search for mobs
it = mapit_geteachmob();
while (true) {
TBL_MOB* md = (TBL_MOB*)mapit_next(it);
if (md == NULL)
break;
if (md->bl.m != m || md->status.hp <= 0)
continue;
if (mob_searched[md->class_] == true)
continue; // Already found, skip it
if (mob_db(md->class_)->mexp) {
mob_searched[md->class_] = true;
mob_mvp[md->class_] = true; // Save id for later
continue; // It's MVP!
}
mob_searched[md->class_] = true;
count = map_foreachinmap(count_mob, m, BL_MOB, md->class_);
sprintf(temp, " %s[%d] : %d", mob_db(md->class_)->jname, md->class_, count);
clif_displaymessage(fd, temp);
}
mapit_free(it);
clif_displaymessage(fd, "MVP: ");
// Looping again and search for mvp, not sure if this is the best way..
for (i = 1000; i < MAX_MOB_DB; i++) { //First monster start at 1001 (Scorpion)
if (mob_mvp[i] == true) {
count = map_foreachinmap(count_mob, m, BL_MOB, i);
sprintf(temp, " %s[%d] : %d", mob_db(i)->jname, i, count);
clif_displaymessage(fd, temp);
}
}
return 0;
}
below ACMD_DEF(set),
ACMD_DEF(mapmoblist),
../conf/atcommand_athena.conf
mapmoblist: ["ml"]
../conf/groups.conf
commands: {
...
mapmoblist: true
...
}