/* * BattleArmorAmmoBin.java * * Copyright (c) 2009 Jay Lawson <jaylawson39 at yahoo.com>. All rights reserved. * * This file is part of MekHQ. * * MekHQ 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. * * MekHQ 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 MekHQ. If not, see <http://www.gnu.org/licenses/>. */ package mekhq.campaign.parts.equipment; import megamek.common.AmmoType; import megamek.common.BattleArmor; import megamek.common.CriticalSlot; import megamek.common.EquipmentType; import megamek.common.Mounted; import mekhq.Utilities; import mekhq.campaign.Campaign; import mekhq.campaign.parts.AmmoStorage; import mekhq.campaign.parts.Part; import mekhq.campaign.work.IAcquisitionWork; /** * * @author Jay Lawson <jaylawson39 at yahoo.com> */ public class BattleArmorAmmoBin extends AmmoBin implements IAcquisitionWork { /** * Battle Armor ammo bins need to look for shots for all the remaining troopers in the * squad. * TODO: Think about how to handle the case of understrength squads. Right now they * pay for more ammo than they need, but this is easier than trying to track ammo per suit * and adjust for different ammo types when suits are added and removed from squads. */ private static final long serialVersionUID = 2421186617583650648L; public BattleArmorAmmoBin() { this(0, null, -1, 0, false, null); } public BattleArmorAmmoBin(int tonnage, EquipmentType et, int equipNum, int shots, boolean singleShot, Campaign c) { super(tonnage, et, equipNum, shots, singleShot, false, c); } public int getNumTroopers() { if(null != unit && unit.getEntity() instanceof BattleArmor) { //we are going to base this on the full squad size, even though this makes understrength //squads overpay for their ammo - that way suits can be moved around without having to adjust //ammo - Tech: "oh you finally got here. Check in the back corner, we stockpiled some ammo for //you." return ((BattleArmor)unit.getEntity()).getSquadSize(); } return 0; } //no salvaging of BA parts @Override public boolean isSalvaging() { return false; } /*@Override public int getFullShots() { return super.getFullShots() * getNumTroopers(); }*/ @Override protected int getCurrentShots() { int shots = getFullShots() * getNumTroopers() - shotsNeeded; //replace with actual entity values if entity not null because the previous number will not //be correct for ammo swaps if(null != unit && null != unit.getEntity()) { Mounted m = unit.getEntity().getEquipment(equipmentNum); if(null != m) { shots = m.getBaseShotsLeft() * getNumTroopers(); } } return shots; } @Override public void updateConditionFromEntity(boolean checkForDestruction) { if(null != unit) { Mounted mounted = unit.getEntity().getEquipment(equipmentNum); if(null != mounted) { long currentMuniType = 0; if(mounted.getType() instanceof AmmoType) { currentMuniType = ((AmmoType)mounted.getType()).getMunitionType(); } if(currentMuniType == getMunitionType()) { shotsNeeded = (getFullShots() - mounted.getBaseShotsLeft()) * getNumTroopers(); } else { //we have a change of munitions shotsNeeded = getFullShots() * getNumTroopers(); } } } } @Override public int getBaseTime() { if(null != unit) { Mounted mounted = unit.getEntity().getEquipment(equipmentNum); if(null != mounted) { if(!type.equals(mounted.getType())) { return 30; } } } return 15; } @Override public int getDifficulty() { return 0; } @Override public void updateConditionFromPart() { if(null != unit) { Mounted mounted = unit.getEntity().getEquipment(equipmentNum); if(null != mounted) { mounted.setHit(false); mounted.setDestroyed(false); mounted.setRepairable(true); unit.repairSystem(CriticalSlot.TYPE_EQUIPMENT, equipmentNum); mounted.setShotsLeft(getFullShots() - shotsNeeded/getNumTroopers()); } } } @Override public void loadBin() { int shots = Math.min(getAmountAvailable(), shotsNeeded); int shotsPerTrooper = shots / getNumTroopers(); shots = shotsPerTrooper * getNumTroopers(); if(null != unit) { Mounted mounted = unit.getEntity().getEquipment(equipmentNum); if(null != mounted) { if(mounted.getType().equals(type) && ((AmmoType)mounted.getType()).getMunitionType() == getMunitionType()) { //just a simple reload mounted.setShotsLeft(mounted.getBaseShotsLeft() + shotsPerTrooper); } else { //loading a new type of ammo unload(); mounted.changeAmmoType((AmmoType)type); mounted.setShotsLeft(shotsPerTrooper); } } } changeAmountAvailable(-1 * shots, (AmmoType)type); shotsNeeded -= shots; } @Override public void unload() { int shots = 0; AmmoType curType = (AmmoType)type; if(null != unit) { Mounted mounted = unit.getEntity().getEquipment(equipmentNum); if(null != mounted) { shots = mounted.getBaseShotsLeft() * getNumTroopers(); mounted.setShotsLeft(0); curType = (AmmoType)mounted.getType(); } } shotsNeeded = getFullShots() * getNumTroopers(); if(shots > 0) { changeAmountAvailable(shots, curType); } } @Override public String checkFixable() { int amountAvailable = getAmountAvailable(); if(amountAvailable > 0 && amountAvailable < getNumTroopers()) { return "Cannot do a partial reload of Battle Armor ammo less than the number of troopers"; } return super.checkFixable(); } @Override public void remove(boolean salvage) { //shouldnt be here return; } @Override public Part getNewPart() { int shots = (int) Math.floor(1000/((AmmoType)type).getKgPerShot()); if(shots <= 0) { //FIXME: no idea what to do here, these really should be fixed on the MM side //because presumably this is happening because KgperShot is -1 or 0 shots = 20; } return new AmmoStorage(1,type,shots,campaign); } @Override public IAcquisitionWork getAcquisitionWork() { int shots = (int) Math.floor(1000/((AmmoType)type).getKgPerShot()); if(shots <= 0) { //FIXME: no idea what to do here, these really should be fixed on the MM side //because presumably this is happening because KgperShot is -1 or 0 shots = 20; } return new AmmoStorage(1,type,shots,campaign); } @Override public String getAcquisitionDesc() { String toReturn = "<html><font size='2'"; toReturn += ">"; toReturn += "<b>" + getAcquisitionDisplayName() + "</b> " + getAcquisitionBonus() + "<br/>"; toReturn += getAcquisitionExtraDesc() + "<br/>"; String[] inventories = campaign.getPartInventory(getAcquisitionPart()); toReturn += inventories[1] + " in transit, " + inventories[2] + " on order<br>"; toReturn += Utilities.getCurrencyString(getBuyCost()) + "<br/>"; toReturn += "</font></html>"; return toReturn; } @Override public String getAcquisitionDisplayName() { return type.getDesc(); } private int calculateShots() { int shots = (int) Math.floor(1000/((AmmoType)type).getKgPerShot()); if(shots <= 0) { //FIXME: no idea what to do here, these really should be fixed on the MM side //because presumably this is happening because KgperShot is -1 or 0 shots = 20; } return shots; } @Override public String getAcquisitionExtraDesc() { return calculateShots() + " shots"; } @Override public String getAcquisitionBonus() { String bonus = getAllAcquisitionMods().getValueAsString(); if(getAllAcquisitionMods().getValue() > -1) { bonus = "+" + bonus; } return "(" + bonus + ")"; } @Override public Part getAcquisitionPart() { return getNewPart(); } public boolean needsMaintenance() { return false; } public boolean canNeverScrap() { return true; } /** * Restores the equipment from the name */ public void restore() { if (typeName == null) { typeName = type.getName(); } else { type = EquipmentType.get(typeName); } //fIXME, this is a crappy hack, but we want something along these lines //to make sure that BA ammo gets removed from all parts - It might be better to run //a check on the XML loading after restore - we also will need to to the same for proto //ammo but we can only do this if we have all the correct ammo rack sizes for the //generics (e.g. LRM1, LRM2, LRM3, etc) /*if(typeName.contains("BA-")) { String newTypeName = "IS" + typeName.split("BA-")[1]; EquipmentType newType = EquipmentType.get(newTypeName); if(null != newType) { typeName = newTypeName; type = newType; } }*/ if (type == null) { System.err .println("Mounted.restore: could not restore equipment type \"" + typeName + "\""); return; } try { equipTonnage = type.getTonnage(null); } catch(NullPointerException ex) { //System.out.println("Found a null entity while calculating tonnage for " + name); } } @Override public int getMassRepairOptionType() { return Part.REPAIR_PART_TYPE.AMMO; } }