Skip to content
This repository has been archived by the owner on Apr 14, 2020. It is now read-only.

Commit

Permalink
Implemented smoke into CE shooting mechanics (#216)
Browse files Browse the repository at this point in the history
Each tile of smoke on the LoS between shooter and target now contributes to visibility error. Smokepop belts now correctly activate when wearer is shot with CE weapon.
  • Loading branch information
NoImageAvailable authored Jun 4, 2017
1 parent 11d0ebc commit fe6c85d
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 19 deletions.
Binary file modified Assemblies/CombatExtended.dll
Binary file not shown.
1 change: 1 addition & 0 deletions Languages/English/Keyed/Keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
<CE_MarkedForArtillery>Marked for artillery, expires in</CE_MarkedForArtillery>

<CE_VisibilityError>Visibility error</CE_VisibilityError>
<CE_SmokeDensity>Smoke</CE_SmokeDensity>
<CE_LeadError>Lead error</CE_LeadError>
<CE_RangeError>Range error</CE_RangeError>
<CE_Sway>Sway</CE_Sway>
Expand Down
7 changes: 7 additions & 0 deletions Patches/Core/ThingDefs_Buildings/Buildings_Security.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@

<!-- ========== Sandbags ========== -->

<Operation Class="PatchOperationReplace">
<xpath>*/ThingDef[defName="Sandbags"]/costList/Steel</xpath>
<value>
<Steel>2</Steel>
</value>
</Operation>

<Operation Class="PatchOperationReplace">
<xpath>*/ThingDef[defName="Sandbags"]/fillPercent</xpath>
<value>
Expand Down
2 changes: 1 addition & 1 deletion Patches/Core/ThingDefs_Misc/Weapons_Grenades.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
<projectile>
<explosionRadius>1.5</explosionRadius>
<damageDef>Bomb</damageDef>
<damageAmountBase>80</damageAmountBase>
<damageAmountBase>50</damageAmountBase>
<explosionDelay>60</explosionDelay>
<dropsCasings>true</dropsCasings>
<casingMoteDefname>Mote_GrenadePin</casingMoteDefname>
Expand Down
2 changes: 2 additions & 0 deletions Source/CombatExtended/CombatExtended.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,12 @@
<Compile Include="Harmony\Harmony-HediffComp_TendDuration.cs" />
<Compile Include="Harmony\Harmony-HediffWithComps.cs" />
<Compile Include="Harmony\Harmony-Hediff_MissingPart.cs" />
<Compile Include="Harmony\Harmony-JobDriverWait.cs" />
<Compile Include="Harmony\Harmony-JobGiver_UnloadYourInventory.cs" />
<Compile Include="Harmony\Harmony-MassUtility.cs" />
<Compile Include="Harmony\Harmony-Pawn_EquipmentTracker.cs" />
<Compile Include="Harmony\Harmony-Pawn_HealthTracker.cs" />
<Compile Include="Harmony\Harmony-SmokepopBelt.cs" />
<Compile Include="Harmony\Harmony-ThingOwner.cs" />
<Compile Include="Harmony\Harmony-TooltipUtility.cs" />
<Compile Include="Harmony\Harmony-TradeDeal.cs" />
Expand Down
2 changes: 1 addition & 1 deletion Source/CombatExtended/CombatExtended/ArmorUtilityCE.cs
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ public static void ApplyParryDamage(DamageInfo dinfo, Thing parryThing)
}
else
{
float dmgAmount = dinfo.Amount;
float dmgAmount = dinfo.Amount * 0.5f;
float penAmount = GetPenetrationValue(dinfo);
TryPenetrateArmor(dinfo.Def, parryThing.GetStatValue(dinfo.Def.armorCategory.deflectionStat), ref penAmount, ref dmgAmount, parryThing);
}
Expand Down
8 changes: 7 additions & 1 deletion Source/CombatExtended/CombatExtended/ShiftVecReport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public float visibilityShift
{
if (visibilityShiftInt < 0)
{
visibilityShiftInt = (lightingShift + weatherShift) * (shotDist / 50) * (2 - aimingAccuracy);
visibilityShiftInt = (lightingShift + weatherShift + smokeDensity) * (shotDist / 50) * (2 - aimingAccuracy);
}
return visibilityShiftInt;
}
Expand Down Expand Up @@ -105,6 +105,7 @@ public float distShift
public float swayDegrees = 0f;
public float spreadDegrees = 0f;
public Thing cover = null;
public float smokeDensity = 0f;

// Copy-constructor
public ShiftVecReport(ShiftVecReport report)
Expand All @@ -121,6 +122,7 @@ public ShiftVecReport(ShiftVecReport report)
swayDegrees = report.swayDegrees;
spreadDegrees = report.spreadDegrees;
cover = report.cover;
smokeDensity = report.smokeDensity;
}

