Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AP factors #3134

Merged
merged 12 commits into from
Jun 11, 2024
2 changes: 2 additions & 0 deletions Languages/English/Keyed/Keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@
<CE_degrees>&#176;</CE_degrees>
<CE_meters>m</CE_meters>
<CE_WeaponPenetrationFactor>Weapon penetration factor</CE_WeaponPenetrationFactor>
<CE_WeaponPenetrationSkillFactor>Skill factor</CE_WeaponPenetrationSkillFactor>
<CE_WeaponPenetrationOtherFactors>Other factors</CE_WeaponPenetrationOtherFactors>
<CE_AdjustedForWeapon>Adjusted for weapon</CE_AdjustedForWeapon>
<CE_DPS>Damage per second</CE_DPS>
<CE_DamageVariation>Damage variation</CE_DamageVariation>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,15 @@ public override string GetExplanationUnfinalized(StatRequest req, ToStringNumber
}
var stringBuilder = new StringBuilder();
var penetrationFactor = GetPenetrationFactor(req);
var skillFactor = GetSkillFactor(req);
stringBuilder.AppendLine("CE_WeaponPenetrationFactor".Translate() + ": " + penetrationFactor.ToStringByStyle(ToStringStyle.PercentZero));
if (Mathf.Abs(skillFactor - 1f) > 0.001f)
{
stringBuilder.AppendLine("CE_WeaponPenetrationSkillFactor".Translate() + ": " + skillFactor.ToStringByStyle(ToStringStyle.PercentZero));
}

stringBuilder.AppendLine();

foreach (ToolCE tool in tools)
{
var maneuvers = DefDatabase<ManeuverDef>.AllDefsListForReading.Where(d => tool.capacities.Contains(d.requiredCapacity));
Expand All @@ -37,19 +44,44 @@ public override string GetExplanationUnfinalized(StatRequest req, ToStringNumber
maneuverString += maneuver.ToString() + "/";
}
maneuverString = maneuverString.TrimmedToLength(maneuverString.Length - 1) + ")";

stringBuilder.AppendLine(" " + "Tool".Translate() + ": " + tool.ToString() + " " + maneuverString);
stringBuilder.AppendLine(string.Format(" {0}: {1} x {2} = {3} {4}",
var otherFactors = GetOtherFactors(req).Aggregate(1f, (x, y) => x * y);
if (Mathf.Abs(otherFactors - 1f) > 0.001f)
{
stringBuilder.AppendLine(" " + "CE_WeaponPenetrationOtherFactors".Translate() + ": " + otherFactors.ToStringByStyle(ToStringStyle.PercentZero));
}

stringBuilder.Append(string.Format(" {0}: {1} x {2}",
"CE_DescSharpPenetration".Translate(),
tool.armorPenetrationSharp.ToStringByStyle(ToStringStyle.FloatMaxTwo),
penetrationFactor.ToStringByStyle(ToStringStyle.FloatMaxThree),
(tool.armorPenetrationSharp * penetrationFactor).ToStringByStyle(ToStringStyle.FloatMaxTwo),
"CE_mmRHA".Translate()));
stringBuilder.AppendLine(string.Format(" {0}: {1} x {2} = {3} {4}",
penetrationFactor.ToStringByStyle(ToStringStyle.FloatMaxThree)));
if (Mathf.Abs(skillFactor - 1f) > 0.001f)
{
stringBuilder.Append(string.Format(" x {0}", skillFactor.ToStringByStyle(ToStringStyle.FloatMaxTwo)));
}
if (Mathf.Abs(otherFactors - 1f) > 0.001f)
{
stringBuilder.Append(string.Format(" x {0}", otherFactors.ToStringByStyle(ToStringStyle.FloatMaxTwo)));
}
stringBuilder.AppendLine(string.Format(" = {0} {1}",
(tool.armorPenetrationSharp * penetrationFactor * skillFactor * otherFactors).ToStringByStyle(ToStringStyle.FloatMaxTwo),
"CE_mmRHA".Translate()));


stringBuilder.Append(string.Format(" {0}: {1} x {2}",
"CE_DescBluntPenetration".Translate(),
tool.armorPenetrationBlunt.ToStringByStyle(ToStringStyle.FloatMaxTwo),
penetrationFactor.ToStringByStyle(ToStringStyle.FloatMaxThree),
(tool.armorPenetrationBlunt * penetrationFactor).ToStringByStyle(ToStringStyle.FloatMaxTwo),
penetrationFactor.ToStringByStyle(ToStringStyle.FloatMaxThree)));
if (Mathf.Abs(skillFactor - 1f) > 0.001f)
{
stringBuilder.Append(string.Format(" x {0}", skillFactor.ToStringByStyle(ToStringStyle.FloatMaxTwo)));
}
if (Mathf.Abs(otherFactors - 1f) > 0.001f)
{
stringBuilder.Append(string.Format(" x {0}", otherFactors.ToStringByStyle(ToStringStyle.FloatMaxTwo)));
}
stringBuilder.AppendLine(string.Format(" = {0} {1}",
(tool.armorPenetrationBlunt * penetrationFactor * skillFactor * otherFactors).ToStringByStyle(ToStringStyle.FloatMaxTwo),
"CE_MPa".Translate()));
stringBuilder.AppendLine();
}
Expand Down Expand Up @@ -84,14 +116,16 @@ private string GetFinalDisplayValue(StatRequest optionalReq)
foreach (ToolCE tool in tools)
{
var weightFactor = tool.chanceFactor / totalSelectionWeight;
totalAveragePenSharp += weightFactor * tool.armorPenetrationSharp;
totalAveragePenBlunt += weightFactor * tool.armorPenetrationBlunt;
var otherFactors = GetOtherFactors(optionalReq).Aggregate(1f, (x, y) => x * y);
totalAveragePenSharp += weightFactor * tool.armorPenetrationSharp * otherFactors;
totalAveragePenBlunt += weightFactor * tool.armorPenetrationBlunt * otherFactors;
}
var penetrationFactor = GetPenetrationFactor(optionalReq);
var skillFactor = GetSkillFactor(optionalReq);

return (totalAveragePenSharp * penetrationFactor).ToStringByStyle(ToStringStyle.FloatMaxTwo) + " " + "CE_mmRHA".Translate()
return (totalAveragePenSharp * penetrationFactor * skillFactor).ToStringByStyle(ToStringStyle.FloatMaxTwo) + " " + "CE_mmRHA".Translate()
+ ", "
+ (totalAveragePenBlunt * penetrationFactor).ToStringByStyle(ToStringStyle.FloatMaxTwo) + " " + "CE_MPa".Translate();
+ (totalAveragePenBlunt * penetrationFactor * skillFactor).ToStringByStyle(ToStringStyle.FloatMaxTwo) + " " + "CE_MPa".Translate();
}

private float GetPenetrationFactor(StatRequest req)
Expand All @@ -109,6 +143,33 @@ private float GetPenetrationFactor(StatRequest req)
}
return penetrationFactor;
}

