Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Defs/GameSetupSteps/SubsequentShotCurve.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<Defs>

<GameSetupStepDef>
<defName>CE_SubsequentShotCurve</defName>
<order>1000</order>
<setupStep Class="CombatExtended.GameSetupStep_SubsequentShotCurve">
<defaultSubsequentShotCurve>
<!-- (recoil accumulated this burst / subsequent shot aim time multipler) -->
<points>
<li>(0, 0)</li><!--laser-->
<li>(1.5, 0.60)</li><!--m16 single shot-->
<li>(1.9, 0.80)</li><!--fal single-->
<li>(13.0, 0.95)</li><!--fal auto cyborg-->
<li>(17.0, 1.0)</li><!--fal auto 0 skill-->
</points>
</defaultSubsequentShotCurve>
</setupStep>
</GameSetupStepDef>
</Defs>
3 changes: 3 additions & 0 deletions Languages/English/Keyed/ModMenu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@
<CE_Settings_FragmentsFromWallsIntensity_Desc>Controls how many wall fragments will spawn and how big they will be.</CE_Settings_FragmentsFromWallsIntensity_Desc>
<CE_Settings_FragmentsFromWallsIntensity_Title>Fragments from walls intensity</CE_Settings_FragmentsFromWallsIntensity_Title>

<CE_Settings_FasterRepeatShotsMultiplier_Desc>Controls how fast subsequent shot bonuses will accumulate.</CE_Settings_FasterRepeatShotsMultiplier_Desc>
<CE_Settings_FasterRepeatShotsMultiplier_Title>Subsequent shot difficulty</CE_Settings_FasterRepeatShotsMultiplier_Title>

<CE_Settings_FasterRepeatShots_Desc>When enabled, subsequent shots at the same, or nearby, targets are faster.</CE_Settings_FasterRepeatShots_Desc>
<CE_Settings_FasterRepeatShots_Title>Faster subsequent shots</CE_Settings_FasterRepeatShots_Title>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Verse;

namespace CombatExtended;

public class GameSetupStep_SubsequentShotCurve : GameSetupStep
{
public SimpleCurve defaultSubsequentShotCurve;

public override int SeedPart => 58224852; // unused, but required

public override void GenerateFresh()
{
Verb_ShootCE.SubsequentShotCurve = defaultSubsequentShotCurve;
}

public override void GenerateFromScribe()
{
Verb_ShootCE.SubsequentShotCurve = defaultSubsequentShotCurve;
}
}
13 changes: 12 additions & 1 deletion Source/CombatExtended/CombatExtended/ModSettings/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class Settings : ModSettings, ISettingsCE

private bool midBurstRetarget = true;
private bool fasterRepeatShots = true;
private float fasterRepeatShotsRecoilMult = 1.0f;

private float explosionPenMultiplier = 1.0f;
private float explosionFalloffFactor = 1.0f;
Expand Down Expand Up @@ -121,6 +122,7 @@ public class Settings : ModSettings, ISettingsCE
private bool debugDisplayCellCoverRating = false;
private bool debugDisplayAttritionInfo = false;
private bool debugWorldShellingDamageRandomness = false;
private bool debugSubsequentShotLogging = false;

public bool DebuggingMode => debuggingMode;
public bool DebugVerbose => debugVerbose;
Expand All @@ -136,6 +138,7 @@ public class Settings : ModSettings, ISettingsCE
public bool DebugDisplayCellCoverRating => debugDisplayCellCoverRating && debuggingMode;
public bool DebugDisplayAttritionInfo => debugDisplayAttritionInfo && debuggingMode;
public bool DebugWorldShellingDamageRandomness => debugWorldShellingDamageRandomness && debuggingMode;
public bool DebugSubsequentShotLogging => debugSubsequentShotLogging && debuggingMode;
#endregion

#region Autopatcher
Expand All @@ -160,6 +163,7 @@ public class Settings : ModSettings, ISettingsCE
public float FragmentsFromWallsIntensity => fragmentsFromWallsIntensity;

public bool FasterRepeatShots => fasterRepeatShots;
public float FasterRepeatShotsRecoilMult => fasterRepeatShotsRecoilMult;
public bool MidBurstRetarget => midBurstRetarget;