public ShiftVecReport()
Expand Down Expand Up @@ -176,6 +178,10 @@ public string GetTextReadout()
{
stringBuilder.AppendLine(" " + "Weather".Translate() + "\t" + AsPercent(weatherShift));
}
if (smokeDensity > 0)
{
stringBuilder.AppendLine(" " + "CE_SmokeDensity".Translate() + "\t" + AsPercent(smokeDensity));
}
}
if (leadShift > 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,10 @@ public virtual ShiftVecReport ShiftVecReportFor(LocalTargetInfo target)
report.swayDegrees = this.SwayAmplitude;
report.spreadDegrees = this.ownerEquipment.GetStatValue(StatDef.Named("ShotSpread")) * this.projectilePropsCE.spreadMult;
Thing cover;
this.GetHighestCoverForTarget(target, out cover);
float smokeDensity;
this.GetHighestCoverAndSmokeForTarget(target, out cover, out smokeDensity);
report.cover = cover;
report.smokeDensity = smokeDensity;

return report;
}
Expand All @@ -355,14 +357,16 @@ public virtual ShiftVecReport ShiftVecReportFor(LocalTargetInfo target)
/// <param name="target">The target of which to find cover of</param>
/// <param name="cover">Output parameter, filled with the highest cover object found</param>
/// <returns>True if cover was found, false otherwise</returns>
private bool GetHighestCoverForTarget(LocalTargetInfo target, out Thing cover)
private bool GetHighestCoverAndSmokeForTarget(LocalTargetInfo target, out Thing cover, out float smokeDensity)
{
Map map = caster.Map;
Thing targetThing = target.Thing;
Thing highestCover = null;
float highestCoverHeight = 0f;

// Iterate through all cells on second half of line of sight and check for cover
smokeDensity = 0;

// Iterate through all cells on line of sight and check for cover and smoke
var cells = GenSight.PointsOnLineOfSight(target.Cell, caster.Position).ToArray();
if (cells.Length < 3)
{
Expand All @@ -375,20 +379,31 @@ private bool GetHighestCoverForTarget(LocalTargetInfo target, out Thing cover)

if (cell.AdjacentTo8Way(caster.Position)) continue;

Pawn pawn = cell.GetFirstPawn(map);
Thing newCover = pawn == null ? cell.GetCover(map) : pawn;
float newCoverHeight = new CollisionVertical(newCover).Max;

// Cover check, if cell has cover compare collision height and get the highest piece of cover, ignore if cover is the target (e.g. solar panels, crashed ship, etc)
if (newCover != null
&& (targetThing == null || !newCover.Equals(targetThing))
&& (highestCover == null || highestCoverHeight < newCoverHeight)
&& newCover.def.Fillage == FillCategory.Partial
&& !newCover.IsTree())
// Check for smoke
var gas = cell.GetGas(map);
if (gas != null)
{
smokeDensity += gas.def.gas.accuracyPenalty;
}

// Check for cover in the second half of LoS
if (i <= cells.Length / 2)
{
highestCover = newCover;
highestCoverHeight = newCoverHeight;
if (Controller.settings.DebugDrawTargetCoverChecks) map.debugDrawer.FlashCell(cell, highestCoverHeight, highestCoverHeight.ToString());
Pawn pawn = cell.GetFirstPawn(map);
Thing newCover = pawn == null ? cell.GetCover(map) : pawn;
float newCoverHeight = new CollisionVertical(newCover).Max;

// Cover check, if cell has cover compare collision height and get the highest piece of cover, ignore if cover is the target (e.g. solar panels, crashed ship, etc)
if (newCover != null
&& (targetThing == null || !newCover.Equals(targetThing))
&& (highestCover == null || highestCoverHeight < newCoverHeight)
&& newCover.def.Fillage == FillCategory.Partial
&& !newCover.IsTree())
{
highestCover = newCover;
highestCoverHeight = newCoverHeight;
if (Controller.settings.DebugDrawTargetCoverChecks) map.debugDrawer.FlashCell(cell, highestCoverHeight, highestCoverHeight.ToString());
}
}
}
cover = highestCover;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace CombatExtended.Harmony
{
// FIXME: Destructive detour
[HarmonyPatch(typeof(Hediff_MissingPart))]
[HarmonyPatch("IsFreshNonSolidExtremity", PropertyMethod.Getter)]
static class Harmony_Hediff_MissingPart_IsFresh_Patch
Expand Down
31 changes: 31 additions & 0 deletions Source/CombatExtended/Harmony/Harmony-SmokepopBelt.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RimWorld;
using Verse;
using UnityEngine;
using Harmony;

namespace CombatExtended.Harmony
{
// FIXME: Destructive detour
[HarmonyPatch(typeof(SmokepopBelt), "CheckPreAbsorbDamage")]
static class Harmony_SmokepopBelt
{
public static bool Prefix(SmokepopBelt __instance, DamageInfo dinfo)
{
if (!dinfo.Def.isExplosive
&& dinfo.Def.harmsHealth
&& dinfo.Def.externalViolence
&& dinfo.WeaponGear != null
&& (dinfo.WeaponGear.IsRangedWeapon || dinfo.WeaponGear.projectile is ProjectilePropertiesCE)) // Add a check for CE projectiles since we're using them as weaponGear to pass data to our ArmorUtility
{
ThingDef gas_Smoke = ThingDefOf.Gas_Smoke;
GenExplosion.DoExplosion(__instance.Wearer.Position, __instance.Wearer.Map, __instance.GetStatValue(StatDefOf.SmokepopBeltRadius, true), DamageDefOf.Smoke, null, null, null, null, gas_Smoke, 1f, 1, false, null, 0f, 1);
__instance.Destroy(DestroyMode.Vanish);
}
return false;
}
}
}

0 comments on commit fe6c85d

Please sign in to comment.