📄 hmvfile.java
字号:
/* * 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.InputStream;import java.io.IOException;import java.util.Enumeration;import java.util.Hashtable;import java.util.List;import java.util.ArrayList;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 HMVTechType armorTechType; private int engineRating; private HMVEngineType engineType; private int cruiseMP; private int jumpMP; private int heatSinks; private HMVArmorType armorType; private int roundedInternalStructure; private int turretArmor; private int frontArmor; private int leftArmor; private int rightArmor; private int rearArmor; private int artemisType; private Hashtable equipment = new Hashtable(); private float troopSpace = 0; private String fluff; private List<String> failedEquipment = new ArrayList(); private boolean hasTurret = false; public HmvFile(InputStream is) throws EntityLoadingException { try { DataInputStream dis = new DataInputStream(is); byte[] buffer = new byte[5]; dis.read(buffer); 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); 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_IS_LEVEL_1 ) { 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; //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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -