Files
Server/src/engine/devcmd/cmds/SimulateBootyCmd.java
T
MagicBotandClaude Opus 5.5 566870de79 Move the remaining legacy item template lookups to CObjectTemplate
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>
2026-10-20 07:56:08 -04:00

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'";
}
}