public const float skillFactorPerLevel = (25f / 19f) / 100f;
public const float powerForOtherFactors = 0.75f;
private float GetSkillFactor(StatRequest req)
{
var skillFactor = 1f;
if (req.Thing is Pawn pawn && pawn.skills != null)
{
skillFactor += skillFactorPerLevel * (pawn.skills.GetSkill(SkillDefOf.Melee).Level - 1);
}
else
{
var thingHolder = (req.Thing?.ParentHolder as Pawn_EquipmentTracker)?.pawn;
if (thingHolder != null && thingHolder.skills != null)
{
skillFactor += skillFactorPerLevel * (thingHolder.skills.GetSkill(SkillDefOf.Melee).Level - 1);
}
}
return skillFactor;
}
private IEnumerable<float> GetOtherFactors(StatRequest req)
{
var pawn = req.Thing as Pawn ?? (req.Thing?.ParentHolder as Pawn_EquipmentTracker)?.pawn;
if (pawn != null)
{
yield return Mathf.Pow(pawn.ageTracker.CurLifeStage.meleeDamageFactor, powerForOtherFactors);
yield return Mathf.Pow(pawn.GetStatValue(StatDefOf.MeleeDamageFactor, true, -1), powerForOtherFactors);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ public static Verb_MeleeAttackCE LastAttackVerb
private set;
}

public float ArmorPenetrationSharp => (tool as ToolCE)?.armorPenetrationSharp * (EquipmentSource?.GetStatValue(CE_StatDefOf.MeleePenetrationFactor) ?? 1) ?? 0;
public float ArmorPenetrationBlunt => (tool as ToolCE)?.armorPenetrationBlunt * (EquipmentSource?.GetStatValue(CE_StatDefOf.MeleePenetrationFactor) ?? 1) ?? 0;
protected virtual float PenetrationSkillMultiplier => 1f + (CasterPawn?.skills?.GetSkill(SkillDefOf.Melee).Level ?? 1 - 1) * StatWorker_MeleeArmorPenetration.skillFactorPerLevel;
protected virtual float PenetrationOtherMultipliers => CasterIsPawn ? Mathf.Pow(this.verbProps.GetDamageFactorFor(this, CasterPawn), StatWorker_MeleeArmorPenetration.powerForOtherFactors) : 1f;
public float ArmorPenetrationSharp => (tool as ToolCE)?.armorPenetrationSharp * PenetrationOtherMultipliers * PenetrationSkillMultiplier * (EquipmentSource?.GetStatValue(CE_StatDefOf.MeleePenetrationFactor) ?? 1) ?? 0;
public float ArmorPenetrationBlunt => (tool as ToolCE)?.armorPenetrationBlunt * PenetrationOtherMultipliers * PenetrationSkillMultiplier * (EquipmentSource?.GetStatValue(CE_StatDefOf.MeleePenetrationFactor) ?? 1) ?? 0;

public bool Enabled
{
Expand Down
Loading