public float ExplosionPenMultiplier => explosionPenMultiplier;
Expand Down Expand Up @@ -220,6 +224,7 @@ public override void ExposeData()
Scribe_Values.Look(ref debugDisplayCellCoverRating, "debugDisplayCellCoverRating", false);
Scribe_Values.Look(ref debugDisplayAttritionInfo, "debugDisplayAttritionInfo", false);
Scribe_Values.Look(ref debugWorldShellingDamageRandomness, "debugWorldShellingDamageRandomness", false);
Scribe_Values.Look(ref debugSubsequentShotLogging, "debugSubsequentShotLogging", false);
Scribe_Values.Look(ref debugGenClosetPawn, "debugGenClosetPawn", false);
Scribe_Values.Look(ref debugVerbose, "debugVerbose", false);
Scribe_Values.Look(ref debugMuzzleFlash, "debugMuzzleFlash", false);
Expand Down Expand Up @@ -256,6 +261,7 @@ public override void ExposeData()
Scribe_Values.Look(ref fragmentsFromWallsReflected, "fragmentsFromWallsReflected", false);
Scribe_Values.Look(ref fragmentsFromWallsIntensity, "fragmentsFromWallsIntensity", 1.0f);
Scribe_Values.Look(ref fasterRepeatShots, "fasterRepeatShots", false);
Scribe_Values.Look(ref fasterRepeatShotsRecoilMult, "fasterRepeatShotsRecoilMult", 1.0f);
Scribe_Values.Look(ref midBurstRetarget, "midBurstRetarget", true);
Scribe_Values.Look(ref explosionPenMultiplier, "explosionPenMultiplier", 1.0f);
Scribe_Values.Look(ref explosionFalloffFactor, "explosionFalloffFactor", 1.0f);
Expand Down Expand Up @@ -305,7 +311,6 @@ private void DoSettingsWindowContents_Mechanics(Listing_Standard list)
left.CheckboxLabeled("CE_Settings_AllowMeleeHunting_Title".Translate(), ref allowMeleeHunting, "CE_Settings_AllowMeleeHunting_Desc".Translate());
left.CheckboxLabeled("CE_Settings_SmokeEffects_Title".Translate(), ref smokeEffects, "CE_Settings_SmokeEffects_Desc".Translate());
left.CheckboxLabeled("CE_Settings_TurretsBreakShields_Title".Translate(), ref turretsBreakShields, "CE_Settings_TurretsBreakShields_Desc".Translate());
left.CheckboxLabeled("CE_Settings_FasterRepeatShots_Title".Translate(), ref fasterRepeatShots, "CE_Settings_FasterRepeatShots_Desc".Translate());
left.CheckboxLabeled("CE_Settings_MidBurstRetarget_Title".Translate(), ref midBurstRetarget, "CE_Settings_MidBurstRetarget_Desc".Translate());
left.CheckboxLabeled("CE_Settings_EnableArcOfFire_Title".Translate(), ref enableArcOfFire, "CE_Settings_EnableArcOfFire_Desc".Translate());
left.CheckboxLabeled("CE_Settings_EnableCIWS".Translate(), ref enableCIWS, "CE_Settings_EnableCIWS_Desc".Translate());
Expand Down Expand Up @@ -333,6 +338,9 @@ private void DoSettingsWindowContents_Mechanics(Listing_Standard list)
right.Label("CE_Settings_StabilizationSettings".Translate());
right.Gap();
medicineSearchRadius = right.SliderLabeled("CE_Settings_MedicineSearchRadius_Title".Translate() + ": " + medicineSearchRadius.ToString("F0"), medicineSearchRadius, 1f, 100f, tooltip: "CE_Settings_MedicineSearchRadius_Desc".Translate(), labelPct: 0.6f);
right.GapLine();
left.CheckboxLabeled("CE_Settings_FasterRepeatShots_Title".Translate(), ref fasterRepeatShots, "CE_Settings_FasterRepeatShots_Desc".Translate());
fasterRepeatShotsRecoilMult = left.SliderLabeled("CE_Settings_FasterRepeatShotsMultiplier_Title".Translate() + ": " + fasterRepeatShotsRecoilMult.ToString("F1"), fasterRepeatShotsRecoilMult, 0.1f, 3f, tooltip: "CE_Settings_FasterRepeatShotsMultiplier_Desc".Translate(), labelPct: 0.6f);
right.End();
}

