/*
* Copyright (C) 2017 MegaMek team
*
* 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 org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import megamek.common.Aero;
import megamek.common.EquipmentType;
import megamek.common.MiscType;
import megamek.common.TechConstants;
import mekhq.MekHQ;
import mekhq.MekHqXmlUtil;
import mekhq.campaign.Campaign;
import mekhq.campaign.parts.equipment.EquipmentPart;
import mekhq.campaign.parts.equipment.HeatSink;
import mekhq.campaign.parts.equipment.JumpJet;
import mekhq.campaign.parts.equipment.MASC;
import mekhq.campaign.personnel.SkillType;
/**
* An empty omnipod, which can be purchased or created when equipment is removed from a pod.
* When fixed, the omnipod is removed from the warehouse and one replacement part is podded.
*
* @author Neoancient
*
*/
public class OmniPod extends Part {
private static final long serialVersionUID = -8236359530423260992L;
// Pods are specific to the type of equipment they contain.
private Part partType;
public OmniPod() {
this(new EquipmentPart(), null);
}
public OmniPod(Part partType, Campaign c) {
super(0, false, c);
this.partType = partType;
if (null != partType) {
partType.setOmniPodded(false);
}
name = "OmniPod";
}
@Override
public void setCampaign(Campaign c) {
super.setCampaign(c);
partType.setCampaign(c);
}
@Override
public String getDetails() {
return partType.getName();
}
@Override
public int getBaseTime() {
return partType.getMissingPart().getBaseTime();
}
@Override
public void updateConditionFromPart() {
// do nothing
}
//This can only be found in the warehouse
@Override
public int getLocation() {
return -1;
}
@Override
public String checkFixable() {
if (partType.getMissingPart().isReplacementAvailable()) {
return null;
}
return "No equipment available to install";
}
//Podding equipment is a Class D (Maintenance) refit, which carries a +2 modifier.
@Override
public int getDifficulty() {
return partType.getDifficulty() + 2;
}
@Override
public String getRepairDesc() {
if (partType.getMissingPart().isReplacementAvailable()) {
return super.getRepairDesc();
} else {
return "Part not available";
}
}
//Weight is negligible
@Override
public double getTonnage() {
return 0;
}
//Using tech rating for Omni construction option from IOps.
@Override
public int getTechRating() {
return EquipmentType.RATING_E;
}
@Override
public int getAvailability(int era) {
if (era == EquipmentType.ERA_SL
|| (era == EquipmentType.ERA_SW && partType.getTechBase() == T_IS)) {
return EquipmentType.RATING_X;
} else if (era == EquipmentType.ERA_DA) {
return Math.max(partType.getAvailability(era), EquipmentType.RATING_D);
} else {
return Math.max(partType.getAvailability(era), EquipmentType.RATING_E);
}
}
@Override
public int getIntroDate() {
if (partType.getTechBase() == T_IS) {
return Math.max(3052, partType.getIntroDate());
} else {
return Math.max(2850, partType.getIntroDate());
}
}
@Override
public int getExtinctDate() {
return partType.getExtinctDate();
}
@Override
public int getReIntroDate() {
return partType.getReIntroDate();
}
@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("partType")) {
if (null == wn2.getAttributes().getNamedItem("type")) {
MekHQ.logError("OmniPod lacks part type attribute.");
} else if (null == wn2.getAttributes().getNamedItem("tonnage")) {
MekHQ.logError("OmniPod lacks partType tonnage attribute.");
} else {
String type = wn2.getAttributes().getNamedItem("type").getTextContent();
int tonnage = Integer.parseInt(wn2.getAttributes().getNamedItem("tonnage").getTextContent());
if (type.equals("AeroHeatSink")) {
int hsType = -1;
if (null != wn2.getAttributes().getNamedItem("hsType")) {
hsType = Integer.parseInt(wn2.getAttributes().getNamedItem("hsType").getTextContent());
}
if (hsType != Aero.HEAT_SINGLE && hsType != Aero.HEAT_DOUBLE) {
MekHQ.logError("Aero heatsink OmniPod does not have a legal value for heat sink type; using SINGLE");
hsType = Aero.HEAT_SINGLE;
}
partType = new AeroHeatSink(0, hsType, false, campaign);
} else {
EquipmentType et = EquipmentType.get(type);
if (null == et) {
MekHQ.logError("Unknown part type " + type + " for OmniPod");
//Throw a generic value in there to prevent NPE but still indicate a problem
et = EquipmentType.get(EquipmentType
.getStructureTypeName(EquipmentType.T_STRUCTURE_STANDARD));
}
if (et instanceof MiscType
&& (et.hasFlag(MiscType.F_HEAT_SINK)
|| et.hasFlag(MiscType.F_DOUBLE_HEAT_SINK)
|| et.hasFlag(MiscType.F_IS_DOUBLE_HEAT_SINK_PROTOTYPE))) {
partType = new HeatSink(0, et, -1, false, campaign);
} else if (et instanceof MiscType && et.hasFlag(MiscType.F_JUMP_JET)) {
partType = new JumpJet(tonnage, et, -1, false, campaign);
} else if (et instanceof MiscType
&& et.hasFlag(MiscType.F_MASC)
&& (et.getSubType() & MiscType.S_SUPERCHARGER) == 0) {
if (null != wn2.getAttributes().getNamedItem("rating")) {
int rating = Integer.parseInt(wn2.getAttributes().getNamedItem("rating").getTextContent());
partType = new MASC(tonnage, et, -1, campaign, rating, false);
} else {
MekHQ.logError("OmniPod for MASC lacks engine rating");
}
} else {
partType = new EquipmentPart(tonnage, et, -1, false, campaign);
}
}
}
}
}
}
@Override
public String getLocationName() {
return null;
}
@Override
public void updateConditionFromEntity(boolean checkForDestruction) {
//do nothing
}
@Override
public void remove(boolean salvage) {
//do nothing
}
@Override
public MissingPart getMissingPart() {
return null;
}
@Override
public boolean needsFixing() {
return true;
}
@Override
public void fix() {
Part newPart = partType.clone();
Part oldPart = campaign.checkForExistingSparePart(newPart.clone());
if(null != oldPart) {
newPart.setOmniPodded(true);
campaign.addPart(newPart, 0);
oldPart.decrementQuantity();
}
}
@Override
public String fail(int rating) {
skillMin = ++rating;
timeSpent = 0;
shorthandedMod = 0;
if(skillMin > SkillType.EXP_ELITE) {
return " <font color='red'><b> failed and part destroyed.</b></font>";
} else {
//OmniPod is only added back to warehouse if repair fails without destroying part.
campaign.addPart(this, 0);
return " <font color='red'><b> failed.</b></font>";
}
}
@Override
public String getStatus() {
String toReturn = "Empty";
if(isReservedForRefit()) {
toReturn = "Reserved for Refit";
}
if(isReservedForReplacement()) {
toReturn = "Reserved for Repair";
}
if(isBeingWorkedOn()) {
toReturn = "Being worked on";
}
if(!isPresent()) {
//toReturn = "" + getDaysToArrival() + " days to arrival";
String dayName = "day";
if(getDaysToArrival() > 1) {
dayName += "s";
}
toReturn = "In transit (" + getDaysToArrival() + " " + dayName + ")";
}
return toReturn;
}
@Override
public long getStickerPrice() {
return (long)Math.ceil(partType.getStickerPrice() / 5.0);
}
@Override
public int getTechLevel() {
if (partType.isClanTechBase()) {
return TechConstants.T_CLAN_TW;
}
return TechConstants.T_IS_TW_ALL;
}
@Override
public boolean isSamePartType(Part part) {
return part instanceof OmniPod
&& (partType.isSamePartType(((OmniPod)part).partType));
}
@Override
public void writeToXml(PrintWriter pw1, int indent) {
writeToXmlBegin(pw1, indent);
pw1.print(MekHqXmlUtil.indentStr(indent + 1) + "<partType tonnage='" + partType.getUnitTonnage()
+ "' type='");
if (partType instanceof AeroHeatSink) {
pw1.print("AeroHeatSink' hsType='" + ((AeroHeatSink)partType).getType());
} else if (partType instanceof EquipmentPart) {
pw1.print(((EquipmentPart)partType).getType().getInternalName());
if (partType instanceof MASC) {
pw1.print("' rating='" + ((MASC)partType).getEngineRating());
}
} else {
MekHQ.logError("OmniPod partType is not EquipmentType");
}
pw1.println("'/>");
writeToXmlEnd(pw1, indent);
}
@Override
public Part clone() {
Part p = new OmniPod(partType, campaign);
p.copyBaseData(this);
return p;
}
}