Files
Server/src/engine/devcmd/cmds/InfoCmd.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

553 lines
23 KiB
Java

// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2026
// https://www.magicbane.com
package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.BuildingManager;
import engine.gameManager.SessionManager;
import engine.math.Vector3fImmutable;
import engine.mbEnums;
import engine.mbEnums.BuildingGroup;
import engine.mbEnums.GameObjectType;
import engine.mbEnums.TargetColor;
import engine.objects.*;
import engine.parsers.objects.CObjectTemplate;
import engine.util.StringUtils;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author
*/
public class InfoCmd extends AbstractDevCmd {
public InfoCmd() {
super("info");
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
// Arg Count Check
if (words.length != 1) {
this.sendUsage(pc);
return;
}
if (pc == null) {
return;
}
String newline = "\r\n ";
try {
int targetID = Integer.parseInt(words[0]);
Building b = BuildingManager.getBuilding(targetID);
if (b == null)
throwbackError(pc, "Building with ID " + targetID
+ " not found");
else
target = b;
} catch (Exception e) {
}
if (target == null) {
throwbackError(pc, "Target is unknown or of an invalid type."
+ newline + "Type ID: 0x"
+ pc.getLastTargetType().toString()
+ " Table ID: " + pc.getLastTargetID());
return;
}
GameObjectType objType = target.getObjectType();
int objectUUID = target.getObjectUUID();
String output;
output = "Target Information:" + newline;
output += StringUtils.addWS("UUID: " + objectUUID, 20);
output += newline;
output += "Type: " + target.getClass().getSimpleName();
output += " [0x" + objType.toString() + ']';
if (target instanceof AbstractWorldObject) {
AbstractWorldObject targetAWO = (AbstractWorldObject) target;
Vector3fImmutable targetLoc = targetAWO.getLoc();
output += newline;
output += StringUtils.addWS("Lat: " + targetLoc.x, 20);
output += "Lon: " + -targetLoc.z;
output += newline;
output += StringUtils.addWS("Alt: " + targetLoc.y, 20);
output += newline;
output += "Rot: " + targetAWO.getRot().y;
output += newline;
double radian = 0;
if (targetAWO.getBounds() != null && targetAWO.getBounds().getQuaternion() != null)
radian = targetAWO.getBounds().getQuaternion().angleY;
int degrees = (int) Math.toDegrees(radian);
output += "Degrees: " + degrees;
output += newline;
}
switch (objType) {
case Building:
Building targetBuilding = (Building) target;
output += StringUtils.addWS("Lac: "
+ targetBuilding.getw(), 20);
output += "Blueprint : ";
output += targetBuilding.getBlueprintUUID();
output += newline;
output += " MeshUUID : ";
output += targetBuilding.getMeshUUID();
output += newline;
if (targetBuilding.getBlueprintUUID() != 0)
output += ' ' + targetBuilding.getBlueprint().getName();
output += newline;
output += targetBuilding.getBlueprint() != null ? targetBuilding.getBlueprint().getBuildingGroup().name() : " no building group";
output += newline;
output += "EffectFlags: " + targetBuilding.getEffectFlags();
output += newline;
output += StringUtils.addWS("rank: " + targetBuilding.getRank(),
20);
output += "HP: " + targetBuilding.getHealth() + '/'
+ targetBuilding.getMaxHitPoints();
output += newline;
output += "Scale: (" + targetBuilding.getMeshScale().getX();
output += ", " + targetBuilding.getMeshScale().getY();
output += ", " + targetBuilding.getMeshScale().getZ() + ')';
output += newline;
output += "Owner UID: " + targetBuilding.getOwnerUUID();
output += (targetBuilding.isOwnerIsNPC() ? " (NPC)" : " (PC)");
output += newline;
output += "ProtectionState: " + targetBuilding.getProtectionState().name();
output += newline;
if (targetBuilding.getUpgradeDateTime() != null) {
output += targetBuilding.getUpgradeDateTime().toString();
output += newline;
}
Guild guild = targetBuilding.getGuild();
Guild nation = null;
String guildId = "-1";
String nationId = "-1";
String gTag = "";
String nTag = "";
if (guild != null) {
int id = guild.getObjectUUID();
if (id == 0) {
guildId = id + " [" + guild.hashCode() + ']';
} else
guildId = Integer.toString(id);
gTag = guild.getGuildTag().summarySentence();
nation = guild.getNation();
if (nation != null) {
id = nation.getObjectUUID();
if (id == 0) {
nationId = id + " [" + nation.hashCode() + ']';
} else {
nationId = Integer.toString(id);
}
nTag = nation.getGuildTag().summarySentence();
}
}
output += StringUtils.addWS("Guild UID: " + guildId, 20);
if (gTag.length() > 0)
output += "Guild crest: " + gTag;
output += newline;
output += StringUtils.addWS("Nation UID: " + nationId, 20);
if (nTag.length() > 0) {
output += "Nation crest: " + nTag;
}
output += newline;
if (targetBuilding.getBlueprint() != null) {
if (targetBuilding.getBlueprint().getBuildingGroup() == BuildingGroup.MINE) {
Mine mine = Mine.getMineFromTower(targetBuilding.getObjectUUID());
if (mine != null) {
output += newline;
output += "Mine active: " + mine.getIsActive();
output += newline;
output += "Was claimed: " + mine.wasClaimed;
output += newline;
output += "Mine Type: " + mine.getMineType().name;
output += newline;
output += "Expansion : " + mine.isExpansion();
output += newline;
output += "Production type: " + mine.getProduction().name();
}
}
output += newline;
if (targetBuilding.maintDateTime != null) {
output += targetBuilding.maintDateTime.toString();
output += newline;
}
}
output += "Reserve : " + targetBuilding.reserve;
output += newline;
output += "Strongbox : " + targetBuilding.getStrongboxValue();
output += newline;
// List hirelings
if (targetBuilding.getHirelings().isEmpty() == false) {
output += newline;
output += "Hirelings List: name / slot / floor";
for (AbstractCharacter npc : targetBuilding.getHirelings().keySet()) {
if (npc.getObjectType() != GameObjectType.NPC)
continue;
output += newline + npc.getName() + " slot " + targetBuilding.getHirelings().get(npc);
output += newline + "location " + npc.getLoc();
}
}
ArrayList<BuildingRegions> tempList = BuildingRegions._staticRegions.get(targetBuilding.getMeshUUID());
output += newline;
output += "Building Regions: Size - " + tempList.size();
output += newline;
output += "Building Regions from Bounds: Size - " + targetBuilding.getBounds().getRegions().size();
output += newline;
for (Regions regions : targetBuilding.getBounds().getRegions()) {
//TODO ADD REGION INFO
}
break;
case PlayerCharacter:
output += newline;
PlayerCharacter targetPC = (PlayerCharacter) target;
output += StringUtils.addWS("Name: " + targetPC.getName(), 20);
output += newline;
output += "InSession : " + SessionManager.getPlayerCharacterByID(target.getObjectUUID()) != null ? " true " : " false";
output += newline;
output += "RaceType: " + targetPC.race.getRaceType().name();
output += newline;
output += "Race: " + targetPC.race.getName();
output += newline;
output += "Safe:" + targetPC.inSafeZone();
output += newline;
output += "Experience : " + targetPC.getExp();
output += newline;
output += "OverFlowExperience : " + targetPC.getOverFlowEXP();
output += newline;
output += StringUtils.addWS("Level: "
+ targetPC.getLevel() + " (" +
TargetColor.getCon(targetPC, pc).toString() + ')', 20);
Account acpc = SessionManager.getAccount(pc);
Account ac = SessionManager.getAccount(targetPC);
if (acpc != null && ac != null) {
output += "Account ID: " + ac.getObjectUUID();
output += newline;
output += "Access Level: " + ac.status.name();
} else
output += "Account ID: UNKNOWN";
output += newline;
output += "Inventory Weight:" + (targetPC.charItemManager.getInventoryWeight() + targetPC.charItemManager.getEquipWeight());
output += newline;
output += "Max Inventory Weight:" + ((int) targetPC.statStrBase * 3);
output += newline;
output += "ALTITUDE :" + targetPC.getAltitude();
output += newline;
output += "BuildingID :" + targetPC.getInBuildingID();
output += newline;
output += "inBuilding :" + targetPC.getInBuilding();
output += newline;
output += "inFloor :" + targetPC.getInFloorID();
output += newline;
BaseClass baseClass = targetPC.baseClass;
if (baseClass != null)
output += StringUtils.addWS("Class: " + baseClass.getName(), 20);
else
output += StringUtils.addWS("", 20);
PromotionClass promotionClass = targetPC.getPromotionClass();
if (promotionClass != null) {
output += "Pro. Class: " + promotionClass.getName();
} else {
output += "Pro. Class: ";
}
output += newline;
output += "====Guild Info====";
output += newline;
if (targetPC.getGuild() != null) {
output += "Name: " + targetPC.getGuild().getName();
output += newline;
output += "State: " + targetPC.getGuild().guildState;
output += newline;
output += "Realms Owned:" + targetPC.getGuild().realmsOwned;
output += newline;
output += "====Nation====";
output += newline;
output += "Nation Name: " + targetPC.getGuild().getNation().getName();
output += newline;
output += "Nation State: " + targetPC.getGuild().getNation().guildState;
output += newline;
output += "Realms Owned:" + targetPC.getGuild().getNation().realmsOwned;
output += newline;
output += "Guild Rank:" + (GuildStatusController.getRank(targetPC.getGuildStatus()) + targetPC.getGuild().getRealmsOwnedFlag());
}
output += newline;
output += "Movement State: " + targetPC.getMovementState().name();
output += newline;
output += "Movement Speed: " + targetPC.getSpeed();
output += "Altitude : " + targetPC.getLoc().y;
output += "Swimming : " + targetPC.isSwimming();
output += newline;
output += "isMoving : " + targetPC.isMoving();
break;
case NPC:
NPC targetNPC = (NPC) target;
output += "databaseID: " + targetNPC.getDBID() + newline;
output += "Name: " + targetNPC.getName();
output += newline;
output += StringUtils.addWS("Level: " + targetNPC.getLevel(), 20);
MobBase mobBase;
if (targetNPC.getContract() == null)
mobBase = targetNPC.getMobBase();
else
mobBase = MobBase.getMobBase(targetNPC.getContract().getMobbaseID());
if (mobBase != null) {
output += "Mobbbase: " + mobBase.getObjectUUID();
output += newline;
output += "Flags: " + mobBase.getFlags().toString();
}
output += newline;
output += "Spawn: (" + targetNPC.getBindLoc().getX();
output += ", " + targetNPC.getBindLoc().getY();
output += ", " + targetNPC.getBindLoc().getZ() + ')';
output += newline;
output += "ContractID: " + targetNPC.getContractID();
output += newline;
output += "InventorySet: " + targetNPC.getContract().inventorySet;
output += newline;
Contract contract1 = targetNPC.getContract();
output += contract1.allowedBuildings.toString();
output += newline;
output += "Extra Rune: " + targetNPC.getContract().getExtraRune();
output += newline;
output += "isTrainer: " + targetNPC.getContract().isTrainer();
output += newline;
output += "Buy Cost: " + targetNPC.getBuyPercent();
output += "\tSell Cost: " + targetNPC.getSellPercent();
output += newline;
output += "fromInit: " + targetNPC.isStatic();
output += newline;
if (mobBase != null) {
output += newline;
Contract contract = targetNPC.getContract();
output += "Slottable: " + contract.allowedBuildings.toString();
output += newline;
output += "EquipSet: " + targetNPC.getEquipmentSetID();
output += newline;
output += "Parent Zone LoadNum : " + targetNPC.getParentZone().templateID;
}
if (targetNPC.region != null) {
output += newline;
output += "Region found: " + "Building : " + targetNPC.region.parentBuildingID + newline;
output += "building level : " + targetNPC.region.level + newline;
output += "building room : " + targetNPC.region.room + newline;
} else {
output += newline;
output += "No region was found.";
}
if (targetNPC.getBuilding() != null) {
output += newline;
output += "Building : " + targetNPC.getBuilding();
} else {
output += newline;
output += "No building found.";
}
break;
case Mob:
Mob targetMob = (Mob) target;
output += "databaseID: " + targetMob.getDBID() + newline;
output += "Name: " + targetMob.getName();
output += newline;
output += StringUtils.addWS("Level: " + targetMob.getLevel(), 20);
mobBase = targetMob.getMobBase();
if (mobBase != null)
output += "RaceID: " + mobBase.getObjectUUID();
else
output += "RaceID: " + targetMob.getLoadID();
output += newline;
try {
output += "notEnemy: " + targetMob.notEnemy.toString();
output += newline;
output += "enemy: " + targetMob.enemy.toString();
output += newline;
} catch (Exception ex) {
//who cares its info
}
output += "Spawn: (" + targetMob.getBindLoc().getX();
output += ", " + targetMob.getBindLoc().getY();
output += ", " + targetMob.getBindLoc().getZ() + ')';
output += newline;
if (targetMob.isPet()) {
output += "isPet: true";
output += newline;
if ((targetMob.agentType.equals(mbEnums.AIAgentType.PET)))
output += "isSummonedPet: true";
else
output += "isSummonedPet: false";
PlayerCharacter owner = (PlayerCharacter) targetMob.guardCaptain;
if (owner != null)
output += " owner: " + owner.getObjectUUID();
output += newline;
output += "assist: " + targetMob.assist + " resting: " + targetMob.isSit();
output += newline;
}
if (targetMob.getMobBase() != null) {
output += "Mobbase: " + targetMob.getMobBase().getObjectUUID();
output += newline;
output += "Flags: " + targetMob.getMobBase().getFlags().toString();
output += newline;
}
if ((targetMob.agentType.equals(mbEnums.AIAgentType.MOBILE))) {
output += "SpawnRadius: " + targetMob.getSpawnRadius();
output += newline;
output += "Spawn Timer: " + targetMob.getSpawnTimeAsString();
output += newline;
}
output += StringUtils.addWS("isAlive: "
+ targetMob.isAlive(), 20);
output += newline;
//output += "Mob State: " + targetMob.state.name();
output += newline;
output += "Speed : " + targetMob.getSpeed();
output += newline;
output += "EquipSet: " + targetMob.equipmentSetID;
output += newline;
try {
output += "Parent Zone LoadNum : " + targetMob.parentZone.templateID;
} catch (Exception ex) {
//who cares
}
output += newline;
output += "isMoving : " + targetMob.isMoving();
if (targetMob.region != null) {
output += newline;
output += "BuildingID : " + targetMob.region.parentBuildingID;
output += "building level : " + targetMob.region.level;
output += "building room : " + targetMob.region.room;
}
if (targetMob.building != null) {
output += "Building Name: " + targetMob.building.getName() + newline;
output += "BuildingID : " + targetMob.building + newline;
output += "Bind Loc : " + targetMob.getBindLoc() + newline;
output += "Curr Loc : " + targetMob.getLoc() + newline;
} else {
output += newline;
output += "No building found." + newline;
}
int max = (int) (4.882 * targetMob.level + 121.0);
if (max > 321) {
max = 321;
}
int min = (int) (4.469 * targetMob.level - 3.469);
output += "Min Loot Roll = " + min;
output += "Max Loot Roll = " + max;
break;
case Item: //intentional passthrough
case MobLoot:
Item item = (Item) target;
CObjectTemplate template = CObjectTemplate.lookup(item.templateID);
output += StringUtils.addWS("Template: " + template.getTemplateId(), 20);
output += "Weight: " + template.getItemWt();
output += newline;
DecimalFormat df = new DecimalFormat("###,###,###,###,##0");
output += StringUtils.addWS("Qty: "
+ df.format(item.getNumOfItems()), 20);
output += "Charges: " + (byte) item.chargesRemaining
+ '/' + item.template.getItemInitialCharges();
output += newline;
output += "Name: " + template.getItemBaseName();
output += newline;
output += item.getContainerInfo();
throwbackInfo(pc, output);
output = "Effects:" + newline;
ConcurrentHashMap<String, Effect> effects = item.getEffects();
for (String name : effects.keySet()) {
Effect eff = effects.get(name);
output += eff.getEffectsBase().getIDString();
output += newline;
// output += eff.getEffectToken() + (eff.bakedInStat() ? " (baked in)" : "") + newline;
}
break;
}
throwbackInfo(pc, output);
}
@Override
protected String _getHelpString() {
return "Gets information on an Object.";
}
@Override
protected String _getUsageString() {
return "' /info targetID'";
}
}