Expand Down Expand Up @@ -435,6 +443,7 @@ private void DoSettingsWindowContents_Misc(Listing_Standard list)
list.CheckboxLabeled("Display danger buildup within cells", ref debugDisplayDangerBuildup);
list.CheckboxLabeled("Display cover rating of cells of suppressed pawns", ref debugDisplayCellCoverRating);
list.CheckboxLabeled("Disable randomness in world shelling", ref debugWorldShellingDamageRandomness);
list.CheckboxLabeled("Log subsequent shot calculations", ref debugSubsequentShotLogging);
}
#endif
list.Gap();
Expand Down Expand Up @@ -499,6 +508,7 @@ private void ResetToDefault_Mechanics()
smokeEffects = true;
turretsBreakShields = true;
fasterRepeatShots = true;
fasterRepeatShotsRecoilMult = 1.0f;
midBurstRetarget = true;
enableCIWS = true;
fragmentsFromWalls = false;
Expand Down Expand Up @@ -567,6 +577,7 @@ private void ResetToDefault_Misc()
debugDisplayDangerBuildup = false;
debugDisplayCellCoverRating = false;
debugWorldShellingDamageRandomness = false;
debugSubsequentShotLogging = false;
#endif
}
#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ private void GetRecoilVec(ref float rotation, ref float angle)
rotation += recoilMagnitude * Rand.Range(minX, maxX);
var trd = Rand.Range(minY, maxY);
angle += recoilMagnitude * Mathf.Deg2Rad * trd;
lastRecoilDeg += nextRecoilMagnitude * trd;
lastRecoilDeg += nextRecoilMagnitude * recoil; //always store non-randomized max recoil for subsequent shot purposes
}

/// <summary>
Expand Down Expand Up @@ -1083,7 +1083,7 @@ public override bool TryCastShot()
didRetarget = Retarget();
repeating = true;
doRetarget = true;
storedShotReduction = null;

var props = VerbPropsCE;
var midBurst = numShotsFired > 0;
var suppressing = CompFireModes?.CurrentAimMode == AimMode.SuppressFire;
Expand Down
29 changes: 23 additions & 6 deletions Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public class Verb_ShootCE : Verb_LaunchProjectileCE

public Vector3 drawPos;

internal static SimpleCurve SubsequentShotCurve = new SimpleCurve(); // Populated on game start from a SetupStepDef

#endregion

#region Properties
Expand Down Expand Up @@ -327,13 +329,28 @@ public override void RecalculateWarmupTicks()

var d = v - u;
var newShotRotation = (-90 + Mathf.Rad2Deg * Mathf.Atan2(d.z, d.x)) % 360;
var delta = Mathf.Abs(newShotRotation - lastShotRotation) + lastRecoilDeg;
var delta = Mathf.Abs(newShotRotation - lastShotRotation);

//max possible reduction for this weapon
float maxReduction = CompFireModes?.CurrentAimMode == AimMode.SuppressFire ? 0.1f : _isAiming ? 0.5f : 0.25f;
maxReduction += RecoilAmount * RecoilAmount * 0.1f;

//current reduction after pawn stats
float reduction = (delta / 45f) + (SubsequentShotCurve.Evaluate(lastRecoilDeg) * Controller.settings.FasterRepeatShotsRecoilMult);

if (storedShotReduction != null)
{
reduction *= (float)storedShotReduction;
}

reduction = Mathf.Max(maxReduction, reduction);
if (Controller.settings.DebugSubsequentShotLogging)
{
Log.Message($"{caster?.LabelShort} ({EquipmentSource?.LabelShort}) subsequent shot:\nreduction {reduction}; storedShotReduction {storedShotReduction}; maxReduction {maxReduction}; lastRecoilDeg {lastRecoilDeg}; delta {delta}; delta/45 {delta / 45f}");
}

lastRecoilDeg = 0;
var maxReduction = storedShotReduction ?? (CompFireModes?.CurrentAimMode == AimMode.SuppressFire ?
0.1f :
(_isAiming ? 0.5f : 0.25f));
var reduction = Mathf.Max(maxReduction, delta / 45f);
storedShotReduction = reduction;
storedShotReduction = Mathf.Clamp01(reduction);

if (reduction < 1.0f)
{
Expand Down