Skip to content

Commit

Permalink
Merge pull request #2088 from sixlettervariables/avoid-child-part-ref…
Browse files Browse the repository at this point in the history
…-errors

Switch to strong references instead of IDs for child parts
  • Loading branch information
sixlettervariables committed Oct 2, 2020
2 parents ab073fc + 5ff7e79 commit 032d917
Show file tree
Hide file tree
Showing 12 changed files with 370 additions and 285 deletions.
28 changes: 17 additions & 11 deletions MekHQ/src/mekhq/campaign/Campaign.java
Original file line number Diff line number Diff line change
Expand Up @@ -1634,7 +1634,7 @@ public void addPart(Part p, int transitDays) {
p.setId(-1);
return;
}
if (null == p.getUnit()) {
if ((null == p.getUnit()) && !p.hasParentPart()) {
Part spare = checkForExistingSparePart(p);
if (null != spare) {
if (p instanceof Armor) {
Expand Down Expand Up @@ -1713,14 +1713,23 @@ public void arrivePart(Part p) {
}
}



/**
* Imports a {@link Part} into the campaign.
* Imports a collection of parts into the campaign.
*
* @param p The {@link Part} to import into the campaign.
* @param newParts The collection of {@link Part} instances
* to import into the campaign.
*/
public void importPart(Part p) {
p.setCampaign(this);
addPartWithoutId(p);
public void importParts(Collection<Part> newParts) {
for (Part p : newParts) {
p.setCampaign(this);
addPartWithoutId(p);
}

for (Part p : newParts) {
p.fixupPartReferences(parts);
}
}

public void addPartWithoutId(Part p) {
Expand Down Expand Up @@ -3906,11 +3915,8 @@ public void removePart(Part part) {
}
parts.remove(part.getId());
//remove child parts as well
for (int childId : part.getChildPartIds()) {
Part childPart = getPart(childId);
if (null != childPart) {
removePart(childPart);
}
for (Part childPart : part.getChildParts()) {
removePart(childPart);
}
MekHQ.triggerEvent(new PartRemovedEvent(part));
}
Expand Down
5 changes: 4 additions & 1 deletion MekHQ/src/mekhq/campaign/io/CampaignXmlParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -1483,6 +1483,7 @@ private static void processPartNodes(Campaign retVal, Node wn, Version version)
NodeList wList = wn.getChildNodes();

// Okay, lets iterate through the children, eh?
List<Part> parts = new ArrayList<>();
for (int x = 0; x < wList.getLength(); x++) {
Node wn2 = wList.item(x);

Expand Down Expand Up @@ -1577,10 +1578,12 @@ private static void processPartNodes(Campaign retVal, Node wn, Version version)
}

if (p != null) {
retVal.importPart(p);
parts.add(p);
}
}

retVal.importParts(parts);

MekHQ.getLogger().info(CampaignXmlParser.class, "Load Part Nodes Complete!");
}

Expand Down
56 changes: 29 additions & 27 deletions MekHQ/src/mekhq/campaign/parts/BattleArmorSuit.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ public class BattleArmorSuit extends Part {
private Money alternateCost = Money.zero();
private double alternateTon;
private int introYear;
private boolean isReplacement;

public BattleArmorSuit() {
super(0, null);
Expand Down Expand Up @@ -139,7 +140,7 @@ public void setTrooper(int i) {
public double getTonnage() {
//if there are no linked parts and the unit is null,
//then use the pre-recorded alternate costs
if(null == unit && getChildPartIds().size()==0) {
if ((null == unit) && getChildParts().isEmpty()) {
return alternateTon;
}
double tons = 0;
Expand Down Expand Up @@ -218,12 +219,11 @@ else if(jumpType == EntityMovementMode.VTOL) {
}
//if there are no linked parts and the unit is null,
//then use the pre-recorded extra costs
if(null == unit && getChildPartIds().size()==0) {
if ((null == unit) && getChildParts().isEmpty()) {
tons += alternateTon;
}
for(int childId : getChildPartIds()) {
Part p = campaign.getPart(childId);
if(null != p && !(p instanceof BattleArmorSuit)) {
for (Part p : getChildParts()) {
if (!(p instanceof BattleArmorSuit)) {
tons += p.getTonnage();
}
}
Expand All @@ -234,7 +234,7 @@ else if(jumpType == EntityMovementMode.VTOL) {
public Money getStickerPrice() {
//if there are no linked parts and the unit is null,
//then use the pre-recorded alternate costs
if(null == unit && getChildPartIds().size()==0) {
if ((null == unit) && getChildParts().isEmpty()) {
return alternateCost;
}
Money cost = Money.zero();
Expand Down Expand Up @@ -267,14 +267,11 @@ public Money getStickerPrice() {
cost = cost.plus(50000 * (jumpMP + 1));
}
cost = cost.plus(25000 * (groundMP-1));
for(int childId : getChildPartIds()) {
Part p = campaign.getPart(childId);
if(null != p) {
if(p instanceof BaArmor) {
cost = cost.plus(p.getCurrentValue());
} else if (!(p instanceof BattleArmorSuit)) {
cost = cost.plus(p.getStickerPrice());
}
for (Part p : getChildParts()) {
if (p instanceof BaArmor) {
cost = cost.plus(p.getCurrentValue());
} else if (!(p instanceof BattleArmorSuit)) {
cost = cost.plus(p.getStickerPrice());
}
}

Expand Down Expand Up @@ -445,7 +442,7 @@ public void remove(boolean salvage) {
if(part instanceof BaArmor && ((BaArmor)part).getLocation() == trooper) {
BaArmor armorClone = (BaArmor)part.clone();
armorClone.setAmount(((BaArmor)part).getAmount());
armorClone.setParentPartId(getId());
armorClone.setParentPart(this);
campaign.addPart(armorClone, 0);
addChildPart(armorClone);
}
Expand Down Expand Up @@ -529,15 +526,12 @@ public String getDetails(boolean includeRepairDetails) {
} else {
int nEquip = 0;
int armor = 0;
if(getChildPartIds().size() > 0) {
for(int childId : getChildPartIds()) {
Part p = campaign.getPart(childId);
if(null != p) {
if(p instanceof BaArmor) {
armor = ((BaArmor)p).getAmount();
} else {
nEquip++;
}
if (!getChildParts().isEmpty()) {
for (Part p : getChildParts()) {
if (p instanceof BaArmor) {
armor = ((BaArmor)p).getAmount();
} else {
nEquip++;
}
}
return nEquip + " pieces of equipment; " + armor + " armor points";
Expand Down Expand Up @@ -629,24 +623,32 @@ private void addSubParts() {
for(Part part : newUnit.getParts()) {
if(part instanceof BattleArmorEquipmentPart && ((BattleArmorEquipmentPart)part).getTrooper() == BattleArmor.LOC_TROOPER_1) {
Part newEquip = part.clone();
newEquip.setParentPartId(getId());
newEquip.setParentPart(this);
campaign.addPart(newEquip, 0);
addChildPart(newEquip);
}
else if(part instanceof BaArmor && ((BaArmor)part).getLocation() == BattleArmor.LOC_TROOPER_1) {
BaArmor armorClone = (BaArmor)part.clone();
armorClone.setAmount(newUnit.getEntity().getOArmor(BattleArmor.LOC_TROOPER_1));
armorClone.setParentPartId(getId());
armorClone.setParentPart(this);
campaign.addPart(armorClone, 0);
addChildPart(armorClone);
}
}
}
}

/**
* Sets a value indicating whether or not this part
* is being used as a replacement.
*/
public void isReplacement(boolean value) {
isReplacement = value;
}

@Override
public void postProcessCampaignAddition() {
if(getChildPartIds().isEmpty()) {
if (!isReplacement && getChildParts().isEmpty()) {
addSubParts();
}
}
Expand Down
39 changes: 18 additions & 21 deletions MekHQ/src/mekhq/campaign/parts/BayDoor.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/*
* Copyright (c) 2017 - The MegaMek Team. 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/>.
*/
Expand All @@ -34,30 +34,29 @@
*
*/
public class BayDoor extends Part {

/**
*
*
*/
private static final long serialVersionUID = 685375245347077715L;

public BayDoor() {
this(0, null);
}

public BayDoor(int tonnage, Campaign c) {
super(tonnage, false, c);
name = "Bay Door";
}

@Override
public String getName() {
Part parent = campaign.getPart(parentPartId);
if (null != parent) {
return parent.getName() + " Door";
if (null != parentPart) {
return parentPart.getName() + " Door";
}
return super.getName();
}

@Override
public int getBaseTime() {
if (isSalvaging()) {
Expand All @@ -75,13 +74,12 @@ public void updateConditionFromEntity(boolean checkForDestruction) {
public void updateConditionFromPart() {
// This is handled by the transport bay part to coordinate all the doors
}

@Override
public void fix() {
super.fix();
Part bayPart = campaign.getPart(parentPartId);
if (null != bayPart) {
Bay bay = ((TransportBayPart) bayPart).getBay();
if (parentPart instanceof TransportBayPart) {
Bay bay = ((TransportBayPart) parentPart).getBay();
if (null != bay) {
bay.setCurrentDoors(Math.min(bay.getCurrentDoors() + 1, bay.getDoors()));
}
Expand All @@ -90,8 +88,7 @@ public void fix() {

@Override
public void remove(boolean salvage) {
Part bayPart = campaign.getPart(parentPartId);
if (null != bayPart) {
if (null != parentPart) {
Part spare = campaign.checkForExistingSparePart(this);
if (!salvage) {
campaign.removePart(this);
Expand All @@ -103,9 +100,9 @@ public void remove(boolean salvage) {
Part missing = getMissingPart();
unit.addPart(missing);
campaign.addPart(missing, 0);
bayPart.removeChildPart(id);
bayPart.addChildPart(missing);
bayPart.updateConditionFromPart();
parentPart.removeChildPart(this);
parentPart.addChildPart(missing);
parentPart.updateConditionFromPart();
}
setUnit(null);
}
Expand Down
14 changes: 6 additions & 8 deletions MekHQ/src/mekhq/campaign/parts/Cubicle.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ public BayType getBayType() {

@Override
public String getName() {
Part parent = campaign.getPart(parentPartId);
if (null != parent) {
return parent.getName() + " Cubicle";
if (null != parentPart) {
return parentPart.getName() + " Cubicle";
}
return super.getName();
}
Expand All @@ -84,8 +83,7 @@ public void updateConditionFromPart() {

@Override
public void remove(boolean salvage) {
Part bayPart = campaign.getPart(parentPartId);
if (null != bayPart) {
if (null != parentPart) {
Part spare = campaign.checkForExistingSparePart(this);
if (!salvage) {
campaign.removePart(this);
Expand All @@ -97,9 +95,9 @@ public void remove(boolean salvage) {
Part missing = getMissingPart();
unit.addPart(missing);
campaign.addPart(missing, 0);
bayPart.removeChildPart(id);
bayPart.addChildPart(missing);
bayPart.updateConditionFromPart();
parentPart.removeChildPart(this);
parentPart.addChildPart(missing);
parentPart.updateConditionFromPart();
}
setUnit(null);
}
Expand Down

0 comments on commit 032d917

Please sign in to comment.