diff --git a/MekHQ/src/mekhq/campaign/unit/damage/AeroDamageApplier.java b/MekHQ/src/mekhq/campaign/unit/damage/AeroDamageApplier.java
deleted file mode 100644
index 389081a155..0000000000
--- a/MekHQ/src/mekhq/campaign/unit/damage/AeroDamageApplier.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2024 - 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 .
- */
-
-package mekhq.campaign.unit.damage;
-
-import megamek.common.Aero;
-import megamek.common.HitData;
-import megamek.common.IEntityRemovalConditions;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static megamek.common.Compute.randomInt;
-
-/**
- * Applies damage to an Aero entity.
- * @param entity Aero entity
- * @param crewMustSurvive Whether the crew must survive
- * @param entityMustSurvive Whether the entity must survive
- * @author Luana Coppio
- */
-public record AeroDamageApplier(Aero entity, boolean crewMustSurvive, boolean entityMustSurvive) implements DamageApplier {
-
- @Override
- public int getRandomHitLocation() {
- var entity = entity();
- List validLocations = new ArrayList<>();
- for (int i = 0; i < entity.locations(); i++) {
- if (entity.getOArmor(i) <= 0) {
- continue;
- }
- if (!entity.isLocationBlownOff(i) && entity.getSI() > 0) {
- validLocations.add(i);
- }
- }
-
- return validLocations.isEmpty() ? -1 : validLocations.get(randomInt(validLocations.size()));
- }
-
- @Override
- public void destroyLocationAfterEjection() {
- entity().setDestroyed(true);
- entity().setRemovalCondition(IEntityRemovalConditions.REMOVE_DEVASTATED);
- }
-
- @Override
- public HitDetails damageInternals(HitDetails hitDetails) {
- HitData hit = hitDetails.hit();
- var entity = entity();
- int currentInternalValue = entity.getSI();
- int newInternalValue = Math.max(currentInternalValue + hitDetails.setArmorValueTo(), 0);
- entity.setArmor(0, hit);
- entity.setSI(newInternalValue);
- applyDamageToEquipments(hit);
- if (newInternalValue == 0) {
- hitDetails = destroyLocation(hitDetails);
- }
- return hitDetails;
- }
-}
diff --git a/MekHQ/src/mekhq/campaign/unit/damage/DamageApplier.java b/MekHQ/src/mekhq/campaign/unit/damage/DamageApplier.java
deleted file mode 100644
index d484f441b0..0000000000
--- a/MekHQ/src/mekhq/campaign/unit/damage/DamageApplier.java
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (c) 2024 - 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 .
- */
-package mekhq.campaign.unit.damage;
-
-import megamek.common.*;
-import megamek.logging.MMLogger;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * @author Luana Coppio
- */
-public interface DamageApplier {
- MMLogger logger = MMLogger.create(DamageApplier.class);
-
- record HitDetails(HitData hit, int damageToApply, int setArmorValueTo, boolean hitInternal, int hitCrew) {
- public HitDetails withCrewDamage(int crewDamage) {
- return new HitDetails(hit, damageToApply, setArmorValueTo, hitInternal, crewDamage);
- }
- public HitDetails killsCrew() {
- return new HitDetails(hit, damageToApply, setArmorValueTo, hitInternal, Crew.DEATH);
- }
- }
-
- E entity();
-
- boolean crewMustSurvive();
-
- boolean entityMustSurvive();
-
- /**
- * Applies damage to the entity in clusters of a given size.
- * This is USUALLY the function you will want to use.
- *
- * @param dmg the total damage to apply
- * @param clusterSize the size of the clusters
- */
- default int applyDamageInClusters(int dmg, int clusterSize) {
- int totalDamage = dmg;
- int damageApplied = 0;
- while (totalDamage > 0) {
- if (entity().isCrippled() && entity().getRemovalCondition() == IEntityRemovalConditions.REMOVE_DEVASTATED) {
- // devastated units don't need to take any damage anymore
- break;
- }
- var clusterDamage = Math.min(totalDamage, clusterSize);
- applyDamage(clusterDamage);
- totalDamage -= clusterDamage;
- damageApplied += clusterDamage;
- }
- return damageApplied;
- }
-
- /**
- * Applies damage to the entity.
- *
- * @param dmg the total damage to apply
- */
- default void applyDamage(int dmg) {
- int hitLocation = getRandomHitLocation();
- if (hitLocation == -1) {
- entity().setDestroyed(true);
- return;
- }
- HitData hit = getHitData(hitLocation);
- HitDetails hitDetails = setupHitDetails(hit, dmg);
- applyDamage(hitDetails);
- }
-
- /**
- * Returns the location to hit.
- *
- * @return returns a valid random location to be hit.
- */
- default int getRandomHitLocation() {
- var entity = entity();
- List validLocations = new ArrayList<>();
- for (int i = 0; i < entity.locations(); i++) {
- if (entity.getOArmor(i) <= 0) {
- continue;
- }
- var locationIsNotBlownOff = !entity.isLocationBlownOff(i);
- var locationIsNotDestroyed = entity.getInternal(i) > 0;
- if (locationIsNotBlownOff && locationIsNotDestroyed) {
- validLocations.add(i);
- }
- }
- Collections.shuffle(validLocations);
- return validLocations.isEmpty() ? -1 : validLocations.get(0);
- }
-
- /**
- * Hits the entity with the given hit details.
- *
- * @param hitDetails the hit details
- */
- default void applyDamage(HitDetails hitDetails) {
- hitDetails = damageArmor(hitDetails);
- if (hitDetails.hitInternal()) {
- hitDetails = damageInternals(hitDetails);
- }
- tryToDamageCrew(hitDetails.hitCrew());
- }
-
- /**
- * Destroys the location after the crew has been ejected.
- */
- default void destroyLocationAfterEjection() {
- // default implementation does nothing
- }
-
- /**
- * Applies damage to the internals of the entity.
- *
- * @param hitDetails the hit details
- */
- default HitDetails damageInternals(HitDetails hitDetails) {
- HitData hit = hitDetails.hit();
- var entity = entity();
- int currentInternalValue = entity.getInternal(hit);
- int newInternalValue = Math.max(currentInternalValue + hitDetails.setArmorValueTo(), entityMustSurvive() ? 1 : 0);
- entity.setArmor(0, hit);
- logger.trace("[{}] Damage: {} - Internal at: {}", entity.getDisplayName(), hitDetails.damageToApply(), newInternalValue);
- entity.setInternal(newInternalValue, hit);
- applyDamageToEquipments(hit);
- if (newInternalValue == 0) {
- hitDetails = destroyLocation(hitDetails);
- }
- return hitDetails;
- }
-
- /**
- * Destroys the location of the entity. This one is used when you have the HitData.
- *
- * @param hitDetails the hit details with information about the location
- */
- default HitDetails destroyLocation(HitDetails hitDetails) {
- destroyLocation(hitDetails.hit().getLocation());
- return hitDetails.killsCrew();
- }
-
- /**
- * Destroys the location of the entity. This one is used when the location is already known.
- *
- * @param location the location index in the entity
- */
- default void destroyLocation(int location) {
- var entity = entity();
- logger.trace("[{}] Destroying location {}", entity.getDisplayName(), location);
- entity.destroyLocation(location);
- entity.setDestroyed(true);
- setEntityDestroyed(entity);
- }
-
- /**
- * Tries to damage the crew of the entity. If the crew is dead, the entity is marked as destroyed.
- * The crew won't be damaged if they are already ejected or already dead.
- * This function also does try to not outright kill the crew, as it has proven to be a bit too deadly.
- * @param hitCrew the amount of hits to apply to ALL crew
- */
- default void tryToDamageCrew(int hitCrew) {
- if (hitCrew == 0) {
- return;
- }
-
- var entity = entity();
- Crew crew = entity.getCrew();
- if (crew == null || crew.isEjected() || crew.isDead()) {
- return;
- }
- var hits = tryToNotKillTheCrew(hitCrew, crew);
-
- crew.setHits(hits, 0);
- logger.trace("[{}] Crew hit ({} hits)", entity().getDisplayName(), crew.getHits());
- if (crew.isDead()) {
- logger.trace("[{}] Crew died", entity().getDisplayName());
- entity.setDestroyed(true);
- setEntityDestroyed(entity);
- }
- }
-
- /**
- * Tries to not kill the crew. This function will set the amount of hits the crew will take.
- * If the crew must survive, the crew will try to eject instead, and if they can't be
- * ejected, it will set the total hits to DEATH - 1 (so... 5).
- * @param hitCrew the amount of hits to apply to ALL crew
- * @param crew the crew to apply the hits to
- * @return the amount of hits to apply to the crew
- */
- private Integer tryToNotKillTheCrew(int hitCrew, Crew crew) {
- var hits = Math.min(crew.getHits() + hitCrew, Crew.DEATH);
-
- if (hits == Crew.DEATH) {
- if (crewMustSurvive()) {
- hits = Compute.randomIntInclusive(4) + 1;
- }
- if (tryToEjectCrew()) {
- destroyLocationAfterEjection();
- }
- }
- return hits;
- }
-
- /**
- * Sets the entity as destroyed.
- * @param entity entity to be set as destroyed
- * @param the type of the entity
- */
- static void setEntityDestroyed(E entity) {
- if (entity.getRemovalCondition() != IEntityRemovalConditions.REMOVE_DEVASTATED) {
- entity.setRemovalCondition(IEntityRemovalConditions.REMOVE_SALVAGEABLE);
- entity.setSalvage(true);
- logger.trace("[{}] Entity destroyed", entity.getDisplayName());
- }
- }
-
- /**
- * Sets the entity as destroyed by ejection if possible.
- * @param entity entity to be set as destroyed
- * @param the type of the entity
- */
- static void setEntityDestroyedByEjection(E entity) {
- if (entity.getRemovalCondition() != IEntityRemovalConditions.REMOVE_DEVASTATED) {
- entity.setRemovalCondition(IEntityRemovalConditions.REMOVE_EJECTED);
- entity.setSalvage(true);
- logger.trace("[{}] Entity destroyed by ejection", entity.getDisplayName());
- }
- }
-
- /**
- * Tries to eject the crew of the entity if possible.
- *
- * @return true if the crew was ejected
- */
- default boolean tryToEjectCrew() {
- var entity = entity();
- var crew = entity.getCrew();
- if (crew == null || crew.isEjected() || !entity().isEjectionPossible() || entityMustSurvive()) {
- return false;
- }
- crew.setEjected(true);
- entity.setDestroyed(true);
- setEntityDestroyedByEjection(entity);
- logger.trace("[{}] Crew ejected", entity().getDisplayName());
- return true;
- }
-
- /**
- * Applies damage to the equipments of the entity.
- *
- * @param hit the hit data with information about the location
- */
- default void applyDamageToEquipments(HitData hit) {
- var entity = entity();
- var criticalSlots = entity.getCriticalSlots(hit.getLocation());
- Collections.shuffle(criticalSlots);
- for (CriticalSlot slot : criticalSlots) {
- if (slot != null && slot.isHittable() && !slot.isHit() && !slot.isDestroyed()) {
- slot.setHit(true);
- slot.setDestroyed(true);
- logger.trace("[{}] Equipment destroyed: {}", entity.getDisplayName(), slot);
- break;
- }
- }
- }
-
- /**
- * Applies damage only to the armor of the entity.
- *
- * @param hitDetails the hit details
- */
- default HitDetails damageArmor(HitDetails hitDetails) {
- var currentArmorValue = Math.max(hitDetails.setArmorValueTo(), 0);
- entity().setArmor(currentArmorValue, hitDetails.hit());
- logger.trace("[{}] Damage: {} - Armor at: {}", entity().getDisplayName(), hitDetails.damageToApply(), currentArmorValue);
- return hitDetails;
- }
-
- /**
- * Returns the hit data for the given hit location.
- *
- * @param hitLocation the hit location
- * @return the hit data
- */
- default HitData getHitData(int hitLocation) {
- return new HitData(hitLocation, false, HitData.EFFECT_NONE);
- }
-
- /**
- * Sets up the hit details for the given hit and damage.
- *
- * @param hit the hit data
- * @param damageToApply the damage to apply
- * @return the hit details
- */
- default HitDetails setupHitDetails(HitData hit, int damageToApply) {
- int currentArmorValue = entity().getArmor(hit);
- int setArmorValueTo = currentArmorValue - damageToApply;
- boolean hitInternal = setArmorValueTo < 0;
- int hitCrew = hitInternal ? 1 : 0;
-
- return new HitDetails(hit, damageToApply, setArmorValueTo, hitInternal, hitCrew);
- }
-}
diff --git a/MekHQ/src/mekhq/campaign/unit/damage/DamageApplierChooser.java b/MekHQ/src/mekhq/campaign/unit/damage/DamageApplierChooser.java
deleted file mode 100644
index e1aaad37d6..0000000000
--- a/MekHQ/src/mekhq/campaign/unit/damage/DamageApplierChooser.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2024 - 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 .
- */
-
-package mekhq.campaign.unit.damage;
-
-import megamek.common.*;
-
-/**
- * @author Luana Coppio
- */
-public class DamageApplierChooser {
-
-
- /**
- * Choose the correct DamageHandler for the given entity.
- * A damage handler is a class that handles applying damage on an entity, be it a Mek, Infantry, etc.
- * It can damage internal, armor, cause criticals, kill crew, set limbs as blown-off, can even destroy the entity,
- * @param entity the entity to choose the handler for
- * @return the correct DamageHandler for the given entity
- */
- public static DamageApplier> choose(Entity entity) {
- return choose(entity, EntityFinalState.ANY);
- }
-
- /**
- * Choose the correct DamageHandler for the given entity.
- * A damage handler is a class that handles applying damage on an entity, be it a Mek, Infantry, etc.
- * It can damage internal, armor, cause criticals, kill crew, set limbs as blown-off, can even destroy the entity,
- * This one also accepts parameters to indicate if the crew must survive and if the entity must survive.
- * @param entity the entity to choose the handler for
- * @param entityFinalState if the crew must survive and/or entity must survive
- * @return the correct DamageHandler for the given entity
- */
- public static DamageApplier> choose(
- Entity entity, EntityFinalState entityFinalState) {
- return choose(entity, entityFinalState.crewMustSurvive, entityFinalState.entityMustSurvive);
- }
-
- /**
- * Choose the correct DamageHandler for the given entity.
- * A damage handler is a class that handles applying damage on an entity, be it a Mek, Infantry, etc.
- * It can damage internal, armor, cause critical, kill crew, set limbs as blown-off, can even destroy the entity,
- * This one also accepts parameters to indicate if the crew must survive and if the entity must survive.
- * @param entity the entity to choose the handler for
- * @param crewMustSurvive if the crew must survive
- * @param entityMustSurvive if the entity must survive
- * @return the correct DamageHandler for the given entity
- */
- public static DamageApplier> choose(
- Entity entity, boolean crewMustSurvive, boolean entityMustSurvive) {
-
- if (entity instanceof Infantry) {
- return new InfantryDamageApplier((Infantry) entity);
- } else if (entity instanceof Mek) {
- return new MekDamageApplier((Mek) entity, crewMustSurvive, entityMustSurvive);
- } else if (entity instanceof GunEmplacement) {
- return new GunEmplacementDamageApplier((GunEmplacement) entity, crewMustSurvive, entityMustSurvive);
- } else if (entity instanceof Aero) {
- return new AeroDamageApplier((Aero) entity, crewMustSurvive, entityMustSurvive);
- }
- return new SimpleDamageApplier(entity, crewMustSurvive, entityMustSurvive);
- }
-
- /**
- * Automatically applies damage to the entity based on the "removal condition" provided.
- * The damage is calculated as being a percentage of the total armor of the unit, then it is transformed in a roll of dices
- * which the average roll is that amount, then the total damage is calculated and applied in clusters of 5 damage. It rolls a minimum of
- * 1 dice of damage.
- * The removal condition is a code that indicates why the entity is being removed from the game.
- * It will decide if the unit or entity must survive based on the type of removal condition.
- * The removal conditions are:
- * * RETREAT: crew must survive, entity must survive, 80% of the total armor is applied as damage
- * * SALVAGEABLE: crew may die, entity must be destroyed, 75% of the total armor is applied as damage
- * * CAPTURED: crew must survive, entity must be destroyed, 33% of the total armor is applied as damage
- * * EJECTED: crew must survive, entity must be destroyed, 33% of the total armor is applied as damage
- * * DEVASTATED: crew may survive, entity must be destroyed, 500% of the total armor is applied as damage
- * * OTHER: crew may die, entity may be destroyed, 33% of the total armor applied as damage
- * The amount of damage applied present right now was decided arbitrarily and can be changed later, maybe even make it follow
- * a config file, client settings, etc.
- *
- * @param entity the entity to choose the handler for
- * @param removalCondition the reason why the entity is being removed
- */
- public static void damageRemovedEntity(Entity entity, int removalCondition) {
- var numberOfDices = getNumberOfDices(entity, removalCondition);
- var damage = Compute.d6(numberOfDices);
- var clusterSize = 5;
-
- var retreating = removalCondition == IEntityRemovalConditions.REMOVE_IN_RETREAT;
- var captured = removalCondition == IEntityRemovalConditions.REMOVE_CAPTURED;
- var ejected = removalCondition == IEntityRemovalConditions.REMOVE_EJECTED;
- var devastated = removalCondition == IEntityRemovalConditions.REMOVE_DEVASTATED;
- var salvageable = removalCondition == IEntityRemovalConditions.REMOVE_SALVAGEABLE;
-
- var crewMustSurvive = retreating || captured || ejected;
- var entityMustSurvive = !devastated && !salvageable && !ejected;
-
- DamageApplierChooser.choose(entity, crewMustSurvive, entityMustSurvive)
- .applyDamageInClusters(damage, clusterSize);
- }
-
- private static int getNumberOfDices(Entity entity, int removalCondition) {
- double targetDamage = switch (removalCondition) {
- case IEntityRemovalConditions.REMOVE_CAPTURED, IEntityRemovalConditions.REMOVE_EJECTED -> entity.getTotalOArmor() * 1.2;
- case IEntityRemovalConditions.REMOVE_DEVASTATED -> entity.getTotalOArmor() * 5; // no damage is actually applied
- case IEntityRemovalConditions.REMOVE_IN_RETREAT -> entity.getTotalOArmor() * 0.8;
- case IEntityRemovalConditions.REMOVE_SALVAGEABLE -> entity.getTotalOArmor() * 0.75;
- default -> entity.getTotalOArmor() * 0.33;
- };
-
- return Math.max(1, (int) (targetDamage / 6 / 0.6));
- }
-
-}
diff --git a/MekHQ/src/mekhq/campaign/unit/damage/EntityFinalState.java b/MekHQ/src/mekhq/campaign/unit/damage/EntityFinalState.java
deleted file mode 100644
index d819434cff..0000000000
--- a/MekHQ/src/mekhq/campaign/unit/damage/EntityFinalState.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2024 - 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 .
- */
-
-package mekhq.campaign.unit.damage;
-
-
-public enum EntityFinalState {
- ANY(false, false),
- CREW_MUST_SURVIVE(true, false),
- ENTITY_MUST_SURVIVE(false, true),
- CREW_AND_ENTITY_MUST_SURVIVE(true, true);
-
- final boolean crewMustSurvive;
- final boolean entityMustSurvive;
-
- EntityFinalState(boolean crewMustSurvive, boolean entityMustSurvive) {
- this.crewMustSurvive = crewMustSurvive;
- this.entityMustSurvive = entityMustSurvive;
- }
-}
diff --git a/MekHQ/src/mekhq/campaign/unit/damage/GunEmplacementDamageApplier.java b/MekHQ/src/mekhq/campaign/unit/damage/GunEmplacementDamageApplier.java
deleted file mode 100644
index 6830960112..0000000000
--- a/MekHQ/src/mekhq/campaign/unit/damage/GunEmplacementDamageApplier.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2024 - 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 .
- */
-
-package mekhq.campaign.unit.damage;
-
-
-import megamek.common.GunEmplacement;
-
-public record GunEmplacementDamageApplier(GunEmplacement entity, boolean crewMustSurvive, boolean entityMustSurvive)
- implements DamageApplier {
-
- @Override
- public int getRandomHitLocation() {
- if (entity.isDestroyed()) {
- return -1;
- }
- return 0;
- }
-
-}
diff --git a/MekHQ/src/mekhq/campaign/unit/damage/InfantryDamageApplier.java b/MekHQ/src/mekhq/campaign/unit/damage/InfantryDamageApplier.java
deleted file mode 100644
index 40dfc54436..0000000000
--- a/MekHQ/src/mekhq/campaign/unit/damage/InfantryDamageApplier.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2024 - 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 .
- */
-
-package mekhq.campaign.unit.damage;
-
-import megamek.common.*;
-
-/**
- * @author Luana Coppio
- */
-public record InfantryDamageApplier(Infantry entity) implements DamageApplier {
-
- @Override
- public boolean crewMustSurvive() {
- return false;
- }
-
- @Override
- public boolean entityMustSurvive() {
- return false;
- }
-
- @Override
- public HitDetails damageArmor(HitDetails hitDetails) {
- if (entity() instanceof BattleArmor te) {
- for (int i = 0; i < te.getTroopers(); i++) {
- var currentValueArmor = te.getArmor(BattleArmor.LOC_SQUAD);
- var newArmorValue = Math.max(currentValueArmor - 1, 0);
- if (te.getArmor(BattleArmor.LOC_TROOPER_1 + i) > 0) {
- te.setArmor(newArmorValue, BattleArmor.LOC_TROOPER_1 + i);
- }
- }
- }
- if (entity().isCrippled()) {
- entity().setDestroyed(true);
- }
- return hitDetails;
- }
-
- @Override
- public HitDetails damageInternals(HitDetails hitDetails) {
- if (entity() instanceof BattleArmor te) {
- for (int i = 0; i < te.getTroopers(); i++) {
- var currentValue = te.getInternal(BattleArmor.LOC_SQUAD);
- var newValue = Math.max(currentValue - 1, 0);
- if (te.getInternal(BattleArmor.LOC_TROOPER_1 + i) > 0) {
- te.setInternal(newValue, BattleArmor.LOC_TROOPER_1 + i);
- }
- }
- } else {
- var currentValue = entity().getInternal(Infantry.LOC_INFANTRY);
- var newValue = Math.max(currentValue - 1, 0);
- entity().setInternal(newValue, Infantry.LOC_INFANTRY);
- }
-
- if (entity().isCrippled()) {
- entity().setDestroyed(true);
- }
- return hitDetails;
- }
-}
diff --git a/MekHQ/src/mekhq/campaign/unit/damage/MekDamageApplier.java b/MekHQ/src/mekhq/campaign/unit/damage/MekDamageApplier.java
deleted file mode 100644
index be083408e5..0000000000
--- a/MekHQ/src/mekhq/campaign/unit/damage/MekDamageApplier.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (c) 2024 - 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 .
- */
-
-package mekhq.campaign.unit.damage;
-
-
-import megamek.common.*;
-import megamek.common.util.weightedMaps.WeightedDoubleMap;
-
-import java.util.Collections;
-import java.util.Objects;
-import java.util.Set;
-
-import static megamek.common.Compute.rollD6;
-import static megamek.common.CriticalSlot.TYPE_SYSTEM;
-
-/**
- * @author Luana Coppio
- */
-public record MekDamageApplier(Mek entity, boolean crewMustSurvive, boolean entityMustSurvive) implements DamageApplier {
-
- // Target roll to hit the rear arc of the mek randomly
- private static final int REAR_ARC_HIT_CHANCE = 11;
- private static final Set criticalSystems = Set.of(Mek.SYSTEM_ENGINE, Mek.SYSTEM_GYRO, Mek.SYSTEM_LIFE_SUPPORT,
- Mek.SYSTEM_SENSORS, Mek.SYSTEM_COCKPIT);
- private static final Set criticalLocations = Set.of(Mek.LOC_CT, Mek.LOC_HEAD, Mek.LOC_LT, Mek.LOC_RT);
-
- @Override
- public int getRandomHitLocation() {
- var entity = entity();
- WeightedDoubleMap weightedDoubleMap = new WeightedDoubleMap<>();
- for (int i = 0; i < entity.locations(); i++) {
- if (entity.getOArmor(i) <= 0) {
- continue;
- }
- var locationIsNotBlownOff = !entity.isLocationBlownOff(i);
- var locationIsNotDestroyed = entity.getInternal(i) > 0;
- var locationIsNotHead = Mek.LOC_HEAD != i;
- var weight = locationIsNotHead ? 6.0 : 1.0;
- if (locationIsNotBlownOff && locationIsNotDestroyed) {
- weightedDoubleMap.add(weight, i);
- }
- }
- return weightedDoubleMap.randomOptionalItem().orElse(-1);
- }
-
- @Override
- public HitDetails setupHitDetails(HitData hit, int dmg) {
- int currentArmorValue = entity.getArmor(hit);
- int setArmorValueTo = currentArmorValue - dmg;
- boolean hitInternal = setArmorValueTo < 0;
- boolean isHeadHit = (entity.getCockpitType() != Mek.COCKPIT_TORSO_MOUNTED) && (hit.getLocation() == Mek.LOC_HEAD);
- int hitCrew = isHeadHit || hitInternal ? 1 : 0;
-
- return new HitDetails(hit, dmg, setArmorValueTo, hitInternal, hitCrew);
- }
-
- @Override
- public HitData getHitData(int hitLocation) {
- boolean hitRearArc = Compute.rollD6(2).isTargetRollSuccess(REAR_ARC_HIT_CHANCE);
- return getHitData(hitLocation, hitRearArc);
- }
-
- /**
- * Returns the hit data for the given location, considering if the hit is on the rear arc or not.
- * @param hitLocation the location of the hit
- * @param hitRearArc if the hit is on the rear arc
- * @return the hit data
- */
- public HitData getHitData(int hitLocation, boolean hitRearArc) {
- return new HitData(hitLocation, hitRearArc && hitLocationHasRear(hitLocation), HitData.EFFECT_NONE);
- }
-
- private boolean hitLocationHasRear(int hitLocation) {
- return switch(hitLocation) {
- case Mek.LOC_CT, Mek.LOC_LT, Mek.LOC_RT -> true;
- default -> false;
- };
- }
-
-
- @Override
- public HitDetails destroyLocation(HitDetails hitDetails) {
- var entity = entity();
- var hit = hitDetails.hit();
- entity.destroyLocation(hit.getLocation());
- if (hit.getLocation() == Mek.LOC_CT || hit.getLocation() == Mek.LOC_HEAD) {
- entity.setDestroyed(true);
- if (hit.getLocation() == Mek.LOC_HEAD) {
- if (entity.isEjectionPossible()) {
- var toHit = new ToHitData();
- toHit.addModifier(4, "Ejection");
- if (rollD6(2).isTargetRollSuccess(toHit)) {
- hitDetails = hitDetails.withCrewDamage(2);
- } else {
- hitDetails = hitDetails.killsCrew();
- }
- } else {
- hitDetails = hitDetails.killsCrew();
- }
- DamageApplier.setEntityDestroyed(entity);
- } else {
- entity.setSalvage(false);
- entity.setRemovalCondition(IEntityRemovalConditions.REMOVE_DEVASTATED);
- logger.trace("[{}] Mek devastated!", entity.getDisplayName());
- }
- }
- if (hit.getLocation() == Mek.LOC_RLEG || hit.getLocation() == Mek.LOC_LLEG) {
- // leg destroyed causes a fall which damages the pilot
- hitDetails.withCrewDamage(1);
- }
- return hitDetails;
- }
-
- @Override
- public void applyDamageToEquipments(HitData hit) {
- var entity = entity();
- var criticalSlots = entity.getCriticalSlots(hit.getLocation());
- Collections.shuffle(criticalSlots);
- if (entityMustSurvive() && criticalLocations.contains(hit.getLocation())) {
- criticalSlots = criticalSlots.stream().filter(Objects::nonNull)
- .filter(slot -> !(slot.getType() == TYPE_SYSTEM && criticalSystems.contains(slot.getIndex())))
- .toList();
- }
- for (CriticalSlot slot : criticalSlots) {
- if (slot != null && slot.isHittable() && !slot.isHit() && !slot.isDestroyed()) {
- slot.setHit(true);
- slot.setDestroyed(true);
- logger.trace("[{}] Slot {} destroyed", entity.getDisplayName(), slot.getIndex());
- break;
- }
- }
- // TODO: check if damage on ammo
- // TODO: check if damage on life support
- // TODO: check if damage on cockpit
- }
-
- @Override
- public void destroyLocationAfterEjection(){
- var entity = entity();
- entity.destroyLocation(Mek.LOC_HEAD);
- }
-
- @Override
- public HitDetails damageInternals(HitDetails hitDetails) {
- HitData hit = hitDetails.hit();
- var entity = entity();
- int currentInternalValue = entity.getInternal(hit);
- int newInternalValue = Math.max(currentInternalValue + hitDetails.setArmorValueTo(), 0);
- entity.setArmor(0, hit);
- if (entityMustSurvive() && !canLoseLocation(hit)) {
- newInternalValue = Math.max(newInternalValue, Compute.d6());
- }
- entity.setInternal(newInternalValue, hit);
- applyDamageToEquipments(hit);
- if (newInternalValue == 0) {
- hitDetails = destroyLocation(hitDetails);
- }
- return hitDetails;
- }
-
- private boolean canLoseLocation(HitData hitData) {
- var location = hitData.getLocation();
- if (!entityMustSurvive()) {
- return true;
- }
-
- if (location == Mek.LOC_CT || location == Mek.LOC_HEAD) {
- return false;
- }
- if (location == Mek.LOC_LT || location == Mek.LOC_RT) {
- if (entity.getCritical(location, Mek.SYSTEM_ENGINE) == null) {
- return true;
- }
- }
- if (location == Mek.LOC_LLEG || location == Mek.LOC_RLEG) {
- return !entity.isLocationBlownOff(Mek.LOC_LLEG) && !entity.isLocationBlownOff(Mek.LOC_RLEG);
- }
-
- return true;
- }
-}
diff --git a/MekHQ/src/mekhq/campaign/unit/damage/SimpleDamageApplier.java b/MekHQ/src/mekhq/campaign/unit/damage/SimpleDamageApplier.java
deleted file mode 100644
index 506c2ea16e..0000000000
--- a/MekHQ/src/mekhq/campaign/unit/damage/SimpleDamageApplier.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2024 - 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 .
- */
-
-package mekhq.campaign.unit.damage;
-
-
-import megamek.common.Entity;
-
-/**
- * @author Luana Coppio
- */
-public record SimpleDamageApplier(Entity entity, boolean crewMustSurvive, boolean entityMustSurvive)
- implements DamageApplier {}