Skip to content

Commit

Permalink
Merge pull request #4971 from SJuliez/entity-debug-output
Browse files Browse the repository at this point in the history
Entity debug helper
  • Loading branch information
SJuliez authored Dec 21, 2023
2 parents 41ffb2c + b45d9be commit 31fa3c6
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 5 deletions.
20 changes: 20 additions & 0 deletions megamek/src/megamek/common/CriticalSlot.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
package megamek.common;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class CriticalSlot implements Serializable {
Expand Down Expand Up @@ -223,4 +225,22 @@ public void setRepairable(boolean repair) {
public boolean isRepairable() {
return repairable;
}

@Override
public String toString() {
String typeString = type == 0 ? "System Slot" : "Equipment Slot";
List<String> state = new ArrayList<>();
if (type == 0) state.add("System No: " + index);
if (mount != null) state.add("[" + mount.equipmentIndex() + "] " + mount.getType().getInternalName());
if (mount2 != null) state.add("Mount 2: [" + mount2.equipmentIndex() + "] " + mount2.getType().getInternalName());
if (destroyed) state.add("Destroyed");
if (hit) state.add("Hit");
if (!hittable) state.add("Not hittable");
if (breached) state.add("Breached");
if (missing) state.add("Missing");
if (armored) state.add("Armored");
if (repairing) state.add("Repairing");
if (!repairable) state.add("Not repairable");
return typeString + " { " + String.join(", ", state) + " }";
}
}
63 changes: 58 additions & 5 deletions megamek/src/megamek/common/Mounted.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
* This describes equipment mounted on a mech.
Expand Down Expand Up @@ -1461,11 +1462,6 @@ public int getVibraSetting() {
return vibraSetting;
}

@Override
public String toString() {
return "megamek.common.Mounted (" + typeName + ")";
}

public int getBaseDamageAbsorptionRate() {
return baseDamageAbsorptionRate;
}
Expand Down Expand Up @@ -2128,4 +2124,61 @@ public boolean isHomingAmmoInHomingMode() {
return ammoType.getMunitionType().contains(AmmoType.Munitions.M_HOMING) &&
curMode().equals("Homing");
}

public int equipmentIndex() {
if (entity != null) {
return entity.getEquipmentNum(this);
} else {
return -1;
}
}

@Override
public String toString() {
List<String> locations = allLocations().stream().map(entity::getLocationAbbr).collect(Collectors.toList());
String intro = getType().getInternalName()
+ " (" + String.join("/", locations)
+ (rearMounted ? "-R" : "")
+ (mechTurretMounted ? "-MTu" : "")
+ (sponsonTurretMounted ? "-STu" : "")
+ (pintleTurretMounted ? "-PTu" : "")
+ (isDWPMounted ? "-DWP" : "")
+ (isAPMMounted ? "-APM" : "")
+ (squadSupportWeapon ? "-SSW" : "")
+ (baMountLoc != -1 ? "-" + BattleArmor.MOUNT_LOC_NAMES[baMountLoc] : "")
+ (omniPodMounted ? "-Pod" : "")

+ ")";

List<String> state = new ArrayList<>();
if (linked != null) state.add("Linked: [" + entity.getEquipment().indexOf(linked) + "]");
if (linkedBy != null) state.add("LinkedBy: [" + entity.getEquipment().indexOf(linkedBy) + "]");
if (crossLinkedBy != null) state.add("CrossLinkedBy: [" + entity.getEquipment().indexOf(crossLinkedBy) + "]");
if (linkedBayId != -1) state.add("LinkedBay: [" + linkedBayId + "]");
if (!bayWeapons.isEmpty()) {
List<String> bayWeaponIds = bayWeapons.stream().map(id -> "[" + id + "]").collect(Collectors.toList());
state.add("Bay Weapons: " + String.join(", ", bayWeaponIds));
}
if (!bayAmmo.isEmpty()) {
List<String> bayAmmoIds = bayAmmo.stream().map(id -> "[" + id + "]").collect(Collectors.toList());
state.add("Bay Ammo: " + String.join(", ", bayAmmoIds));
}
if (type instanceof AmmoType) {
state.add("Shots: " + shotsLeft);
}
if (destroyed) state.add("Destroyed");
if (hit) state.add("Hit");
if (missing) state.add("Missing");
if (fired) state.add("Fired");
if (rapidfire) state.add("Rapidfire");
if (jammed) state.add("Jammed");
if (useless) state.add("Useless");
if (armoredComponent) state.add("Armored");
if (facing != -1) state.add("Facing: " + facing);
if (!quirks.activeQuirks().isEmpty()) state.add("Quirks: " + quirks.getOptionList("/"));
if (weaponGroup) state.add("Group");
if (nweapons != 1) state.add("#Weapons: " + nweapons);
if (size != 1) state.add("Size: " + size);
return intro + " { " + String.join(", ", state) + " }";
}
}
103 changes: 103 additions & 0 deletions megamek/src/megamek/utilities/DebugEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright (c) 2023 - The MegaMek Team. All Rights Reserved.
*
* This file is part of MegaMek.
*
* MegaMek is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MegaMek is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MegaMek. If not, see <http://www.gnu.org/licenses/>.
*/
package megamek.utilities;

import megamek.common.CriticalSlot;
import megamek.common.Entity;
import megamek.common.Mech;
import megamek.common.Protomech;

import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;

/**
* This class is for debugging Entity with respect to the internal state of equipment.
*/
@SuppressWarnings("unused")
public class DebugEntity {

/**
* Gets a full listing of the internal representation of the unit's equipment and crit slots with most
* of the internal state of each ({@link #getEquipmentState(Entity)}) and copies it to the clipboard.
*
* @param entity The entity to debug
*/
public static void copyEquipmentState(Entity entity) {
copyToClipboard(getEquipmentState(entity));
}

/** Copies the given text to the Clipboard. */
public static void copyToClipboard(String text) {
StringSelection stringSelection = new StringSelection(text);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, null);
}

/**
* Returns a full listing of the internal representation of the unit's equipment and crit slots with most
* of the internal state of each.
*
* @param entity The entity to debug
* @return A String describing the internal state of the Entity's equipment
*/
public static String getEquipmentState(Entity entity) {
StringBuilder result = new StringBuilder();
try {
result.append("Chassis: >").append(entity.getChassis()).append("<\n");
result.append("Model: >").append(entity.getModel()).append("<\n");

result.append("Equipment:\n");
for (int i = 0; i < entity.getEquipment().size(); i++) {
result.append("[" + i + "] ").append(entity.getEquipment(i)).append("\n");
if (entity != entity.getEquipment(i).getEntity()) {
result.append("Different Entity!");
}
}
result.append("\n");

result.append("Locations:\n");
for (int location = 0; location < entity.locations(); location++) {
result.append(entity.getLocationAbbr(location)).append(":\n");
for (int slot = 0; slot < entity.getNumberOfCriticals(location); slot++) {
CriticalSlot criticalSlot = entity.getCritical(location, slot);
if (criticalSlot != null) {
result.append("[" + slot + "] ").append(criticalSlot);
if (criticalSlot.getType() == 0) {
result.append(" (");
if (entity instanceof Mech) {
result.append(((Mech) entity).getSystemName(criticalSlot.getIndex()));
} else if (entity instanceof Protomech) {
result.append(Protomech.systemNames[criticalSlot.getIndex()]);
}
result.append(")");
}
result.append("\n");
}
}
}
} catch (Exception e) {
result.append("\nAn exception was encountered here. " + e.getMessage());
}

return result.toString();
}

private DebugEntity() { }
}

0 comments on commit 31fa3c6

Please sign in to comment.