/*
* MegaMek - Copyright (C) 2004 Ben Mazur (bmazur@sev.org)
*
* This program 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 2 of the License, or (at your option)
* any later version.
*
* This program 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.
*/
package megamek.common.loaders;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import megamek.common.AmmoType;
import megamek.common.Engine;
import megamek.common.Entity;
import megamek.common.EquipmentType;
import megamek.common.IEntityMovementMode;
import megamek.common.Mounted;
import megamek.common.Tank;
import megamek.common.TechConstants;
import megamek.common.TroopSpace;
import megamek.common.VTOL;
import megamek.common.WeaponType;
/**
* Based on the hmpread.c program and the MtfFile object. This class can not
* load any Mixed tech or Level 3 vehicles.
*
* @author <a href="mailto:mnewcomb@sourceforge.net">Michael Newcomb</a>
*/
public class HmvFile implements IMechLoader {
private String name;
private String model;
private HMVMovementType movementType;
private int rulesLevel;
private int year;
private boolean isOmni = false;
private HMVTechType techType;
private HMVTechType engineTechType;
private HMVTechType baseTechType;
private HMVTechType targetingComputerTechType;
private int engineRating;
private HMVEngineType engineType;
private int cruiseMP;
private int jumpMP;
private HMVArmorType armorType;
private HMVTechType armorTechType;
private int roundedInternalStructure;
private int turretArmor;
private int frontArmor;
private int leftArmor;
private int rightArmor;
private int rearArmor;
private int artemisType;
private Hashtable<HMVWeaponLocation, Hashtable<EquipmentType, Integer>> equipment = new Hashtable<HMVWeaponLocation, Hashtable<EquipmentType, Integer>>();
private float troopSpace = 0;
private String fluff;
private List<String> failedEquipment = new ArrayList<String>();
private boolean hasTurret = false;
public HmvFile(InputStream is) throws EntityLoadingException {
try {
DataInputStream dis = new DataInputStream(is);
byte[] buffer = new byte[5];
dis.read(buffer);
// version is never used.
// String version = new String(buffer);
// ??
dis.skipBytes(2);
int type = readUnsignedShort(dis);
movementType = HMVMovementType.getType(type);
if (null == movementType) {
throw new EntityLoadingException(
"Could not locate movement type for " + type + ".");
}
// ??
dis.skipBytes(12);
buffer = new byte[readUnsignedShort(dis)];
dis.read(buffer);
name = new String(buffer);
buffer = new byte[readUnsignedShort(dis)];
dis.read(buffer);
model = new String(buffer);
// This next one appears to be wrong. FIXME
rulesLevel = readUnsignedShort(dis);
year = readUnsignedShort(dis);
// ??
dis.skipBytes(32);
// The "bf2" buffer contains the word "omni" for OmniVehicles.
int bf2Length = readUnsignedShort(dis);
byte[] bf2Buffer = new byte[bf2Length];
dis.read(bf2Buffer);
isOmni = containsOmni(bf2Buffer);
techType = HMVTechType.getType(readUnsignedShort(dis));
if (techType.equals(HMVTechType.MIXED)) {
// THESE ARE GUESSES. Need example hmv files to verify.
baseTechType = HMVTechType.getType(readUnsignedShort(dis));
engineTechType = HMVTechType.getType(readUnsignedShort(dis));
targetingComputerTechType = HMVTechType
.getType(readUnsignedShort(dis));
armorTechType = HMVTechType.getType(readUnsignedShort(dis));
} else if (techType.equals(HMVTechType.CLAN)) {
engineTechType = HMVTechType.CLAN;
baseTechType = HMVTechType.CLAN;
targetingComputerTechType = HMVTechType.CLAN;
armorTechType = HMVTechType.CLAN;
} else {
engineTechType = HMVTechType.INNER_SPHERE;
baseTechType = HMVTechType.INNER_SPHERE;
targetingComputerTechType = HMVTechType.INNER_SPHERE;
armorTechType = HMVTechType.INNER_SPHERE;
}
// ??
dis.skipBytes(4);
engineRating = readUnsignedShort(dis);
engineType = HMVEngineType.getType(readUnsignedShort(dis));
cruiseMP = readUnsignedShort(dis);
jumpMP = readUnsignedShort(dis);
// Even if we aren't using this, we need to read past its location.
readUnsignedShort(dis);
// heatSinks = readUnsignedShort(dis);
armorType = HMVArmorType.getType(readUnsignedShort(dis));
roundedInternalStructure = readUnsignedShort(dis);
turretArmor = readUnsignedShort(dis);
if (turretArmor > 0) {
hasTurret = true;
}
// internal structure again ??
dis.skipBytes(2);
frontArmor = readUnsignedShort(dis);
// internal structure again ??
dis.skipBytes(2);
leftArmor = readUnsignedShort(dis);
// internal structure again ??
dis.skipBytes(2);
rightArmor = readUnsignedShort(dis);
// internal structure again ??
dis.skipBytes(2);
rearArmor = readUnsignedShort(dis);
// ??
if (isOmni) {
// Skip 12 bytes for OmniVehicles
dis.skipBytes(12);
// Decide whether or not the turret is a fixed weight
int lockedTurret = readUnsignedShort(dis);
if (lockedTurret == 2) {
// Skip something else?...
dis.skipBytes(12);
}
} else {
// Skip 14 bytes for non-OmniVehicles
dis.skipBytes(14);
}
int weapons = readUnsignedShort(dis);
for (int i = 1; i <= weapons; i++) {
int weaponCount = readUnsignedShort(dis);
int weaponType = readUnsignedShort(dis);
// manufacturer name
dis.skipBytes(readUnsignedShort(dis));
HMVWeaponLocation weaponLocation = HMVWeaponLocation
.getType(readUnsignedShort(dis));
if (weaponLocation == HMVWeaponLocation.TURRET) {
hasTurret = true;
}
int weaponAmmo = readUnsignedShort(dis);
EquipmentType equipmentType = getEquipmentType(weaponType,
techType);
if (equipmentType != null) {
addEquipmentType(equipmentType, weaponCount, weaponLocation);
if (weaponAmmo > 0) {
AmmoType ammoType = getAmmoType(weaponType, techType);
if (ammoType != null) {
// Need to play games for half ton MG ammo.
if ((weaponAmmo < ammoType.getShots())
|| (weaponAmmo % ammoType.getShots() > 0)) {
switch (ammoType.getAmmoType()) {
case AmmoType.T_MG:
if (ammoType.getTechLevel() == TechConstants.T_INTRO_BOXSET) {
ammoType = (AmmoType) EquipmentType
.get("ISMG Ammo (100)");
} else {
ammoType = (AmmoType) EquipmentType
.get("CLMG Ammo (100)");
}
break;
case AmmoType.T_MG_LIGHT:
ammoType = (AmmoType) EquipmentType
.get("CLLightMG Ammo (100)");
break;
case AmmoType.T_MG_HEAVY:
ammoType = (AmmoType) EquipmentType
.get("CLHeavyMG Ammo (50)");
break;
default:
// Only MG ammo comes in half ton lots.
throw new EntityLoadingException(
ammoType.getName()
+ " has "
+ ammoType.getShots()
+ " shots per ton, but "
+ name + " " + model
+ " wants "
+ weaponAmmo
+ " shots.");
}
}
// Add as many copies of the AmmoType as needed.
addEquipmentType(ammoType, weaponAmmo
/ ammoType.getShots(),
HMVWeaponLocation.BODY);
} // End found-ammoType
} // End have-rounds-of-ammo
} // End found-equipmentType
// ??
dis.skipBytes(4);
} // Handle the next piece of equipment
// Read the amount of troop/cargo bays.
int bayCount = readUnsignedShort(dis);
for (int loop = 0; loop < bayCount; loop++) {
// Read the size of this bay.
// dis.skipBytes(2);
float baySize = readFloat(dis);
// bay name (this is free text, so we can't be certain if it is
// an infantry bay or something else)
dis.skipBytes(readUnsignedShort(dis));
// Add the troopSpace of this bay to our running total.
troopSpace += baySize;
} // Handle the next bay.
dis.skipBytes(12);
int CASE = readUnsignedShort(dis);
if (CASE == 0xFFFF) {
if (techType.equals(HMVTechType.INNER_SPHERE)) {
addEquipmentType(EquipmentType.get("ISCASE"), 1,
HMVWeaponLocation.REAR);
} else {
addEquipmentType(EquipmentType.get("CLCASE"), 1,
HMVWeaponLocation.REAR);
}
}
int targetingComp = readUnsignedShort(dis);
if (targetingComp == 1) {
if (targetingComputerTechType.equals(HMVTechType.CLAN)) {
addEquipmentType(EquipmentType.get("CLTargeting Computer"),
1, HMVWeaponLocation.BODY);
} else {
addEquipmentType(EquipmentType.get("ISTargeting Computer"),
1, HMVWeaponLocation.BODY);
}
}
artemisType = readUnsignedShort(dis);
// the artemis is a bit field: 1 = SRM artemis IV, 2 = LRM artemis
// IV,
// 4 = SRM artemis V, 8 = LRM artemis V
dis.skipBytes(4);
int VTOLoptions = readUnsignedShort(dis);
// Yuck, a decimal field: 10 = main/tail, 20 = dual, 30 = coax
// rotors
// 100 = beagle/clan AP, 200 = bloodhound/light AP, 300 = c3 slave
// mast mount
int mastEq = VTOLoptions / 100;
// int rotorType = VTOLoptions % 100; //rorottype is never read
// TODO read rotottype from a file.
// Mast mounted equipment is not supported - put it in the rotor and
// hope for the best
if (mastEq == 1) {
if (baseTechType.equals(HMVTechType.CLAN)) {
addEquipmentType(EquipmentType.get("CLActiveProbe"), 1,
HMVWeaponLocation.TURRET);
} else {
addEquipmentType(EquipmentType.get("BeagleActiveProbe"), 1,
HMVWeaponLocation.TURRET);
}
} else if (mastEq == 2) {
if (baseTechType.equals(HMVTechType.CLAN)) {
addEquipmentType(EquipmentType.get("CLLightActiveProbe"),
1, HMVWeaponLocation.TURRET);
} else {
addEquipmentType(
EquipmentType.get("BloodhoundActiveProbe"), 1,
HMVWeaponLocation.TURRET);
}
} else if (mastEq == 3) {
addEquipmentType(EquipmentType.get("ISC3SlaveUnit"), 1,
HMVWeaponLocation.TURRET);
}
dis.skipBytes(4);
int fluffSize = 0;
fluff = "Overview:\n\r";
buffer = new byte[readUnsignedShort(dis)];
dis.read(buffer);
fluff += new String(buffer);
fluffSize += new String(buffer).length();
fluff += "\n\rCapability:\n\r";
buffer = new byte[readUnsignedShort(dis)];
dis.read(buffer);
fluff += new String(buffer);
fluffSize += new String(buffer).length();
fluff += "\n\rBattle History:\n\r";
buffer = new byte[readUnsignedShort(dis)];
dis.read(buffer);
fluff += new String(buffer);
fluffSize += new String(buffer).length();
fluff += "\n\rVariants:\n\r";
buffer = new byte[readUnsignedShort(dis)];
dis.read(buffer);
fluff += new String(buffer);
fluffSize += new String(buffer).length();
fluff += "\n\rFamous Vehicles and Pilots:\n\r";
buffer = new byte[readUnsignedShort(dis)];
dis.read(buffer);
fluff += new String(buffer);
fluffSize += new String(buffer).length();
fluff += "\n\rDeployment:\n\r";
buffer = new byte[readUnsignedShort(dis)];
dis.read(buffer);
fluff += new String(buffer);
fluffSize += new String(buffer).length();
dis.skipBytes(readUnsignedShort(dis)); // notes
// just a catch all for small Fluffs anything well less then 10
// characters, per section, isn't worth printing.
if (fluffSize <= 60) {
fluff = null;
}
int supercharger = readUnsignedShort(dis);
if (supercharger > 0) {
addEquipmentType(EquipmentType.get("Supercharger"), 1,
HMVWeaponLocation.BODY);
}
dis.close();
} catch (IOException ex) {
ex.printStackTrace();
throw new EntityLoadingException("I/O Error reading file");
}
}
private short readUnsignedByte(DataInputStream dis) throws IOException {
short b = dis.readByte();
b += b < 0 ? 256 : 0;
return b;
}
private int readUnsignedShort(DataInputStream dis) throws IOException {
int b2 = readUnsignedByte(dis);
int b1 = readUnsignedByte(dis);
b1 <<= 8;
return b1 + b2;
}
/**
* Read a single precision float from a file in little endian format
*
* @param dis
* @return
* @throws IOException
*/
private float readFloat(DataInputStream dis) throws IOException {
int bits = dis.readInt();
// Integer.reverseBytes is not supported in 1.4
// return Float.intBitsToFloat(Integer.reverseBytes(bits));
bits = ((bits & 0xFF000000) >> 24) | ((bits & 0x00FF0000) >> 8)
| ((bits & 0x0000FF00) << 8) | ((bits & 0x000000FF) << 24);
return Float.intBitsToFloat(bits);
}
/**
* Determine if the buffer contains the "is omni" flag.
*
* @param buffer the array of <code>byte</code>s to be scanned.
* @return <code>true</code> if the buffer contains the "is omni" flag.
*/
private boolean containsOmni(byte[] buffer) {
int index;
// Look for the 4 byte flag.
for (index = buffer.length - 4; index >= 0; index--) {
if ((0x6f == buffer[index]) && // 'o'
(0x6d == buffer[index + 1]) && // 'm'
(0x6e == buffer[index + 2]) && // 'n'
(0x69 == buffer[index + 3])) { // 'i'
// We found it!
return true;
}
}
// We didn't find the "is omni" flag;
return false;
}
public Entity getEntity() throws EntityLoadingException {
try {
Tank vehicle = null;
if ((movementType == HMVMovementType.TRACKED)
|| (movementType == HMVMovementType.WHEELED)
|| (movementType == HMVMovementType.HOVER)
|| (movementType == HMVMovementType.DISPLACEMENT_HULL)
|| (movementType == HMVMovementType.HYDROFOIL)
|| (movementType == HMVMovementType.SUBMARINE)) {
vehicle = new Tank();
} else if (movementType == HMVMovementType.VTOL) {
vehicle = new VTOL();
} else {
throw new EntityLoadingException(
"Unsupported vehicle movement type:" + movementType);
}
vehicle.setChassis(name);
vehicle.setModel(model);
vehicle.setYear(year);
vehicle.setOmni(isOmni);
vehicle.setFluff(fluff);
int techLevel = TechConstants.T_IS_ADVANCED;
if (rulesLevel == 1) {
techLevel = TechConstants.T_INTRO_BOXSET;
} else if (rulesLevel == 2) {
techLevel = techType == HMVTechType.CLAN ? TechConstants.T_CLAN_TW
: TechConstants.T_IS_TW_NON_BOX;
} else if (techType == HMVTechType.CLAN) {
techLevel = TechConstants.T_CLAN_ADVANCED;
}
vehicle.setTechLevel(techLevel);
if (vehicle instanceof VTOL) {
vehicle.setMovementMode(IEntityMovementMode.VTOL);
} else {
vehicle
.setMovementMode(movementType == HMVMovementType.DISPLACEMENT_HULL ? IEntityMovementMode.NAVAL
: movementType == HMVMovementType.HYDROFOIL ? IEntityMovementMode.HYDROFOIL
: movementType == HMVMovementType.HOVER ? IEntityMovementMode.HOVER
: movementType == HMVMovementType.WHEELED ? IEntityMovementMode.WHEELED
: movementType == HMVMovementType.SUBMARINE ? IEntityMovementMode.SUBMARINE
: IEntityMovementMode.TRACKED);
}
// This next line sets the weight to a rounded value
// so that the suspension factor can be retrieved. The
// real weight is set below that. Why is tonnage not directly
// stated in the HMV file?!
vehicle.setWeight(roundedInternalStructure * 10); // temporary
int suspensionFactor = vehicle.getSuspensionFactor();
vehicle.setWeight((engineRating + suspensionFactor) / cruiseMP);
int engineFlags = Engine.TANK_ENGINE;
if ((techType == HMVTechType.CLAN)
|| (engineTechType == HMVTechType.CLAN)) {
engineFlags |= Engine.CLAN_ENGINE;
}
vehicle
.setEngine(new Engine(engineRating, Engine
.getEngineTypeByString(engineType.toString()),
engineFlags));
vehicle.setOriginalJumpMP(jumpMP);
// hmmm...
vehicle.setHasNoTurret(!hasTurret);
vehicle.autoSetInternal();
vehicle.setArmorType(armorType.toString());
if (armorTechType == HMVTechType.CLAN) {
switch (rulesLevel) {
case 2:
vehicle.setArmorTechLevel(TechConstants.T_CLAN_TW);
break;
case 3:
vehicle.setArmorTechLevel(TechConstants.T_CLAN_ADVANCED);
break;
default:
throw new EntityLoadingException(
"Unsupported tech level: " + rulesLevel);
}
} else {
switch (rulesLevel) {
case 1:
vehicle.setArmorTechLevel(TechConstants.T_INTRO_BOXSET);
break;
case 2:
vehicle.setArmorTechLevel(TechConstants.T_IS_TW_NON_BOX);
break;
case 3:
vehicle.setArmorTechLevel(TechConstants.T_IS_ADVANCED);
break;
default:
throw new EntityLoadingException(
"Unsupported tech level: " + rulesLevel);
}
}
vehicle.initializeArmor(frontArmor, Tank.LOC_FRONT);
vehicle.initializeArmor(leftArmor, Tank.LOC_LEFT);
vehicle.initializeArmor(rightArmor, Tank.LOC_RIGHT);
vehicle.initializeArmor(rearArmor, Tank.LOC_REAR);
if (vehicle instanceof VTOL) {
vehicle.initializeArmor(turretArmor, VTOL.LOC_ROTOR);
} else if (!vehicle.hasNoTurret()) {
vehicle.initializeArmor(turretArmor, Tank.LOC_TURRET);
}
addEquipment(vehicle, HMVWeaponLocation.FRONT, Tank.LOC_FRONT);
addEquipment(vehicle, HMVWeaponLocation.LEFT, Tank.LOC_LEFT);
addEquipment(vehicle, HMVWeaponLocation.RIGHT, Tank.LOC_RIGHT);
addEquipment(vehicle, HMVWeaponLocation.REAR, Tank.LOC_REAR);
if (!vehicle.hasNoTurret()) {
addEquipment(vehicle, HMVWeaponLocation.TURRET, Tank.LOC_TURRET);
}
addEquipment(vehicle, HMVWeaponLocation.BODY, Tank.LOC_BODY);
// Do we have any infantry/cargo bays?
int capacity = (int) Math.round(Math.floor(troopSpace));
if (capacity > 0) {
vehicle.addTransporter(new TroopSpace(capacity));
}
addFailedEquipment(vehicle);
return vehicle;
} catch (Exception e) {
e.printStackTrace();
throw new EntityLoadingException(e.getMessage());
}
}
private void addEquipmentType(EquipmentType equipmentType, int weaponCount,
HMVWeaponLocation weaponLocation) {
Hashtable<EquipmentType, Integer> equipmentAtLocation = equipment
.get(weaponLocation);
if (equipmentAtLocation == null) {
equipmentAtLocation = new Hashtable<EquipmentType, Integer>();
equipment.put(weaponLocation, equipmentAtLocation);
}
Integer prevCount = equipmentAtLocation.get(equipmentType);
if (null != prevCount) {
weaponCount += prevCount.intValue();
}
equipmentAtLocation.put(equipmentType, new Integer(weaponCount));
}
private void addEquipment(Tank tank, HMVWeaponLocation weaponLocation,
int location) throws Exception {
Hashtable<EquipmentType, Integer> equipmentAtLocation = equipment
.get(weaponLocation);
if (equipmentAtLocation != null) {
for (Enumeration<EquipmentType> e = equipmentAtLocation.keys(); e
.hasMoreElements();) {
EquipmentType equipmentType = e.nextElement();
Integer count = equipmentAtLocation.get(equipmentType);
for (int i = 0; i < count.intValue(); i++) {
// for experimental or unofficial equipment, we need
// to adjust the mech's techlevel, because HMV only
// knows lvl1/2/3
if ((equipmentType.getTechLevel() > tank.getTechLevel())
&& (tank.getTechLevel() >= TechConstants.T_IS_ADVANCED)) {
boolean isClan = tank.isClan();
if ((equipmentType.getTechLevel() == TechConstants.T_IS_EXPERIMENTAL) ||
(equipmentType.getTechLevel() == TechConstants.T_CLAN_EXPERIMENTAL)) {
tank.setTechLevel(isClan?TechConstants.T_CLAN_EXPERIMENTAL:TechConstants.T_IS_EXPERIMENTAL);
} else if ((equipmentType.getTechLevel() == TechConstants.T_IS_UNOFFICIAL) ||
(equipmentType.getTechLevel() == TechConstants.T_CLAN_UNOFFICIAL)) {
tank.setTechLevel(isClan?TechConstants.T_CLAN_UNOFFICIAL:TechConstants.T_IS_UNOFFICIAL);
}
}
Mounted weapon = tank.addEquipment(equipmentType, location);
// Add artemis?
// Note this is done here because SRM without artemis and
// LRM with artemis
// can be in the same location on a tank. (and might be
// mislinked)
if ((artemisType != 0) && (equipmentType instanceof WeaponType)) {
String artemis = null;
int ammoType = ((WeaponType) equipmentType)
.getAmmoType();
if (ammoType == AmmoType.T_LRM) {
if ((artemisType & 2) == 2) {
artemis = "ArtemisIV";
} else if ((artemisType & 8) == 8) {
artemis = "ArtemisV";
}
} else if (ammoType == AmmoType.T_SRM) {
if ((artemisType & 1) == 1) {
artemis = "ArtemisIV";
} else if ((artemisType & 4) == 4) {
artemis = "ArtemisV";
}
}
if (artemis != null) {
EquipmentType artEq;
if ((equipmentType.getTechLevel() == TechConstants.T_CLAN_TW)
|| (equipmentType.getTechLevel() == TechConstants.T_CLAN_ADVANCED)) {
artEq = EquipmentType.get("CL" + artemis);
} else {
artEq = EquipmentType.get("IS" + artemis);
}
if (artEq != null) {
Mounted fcs = tank
.addEquipment(artEq, location);
fcs.setLinked(weapon);
}
}
}
}
}
}
}
private void addFailedEquipment(Tank tank) {
for (String s : failedEquipment) {
tank.addFailedEquipment(s);
}
}
private static final Hashtable<HMVTechType, Hashtable<Long, String>> EQUIPMENT = new Hashtable<HMVTechType, Hashtable<Long, String>>();
private static final Hashtable<HMVTechType, Hashtable<Long, String>> AMMO = new Hashtable<HMVTechType, Hashtable<Long, String>>();
static {
// inner sphere equipment
// note all weapons should be matched by an ammo entry with the same
// index
//
Hashtable<Long, String> isEquipment = new Hashtable<Long, String>();
EQUIPMENT.put(HMVTechType.INNER_SPHERE, isEquipment);
isEquipment.put(new Long(0x0A), "ISDouble Heat Sink");
isEquipment.put(new Long(0x0B), "Jump Jet");
isEquipment.put(new Long(0x12), "ISTargeting Computer");
isEquipment.put(new Long(0x14), "Endo Steel");
isEquipment.put(new Long(0x15), "Ferro-Fibrous");
isEquipment.put(new Long(0x17), "ISMASC");
isEquipment.put(new Long(0x18), "ISArtemisIV");
isEquipment.put(new Long(0x19), "ISCASE");
isEquipment.put(new Long(0x33), "ISERLargeLaser");
isEquipment.put(new Long(0x34), "ISERPPC");
isEquipment.put(new Long(0x35), "ISFlamer");
isEquipment.put(new Long(0x36), "ISLaserAMS");
isEquipment.put(new Long(0x37), "ISLargeLaser");
isEquipment.put(new Long(0x38), "ISMediumLaser");
isEquipment.put(new Long(0x39), "ISSmallLaser");
isEquipment.put(new Long(0x3A), "ISPPC");
isEquipment.put(new Long(0x3B), "ISLargePulseLaser");
isEquipment.put(new Long(0x3C), "ISMediumPulseLaser");
isEquipment.put(new Long(0x3D), "ISSmallPulseLaser");
isEquipment.put(new Long(0x3E), "ISAC2");
isEquipment.put(new Long(0x3F), "ISAC5");
isEquipment.put(new Long(0x40), "ISAC10");
isEquipment.put(new Long(0x41), "ISAC20");
isEquipment.put(new Long(0x42), "ISAntiMissileSystem");
isEquipment.put(new Long(0x43), "Long Tom Cannon");
isEquipment.put(new Long(0x44), "Sniper Cannon");
isEquipment.put(new Long(0x45), "Thumper Cannon");
isEquipment.put(new Long(0x46), "ISLightGaussRifle");
isEquipment.put(new Long(0x47), "ISGaussRifle");
isEquipment.put(new Long(0x48), "ISLargeXPulseLaser");
isEquipment.put(new Long(0x49), "ISMediumXPulseLaser");
isEquipment.put(new Long(0x4A), "ISSmallXPulseLaser");
isEquipment.put(new Long(0x4B), "ISLBXAC2");
isEquipment.put(new Long(0x4C), "ISLBXAC5");
isEquipment.put(new Long(0x4D), "ISLBXAC10");
isEquipment.put(new Long(0x4E), "ISLBXAC20");
isEquipment.put(new Long(0x4F), "ISMachine Gun");
isEquipment.put(new Long(0x50), "ISLAC2");
isEquipment.put(new Long(0x51), "ISLAC5");
isEquipment.put(new Long(0x52), "ISHeavyFlamer");
isEquipment.put(new Long(0x53), "ISPPCCapacitor");
isEquipment.put(new Long(0x54), "ISUltraAC2");
isEquipment.put(new Long(0x55), "ISUltraAC5");
isEquipment.put(new Long(0x56), "ISUltraAC10");
isEquipment.put(new Long(0x57), "ISUltraAC20");
isEquipment.put(new Long(0x59), "ISPPCCapacitor");
isEquipment.put(new Long(0x5A), "ISERMediumLaser");
isEquipment.put(new Long(0x5B), "ISERSmallLaser");
isEquipment.put(new Long(0x5C), "ISAntiPersonnelPod");
isEquipment.put(new Long(0x60), "ISLRM5");
isEquipment.put(new Long(0x61), "ISLRM10");
isEquipment.put(new Long(0x62), "ISLRM15");
isEquipment.put(new Long(0x63), "ISLRM20");
isEquipment.put(new Long(0x66), "ISImprovedNarc");
isEquipment.put(new Long(0x67), "ISSRM2");
isEquipment.put(new Long(0x68), "ISSRM4");
isEquipment.put(new Long(0x69), "ISSRM6");
isEquipment.put(new Long(0x6A), "ISStreakSRM2");
isEquipment.put(new Long(0x6B), "ISStreakSRM4");
isEquipment.put(new Long(0x6C), "ISStreakSRM6");
isEquipment.put(new Long(0x6D), "ISThunderbolt5");
isEquipment.put(new Long(0x6E), "ISThunderbolt10");
isEquipment.put(new Long(0x6F), "ISThunderbolt15");
isEquipment.put(new Long(0x70), "ISThunderbolt20");
isEquipment.put(new Long(0x71), "ISArrowIVSystem");
isEquipment.put(new Long(0x72), "ISAngelECMSuite");
isEquipment.put(new Long(0x73), "ISBeagleActiveProbe");
isEquipment.put(new Long(0x74), "ISBloodhoundActiveProbe");
isEquipment.put(new Long(0x75), "ISC3MasterComputer");
isEquipment.put(new Long(0x76), "ISC3SlaveUnit");
isEquipment.put(new Long(0x77), "ISImprovedC3CPU");
isEquipment.put(new Long(0x78), "ISGuardianECM");
isEquipment.put(new Long(0x79), "ISNarcBeacon");
isEquipment.put(new Long(0x7A), "ISTAG");
isEquipment.put(new Long(0x7B), "ISLRM5 (OS)");
isEquipment.put(new Long(0x7C), "ISLRM10 (OS)");
isEquipment.put(new Long(0x7D), "ISLRM15 (OS)");
isEquipment.put(new Long(0x7E), "ISLRM20 (OS)");
isEquipment.put(new Long(0x7F), "ISSRM2 (OS)");
isEquipment.put(new Long(0x80), "ISSRM4 (OS)");
isEquipment.put(new Long(0x81), "ISSRM6 (OS)");
isEquipment.put(new Long(0x82), "ISStreakSRM2 (OS)");
isEquipment.put(new Long(0x83), "ISStreakSRM4 (OS)");
isEquipment.put(new Long(0x84), "ISStreakSRM6 (OS)");
isEquipment.put(new Long(0x85), "ISVehicleFlamer");
isEquipment.put(new Long(0x86), "ISLongTomArtillery");
isEquipment.put(new Long(0x87), "ISSniperArtillery");
isEquipment.put(new Long(0x88), "ISThumperArtillery");
isEquipment.put(new Long(0x89), "ISMRM10");
isEquipment.put(new Long(0x8A), "ISMRM20");
isEquipment.put(new Long(0x8B), "ISMRM30");
isEquipment.put(new Long(0x8C), "ISMRM40");
isEquipment.put(new Long(0x8E), "ISMRM10 (OS)");
isEquipment.put(new Long(0x8F), "ISMRM20 (OS)");
isEquipment.put(new Long(0x90), "ISMRM30 (OS)");
isEquipment.put(new Long(0x91), "ISMRM40 (OS)");
isEquipment.put(new Long(0x92), "ISLRTorpedo5");
isEquipment.put(new Long(0x93), "ISLRTorpedo10");
isEquipment.put(new Long(0x94), "ISLRTorpedo15");
isEquipment.put(new Long(0x95), "ISLRTorpedo20");
isEquipment.put(new Long(0x96), "ISSRT2");
isEquipment.put(new Long(0x97), "ISSRT4");
isEquipment.put(new Long(0x98), "ISSRT6");
isEquipment.put(new Long(0x99), "ISLRM5 (I-OS)");
isEquipment.put(new Long(0x9A), "ISLRM10 (I-OS)");
isEquipment.put(new Long(0x9B), "ISLRM15 (I-OS)");
isEquipment.put(new Long(0x9C), "ISLRM20 (I-OS)");
isEquipment.put(new Long(0x9D), "ISSRM2 (I-OS)");
isEquipment.put(new Long(0x9E), "ISSRM4 (I-OS)");
isEquipment.put(new Long(0x9f), "ISSRM6 (I-OS)");
isEquipment.put(new Long(0xA0), "ISStreakSRM2 (I-OS)");
isEquipment.put(new Long(0xA1), "ISStreakSRM4 (I-OS)");
isEquipment.put(new Long(0xA2), "ISStreakSRM6 (I-OS)");
isEquipment.put(new Long(0xA3), "ISMRM10 (I-OS)");
isEquipment.put(new Long(0xA4), "ISMRM20 (I-OS)");
isEquipment.put(new Long(0xA5), "ISMRM30 (I-OS)");
isEquipment.put(new Long(0xA6), "ISMRM40 (I-OS)");
isEquipment.put(new Long(0x108), "ISTHBLBXAC2");
isEquipment.put(new Long(0x109), "ISTHBLBXAC5");
isEquipment.put(new Long(0x10A), "ISTHBLBXAC20");
isEquipment.put(new Long(0x10B), "ISUltraAC2 (THB)");
isEquipment.put(new Long(0x10C), "ISUltraAC10 (THB)");
isEquipment.put(new Long(0x10D), "ISUltraAC20 (THB)");
isEquipment.put(new Long(0x11D), "ISTHBAngelECMSuite");
isEquipment.put(new Long(0x11e), "ISTHBBloodhoundActiveProbe");
isEquipment.put(new Long(0x121), "ISRotaryAC2");
isEquipment.put(new Long(0x122), "ISRotaryAC5");
isEquipment.put(new Long(0x123), "ISHeavyGaussRifle");
isEquipment.put(new Long(0x12B), "ISRocketLauncher10");
isEquipment.put(new Long(0x12C), "ISRocketLauncher15");
isEquipment.put(new Long(0x12D), "ISRocketLauncher20");
Hashtable<Long, String> isAmmo = new Hashtable<Long, String>();
AMMO.put(HMVTechType.INNER_SPHERE, isAmmo);
isAmmo.put(new Long(0x3E), "ISAC2 Ammo");
isAmmo.put(new Long(0x3F), "ISAC5 Ammo");
isAmmo.put(new Long(0x40), "ISAC10 Ammo");
isAmmo.put(new Long(0x41), "ISAC20 Ammo");
isAmmo.put(new Long(0x42), "ISAMS Ammo");
isAmmo.put(new Long(0x43), "Long Tom Cannon Ammo");
isAmmo.put(new Long(0x44), "Sniper Cannon Ammo");
isAmmo.put(new Long(0x45), "Thumper Cannon Ammo");
isAmmo.put(new Long(0x46), "ISLightGauss Ammo");
isAmmo.put(new Long(0x47), "ISGauss Ammo");
isAmmo.put(new Long(0x4B), "ISLBXAC2 Ammo");
isAmmo.put(new Long(0x4C), "ISLBXAC5 Ammo");
isAmmo.put(new Long(0x4D), "ISLBXAC10 Ammo");
isAmmo.put(new Long(0x4E), "ISLBXAC20 Ammo");
isAmmo.put(new Long(0x4F), "ISMG Ammo (200)");
isAmmo.put(new Long(0x50), "ISLAC2 Ammo");
isAmmo.put(new Long(0x51), "ISLAC5 Ammo");
isAmmo.put(new Long(0x52), "ISHeavyFlamer Ammo");
isAmmo.put(new Long(0x54), "ISUltraAC2 Ammo");
isAmmo.put(new Long(0x55), "ISUltraAC5 Ammo");
isAmmo.put(new Long(0x56), "ISUltraAC10 Ammo");
isAmmo.put(new Long(0x57), "ISUltraAC20 Ammo");
isAmmo.put(new Long(0x60), "ISLRM5 Ammo");
isAmmo.put(new Long(0x61), "ISLRM10 Ammo");
isAmmo.put(new Long(0x62), "ISLRM15 Ammo");
isAmmo.put(new Long(0x63), "ISLRM20 Ammo");
isAmmo.put(new Long(0x66), "ISiNarc Pods");
isAmmo.put(new Long(0x67), "ISSRM2 Ammo");
isAmmo.put(new Long(0x68), "ISSRM4 Ammo");
isAmmo.put(new Long(0x69), "ISSRM6 Ammo");
isAmmo.put(new Long(0x6A), "ISStreakSRM2 Ammo");
isAmmo.put(new Long(0x6B), "ISStreakSRM4 Ammo");
isAmmo.put(new Long(0x6C), "ISStreakSRM6 Ammo");
isAmmo.put(new Long(0x6D), "ISThunderbolt5 Ammo");
isAmmo.put(new Long(0x6E), "ISThunderbolt10 Ammo");
isAmmo.put(new Long(0x6F), "ISThunderbolt15 Ammo");
isAmmo.put(new Long(0x70), "ISThunderbolt20 Ammo");
isAmmo.put(new Long(0x71), "ISArrowIV Ammo");
isAmmo.put(new Long(0x79), "ISNarc Pods");
isAmmo.put(new Long(0x85), "ISVehicleFlamer Ammo");
isAmmo.put(new Long(0x86), "ISLongTom Ammo");
isAmmo.put(new Long(0x87), "ISSniper Ammo");
isAmmo.put(new Long(0x88), "ISThumper Ammo");
isAmmo.put(new Long(0x89), "ISMRM10 Ammo");
isAmmo.put(new Long(0x8A), "ISMRM20 Ammo");
isAmmo.put(new Long(0x8B), "ISMRM30 Ammo");
isAmmo.put(new Long(0x8C), "ISMRM40 Ammo");
isAmmo.put(new Long(0x92), "ISLRTorpedo5 Ammo");
isAmmo.put(new Long(0x93), "ISLRTorpedo10 Ammo");
isAmmo.put(new Long(0x94), "ISLRTorpedo15 Ammo");
isAmmo.put(new Long(0x95), "ISLRTorpedo20 Ammo");
isAmmo.put(new Long(0x96), "ISSRT2 Ammo");
isAmmo.put(new Long(0x97), "ISSRT4 Ammo");
isAmmo.put(new Long(0x98), "ISSRT6 Ammo");
isAmmo.put(new Long(0x108), "ISTHBLBXAC2 Ammo");
isAmmo.put(new Long(0x109), "ISTHBLBXAC5 Ammo");
isAmmo.put(new Long(0x10A), "ISTHBLBXAC20 Ammo");
isAmmo.put(new Long(0x10B), "ISUltraAC2 (THB) Ammo");
isAmmo.put(new Long(0x10C), "ISUltraAC10 (THB) Ammo");
isAmmo.put(new Long(0x10D), "ISUltraAC20 (THB) Ammo");
isAmmo.put(new Long(0x121), "ISRotaryAC2 Ammo");
isAmmo.put(new Long(0x122), "ISRotaryAC5 Ammo");
isAmmo.put(new Long(0x123), "ISHeavyGauss Ammo");
// clan criticals
//
Hashtable<Long, String> clanEquipment = new Hashtable<Long, String>();
EQUIPMENT.put(HMVTechType.CLAN, clanEquipment);
clanEquipment.put(new Long(0x0A), "CLDouble Heat Sink");
clanEquipment.put(new Long(0x0B), "Jump Jet");
clanEquipment.put(new Long(0x12), "CLTargeting Computer");
clanEquipment.put(new Long(0x14), "Endo Steel");
clanEquipment.put(new Long(0x15), "Ferro-Fibrous");
clanEquipment.put(new Long(0x17), "CLMASC");
clanEquipment.put(new Long(0x18), "CLArtemisIV");
clanEquipment.put(new Long(0x33), "CLERLargeLaser");
clanEquipment.put(new Long(0x34), "CLERMediumLaser");
clanEquipment.put(new Long(0x35), "CLERSmallLaser");
clanEquipment.put(new Long(0x36), "CLERPPC");
clanEquipment.put(new Long(0x39), "CLSmallLaser");
clanEquipment.put(new Long(0x37), "CLFlamer");
clanEquipment.put(new Long(0x38), "CLMediumLaser");
clanEquipment.put(new Long(0x3A), "CLPPC");
clanEquipment.put(new Long(0x3C), "CLLargePulseLaser");
clanEquipment.put(new Long(0x3D), "CLMediumPulseLaser");
clanEquipment.put(new Long(0x3E), "CLSmallPulseLaser");
clanEquipment.put(new Long(0x3F), "CLAngelECMSuite");
clanEquipment.put(new Long(0x40), "CLAntiMissileSystem");
clanEquipment.put(new Long(0x41), "CLGaussRifle");
clanEquipment.put(new Long(0x42), "CLLBXAC2");
clanEquipment.put(new Long(0x43), "CLLBXAC5");
clanEquipment.put(new Long(0x44), "CLLBXAC10");
clanEquipment.put(new Long(0x45), "CLLBXAC20");
clanEquipment.put(new Long(0x46), "CLMG");
clanEquipment.put(new Long(0x47), "CLUltraAC2");
clanEquipment.put(new Long(0x48), "CLUltraAC5");
clanEquipment.put(new Long(0x49), "CLUltraAC10");
clanEquipment.put(new Long(0x4A), "CLUltraAC20");
clanEquipment.put(new Long(0x4B), "CLLRM5");
clanEquipment.put(new Long(0x4C), "CLLRM10");
clanEquipment.put(new Long(0x4D), "CLLRM15");
clanEquipment.put(new Long(0x4E), "CLLRM20");
clanEquipment.put(new Long(0x4F), "CLSRM2");
clanEquipment.put(new Long(0x50), "CLSRM4");
clanEquipment.put(new Long(0x51), "CLSRM6");
clanEquipment.put(new Long(0x52), "CLStreakSRM2");
clanEquipment.put(new Long(0x53), "CLStreakSRM4");
clanEquipment.put(new Long(0x54), "CLStreakSRM6");
clanEquipment.put(new Long(0x55), "CLArrowIVSystem");
clanEquipment.put(new Long(0x56), "CLAntiPersonnelPod");
clanEquipment.put(new Long(0x57), "CLActiveProbe");
clanEquipment.put(new Long(0x58), "CLECMSuite");
clanEquipment.put(new Long(0x59), "CLNarcBeacon");
clanEquipment.put(new Long(0x5A), "CLTAG");
clanEquipment.put(new Long(0x5B), "CLERMicroLaser");
clanEquipment.put(new Long(0x5C), "CLLRM5 (OS)");
clanEquipment.put(new Long(0x5D), "CLLRM10 (OS)");
clanEquipment.put(new Long(0x5E), "CLLRM15 (OS)");
clanEquipment.put(new Long(0x5F), "CLLRM20 (OS)");
clanEquipment.put(new Long(0x60), "CLSRM2 (OS)");
clanEquipment.put(new Long(0x61), "CLSRM4 (OS)");
clanEquipment.put(new Long(0x62), "CLSRM6 (OS)");
clanEquipment.put(new Long(0x63), "CLStreakSRM2 (OS)");
clanEquipment.put(new Long(0x64), "CLStreakSRM4 (OS)");
clanEquipment.put(new Long(0x65), "CLStreakSRM6 (OS)");
clanEquipment.put(new Long(0x66), "CLVehicleFlamer");
clanEquipment.put(new Long(0x67), "CLLongTomArtillery");
clanEquipment.put(new Long(0x68), "CLSniperArtillery");
clanEquipment.put(new Long(0x69), "CLThumperArtillery");
clanEquipment.put(new Long(0x6A), "CLLRTorpedo5");
clanEquipment.put(new Long(0x6B), "CLLRTorpedo10");
clanEquipment.put(new Long(0x6C), "CLLRTorpedo15");
clanEquipment.put(new Long(0x6D), "CLLRTorpedo20");
clanEquipment.put(new Long(0x6E), "CLSRT2");
clanEquipment.put(new Long(0x6F), "CLSRT4");
clanEquipment.put(new Long(0x70), "CLSRT6");
clanEquipment.put(new Long(0x7B), "CLLRM5 (OS)");
clanEquipment.put(new Long(0x7C), "CLLRM10 (OS)");
clanEquipment.put(new Long(0x7D), "CLLRM15 (OS)");
clanEquipment.put(new Long(0x7E), "CLLRM20 (OS)");
clanEquipment.put(new Long(0x7F), "CLSRM2 (OS)");
clanEquipment.put(new Long(0x80), "CLHeavyLargeLaser");
clanEquipment.put(new Long(0x81), "CLHeavyMediumLaser");
clanEquipment.put(new Long(0x82), "CLHeavySmallLaser");
clanEquipment.put(new Long(0x85), "CLVehicleFlamer"); // ?
clanEquipment.put(new Long(0x92), "CLLRTorpedo5");
clanEquipment.put(new Long(0x93), "CLLRTorpedo10");
clanEquipment.put(new Long(0x94), "CLLRTorpedo15");
clanEquipment.put(new Long(0x95), "CLLRTorpedo20");
clanEquipment.put(new Long(0x96), "CLSRT2");
clanEquipment.put(new Long(0x97), "CLSRT4");
clanEquipment.put(new Long(0x98), "CLSRT6");
clanEquipment.put(new Long(0xA8), "CLMicroPulseLaser");
clanEquipment.put(new Long(0xAD), "CLLightMG");
clanEquipment.put(new Long(0xAE), "CLHeavyMG");
clanEquipment.put(new Long(0xAF), "CLLightActiveProbe");
clanEquipment.put(new Long(0xB4), "CLLightTAG");
clanEquipment.put(new Long(0xFC), "CLATM3");
clanEquipment.put(new Long(0xFD), "CLATM6");
clanEquipment.put(new Long(0xFE), "CLATM9");
clanEquipment.put(new Long(0xFF), "CLATM12");
Hashtable<Long, String> clAmmo = new Hashtable<Long, String>();
AMMO.put(HMVTechType.CLAN, clAmmo);
clAmmo.put(new Long(0x40), "CLAMS Ammo");
clAmmo.put(new Long(0x41), "CLGauss Ammo");
clAmmo.put(new Long(0x42), "CLLBXAC2 Ammo");
clAmmo.put(new Long(0x43), "CLLBXAC5 Ammo");
clAmmo.put(new Long(0x44), "CLLBXAC10 Ammo");
clAmmo.put(new Long(0x45), "CLLBXAC20 Ammo");
clAmmo.put(new Long(0x46), "CLMG Ammo (200)");
clAmmo.put(new Long(0x47), "CLUltraAC2 Ammo");
clAmmo.put(new Long(0x48), "CLUltraAC5 Ammo");
clAmmo.put(new Long(0x49), "CLUltraAC10 Ammo");
clAmmo.put(new Long(0x4A), "CLUltraAC20 Ammo");
clAmmo.put(new Long(0x4B), "CLLRM5 Ammo");
clAmmo.put(new Long(0x4C), "CLLRM10 Ammo");
clAmmo.put(new Long(0x4D), "CLLRM15 Ammo");
clAmmo.put(new Long(0x4E), "CLLRM20 Ammo");
clAmmo.put(new Long(0x4F), "CLSRM2 Ammo");
clAmmo.put(new Long(0x50), "CLSRM4 Ammo");
clAmmo.put(new Long(0x51), "CLSRM6 Ammo");
clAmmo.put(new Long(0x52), "CLStreakSRM2 Ammo");
clAmmo.put(new Long(0x53), "CLStreakSRM4 Ammo");
clAmmo.put(new Long(0x54), "CLStreakSRM6 Ammo");
clAmmo.put(new Long(0x55), "CLArrowIV Ammo");
clAmmo.put(new Long(0x66), "CLVehicleFlamer Ammo");
clAmmo.put(new Long(0x67), "CLLongTomArtillery Ammo");
clAmmo.put(new Long(0x68), "CLSniperArtillery Ammo");
clAmmo.put(new Long(0x69), "CLThumperArtillery Ammo");
clAmmo.put(new Long(0x6A), "CLTorpedoLRM5 Ammo");
clAmmo.put(new Long(0x6B), "CLTorpedoLRM10 Ammo");
clAmmo.put(new Long(0x6C), "CLTorpedoLRM15 Ammo");
clAmmo.put(new Long(0x6D), "CLTorpedoLRM20 Ammo");
clAmmo.put(new Long(0x6E), "CLTorpedoSRM2 Ammo");
clAmmo.put(new Long(0x6F), "CLTorpedoSRM4 Ammo");
clAmmo.put(new Long(0x70), "CLTorpedoSRM6 Ammo");
clAmmo.put(new Long(0x85), "CLVehicleFlamer Ammo"); // ?
clAmmo.put(new Long(0x92), "CLTorpedoLRM5 Ammo");
clAmmo.put(new Long(0x93), "CLTorpedoLRM10 Ammo");
clAmmo.put(new Long(0x94), "CLTorpedoLRM15 Ammo");
clAmmo.put(new Long(0x95), "CLTorpedoLRM20 Ammo");
clAmmo.put(new Long(0x96), "CLTorpedoSRM2 Ammo");
clAmmo.put(new Long(0x97), "CLTorpedoSRM4 Ammo");
clAmmo.put(new Long(0x98), "CLTorpedoSRM6 Ammo");
clAmmo.put(new Long(0xAD), "CLLightMG Ammo (200)");
clAmmo.put(new Long(0xAE), "CLHeavyMG Ammo (100)");
clAmmo.put(new Long(0xFC), "CLATM3 Ammo");
clAmmo.put(new Long(0xFD), "CLATM6 Ammo");
clAmmo.put(new Long(0xFE), "CLATM9 Ammo");
clAmmo.put(new Long(0xFF), "CLATM12 Ammo");
// mixed *seems* to be the same as IS-base for HMP files
Hashtable<Long, String> mixedEquipment = new Hashtable<Long, String>(
isEquipment);
EQUIPMENT.put(HMVTechType.MIXED, mixedEquipment);
mixedEquipment.put(new Long(0x58), "CLERMicroLaser");
mixedEquipment.put(new Long(0x5E), "CLLightMG");
mixedEquipment.put(new Long(0x5F), "CLHeavyMG");
mixedEquipment.put(new Long(0x64), "CLLightActiveProbe");
mixedEquipment.put(new Long(0x65), "CLLightTAG");
mixedEquipment.put(new Long(0xA7), "CLERLargeLaser");
mixedEquipment.put(new Long(0xA8), "CLERMediumLaser");
mixedEquipment.put(new Long(0xA9), "CLERSmallLaser");
mixedEquipment.put(new Long(0xAA), "CLERPPC");
mixedEquipment.put(new Long(0xAB), "CLFlamer");
mixedEquipment.put(new Long(0xB0), "CLLargePulseLaser");
mixedEquipment.put(new Long(0xB1), "CLMediumPulseLaser");
mixedEquipment.put(new Long(0xB2), "CLSmallPulseLaser");
mixedEquipment.put(new Long(0xB4), "CLAntiMissileSystem");
mixedEquipment.put(new Long(0xB5), "CLGaussRifle");
mixedEquipment.put(new Long(0xB6), "CLLBXAC2");
mixedEquipment.put(new Long(0xB7), "CLLBXAC5");
mixedEquipment.put(new Long(0xB8), "CLLBXAC10");
mixedEquipment.put(new Long(0xB9), "CLLBXAC20");
mixedEquipment.put(new Long(0xBA), "CLMG");
mixedEquipment.put(new Long(0xBB), "CLUltraAC2");
mixedEquipment.put(new Long(0xBC), "CLUltraAC5");
mixedEquipment.put(new Long(0xBD), "CLUltraAC10");
mixedEquipment.put(new Long(0xBE), "CLUltraAC20");
mixedEquipment.put(new Long(0xBF), "CLLRM5");
mixedEquipment.put(new Long(0xC0), "CLLRM10");
mixedEquipment.put(new Long(0xC1), "CLLRM15");
mixedEquipment.put(new Long(0xC2), "CLLRM20");
mixedEquipment.put(new Long(0xC3), "CLSRM2");
mixedEquipment.put(new Long(0xC4), "CLSRM4");
mixedEquipment.put(new Long(0xC5), "CLSRM6");
mixedEquipment.put(new Long(0xC6), "CLStreakSRM2");
mixedEquipment.put(new Long(0xC7), "CLStreakSRM4");
mixedEquipment.put(new Long(0xC8), "CLStreakSRM6");
mixedEquipment.put(new Long(0xC9), "CLArrowIVSystem");
mixedEquipment.put(new Long(0xCA), "CLAntiPersonnelPod");
mixedEquipment.put(new Long(0xCB), "CLActiveProbe");
mixedEquipment.put(new Long(0xCC), "CLECMSuite");
mixedEquipment.put(new Long(0xCD), "CLNarcBeacon");
mixedEquipment.put(new Long(0xCE), "CLTAG");
mixedEquipment.put(new Long(0xD0), "CLLRM5 (OS)");
mixedEquipment.put(new Long(0xD1), "CLLRM10 (OS)");
mixedEquipment.put(new Long(0xD2), "CLLRM15 (OS)");
mixedEquipment.put(new Long(0xD3), "CLLRM20 (OS)");
mixedEquipment.put(new Long(0xD4), "CLSRM2 (OS)");
mixedEquipment.put(new Long(0xD5), "CLSRM2 (OS)");
mixedEquipment.put(new Long(0xD6), "CLSRM2 (OS)");
mixedEquipment.put(new Long(0xD7), "CLStreakSRM2 (OS)");
mixedEquipment.put(new Long(0xD8), "CLStreakSRM4 (OS)");
mixedEquipment.put(new Long(0xD9), "CLStreakSRM6 (OS)");
mixedEquipment.put(new Long(0xDA), "CLVehicleFlamer");
mixedEquipment.put(new Long(0xDB), "CLLongTomArtillery");
mixedEquipment.put(new Long(0xDC), "CLSniperArtillery");
mixedEquipment.put(new Long(0xDD), "CLThumperArtillery");
mixedEquipment.put(new Long(0xDE), "CLLRTorpedo5");
mixedEquipment.put(new Long(0xDF), "CLLRTorpedo10");
mixedEquipment.put(new Long(0xE0), "CLLRTorpedo15");
mixedEquipment.put(new Long(0xE1), "CLLRTorpedo20");
mixedEquipment.put(new Long(0xE2), "CLSRT2");
mixedEquipment.put(new Long(0xE3), "CLSRT4");
mixedEquipment.put(new Long(0xE4), "CLSRT6");
mixedEquipment.put(new Long(0xF4), "CLHeavyLargeLaser");
mixedEquipment.put(new Long(0xF5), "CLHeavyMediumLaser");
mixedEquipment.put(new Long(0xF6), "CLHeavySmallLaser");
mixedEquipment.put(new Long(0xFC), "CLATM3");
mixedEquipment.put(new Long(0xFD), "CLATM6");
mixedEquipment.put(new Long(0xFE), "CLATM9");
mixedEquipment.put(new Long(0xFF), "CLATM12");
// but ammo *seems* to use the same numbers as the weapon it goes with
Hashtable<Long, String> mixedAmmo = new Hashtable<Long, String>(isAmmo);
AMMO.put(HMVTechType.MIXED, mixedAmmo);
mixedAmmo.put(new Long(0x5E), "CLLightMG Ammo");
mixedAmmo.put(new Long(0x5F), "CLHeavyMG Ammo");
mixedAmmo.put(new Long(0xB4), "CLAntiMissileSystem Ammo");
mixedAmmo.put(new Long(0xB5), "CLGaussRifle Ammo");
mixedAmmo.put(new Long(0xB6), "CLLBXAC2 Ammo");
mixedAmmo.put(new Long(0xB7), "CLLBXAC5 Ammo");
mixedAmmo.put(new Long(0xB8), "CLLBXAC10 Ammo");
mixedAmmo.put(new Long(0xB9), "CLLBXAC20 Ammo");
mixedAmmo.put(new Long(0xBA), "CLMG Ammo");
mixedAmmo.put(new Long(0xBB), "CLUltraAC2 Ammo");
mixedAmmo.put(new Long(0xBC), "CLUltraAC5 Ammo");
mixedAmmo.put(new Long(0xBD), "CLUltraAC10 Ammo");
mixedAmmo.put(new Long(0xBE), "CLUltraAC20 Ammo");
mixedAmmo.put(new Long(0xBF), "CLLRM5 Ammo");
mixedAmmo.put(new Long(0xC0), "CLLRM10 Ammo");
mixedAmmo.put(new Long(0xC1), "CLLRM15 Ammo");
mixedAmmo.put(new Long(0xC2), "CLLRM20 Ammo");
mixedAmmo.put(new Long(0xC3), "CLSRM2 Ammo");
mixedAmmo.put(new Long(0xC4), "CLSRM4 Ammo");
mixedAmmo.put(new Long(0xC5), "CLSRM6 Ammo");
mixedAmmo.put(new Long(0xC6), "CLStreakSRM2 Ammo");
mixedAmmo.put(new Long(0xC7), "CLStreakSRM4 Ammo");
mixedAmmo.put(new Long(0xC8), "CLStreakSRM6 Ammo");
mixedAmmo.put(new Long(0xC9), "CLArrowIVSystem Ammo");
mixedAmmo.put(new Long(0xCD), "CLNarcBeacon Ammo");
mixedAmmo.put(new Long(0xDA), "CLVehicleFlamer Ammo");
mixedAmmo.put(new Long(0xDB), "CLLongTomArtillery Ammo");
mixedAmmo.put(new Long(0xDC), "CLSniperArtillery Ammo");
mixedAmmo.put(new Long(0xDD), "CLThumperArtillery Ammo");
mixedAmmo.put(new Long(0xDE), "CLLRTorpedo5 Ammo");
mixedAmmo.put(new Long(0xDF), "CLLRTorpedo10 Ammo");
mixedAmmo.put(new Long(0xE0), "CLLRTorpedo15 Ammo");
mixedAmmo.put(new Long(0xE1), "CLLRTorpedo20 Ammo");
mixedAmmo.put(new Long(0xE2), "CLSRT2 Ammo");
mixedAmmo.put(new Long(0xE3), "CLSRT4 Ammo");
mixedAmmo.put(new Long(0xE4), "CLSRT6 Ammo");
}
private String getEquipmentName(long equipment, HMVTechType techType) {
return getEquipmentName(new Long(equipment), techType);
}
private String getEquipmentName(Long equipment, HMVTechType techType) {
if (equipment.longValue() > Short.MAX_VALUE) {
equipment = new Long(equipment.longValue() & 0xFFFF);
}
final long value = equipment.longValue();
String equipName = null;
try {
equipName = EQUIPMENT.get(techType).get(equipment);
} catch (NullPointerException e) {
// is handeled by the if below.
}
if (equipName == null) {
Hashtable<Long, String> techEquipment = EQUIPMENT.get(techType);
if (techEquipment != null) {
equipName = techEquipment.get(equipment);
}
}
// Report unexpected parsing failures.
if ((equipName == null) && (value != 0) && // 0x00 Empty
(value != 7) && // 0x07 Lower Leg Actuator (on a quad)
(value != 8) && // 0x08 Foot Actuator (on a quad)
(value != 15)) { // 0x0F Fusion Engine
System.out.print("unknown critical: 0x");
System.out.print(Integer.toHexString(equipment.intValue())
.toUpperCase());
System.out.print(" (");
System.out.print(techType);
System.out.println(")");
}
return equipName;
}
private EquipmentType getEquipmentType(long equipment, HMVTechType techType) {
EquipmentType equipmentType = null;
String equipmentName = getEquipmentName(equipment, techType);
if (equipmentName != null) {
equipmentType = EquipmentType.get(equipmentName);
if (equipmentType == null) {
failedEquipment.add(equipmentName);
}
} else {
failedEquipment.add("Unknown Equipment ("
+ Long.toHexString(equipment) + ")");
}
return equipmentType;
}
private String getAmmoName(long ammo, HMVTechType techType) {
return getAmmoName(new Long(ammo), techType);
}
private String getAmmoName(Long ammo, HMVTechType techType) {
if (ammo.longValue() > Short.MAX_VALUE) {
ammo = new Long(ammo.longValue() & 0xFFFF);
}
final long value = ammo.longValue();
String ammoName = null;
try {
ammoName = AMMO.get(techType).get(equipment);
} catch (NullPointerException e) {
// is handeled by the if below.
}
if (ammoName == null) {
Hashtable<Long, String> techAmmo = AMMO.get(techType);
if (techAmmo != null) {
ammoName = techAmmo.get(ammo);
}
}
// Report unexpected parsing failures.
if ((ammoName == null) && (value != 0)) {
System.out.print("unknown critical: 0x");
System.out
.print(Integer.toHexString(ammo.intValue()).toUpperCase());
System.out.print(" (");
System.out.print(techType);
System.out.println(")");
}
return ammoName;
}
private AmmoType getAmmoType(long ammo, HMVTechType techType) {
AmmoType ammoType = null;
String ammoName = getAmmoName(ammo, techType);
if (ammoName != null) {
ammoType = (AmmoType) EquipmentType.get(ammoName);
}
return ammoType;
}
/*
* public static void main(String[] args) throws Exception { for (int i = 0;
* i < args.length; i++) { HmvFile hmvFile = new HmvFile(new
* FileInputStream(args[i])); System.out.println(new
* megamek.client.ui.AWT.MechView(hmvFile.getEntity()).getMechReadout()); } }
*/
}
abstract class HMVType {
private String name;
private int id;
protected HMVType(String name, int id) {
this.name = name;
this.id = id;
}
@Override
public String toString() {
return name;
}
@Override
public boolean equals(Object other) {
// Assume the other object doesn't equal this one.
boolean result = false;
// References to the same object are equal.
if (this == other) {
result = true;
}
// If the other object is an instance of
// this object's class, then recast it.
else if (this.getClass().isInstance(other)) {
HMVType cast = (HMVType) other;
// The two objects match if their names and IDs match.
if (name.equals(cast.name) && (id == cast.id)) {
result = true;
}
}
// Return the result
return result;
}
public int getId() {
return id;
}
}
class HMVEngineType extends HMVType {
public static final Hashtable<Integer, HMVEngineType> types = new Hashtable<Integer, HMVEngineType>();
public static final HMVEngineType ICE = new HMVEngineType("I.C.E.", 0);
public static final HMVEngineType FUSION = new HMVEngineType("Fusion", 1);
public static final HMVEngineType XLFUSION = new HMVEngineType("XL Fusion",
2);
public static final HMVEngineType XXLFUSION = new HMVEngineType(
"XXL Fusion", 3);
public static final HMVEngineType LIGHTFUSION = new HMVEngineType(
"Light Fusion", 4);
private HMVEngineType(String name, int id) {
super(name, id);
types.put(new Integer(id), this);
}
public static HMVEngineType getType(int i) {
return types.get(new Integer(i));
}
}
class HMVArmorType extends HMVType {
public static final Hashtable<Integer, HMVArmorType> types = new Hashtable<Integer, HMVArmorType>();
public static final HMVArmorType STANDARD = new HMVArmorType(EquipmentType
.getArmorTypeName(EquipmentType.T_ARMOR_STANDARD), 0);
public static final HMVArmorType FERRO = new HMVArmorType(EquipmentType
.getArmorTypeName(EquipmentType.T_ARMOR_FERRO_FIBROUS), 1);
// public static final HMVArmorType COMPACT = new HMVArmorType("Compact",
// 2);
// public static final HMVArmorType LASER = new HMVArmorType("Laser", 3);
private HMVArmorType(String name, int id) {
super(name, id);
types.put(new Integer(id), this);
}
public static HMVArmorType getType(int i) {
return types.get(new Integer(i));
}
}
class HMVTechType extends HMVType {
public static final Hashtable<Integer, HMVTechType> types = new Hashtable<Integer, HMVTechType>();
public static final HMVTechType INNER_SPHERE = new HMVTechType(
"Inner Sphere", 0);
public static final HMVTechType CLAN = new HMVTechType("Clan", 1);
public static final HMVTechType MIXED = new HMVTechType("Mixed", 2);
private HMVTechType(String name, int id) {
super(name, id);
types.put(new Integer(id), this);
}
public static HMVTechType getType(int i) {
return types.get(new Integer(i));
}
}
class HMVMovementType extends HMVType {
public static final Hashtable<Integer, HMVMovementType> types = new Hashtable<Integer, HMVMovementType>();
public static final HMVMovementType TRACKED = new HMVMovementType(
"Tracked", 8);
public static final HMVMovementType WHEELED = new HMVMovementType(
"Wheeled", 16);
public static final HMVMovementType HOVER = new HMVMovementType("Hover", 32);
public static final HMVMovementType VTOL = new HMVMovementType("V.T.O.L",
64);
public static final HMVMovementType HYDROFOIL = new HMVMovementType(
"Hydrofoil", 128);
public static final HMVMovementType SUBMARINE = new HMVMovementType(
"Submarine", 256);
public static final HMVMovementType DISPLACEMENT_HULL = new HMVMovementType(
"Displacement Hull", 512);
private HMVMovementType(String name, int id) {
super(name, id);
types.put(new Integer(id), this);
}
public static HMVMovementType getType(int i) {
// Only pay attention to the movement type bits.
i &= 1016;
return types.get(new Integer(i));
}
}
class HMVWeaponLocation extends HMVType {
public static final Hashtable<Integer, HMVWeaponLocation> types = new Hashtable<Integer, HMVWeaponLocation>();
public static final HMVWeaponLocation TURRET = new HMVWeaponLocation(
"Turret", 0);
public static final HMVWeaponLocation FRONT = new HMVWeaponLocation(
"Front", 1);
public static final HMVWeaponLocation LEFT = new HMVWeaponLocation("Left",
2);
public static final HMVWeaponLocation RIGHT = new HMVWeaponLocation(
"Right", 3);
public static final HMVWeaponLocation REAR = new HMVWeaponLocation("Rear",
4);
public static final HMVWeaponLocation BODY = new HMVWeaponLocation("Body",
5);
private HMVWeaponLocation(String name, int id) {
super(name, id);
types.put(new Integer(id), this);
}
public static HMVWeaponLocation getType(int i) {
return types.get(new Integer(i));
}
}