ACMD_FUNC(mobinfo) { unsigned char msize[SZ_ALL][7] = { "Small", "Medium", "Large" }; unsigned char mrace[RC_ALL][11] = { "Formless", "Undead", "Beast", "Plant", "Insect", "Fish", "Demon", "Demi-Human", "Angel", "Dragon", "Player" }; unsigned char melement[ELE_ALL][8] = { "Neutral", "Water", "Earth", "Fire", "Wind", "Poison", "Holy", "Dark", "Ghost", "Undead" }; char mmode[29][35] = { "Can Move", "Looter", "Aggressive", "Assist", "Cast Sensor", "No Random Walk", "No Skills", "Can-Attack", "IMAFREEBITCHBABY", "Change Target", "Change Chase", "Aggressive", "Change Target (Melee)", "Change Target (Chase)", "Ignores targets above level %d", "Random Targets", "Ignores Melee", "Ignores Magic", "Ignores Ranged", "Boss-Type", "Plant-Type", "Immune to Knockback", "CAN TELEPORT NO MATTER THE RULES", "ALSOFREE", "NO LOOT", "Fixed Item Drops", "Detector", "Status Immune", "Immune to Skills" }; char atcmd_output2[CHAT_SIZE_MAX]; struct item_data *item_data; struct mob_db *mob; uint16 mob_ids[MAX_SEARCH]; int count; int i, k; memset(atcmd_output, '\0', sizeof(atcmd_output)); memset(atcmd_output2, '\0', sizeof(atcmd_output2)); if (!message || !*message) { clif_displaymessage(fd, msg_txt(sd,1239)); // Please enter a monster name/ID (usage: @mobinfo ). return -1; } // If monster identifier/name argument is a name if ((i = mobdb_checkid(atoi(message)))) { mob_ids[0] = i; count = 1; } else count = mobdb_searchname_array(message, mob_ids, MAX_SEARCH); if (!count) { clif_displaymessage(fd, msg_txt(sd,40)); // Invalid monster ID or name. return -1; } if (count >= MAX_SEARCH) { sprintf(atcmd_output, msg_txt(sd,269), MAX_SEARCH); // Displaying first %d matches clif_displaymessage(fd, atcmd_output); count = MAX_SEARCH; } for (k = 0; k < count; k++) { unsigned int j; char hp[32] = { '\0' }; uint16 maxflee = 0, maxhit = 0; unsigned int base_kp; char kp[32] = { '\0' }; unsigned int base_exp, job_exp; char bxp[32] = { '\0' }; char jxp[32] = { '\0' }; mob = mob_db(mob_ids[k]); base_exp = mob->base_exp; job_exp = mob->job_exp; commas(mob->status.max_hp, hp); if (battle_config.mvpkp_active) { base_kp = mob->kp_party; commas(mob->status.max_hp, hp); commas(base_kp, kp); } commas(base_exp, bxp); commas(job_exp, jxp); if (pc_isvip(sd)) { // Display EXP rate increase for VIP base_exp = (base_exp * battle_config.vip_base_exp_increase) / 100; job_exp = (job_exp * battle_config.vip_job_exp_increase) / 100; } #ifdef RENEWAL_EXP if (battle_config.atcommand_mobinfo_type) { base_exp = base_exp * pc_level_penalty_mod(mob->lv - sd->status.base_level, mob->status.class_, mob->status.mode, 1) / 100; job_exp = job_exp * pc_level_penalty_mod(mob->lv - sd->status.base_level, mob->status.class_, mob->status.mode, 1) / 100; } #endif #ifdef RENEWAL maxhit = MOB_FLEE(mob) + 100; maxflee = MOB_HIT(mob) -5; #else maxhit = MOB_FLEE(mob) + 20; maxflee = MOB_HIT(mob) + 75; #endif // stats if (mob->mexp) sprintf(atcmd_output, msg_txt(sd,1240), mob->name, mob->jname, mob->sprite, mob->vd.class_); // MVP Monster: '%s'/'%s'/'%s' (%d) else sprintf(atcmd_output, msg_txt(sd,1241), mob->name, mob->jname, mob->sprite, mob->vd.class_); // Monster: '%s'/'%s'/'%s' (%d) clif_displaymessage(fd, atcmd_output); sprintf(atcmd_output, " Lv:%u HP:%s ", mob->lv, hp); clif_displaymessage(fd, atcmd_output); if (battle_config.mvpkp_active && mob->mexp) { sprintf(atcmd_output, " KP:%s", kp); clif_displaymessage(fd, atcmd_output); } sprintf(atcmd_output, " BEXP: %s JEXP: %s", bxp, jxp); clif_displaymessage(fd, atcmd_output); sprintf(atcmd_output, " ATK: %d~%d | MATK: %d~%d | DEF: %d+%d | MDEF: %d+%d | ASPD: %3.1f", mob->status.rhw.atk, mob->status.rhw.atk2, mob->status.matk_min, mob->status.matk_max, #ifdef RENEWAL mob->status.def2, mob->status.def, mob->status.mdef2, mob->status.mdef, #else mob->status.def, mob->status.def2, mob->status.mdef, mob->status.mdef2, #endif 200. - (double)mob->status.adelay / 20.); clif_displaymessage(fd, atcmd_output); sprintf(atcmd_output, " 100%% Hit: %d | 95%% Flee: %d | Critshield: %.2f%%", maxhit, maxflee, (double)mob->status.luk / 5.); clif_displaymessage(fd, atcmd_output); sprintf(atcmd_output, " Size: %s | Race: %s | Element: %s (Lv:%d)", msize[mob->status.size], mrace[mob->status.race], melement[mob->status.def_ele], mob->status.ele_lv); clif_displaymessage(fd, atcmd_output); sprintf(atcmd_output, " Range: (Attack: %d View: %d Chase: %d)", mob->status.rhw.range, mob->range2, mob->range3); clif_displaymessage(fd, atcmd_output); clif_displaymessage(fd, " Modes:"); strcpy(atcmd_output, " "); strcpy(atcmd_output2, " "); j = 0; for (i = 0; i < 14; i++) { if (mob->status.mode&(1 << i)) { // let's just output everything because why not flood the chat window sprintf(atcmd_output2, " - %s", mmode[i]); } else continue; strcat(atcmd_output, atcmd_output2); if (++j % 4 == 0) { clif_displaymessage(fd, atcmd_output); strcpy(atcmd_output, " "); } } if (j == 0) clif_displaymessage(fd, "None"); else if (j % 4 != 0) clif_displaymessage(fd, atcmd_output); // drops clif_displaymessage(fd, msg_txt(sd,1245)); // Drops: strcpy(atcmd_output, " "); j = 0; for (i = 0; i < MAX_MOB_DROP_TOTAL; i++) { int droprate; char itemlink[CHAT_SIZE_MAX] = ""; if (mob->dropitem[i].nameid <= 0 || mob->dropitem[i].p < 1 || (item_data = itemdb_exists(mob->dropitem[i].nameid)) == NULL) continue; droprate = mob->dropitem[i].p; #ifdef RENEWAL_DROP if( battle_config.atcommand_mobinfo_type ) { droprate = droprate * pc_level_penalty_mod(mob->lv - sd->status.base_level, mob->status.class_, mob->status.mode, 2) / 100; if (droprate <= 0 && !battle_config.drop_rate0item) droprate = 1; } #endif char itemlink[CHAT_SIZE_MAX] = ""; itemdb_idlinkcreate(itemlink, mob->dropitem[i].nameid); if (pc_isvip(sd)) // Display drop rate increase for VIP droprate += (droprate * battle_config.vip_drop_increase) / 100; sprintf(atcmd_output2, " - %s %02.02f%%", itemlink, (float)droprate / 100); strcat(atcmd_output, atcmd_output2); if (++j % 3 == 0) { clif_displaymessage(fd, atcmd_output); strcpy(atcmd_output, " "); } } if (j == 0) clif_displaymessage(fd, msg_txt(sd,1246)); // This monster has no drops. else if (j % 3 != 0) clif_displaymessage(fd, atcmd_output); // mvp if (mob->mexp) { float mvppercent, mvpremain; char mxp[32] = { '\0' }; commas(mob->mexp, mxp); sprintf(atcmd_output, msg_txt(sd, 1247), mob->mexp); // MVP Bonus EXP:%u clif_displaymessage(fd, atcmd_output); if (battle_config.mvpkp_active) { char mkp[16] = { '\0' }; commas(mob->kp_mvp, mkp); sprintf(atcmd_output, "MVP Bonus KP: %s", mkp); // MVP Bonus EXP:%u clif_displaymessage(fd, atcmd_output); } strcpy(atcmd_output, msg_txt(sd,1248)); // MVP Items: mvpremain = 100.0; //Remaining drop chance for official mvp drop mode j = 0; for (i = 0; i < MAX_MVP_DROP_TOTAL; i++) { if (mob->mvpitem[i].nameid <= 0 || (item_data = itemdb_exists(mob->mvpitem[i].nameid)) == NULL) continue; //Because if there are 3 MVP drops at 50%, the first has a chance of 50%, the second 25% and the third 12.5% mvppercent = (float)mob->mvpitem[i].p * mvpremain / 10000.0f; if(battle_config.item_drop_mvp_mode == 0) { mvpremain -= mvppercent; } if (mvppercent > 0) { char itemlink[CHAT_SIZE_MAX] = ""; j++; itemdb_idlinkcreate(itemlink, mob->mvpitem[i].nameid); if (j == 1) { sprintf(atcmd_output2, " %s %02.02f%%", itemlink, mvppercent); } else { sprintf(atcmd_output2, " - %s %02.02f%%", itemlink, mvppercent); } strcat(atcmd_output, atcmd_output2); } } if (j == 0) clif_displaymessage(fd, msg_txt(sd,1249)); // This monster has no MVP prizes. else clif_displaymessage(fd, atcmd_output); } } return 0; } ACMD_FUNC(iteminfo) { struct item_data *item_array[MAX_SEARCH]; int i, count = 1; if (!message || !*message) { clif_displaymessage(fd, msg_txt(sd,1276)); // Please enter an item name/ID (usage: @ii/@iteminfo ). return -1; } if ((item_array[0] = itemdb_exists(atoi(message))) == NULL) count = itemdb_searchname_array(item_array, MAX_SEARCH, message); if (!count) { clif_displaymessage(fd, msg_txt(sd,19)); // Invalid item ID or name. return -1; } if (count == MAX_SEARCH) { sprintf(atcmd_output, msg_txt(sd,269), MAX_SEARCH); // Displaying first %d matches clif_displaymessage(fd, atcmd_output); } for (i = 0; i < count; i++) { struct item_data * item_data = item_array[i]; char itemlink[CHAT_SIZE_MAX] = ""; itemdb_idlinkcreate(itemlink, item_data->nameid); /* sprintf(atcmd_output, msg_txt(sd,1277), // Item: '%s'/'%s'[%d] (%hu) Type: %s | Extra Effect: %s item_data->name,item_data->jname,item_data->slot,item_data->nameid, (item_data->type != IT_AMMO) ? itemdb_typename((enum item_types)item_data->type) : itemdb_typename_ammo((enum e_item_ammo)item_data->look), (item_data->script==NULL)? msg_txt(sd,1278) : msg_txt(sd,1279) // None / With script ); */ sprintf(atcmd_output, "Item: %s / %s (%hu) Type : %s | Extra Effect : %s", // Item: %s Type: %s | Extra Effect: %s itemlink, item_data->name, item_data->nameid, (item_data->type != IT_AMMO) ? itemdb_typename((enum item_types)item_data->type) : itemdb_typename_ammo((enum e_item_ammo)item_data->look), (item_data->script == NULL) ? msg_txt(sd, 1278) : msg_txt(sd, 1279) // None / With script ); clif_displaymessage(fd, atcmd_output); sprintf(atcmd_output, msg_txt(sd,1280), item_data->value_buy, item_data->value_sell, item_data->weight/10. ); // NPC Buy:%dz, Sell:%dz | Weight: %.1f clif_displaymessage(fd, atcmd_output); if (item_data->maxchance == -1) { strcpy(atcmd_output, msg_txt(sd,1281)); // - Available in the shops only. clif_displaymessage(fd, atcmd_output); } else if (!battle_config.atcommand_mobinfo_type) { if (item_data->maxchance) sprintf(atcmd_output, msg_txt(sd,1282), (float)item_data->maxchance / 100 ); // - Maximal monsters drop chance: %02.02f%% else strcpy(atcmd_output, msg_txt(sd,1283)); // - Monsters don't drop this item. } } return 0; }