/*
* MissingBattleArmorSuit.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;
import java.io.PrintWriter;
import java.util.ArrayList;
import megamek.common.EntityMovementMode;
import megamek.common.EntityWeightClass;
import megamek.common.EquipmentType;
import megamek.common.IArmorState;
import megamek.common.TargetRoll;
import mekhq.MekHqXmlUtil;
import mekhq.campaign.Campaign;
import mekhq.campaign.parts.equipment.BattleArmorEquipmentPart;
import mekhq.campaign.parts.equipment.EquipmentPart;
import mekhq.campaign.parts.equipment.MissingBattleArmorEquipmentPart;
import mekhq.campaign.personnel.Person;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
*
* @author Jay Lawson <jaylawson39 at yahoo.com>
*/
public class MissingBattleArmorSuit extends MissingPart {
/**
*
*/
private static final long serialVersionUID = -3028121751208423160L;
protected String chassis;
protected String model;
protected int trooper;
protected boolean clan;
protected boolean quad;
protected int groundMP;
protected int jumpMP;
protected EntityMovementMode jumpType;
protected int weightClass;
public MissingBattleArmorSuit() {
super(0, null);
}
public MissingBattleArmorSuit(String ch, String m, int ton, int t, int w, int gmp, int jmp, boolean q, boolean clan, EntityMovementMode mode, Campaign c) {
super(ton, c);
this.chassis = ch;
this.model = m;
this.trooper = t;
this.quad = q;
this.weightClass= w;
this.groundMP = gmp;
this.jumpMP = jmp;
this.jumpType = mode;
this.clan = clan;
this.name = chassis + " " + model + " Suit";
}
@Override
public int getBaseTime() {
return 0;
}
@Override
public int getDifficulty() {
return 0;
}
@Override
public void updateConditionFromPart() {
if(null != unit) {
unit.getEntity().setInternal(IArmorState.ARMOR_DESTROYED, trooper);
}
}
@Override
public String checkFixable() {
return null;
}
public boolean isQuad() {
return quad;
}
public int getWeightClass() {
return weightClass;
}
public int getGroundMP() {
return groundMP;
}
public int getJumpMP() {
return jumpMP;
}
public String getChassis() {
return chassis;
}
public String getModel() {
return model;
}
@Override
public boolean isAcceptableReplacement(Part part, boolean refit) {
return part instanceof BattleArmorSuit
&& chassis.equals(((BattleArmorSuit)part).getChassis())
&& model.equals(((BattleArmorSuit)part).getModel());
}
@Override
public Part getNewPart() {
BattleArmorSuit suit = new BattleArmorSuit(chassis, model, getUnitTonnage(), -1, weightClass, groundMP, jumpMP, quad, clan, jumpType, campaign);
return suit;
}
@Override
public TargetRoll getAllMods(Person tech) {
return new TargetRoll(TargetRoll.AUTOMATIC_SUCCESS, "BA suit removal");
}
@Override
public double getTonnage() {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getAvailability(int era) {
int chassisAvail = EquipmentType.RATING_E;
if(weightClass > EntityWeightClass.WEIGHT_ULTRA_LIGHT) {
if(era == EquipmentType.ERA_SW) {
chassisAvail = EquipmentType.RATING_F;
}
}
else if(era < EquipmentType.ERA_CLAN) {
chassisAvail = EquipmentType.RATING_X;
}
if(jumpType == EntityMovementMode.INF_UMU || jumpType == EntityMovementMode.VTOL) {
chassisAvail = EquipmentType.RATING_F;
}
return chassisAvail;
}
@Override
public int getTechRating() {
int rating = EquipmentType.RATING_E;
if(weightClass < EntityWeightClass.WEIGHT_LIGHT) {
rating = EquipmentType.RATING_D;
}
return rating;
}
public int getTrooper() {
return trooper;
}
@Override
public void writeToXml(PrintWriter pw1, int indent) {
writeToXmlBegin(pw1, indent);
pw1.println(MekHqXmlUtil.indentStr(indent+1)
+"<chassis>"
+MekHqXmlUtil.escape(chassis)
+"</chassis>");
pw1.println(MekHqXmlUtil.indentStr(indent+1)
+"<model>"
+MekHqXmlUtil.escape(model)
+"</model>");
pw1.println(MekHqXmlUtil.indentStr(indent+1)
+"<clan>"
+clan
+"</clan>");
pw1.println(MekHqXmlUtil.indentStr(indent+1)
+"<trooper>"
+trooper
+"</trooper>");
pw1.println(MekHqXmlUtil.indentStr(indent+1)
+"<quad>"
+quad
+"</quad>");
pw1.println(MekHqXmlUtil.indentStr(indent+1)
+"<groundMP>"
+groundMP
+"</groundMP>");
pw1.println(MekHqXmlUtil.indentStr(indent+1)
+"<jumpMP>"
+jumpMP
+"</jumpMP>");
pw1.println(MekHqXmlUtil.indentStr(indent+1)
+"<weightClass>"
+weightClass
+"</weightClass>");
pw1.println(MekHqXmlUtil.indentStr(indent+1)
+"<jumpType>"
+MekHqXmlUtil.escape(EntityMovementMode.token(jumpType))
+"</jumpType>");
writeToXmlEnd(pw1, indent);
}
@Override
protected void loadFieldsFromXmlNode(Node wn) {
NodeList nl = wn.getChildNodes();
for (int x=0; x<nl.getLength(); x++) {
Node wn2 = nl.item(x);
if (wn2.getNodeName().equalsIgnoreCase("trooper")) {
trooper = Integer.parseInt(wn2.getTextContent());
} else if (wn2.getNodeName().equalsIgnoreCase("groundMP")) {
groundMP = Integer.parseInt(wn2.getTextContent());
} else if (wn2.getNodeName().equalsIgnoreCase("jumpMP")) {
jumpMP = Integer.parseInt(wn2.getTextContent());
} else if (wn2.getNodeName().equalsIgnoreCase("weightClass")) {
weightClass = Integer.parseInt(wn2.getTextContent());
} else if (wn2.getNodeName().equalsIgnoreCase("quad")) {
quad = Boolean.parseBoolean(wn2.getTextContent().trim());
} else if (wn2.getNodeName().equalsIgnoreCase("clan")) {
clan = Boolean.parseBoolean(wn2.getTextContent().trim());
} else if (wn2.getNodeName().equalsIgnoreCase("chassis")) {
chassis = MekHqXmlUtil.unEscape(wn2.getTextContent());
} else if (wn2.getNodeName().equalsIgnoreCase("model")) {
model = MekHqXmlUtil.unEscape(wn2.getTextContent());
} else if (wn2.getNodeName().equalsIgnoreCase("jumpType")) {
jumpType = EntityMovementMode.type(MekHqXmlUtil.unEscape(wn2.getTextContent()));
}
}
}
@Override
public void fix() {
Part replacement = findReplacement(false);
if(null != replacement) {
BattleArmorSuit newSuit = (BattleArmorSuit)replacement.clone();
//lets also clone the subparts
unit.addPart(newSuit);
//this is admittedly hacky, but lets go ahead and add something to the newSuit
//so it doesnt generate a whole new set of parts
newSuit.childPartIds.add(1);
campaign.addPart(newSuit, 0);
newSuit.childPartIds.clear();
newSuit.setTrooper(trooper);
newSuit.updateConditionFromPart();
//cycle through MissingBattleArmorEquipmentPart for trooper and replace
ArrayList<MissingBattleArmorEquipmentPart> missingStuff = new ArrayList<MissingBattleArmorEquipmentPart>();
BaArmor origArmor = null;
for(Part p : unit.getParts()) {
if(p instanceof BaArmor && ((BaArmor)p).getLocation()== trooper) {
origArmor = (BaArmor)p;
}
if(!(p instanceof MissingBattleArmorEquipmentPart)) {
continue;
}
MissingBattleArmorEquipmentPart missingBaEquip = (MissingBattleArmorEquipmentPart)p;
if(missingBaEquip.getTrooper() != trooper) {
continue;
}
missingStuff.add(missingBaEquip);
}
for(int childId : replacement.getChildPartIds()) {
Part childPart = campaign.getPart(childId);
if(childPart instanceof BaArmor && null != origArmor) {
unit.getEntity().setArmor(((BaArmor)childPart).getAmount(), trooper);
origArmor.updateConditionFromEntity(false);
} else if(childPart instanceof BattleArmorEquipmentPart) {
for(MissingBattleArmorEquipmentPart p : missingStuff) {
if(null != childPart && null != p.getUnit() && p.isAcceptableReplacement(childPart, false)) {
//then add child part and remove current part from unit and campaign
Part newPart = childPart.clone();
unit.addPart(newPart);
((EquipmentPart)newPart).setEquipmentNum(p.getEquipmentNum());
((BattleArmorEquipmentPart)newPart).setTrooper(trooper);
p.remove(false);
newPart.updateConditionFromPart();
break;
}
}
}
}
replacement.decrementQuantity();
unit.getEntity().setInternal(0, trooper);
remove(false);
}
}
@Override
public String getLocationName() {
// TODO Auto-generated method stub
return null;
}
@Override
public int getLocation() {
return trooper;
}
@Override
public String getDetails() {
if(null == unit) {
return super.getDetails();
}
String toReturn = unit.getEntity().getLocationName(trooper) + "<br>";
return toReturn + super.getDetails();
}
@Override
public Part findReplacement(boolean refit) {
Part bestPart = null;
//check to see if we already have a replacement assigned
if(replacementId > -1) {
bestPart = campaign.getPart(replacementId);
if(null != bestPart) {
return bestPart;
}
}
// don't just return with the first part if it is damaged
for(Part part : campaign.getSpareParts()) {
if(part.isReservedForRefit() || part.isBeingWorkedOn() || part.isReservedForReplacement() || !part.isPresent() || part.hasParentPart()) {
continue;
}
if(isAcceptableReplacement(part, refit)) {
if(null == bestPart) {
bestPart = part;
} else {
int bestPartArmor = 0;
int currentPartArmor = 0;
int bestPartQuantity = 0;
int currentPartQuantity = 0;
for(int childId : bestPart.childPartIds) {
Part p = campaign.getPart(childId);
if(p != null) {
if(p instanceof BaArmor) {
bestPartArmor = ((BaArmor)p).getAmount();
} else {
bestPartQuantity++;
}
}
}
for(int childId : part.childPartIds) {
Part p = campaign.getPart(childId);
if(p != null) {
if(p instanceof BaArmor) {
currentPartArmor = ((BaArmor)p).getAmount();
} else {
currentPartQuantity++;
}
}
}
if(currentPartQuantity > bestPartQuantity) {
bestPart = part;
} else if(currentPartArmor > bestPartArmor) {
bestPart = part;
}
}
}
}
return bestPart;
}
@Override
public int getIntroDate() {
return ((BattleArmorSuit)getNewPart()).getIntroDate();
}
@Override
public int getExtinctDate() {
return EquipmentType.DATE_NONE;
}
@Override
public int getReIntroDate() {
return EquipmentType.DATE_NONE;
}
}