Looking for some feedback on my salvage mod, Proportional Mech Salvage.
The aim is to make the amount of salvaged mech parts proportional to the extent of damage done. Also, to make mech salvage symmetrical between player and nonplayer mechs.
For reference, the vanilla behavior is that player mechs are only destroyed IF you make it possible AND you fail the roll AND your mech is CT'd, and if destroyed you get 0 salvaged parts. For enemies, you get 1 part if the mech is CT'd, 2 if legged, and 3 if headshot OR pilot incapacitated, in order of precedence. That is, you can get 3 parts even if you've blown off a leg and both side torsos and then get a lucky headshot, but if you snipe through the CT alone you just get one part.
My proposed changes:
- Player mechs are destroyed IF you make it possible AND you fail the roll AND your mech is CT'd/legged/headshot. (pilot incap doesn't count)
- You salvage 3 parts if you destroyed 1 or fewer sections, 2 parts if you destroyed 2-3 sections, 1 part if you destroyed 4-5 sections, and 0 parts if you destroyed 6-8 sections.
This is intended to be played with default mech part settings (3 parts make a mech) and default contract salvage (2 base priority), since doing otherwise would require rebalancing all the other areas of gameplay, which is beyond the scope of this mod. Also intended to be played with no free loadout.
The relevant code change to BattleTech.Contract.GenerateSalvage:
(paradox forum doesn't support formatting?)
Would you play with these changes? Do they make sense? Any feedback is welcome and appreciated.
The aim is to make the amount of salvaged mech parts proportional to the extent of damage done. Also, to make mech salvage symmetrical between player and nonplayer mechs.
For reference, the vanilla behavior is that player mechs are only destroyed IF you make it possible AND you fail the roll AND your mech is CT'd, and if destroyed you get 0 salvaged parts. For enemies, you get 1 part if the mech is CT'd, 2 if legged, and 3 if headshot OR pilot incapacitated, in order of precedence. That is, you can get 3 parts even if you've blown off a leg and both side torsos and then get a lucky headshot, but if you snipe through the CT alone you just get one part.
My proposed changes:
- Player mechs are destroyed IF you make it possible AND you fail the roll AND your mech is CT'd/legged/headshot. (pilot incap doesn't count)
- You salvage 3 parts if you destroyed 1 or fewer sections, 2 parts if you destroyed 2-3 sections, 1 part if you destroyed 4-5 sections, and 0 parts if you destroyed 6-8 sections.
This is intended to be played with default mech part settings (3 parts make a mech) and default contract salvage (2 base priority), since doing otherwise would require rebalancing all the other areas of gameplay, which is beyond the scope of this mod. Also intended to be played with no free loadout.
The relevant code change to BattleTech.Contract.GenerateSalvage:
for (int i = 0; i < lostUnits.Count; i++)
{
MechDef mech = lostUnits[ i].mech;
float num = simulation.NetworkRandom.Float(0f, 1f);
bool flag = mech.IsDestroyed;
Contract.logger.LogWarning(string.Format("Player Unit {0}: {1} was destroyed in combat? {2}. If true, attempting to recover.", i, mech.Description.Name, flag));
Contract.logger.LogWarning(string.Format("Rolled a recovery roll of {0}, attempting to roll below {1}", num, constants.Salvage.DestroyedMechRecoveryChance));
if (!flag || num <= constants.Salvage.DestroyedMechRecoveryChance)
{
Contract.logger.LogWarning("Recovery Succeeded");
lostUnits[ i].mechLost = false;
}
else
{
Contract.logger.LogWarning("Recovery Failed, Unit Lost");
lostUnits[ i].mechLost = true;
if ((mech.IsLocationDestroyed(ChassisLocations.Head) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.CenterTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftArm) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightArm) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftLeg) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightLeg) ? 1 : 0) <= 1)
{
Contract.logger.LogWarning("3 parts salvaged");
this.SalvageResults.Add(this.CreateMechPart(constants, mech));
this.SalvageResults.Add(this.CreateMechPart(constants, mech));
this.SalvageResults.Add(this.CreateMechPart(constants, mech));
}
else if ((mech.IsLocationDestroyed(ChassisLocations.Head) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.CenterTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftArm) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightArm) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftLeg) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightLeg) ? 1 : 0) <= 3)
{
Contract.logger.LogWarning("2 parts salvaged");
this.SalvageResults.Add(this.CreateMechPart(constants, mech));
this.SalvageResults.Add(this.CreateMechPart(constants, mech));
}
else if ((mech.IsLocationDestroyed(ChassisLocations.Head) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.CenterTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftArm) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightArm) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftLeg) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightLeg) ? 1 : 0) <= 5)
{
Contract.logger.LogWarning("1 part salvaged");
this.SalvageResults.Add(this.CreateMechPart(constants, mech));
}
foreach (MechComponentRef mechComponentRef in mech.Inventory)
{
if (!mech.IsLocationDestroyed(mechComponentRef.MountedLocation) && mechComponentRef.DamageLevel != ComponentDamageLevel.Destroyed)
{
this.AddToFinalSalvage(new SalvageDef
{
MechComponentDef = mechComponentRef.Def,
Description = new DescriptionDef(mechComponentRef.Def.Description),
RewardID = this.GenerateRewardUID(),
Type = SalvageDef.SalvageType.COMPONENT,
ComponentType = mechComponentRef.Def.ComponentType,
Damaged = false,
Count = 1
});
}
}
}
}
int j = 0;
while (j < enemyMechs.Count)
{
MechDef mech2 = enemyMechs[j].mech;
Pilot pilot = enemyMechs[j].pilot;
SalvageDef salvageDef = null;
bool flag2 = false;
bool flag3 = false;
if ((mech2.IsLocationDestroyed(ChassisLocations.Head) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.CenterTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftArm) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightArm) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftLeg) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightLeg) ? 1 : 0) <= 1)
{
this.CreateAndAddMechPart(constants, mech2, 3, this.finalPotentialSalvage);
goto IL_623;
}
if ((mech2.IsLocationDestroyed(ChassisLocations.Head) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.CenterTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftArm) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightArm) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftLeg) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightLeg) ? 1 : 0) <= 3)
{
this.CreateAndAddMechPart(constants, mech2, 2, this.finalPotentialSalvage);
goto IL_623;
}
if ((mech2.IsLocationDestroyed(ChassisLocations.Head) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.CenterTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftArm) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightArm) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftLeg) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightLeg) ? 1 : 0) <= 5)
{
this.CreateAndAddMechPart(constants, mech2, 1, this.finalPotentialSalvage);
goto IL_623;
}
{
MechDef mech = lostUnits[ i].mech;
float num = simulation.NetworkRandom.Float(0f, 1f);
bool flag = mech.IsDestroyed;
Contract.logger.LogWarning(string.Format("Player Unit {0}: {1} was destroyed in combat? {2}. If true, attempting to recover.", i, mech.Description.Name, flag));
Contract.logger.LogWarning(string.Format("Rolled a recovery roll of {0}, attempting to roll below {1}", num, constants.Salvage.DestroyedMechRecoveryChance));
if (!flag || num <= constants.Salvage.DestroyedMechRecoveryChance)
{
Contract.logger.LogWarning("Recovery Succeeded");
lostUnits[ i].mechLost = false;
}
else
{
Contract.logger.LogWarning("Recovery Failed, Unit Lost");
lostUnits[ i].mechLost = true;
if ((mech.IsLocationDestroyed(ChassisLocations.Head) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.CenterTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftArm) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightArm) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftLeg) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightLeg) ? 1 : 0) <= 1)
{
Contract.logger.LogWarning("3 parts salvaged");
this.SalvageResults.Add(this.CreateMechPart(constants, mech));
this.SalvageResults.Add(this.CreateMechPart(constants, mech));
this.SalvageResults.Add(this.CreateMechPart(constants, mech));
}
else if ((mech.IsLocationDestroyed(ChassisLocations.Head) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.CenterTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftArm) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightArm) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftLeg) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightLeg) ? 1 : 0) <= 3)
{
Contract.logger.LogWarning("2 parts salvaged");
this.SalvageResults.Add(this.CreateMechPart(constants, mech));
this.SalvageResults.Add(this.CreateMechPart(constants, mech));
}
else if ((mech.IsLocationDestroyed(ChassisLocations.Head) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.CenterTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightTorso) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftArm) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightArm) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.LeftLeg) ? 1 : 0) + (mech.IsLocationDestroyed(ChassisLocations.RightLeg) ? 1 : 0) <= 5)
{
Contract.logger.LogWarning("1 part salvaged");
this.SalvageResults.Add(this.CreateMechPart(constants, mech));
}
foreach (MechComponentRef mechComponentRef in mech.Inventory)
{
if (!mech.IsLocationDestroyed(mechComponentRef.MountedLocation) && mechComponentRef.DamageLevel != ComponentDamageLevel.Destroyed)
{
this.AddToFinalSalvage(new SalvageDef
{
MechComponentDef = mechComponentRef.Def,
Description = new DescriptionDef(mechComponentRef.Def.Description),
RewardID = this.GenerateRewardUID(),
Type = SalvageDef.SalvageType.COMPONENT,
ComponentType = mechComponentRef.Def.ComponentType,
Damaged = false,
Count = 1
});
}
}
}
}
int j = 0;
while (j < enemyMechs.Count)
{
MechDef mech2 = enemyMechs[j].mech;
Pilot pilot = enemyMechs[j].pilot;
SalvageDef salvageDef = null;
bool flag2 = false;
bool flag3 = false;
if ((mech2.IsLocationDestroyed(ChassisLocations.Head) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.CenterTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftArm) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightArm) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftLeg) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightLeg) ? 1 : 0) <= 1)
{
this.CreateAndAddMechPart(constants, mech2, 3, this.finalPotentialSalvage);
goto IL_623;
}
if ((mech2.IsLocationDestroyed(ChassisLocations.Head) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.CenterTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftArm) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightArm) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftLeg) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightLeg) ? 1 : 0) <= 3)
{
this.CreateAndAddMechPart(constants, mech2, 2, this.finalPotentialSalvage);
goto IL_623;
}
if ((mech2.IsLocationDestroyed(ChassisLocations.Head) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.CenterTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightTorso) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftArm) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightArm) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.LeftLeg) ? 1 : 0) + (mech2.IsLocationDestroyed(ChassisLocations.RightLeg) ? 1 : 0) <= 5)
{
this.CreateAndAddMechPart(constants, mech2, 1, this.finalPotentialSalvage);
goto IL_623;
}
Would you play with these changes? Do they make sense? Any feedback is welcome and appreciated.
Last edited: