Dev commands, BuildingManager, ChatManager, ForgeManager, NPCManager, NPC, Warehouse, WorkOrder and ManageNPCMsg now call CObjectTemplate.lookup instead of ItemTemplate.templates.get. Forge production cost reads getItemResourceCosts(). Only the DB loader and linkCacheTemplates still use the legacy class (removed in Task 1.8). Removes the static_item_templates ParityCheck comparator. Final parity (offline p17.py, 7586 rows): every id has a cache template, 0 item_type differences, 0 item_resource_costs differences (84 ITEMs have costs). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
158 lines
5.8 KiB
Java
158 lines
5.8 KiB
Java
package engine.devcmd.cmds;
|
|
|
|
import engine.devcmd.AbstractDevCmd;
|
|
import engine.gameManager.LootManager;
|
|
import engine.gameManager.ZoneManager;
|
|
import engine.loot.BootySetEntry;
|
|
import engine.objects.*;
|
|
import engine.parsers.objects.CObjectTemplate;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
|
|
public class SimulateBootyCmd extends AbstractDevCmd {
|
|
public SimulateBootyCmd() {
|
|
super("bootysim");
|
|
}
|
|
|
|
@Override
|
|
protected void _doCmd(PlayerCharacter playerCharacter, String[] words,
|
|
AbstractGameObject target) {
|
|
|
|
if (playerCharacter == null)
|
|
return;
|
|
|
|
String newline = "\r\n ";
|
|
|
|
String output;
|
|
|
|
output = "Booty Simulation:" + newline;
|
|
|
|
Mob mob = (Mob) target;
|
|
output += "Name: " + mob.getName() + newline;
|
|
output += "Special Loot:" + newline;
|
|
|
|
if (mob.bootySet != 0) {
|
|
for (BootySetEntry entry : LootManager._bootySetMap.get(mob.bootySet)) {
|
|
|
|
CObjectTemplate template = CObjectTemplate.lookup(entry.templateID);
|
|
|
|
if (template != null)
|
|
output += "[" + entry.bootyType + "] " + template.getItemBaseName() + " [Chance] " + entry.dropChance + newline;
|
|
}
|
|
}
|
|
|
|
ArrayList<Item> GlassItems = new ArrayList<Item>();
|
|
ArrayList<Item> Resources = new ArrayList<Item>();
|
|
ArrayList<Item> Runes = new ArrayList<Item>();
|
|
ArrayList<Item> Contracts = new ArrayList<Item>();
|
|
ArrayList<Item> Offerings = new ArrayList<Item>();
|
|
ArrayList<Item> OtherDrops = new ArrayList<Item>();
|
|
ArrayList<Item> EquipmentDrops = new ArrayList<Item>();
|
|
|
|
int failures = 0;
|
|
int goldAmount = 0;
|
|
|
|
for (int i = 0; i < 100; ++i) {
|
|
|
|
try {
|
|
mob.loadInventory();
|
|
for (Item lootItem : mob.charItemManager.getInventory()) {
|
|
switch (lootItem.template.getItemType()) {
|
|
case EMPLOYMENTCONTRACT: //CONTRACT
|
|
Contracts.add(lootItem);
|
|
break;
|
|
case OFFERING: //OFFERING
|
|
Offerings.add(lootItem);
|
|
break;
|
|
case RESOURCE: //RESOURCE
|
|
Resources.add(lootItem);
|
|
break;
|
|
case RUNE: //RUNE
|
|
Runes.add(lootItem);
|
|
break;
|
|
case WEAPON: //WEAPON
|
|
if (lootItem.getName().toUpperCase().contains("GLASS"))
|
|
GlassItems.add(lootItem);
|
|
else
|
|
OtherDrops.add(lootItem);
|
|
break;
|
|
case GOLD:
|
|
goldAmount += lootItem.getNumOfItems();
|
|
break;
|
|
default:
|
|
OtherDrops.add(lootItem);
|
|
break;
|
|
}
|
|
}
|
|
} catch (Exception ex) {
|
|
failures++;
|
|
}
|
|
if (mob.charItemManager.equipped.isEmpty() == false) {
|
|
for (Item me : mob.charItemManager.equipped.values()) {
|
|
|
|
if (me.drop_chance == 0)
|
|
continue;
|
|
|
|
float equipmentRoll = ThreadLocalRandom.current().nextInt(99) + 1;
|
|
float dropChance = me.drop_chance * 100;
|
|
|
|
if (equipmentRoll > (dropChance))
|
|
continue;
|
|
|
|
MobLoot ml = new MobLoot(mob, me.template, false);
|
|
|
|
if (ml != null)
|
|
EquipmentDrops.add(ml);
|
|
}
|
|
}
|
|
}
|
|
output += "MobBase BootySet: " + mob.getMobBase().bootySet + newline;
|
|
output += "Mob BootySet: " + mob.bootySet + newline;
|
|
output += "Tables Rolled On: " + newline;
|
|
|
|
boolean hotZoneRan = false;
|
|
float dropRate = 1.0f;
|
|
|
|
if (ZoneManager.inHotZone(mob.getLoc()))
|
|
dropRate = LootManager.HOTZONE_DROP_RATE;
|
|
else
|
|
dropRate = LootManager.NORMAL_DROP_RATE;
|
|
|
|
for (BootySetEntry entry : LootManager._bootySetMap.get(mob.getMobBase().bootySet)) {
|
|
|
|
if (entry.bootyType.equals("GOLD"))
|
|
output += "NORMAL TABLE [" + entry.bootyType + "] " + entry.genTable + ": " + entry.dropChance + newline;
|
|
else
|
|
output += "NORMAL TABLE [" + entry.bootyType + "] " + entry.genTable + ": " + entry.dropChance * dropRate + newline;
|
|
|
|
if (hotZoneRan == false && ZoneManager.inHotZone(mob.getLoc()) && LootManager._genTables.containsKey(entry.genTable + 1)) {
|
|
output += "HOTZONE TABLE [" + entry.bootyType + "] " + (entry.genTable + 1) + ": " + entry.dropChance * dropRate + newline;
|
|
hotZoneRan = true;
|
|
}
|
|
}
|
|
|
|
output += "GLASS DROPS: " + GlassItems.size() + newline;
|
|
output += "RUNE DROPS: " + Runes.size() + newline;
|
|
output += "CONTRACTS DROPS: " + Contracts.size() + newline;
|
|
output += "RESOURCE DROPS: " + Resources.size() + newline;
|
|
output += "OFFERINGS DROPPED: " + Offerings.size() + newline;
|
|
output += "ENCHANTED ITEMS DROPPED: " + OtherDrops.size() + newline;
|
|
output += "TOTAL GOLD DROPPED: " + goldAmount + newline;
|
|
output += "EQUIPMENT DROPPED: " + EquipmentDrops.size() + newline;
|
|
output += "FAILED ROLLS: " + failures + newline;
|
|
|
|
throwbackInfo(playerCharacter, output);
|
|
}
|
|
|
|
@Override
|
|
protected String _getHelpString() {
|
|
return "Simulates loot drops";
|
|
}
|
|
|
|
@Override
|
|
protected String _getUsageString() {
|
|
return "'/bootysim targetID'";
|
|
}
|
|
}
|