From 685accb05c769bb05d26ade768621563246a07ef Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 11 Oct 2023 03:21:20 +0600 Subject: [PATCH 01/19] Now it's checks for enemies inside shields --- .../CombatExtended/SuppressionUtility.cs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/SuppressionUtility.cs b/Source/CombatExtended/CombatExtended/SuppressionUtility.cs index d190764a49..a3ce43306f 100644 --- a/Source/CombatExtended/CombatExtended/SuppressionUtility.cs +++ b/Source/CombatExtended/CombatExtended/SuppressionUtility.cs @@ -203,15 +203,9 @@ private static float GetCellCoverRatingForPawn(Pawn pawn, IntVec3 cell, IntVec3 cellRating += 10f - (bonusCellRating * 10f); - for (int i = 0; i < interceptors.Count; i++) - { - CompProjectileInterceptor interceptor = interceptors[i]; - if (interceptor.Active && interceptor.parent.Position.DistanceTo(cell) < interceptor.Props.radius) - { - cellRating += 15f; - } - } - + // If the cell is covered by a shield and there are no enemies inside, then increases by 15 (for each such shield) + cellRating += InterceptorZonesFor(pawn).Where(x => !IsOccupiedByEnemies(x, pawn)).Count(x => x.Contains(cell)) * 15; + // Avoid bullets and other danger sources; // Yet do not discard cover that is extremely good, even if it may be dangerous float dangerAmount = dangerTracker.DangerAt(cell) * DangerTracker.DANGER_TICKS_MAX; @@ -246,7 +240,14 @@ private static float GetCellCoverRatingForPawn(Pawn pawn, IntVec3 cell, IntVec3 } return cellRating; } - + private static IEnumerable> InterceptorZonesFor(Pawn pawn) + { + return interceptors.Where(x => x.Active).Select(x => GenRadial.RadialCellsAround(x.parent.Position, x.Props.radius, true)); + } + private static bool IsOccupiedByEnemies(IEnumerable cells, Pawn pawn) + { + return cells.Any(cell => pawn.Map.thingGrid.ThingsListAt(cell).Any(thing => (thing.HostileTo(pawn)))); + } private static float GetCoverRating(Thing cover) { // Higher values mean more effective at being considered cover. From ff66c4d42f59d98aedf6837b207af37cfca00f6e Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 11 Oct 2023 04:22:03 +0600 Subject: [PATCH 02/19] Ignore suppresion if origin is outside of shield --- .../CombatExtended/Comps/CompSuppressable.cs | 4 ++++ .../CombatExtended/Projectiles/ProjectileCE.cs | 3 ++- .../CombatExtended/SuppressionUtility.cs | 10 +++++----- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs b/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs index b50014a225..0cd6e26ce7 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs @@ -243,6 +243,10 @@ public void AddSuppression(float amount, IntVec3 origin) } } } + public bool IgnoreSuppresion(IntVec3 origin) + { + return SuppressionUtility.InterceptorZonesFor((Pawn)parent).Where(x=>x.Contains(parent.Position)).Any(x=>!x.Contains(origin)); + } public override void CompTick() { diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 87b36d30df..a57b6a7dda 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -1023,7 +1023,8 @@ protected void ApplySuppression(Pawn pawn, float suppressionMultiplier = 1f) var compSuppressable = pawn.TryGetComp(); if (compSuppressable != null && pawn.Faction != launcher?.Faction - && (shield == null || shield.ShieldState == ShieldState.Resetting)) + && (shield == null || shield.ShieldState == ShieldState.Resetting) + && !compSuppressable.IgnoreSuppresion(OriginIV3)) { suppressionAmount = def.projectile.damageAmountBase * suppressionMultiplier; diff --git a/Source/CombatExtended/CombatExtended/SuppressionUtility.cs b/Source/CombatExtended/CombatExtended/SuppressionUtility.cs index a3ce43306f..4ba9d31a47 100644 --- a/Source/CombatExtended/CombatExtended/SuppressionUtility.cs +++ b/Source/CombatExtended/CombatExtended/SuppressionUtility.cs @@ -23,7 +23,7 @@ public static class SuppressionUtility private static DangerTracker dangerTracker; - private static List interceptors; + private static IEnumerable Interceptors(Thing pawn) => pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.ProjectileInterceptor).Select(t => t.TryGetComp()); public static bool TryRequestHelp(Pawn pawn) { @@ -91,7 +91,7 @@ private static bool GetCoverPositionFrom(Pawn pawn, IntVec3 fromPosition, float { List cellList = new List(GenRadial.RadialCellsAround(pawn.Position, maxDist, true)); IntVec3 bestPos = pawn.Position; - interceptors = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.ProjectileInterceptor).Select(t => t.TryGetComp()).ToList(); + //interceptors = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.ProjectileInterceptor).Select(t => t.TryGetComp()).ToList(); lightingTracker = pawn.Map.GetLightingTracker(); dangerTracker = pawn.Map.GetDangerTracker(); @@ -205,7 +205,7 @@ private static float GetCellCoverRatingForPawn(Pawn pawn, IntVec3 cell, IntVec3 // If the cell is covered by a shield and there are no enemies inside, then increases by 15 (for each such shield) cellRating += InterceptorZonesFor(pawn).Where(x => !IsOccupiedByEnemies(x, pawn)).Count(x => x.Contains(cell)) * 15; - + // Avoid bullets and other danger sources; // Yet do not discard cover that is extremely good, even if it may be dangerous float dangerAmount = dangerTracker.DangerAt(cell) * DangerTracker.DANGER_TICKS_MAX; @@ -240,9 +240,9 @@ private static float GetCellCoverRatingForPawn(Pawn pawn, IntVec3 cell, IntVec3 } return cellRating; } - private static IEnumerable> InterceptorZonesFor(Pawn pawn) + public static IEnumerable> InterceptorZonesFor(Pawn pawn) { - return interceptors.Where(x => x.Active).Select(x => GenRadial.RadialCellsAround(x.parent.Position, x.Props.radius, true)); + return Interceptors(pawn).Where(x => x.Active).Select(x => GenRadial.RadialCellsAround(x.parent.Position, x.Props.radius, true)); } private static bool IsOccupiedByEnemies(IEnumerable cells, Pawn pawn) { From 31b9762101bc883918e023caca583ec8bad6ea0c Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 11 Oct 2023 14:15:55 +0600 Subject: [PATCH 03/19] Custom AOE-interceptors compatibility (+VPE as example/test target) --- .../CombatExtended/SuppressionUtility.cs | 9 +++++++- .../Compatibility/BlockerRegistry.cs | 21 +++++++++++++++++-- .../Compatibility/VanillaPsycastExpanded.cs | 6 ++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/SuppressionUtility.cs b/Source/CombatExtended/CombatExtended/SuppressionUtility.cs index 4ba9d31a47..dcd7dec781 100644 --- a/Source/CombatExtended/CombatExtended/SuppressionUtility.cs +++ b/Source/CombatExtended/CombatExtended/SuppressionUtility.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using CombatExtended.AI; +using CombatExtended.Compatibility; using CombatExtended.Utilities; using RimWorld; using UnityEngine; @@ -242,7 +243,13 @@ private static float GetCellCoverRatingForPawn(Pawn pawn, IntVec3 cell, IntVec3 } public static IEnumerable> InterceptorZonesFor(Pawn pawn) { - return Interceptors(pawn).Where(x => x.Active).Select(x => GenRadial.RadialCellsAround(x.parent.Position, x.Props.radius, true)); + var result = Interceptors(pawn).Where(x => x.Active).Select(x => GenRadial.RadialCellsAround(x.parent.Position, x.Props.radius, true)); + var compatibilityZones = BlockerRegistry.ShieldZonesCallback(pawn); + if (compatibilityZones != null) + { + result = result.Union(compatibilityZones); + } + return result; } private static bool IsOccupiedByEnemies(IEnumerable cells, Pawn pawn) { diff --git a/Source/CombatExtended/Compatibility/BlockerRegistry.cs b/Source/CombatExtended/Compatibility/BlockerRegistry.cs index ab526dff6d..6b3bb20a32 100644 --- a/Source/CombatExtended/Compatibility/BlockerRegistry.cs +++ b/Source/CombatExtended/Compatibility/BlockerRegistry.cs @@ -12,6 +12,7 @@ namespace CombatExtended.Compatibility public static class BlockerRegistry { private static bool enabled = false; + private static List>>> shieldZonesCallback; private static List> checkCellForCollisionCallbacks; private static List> impactSomethingCallbacks; @@ -20,6 +21,7 @@ private static void Enable() enabled = true; impactSomethingCallbacks = new List>(); checkCellForCollisionCallbacks = new List>(); + shieldZonesCallback = new List>>>(); } public static void RegisterCheckForCollisionCallback(Func f) @@ -40,6 +42,15 @@ public static void RegisterImpactSomethingCallback(Func>> f) + { + if (!enabled) + { + Enable(); + } + shieldZonesCallback.Add(f); + } + public static bool CheckCellForCollisionCallback(ProjectileCE projectile, IntVec3 cell, Thing launcher) { if (!enabled) @@ -55,7 +66,6 @@ public static bool CheckCellForCollisionCallback(ProjectileCE projectile, IntVec } return false; } - public static bool ImpactSomethingCallback(ProjectileCE projectile, Thing launcher) { if (!enabled) @@ -71,7 +81,14 @@ public static bool ImpactSomethingCallback(ProjectileCE projectile, Thing launch } return false; } - + public static IEnumerable> ShieldZonesCallback(Thing thing) + { + if (!enabled) + { + return null; + } + return shieldZonesCallback.SelectMany(cb => cb(thing)); + } public static Vector3 GetExactPosition(Vector3 origin, Vector3 curPosition, Vector3 shieldPosition, float radiusSq) { Vector3 velocity = curPosition - origin; diff --git a/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs b/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs index 70d8adfec6..6d2d58fc0d 100644 --- a/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs +++ b/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs @@ -28,6 +28,12 @@ public void Install() { BlockerRegistry.RegisterImpactSomethingCallback(ImpactSomething); BlockerRegistry.RegisterCheckForCollisionCallback(CheckIntercept); + BlockerRegistry.RegisterShieldZonesCallback(ShieldZones); + } + + private static IEnumerable> ShieldZones(Thing thing) + { + return thing.Map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn).Cast().SelectMany(x => x.health.hediffSet.hediffs).OfType().Select(x => GenRadial.RadialCellsAround(x.pawn.Position, x.OverlaySize, true)); } private static bool ImpactSomething(ProjectileCE projectile, Thing launcher) From a6f626edc748e97baec0b48b828a183726e28748 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 11 Oct 2023 14:33:36 +0600 Subject: [PATCH 04/19] Additional unsuppresable check (+VPE example/test target) --- .../CombatExtended/Comps/CompSuppressable.cs | 3 ++- .../Compatibility/BlockerRegistry.cs | 25 +++++++++++++++++++ .../Compatibility/VanillaPsycastExpanded.cs | 3 +++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs b/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs index 0cd6e26ce7..e00a3d39a9 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs @@ -7,6 +7,7 @@ using Verse.AI; using UnityEngine; using CombatExtended.AI; +using CombatExtended.Compatibility; namespace CombatExtended { @@ -245,7 +246,7 @@ public void AddSuppression(float amount, IntVec3 origin) } public bool IgnoreSuppresion(IntVec3 origin) { - return SuppressionUtility.InterceptorZonesFor((Pawn)parent).Where(x=>x.Contains(parent.Position)).Any(x=>!x.Contains(origin)); + return BlockerRegistry.PawnUnsuppresableFromCallback(parent as Pawn, origin) || SuppressionUtility.InterceptorZonesFor((Pawn)parent).Where(x=>x.Contains(parent.Position)).Any(x=>!x.Contains(origin)); } public override void CompTick() diff --git a/Source/CombatExtended/Compatibility/BlockerRegistry.cs b/Source/CombatExtended/Compatibility/BlockerRegistry.cs index 6b3bb20a32..9e69271ac7 100644 --- a/Source/CombatExtended/Compatibility/BlockerRegistry.cs +++ b/Source/CombatExtended/Compatibility/BlockerRegistry.cs @@ -15,6 +15,7 @@ public static class BlockerRegistry private static List>>> shieldZonesCallback; private static List> checkCellForCollisionCallbacks; private static List> impactSomethingCallbacks; + private static List> pawnUnsuppresableFromCallback; private static void Enable() { @@ -22,6 +23,7 @@ private static void Enable() impactSomethingCallbacks = new List>(); checkCellForCollisionCallbacks = new List>(); shieldZonesCallback = new List>>>(); + pawnUnsuppresableFromCallback = new List>(); } public static void RegisterCheckForCollisionCallback(Func f) @@ -50,6 +52,14 @@ public static void RegisterShieldZonesCallback(Func f) + { + if (!enabled) + { + Enable(); + } + pawnUnsuppresableFromCallback.Add(f); + } public static bool CheckCellForCollisionCallback(ProjectileCE projectile, IntVec3 cell, Thing launcher) { @@ -89,6 +99,21 @@ public static IEnumerable> ShieldZonesCallback(Thing thing) } return shieldZonesCallback.SelectMany(cb => cb(thing)); } + public static bool PawnUnsuppresableFromCallback(Pawn pawn, IntVec3 origin) + { + if (!enabled) + { + return false; + } + foreach (var cb in pawnUnsuppresableFromCallback) + { + if (cb(pawn, origin)) + { + return true; + } + } + return false; + } public static Vector3 GetExactPosition(Vector3 origin, Vector3 curPosition, Vector3 shieldPosition, float radiusSq) { Vector3 velocity = curPosition - origin; diff --git a/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs b/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs index 6d2d58fc0d..bebcb66b10 100644 --- a/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs +++ b/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs @@ -29,6 +29,7 @@ public void Install() BlockerRegistry.RegisterImpactSomethingCallback(ImpactSomething); BlockerRegistry.RegisterCheckForCollisionCallback(CheckIntercept); BlockerRegistry.RegisterShieldZonesCallback(ShieldZones); + BlockerRegistry.RegisterUnsuppresableFromCallback(Unsuppresable); } private static IEnumerable> ShieldZones(Thing thing) @@ -36,6 +37,8 @@ private static IEnumerable> ShieldZones(Thing thing) return thing.Map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn).Cast().SelectMany(x => x.health.hediffSet.hediffs).OfType().Select(x => GenRadial.RadialCellsAround(x.pawn.Position, x.OverlaySize, true)); } + private static bool Unsuppresable(Pawn pawn, IntVec3 origin) => pawn.health.hediffSet.hediffs.Any(x => x.GetType() == typeof(Hediff_Overshield)); + private static bool ImpactSomething(ProjectileCE projectile, Thing launcher) { From 63c4175bb7a496af2c805c05c38385327d2ab72d Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 11 Oct 2023 14:50:53 +0600 Subject: [PATCH 05/19] Whitespace --- Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs b/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs index e00a3d39a9..322125000f 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs @@ -246,7 +246,7 @@ public void AddSuppression(float amount, IntVec3 origin) } public bool IgnoreSuppresion(IntVec3 origin) { - return BlockerRegistry.PawnUnsuppresableFromCallback(parent as Pawn, origin) || SuppressionUtility.InterceptorZonesFor((Pawn)parent).Where(x=>x.Contains(parent.Position)).Any(x=>!x.Contains(origin)); + return BlockerRegistry.PawnUnsuppresableFromCallback(parent as Pawn, origin) || SuppressionUtility.InterceptorZonesFor((Pawn)parent).Where(x => x.Contains(parent.Position)).Any(x => !x.Contains(origin)); } public override void CompTick() From fd6b0e04522b3563fe24d2f9acf3143db44111a1 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 20 Oct 2023 22:30:27 +0600 Subject: [PATCH 06/19] Removed commented code --- Source/CombatExtended/CombatExtended/SuppressionUtility.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/SuppressionUtility.cs b/Source/CombatExtended/CombatExtended/SuppressionUtility.cs index dcd7dec781..cedbc19d16 100644 --- a/Source/CombatExtended/CombatExtended/SuppressionUtility.cs +++ b/Source/CombatExtended/CombatExtended/SuppressionUtility.cs @@ -92,7 +92,6 @@ private static bool GetCoverPositionFrom(Pawn pawn, IntVec3 fromPosition, float { List cellList = new List(GenRadial.RadialCellsAround(pawn.Position, maxDist, true)); IntVec3 bestPos = pawn.Position; - //interceptors = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.ProjectileInterceptor).Select(t => t.TryGetComp()).ToList(); lightingTracker = pawn.Map.GetLightingTracker(); dangerTracker = pawn.Map.GetDangerTracker(); From 3b28e6674ae31a00af815bbea756d558244fd395 Mon Sep 17 00:00:00 2001 From: Logan Perkins Date: Sun, 22 Oct 2023 11:35:28 -0700 Subject: [PATCH 07/19] resolve conflicts --- Source/CombatExtended/Compatibility/BlockerRegistry.cs | 6 +++++- .../CombatExtended/Compatibility/VanillaPsycastExpanded.cs | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Source/CombatExtended/Compatibility/BlockerRegistry.cs b/Source/CombatExtended/Compatibility/BlockerRegistry.cs index fbbdef9e8a..f0f3fdf7cd 100644 --- a/Source/CombatExtended/Compatibility/BlockerRegistry.cs +++ b/Source/CombatExtended/Compatibility/BlockerRegistry.cs @@ -44,7 +44,7 @@ private static void EnableSZ() enabledSZ = true; shieldZonesCallback = new List>>>(); } - private static void EnableCFC() + private static void EnablePUF() { enabledPUF = true; pawnUnsuppresableFromCallback = new List>(); @@ -168,7 +168,11 @@ public static bool PawnUnsuppresableFromCallback(Pawn pawn, IntVec3 origin) foreach (var cb in pawnUnsuppresableFromCallback) { if (cb(pawn, origin)) + { + return true; + } } + return false; } public static bool BeforeCollideWithCallback(ProjectileCE projectile, Thing collideWith) { diff --git a/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs b/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs index d0419f4325..84fdc286c6 100644 --- a/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs +++ b/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs @@ -34,7 +34,6 @@ public void Install() BlockerRegistry.RegisterShieldZonesCallback(ShieldZones); BlockerRegistry.RegisterUnsuppresableFromCallback(Unsuppresable); } - private static IEnumerable> ShieldZones(Thing thing) { return thing.Map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn).Cast().SelectMany(x => x.health.hediffSet.hediffs).OfType().Select(x => GenRadial.RadialCellsAround(x.pawn.Position, x.OverlaySize, true)); From e57945f9435daa2731e835e1ba64cda0d0497510 Mon Sep 17 00:00:00 2001 From: Logan Perkins Date: Fri, 27 Oct 2023 21:03:42 -0700 Subject: [PATCH 08/19] don't reference VPE types in generator expressions --- .../CombatExtended/Compatibility/VanillaPsycastExpanded.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs b/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs index 72bcaf85a4..b379629b69 100644 --- a/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs +++ b/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs @@ -81,10 +81,11 @@ public static bool AOE_CheckIntercept(ProjectileCE projectile, Vector3 from, Vec { return false; } - foreach (var interceptor in projectile.Map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn).Cast() + foreach (var i in projectile.Map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn).Cast() .SelectMany(x => x.health.hediffSet.hediffs) - .Where(x => x is Hediff_Overshield && x.GetType() != typeof(Hediff_Overshield)).Cast()) + .Where(x => x is Hediff_Overshield && x.GetType() != typeof(Hediff_Overshield))) { + var interceptor = i as Hediff_Overshield; Vector3 shieldPosition = interceptor.pawn.Position.ToVector3ShiftedWithAltitude(0.5f); float radius = interceptor.OverlaySize; float blockRadius = radius + def.projectile.SpeedTilesPerTick + 0.1f; From e1c34d58f819141674c1ec69d9040a6d832e18b1 Mon Sep 17 00:00:00 2001 From: Logan Perkins Date: Sat, 28 Oct 2023 10:54:52 -0700 Subject: [PATCH 09/19] fix missing type errors --- .../CombatExtended/Compatibility/VanillaPsycastExpanded.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs b/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs index b379629b69..7efb0c668e 100644 --- a/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs +++ b/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs @@ -36,7 +36,7 @@ public void Install() } private static IEnumerable> ShieldZones(Thing thing) { - return thing.Map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn).Cast().SelectMany(x => x.health.hediffSet.hediffs).OfType().Select(x => GenRadial.RadialCellsAround(x.pawn.Position, x.OverlaySize, true)); + return thing.Map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn).Cast().SelectMany(x => x.health.hediffSet.hediffs).Select(x => { var ho = x as Hediff_Overshield; return GenRadial.RadialCellsAround(ho.pawn.Position, ho.OverlaySize, true); }); } private static bool Unsuppresable(Pawn pawn, IntVec3 origin) => pawn.health.hediffSet.hediffs.Any(x => x.GetType() == typeof(Hediff_Overshield)); @@ -81,11 +81,10 @@ public static bool AOE_CheckIntercept(ProjectileCE projectile, Vector3 from, Vec { return false; } - foreach (var i in projectile.Map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn).Cast() + foreach (var interceptor in projectile.Map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn).Cast() .SelectMany(x => x.health.hediffSet.hediffs) - .Where(x => x is Hediff_Overshield && x.GetType() != typeof(Hediff_Overshield))) + .Where(x => x is Hediff_Overshield && x.GetType() != typeof(Hediff_Overshield)).Cast()) { - var interceptor = i as Hediff_Overshield; Vector3 shieldPosition = interceptor.pawn.Position.ToVector3ShiftedWithAltitude(0.5f); float radius = interceptor.OverlaySize; float blockRadius = radius + def.projectile.SpeedTilesPerTick + 0.1f; From a917c757fc3d1a93a88722b99721f7a5cb2f1019 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sun, 29 Oct 2023 17:28:42 +0600 Subject: [PATCH 10/19] NRE fix --- Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs b/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs index 7efb0c668e..f6b0367568 100644 --- a/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs +++ b/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs @@ -36,7 +36,7 @@ public void Install() } private static IEnumerable> ShieldZones(Thing thing) { - return thing.Map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn).Cast().SelectMany(x => x.health.hediffSet.hediffs).Select(x => { var ho = x as Hediff_Overshield; return GenRadial.RadialCellsAround(ho.pawn.Position, ho.OverlaySize, true); }); + return thing.Map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn).Cast().SelectMany(x => x.health.hediffSet.hediffs).Where(x => x is Hediff_Overshield).Select(x => { var ho = x as Hediff_Overshield; return GenRadial.RadialCellsAround(ho.pawn.Position, ho.OverlaySize, true); }); } private static bool Unsuppresable(Pawn pawn, IntVec3 origin) => pawn.health.hediffSet.hediffs.Any(x => x.GetType() == typeof(Hediff_Overshield)); @@ -87,7 +87,6 @@ public static bool AOE_CheckIntercept(ProjectileCE projectile, Vector3 from, Vec { Vector3 shieldPosition = interceptor.pawn.Position.ToVector3ShiftedWithAltitude(0.5f); float radius = interceptor.OverlaySize; - float blockRadius = radius + def.projectile.SpeedTilesPerTick + 0.1f; if (CE_Utility.IntersectionPoint(from, newExactPos, shieldPosition, radius, out Vector3[] sect)) { OnIntercepted(interceptor, projectile, sect); From 195eb52b5d18029a8527bdd388de6453888c01c9 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sun, 29 Oct 2023 21:08:50 +0600 Subject: [PATCH 11/19] VPE caching --- .../Compatibility/VanillaPsycastExpanded.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs b/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs index f6b0367568..65322db659 100644 --- a/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs +++ b/Source/CombatExtended/Compatibility/VanillaPsycastExpanded.cs @@ -34,9 +34,23 @@ public void Install() BlockerRegistry.RegisterShieldZonesCallback(ShieldZones); BlockerRegistry.RegisterUnsuppresableFromCallback(Unsuppresable); } + private static Dictionary>> shieldZones; + private static int shieldZonesCacheTick = -1; private static IEnumerable> ShieldZones(Thing thing) { - return thing.Map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn).Cast().SelectMany(x => x.health.hediffSet.hediffs).Where(x => x is Hediff_Overshield).Select(x => { var ho = x as Hediff_Overshield; return GenRadial.RadialCellsAround(ho.pawn.Position, ho.OverlaySize, true); }); + IEnumerable> result = null; + var currentTick = GenTicks.TicksGame; + if (shieldZonesCacheTick != currentTick) + { + shieldZonesCacheTick = currentTick; + shieldZones = new Dictionary>>(); + } + if (!shieldZones.TryGetValue(thing.Map, out result)) + { + result = thing.Map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn).Cast().SelectMany(x => x.health.hediffSet.hediffs).Where(x => x is Hediff_Overshield).Select(x => { var ho = x as Hediff_Overshield; return GenRadial.RadialCellsAround(ho.pawn.Position, ho.OverlaySize, true); }).ToList(); + shieldZones.Add(thing.Map, result); + } + return result; } private static bool Unsuppresable(Pawn pawn, IntVec3 origin) => pawn.health.hediffSet.hediffs.Any(x => x.GetType() == typeof(Hediff_Overshield)); From 521f00aadb54155b06c18f0b9d53c3d333c9cd49 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Mon, 30 Oct 2023 16:59:26 +0600 Subject: [PATCH 12/19] Avoid shields that doens't intercept non hostile projectiles --- Source/CombatExtended/CombatExtended/SuppressionUtility.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/SuppressionUtility.cs b/Source/CombatExtended/CombatExtended/SuppressionUtility.cs index cedbc19d16..6aebbe28fd 100644 --- a/Source/CombatExtended/CombatExtended/SuppressionUtility.cs +++ b/Source/CombatExtended/CombatExtended/SuppressionUtility.cs @@ -24,7 +24,7 @@ public static class SuppressionUtility private static DangerTracker dangerTracker; - private static IEnumerable Interceptors(Thing pawn) => pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.ProjectileInterceptor).Select(t => t.TryGetComp()); + private static IEnumerable Interceptors(Thing pawn) => pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.ProjectileInterceptor).Select(t => t.TryGetComp()).Where(x=>x.Props.interceptNonHostileProjectiles || !x.parent.HostileTo(pawn)); public static bool TryRequestHelp(Pawn pawn) { From 3a1c27f276d024eb14ad5f34ec82ffc4269575c7 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Mon, 30 Oct 2023 17:00:37 +0600 Subject: [PATCH 13/19] Whitespace fix --- Source/CombatExtended/CombatExtended/SuppressionUtility.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/SuppressionUtility.cs b/Source/CombatExtended/CombatExtended/SuppressionUtility.cs index 6aebbe28fd..0fdb81e4e8 100644 --- a/Source/CombatExtended/CombatExtended/SuppressionUtility.cs +++ b/Source/CombatExtended/CombatExtended/SuppressionUtility.cs @@ -24,7 +24,7 @@ public static class SuppressionUtility private static DangerTracker dangerTracker; - private static IEnumerable Interceptors(Thing pawn) => pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.ProjectileInterceptor).Select(t => t.TryGetComp()).Where(x=>x.Props.interceptNonHostileProjectiles || !x.parent.HostileTo(pawn)); + private static IEnumerable Interceptors(Thing pawn) => pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.ProjectileInterceptor).Select(t => t.TryGetComp()).Where(x => x.Props.interceptNonHostileProjectiles || !x.parent.HostileTo(pawn)); public static bool TryRequestHelp(Pawn pawn) { From b8c6610a6fc578c96ef79a2f09b3a51493d1b767 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 29 Nov 2023 23:44:24 +0600 Subject: [PATCH 14/19] ED shields compatibility (not tested yet) --- .../CombatExtended/Compatibility/EDShields.cs | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/Source/CombatExtended/Compatibility/EDShields.cs b/Source/CombatExtended/Compatibility/EDShields.cs index 4889f5b6af..833cc19b88 100644 --- a/Source/CombatExtended/Compatibility/EDShields.cs +++ b/Source/CombatExtended/Compatibility/EDShields.cs @@ -35,9 +35,12 @@ public void Install() { BlockerRegistry.RegisterCheckForCollisionBetweenCallback(EDShields.CheckForCollisionBetweenCallback); BlockerRegistry.RegisterImpactSomethingCallback(EDShields.ImpactSomethingCallback); + BlockerRegistry.RegisterShieldZonesCallback(EDShields.ShieldZonesCallback); Type t = Type.GetType("Jaxxa.EnhancedDevelopment.Shields.Shields.ShieldManagerMapComp, ED-Shields"); HitSoundDef = (SoundDef)t.GetField("HitSoundDef", BindingFlags.Static | BindingFlags.Public).GetValue(null); } + + public IEnumerable GetCompatList() { yield break; @@ -84,7 +87,6 @@ public static bool CheckForCollisionBetweenCallback(ProjectileCE projectile, Vec continue; } - int fieldRadiusSq = fieldRadius * fieldRadius; Quaternion shieldProjAng = Quaternion.LookRotation(from - shieldPosition2D); if ((Quaternion.Angle(targetAngle, shieldProjAng) > 90)) { @@ -156,5 +158,29 @@ public static void getShields(Map map) } } + private static IEnumerable> ShieldZonesCallback(Thing pawnToSuppress) + { + Map map = pawnToSuppress.Map; + getShields(map); + foreach (Building building in shields) + { + var shield = building as Building_Shield; + var generator = shield.GetComp(); + bool isActive = generator.IsActive(); + if (!isActive) + { + continue; + } + bool blockDirect = generator.BlockDirect_Active(); + if (!blockDirect) + { + continue; + } + //Is there no shields that doesn't intercept ingoing friendly projectiles? + int fieldRadius = (int)generator.FieldRadius_Active(); + yield return GenRadial.RadialCellsAround(shield.Position, fieldRadius, true); + } + } + } } From 9f9a4cac5344c3ed788b7a48cee135cf83d5d40e Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 29 Nov 2023 23:52:56 +0600 Subject: [PATCH 15/19] Rimatomics suppression compatibility (not tested yet) --- .../Compatibility/Rimatomics.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/Source/CombatExtended/Compatibility/Rimatomics.cs b/Source/CombatExtended/Compatibility/Rimatomics.cs index c9e156cfed..40b4b5afb7 100644 --- a/Source/CombatExtended/Compatibility/Rimatomics.cs +++ b/Source/CombatExtended/Compatibility/Rimatomics.cs @@ -32,6 +32,7 @@ public void Install() { BlockerRegistry.RegisterCheckForCollisionBetweenCallback(Rimatomics.CheckForCollisionBetweenCallback); BlockerRegistry.RegisterImpactSomethingCallback(Rimatomics.ImpactSomethingCallback); + BlockerRegistry.RegisterShieldZonesCallback(Rimatomics.ShieldZonesCallback); } public IEnumerable GetCompatList() @@ -149,6 +150,26 @@ public static bool ImpactSomethingCallback(ProjectileCE projectile, Thing launch return false; } + private static IEnumerable> ShieldZonesCallback(Thing pawnToSuppress) + { + Map map = pawnToSuppress.Map; + getShields(map); + foreach (CompRimatomicsShield shield in shields) + { + if (!shield.Active || shield.ShieldState != ShieldState.Active) + { + continue; + } + if (GenHostility.HostileTo(pawnToSuppress, shield.parent) && !shield.debugInterceptNonHostileProjectiles && !shield.Props.interceptNonHostileProjectiles) + { + // Avoid hostile shields because they aren't intercepting friendly projectiles + continue; + } + + int fieldRadius = (int)shield.Radius; + yield return GenRadial.RadialCellsAround(shield.parent.Position, fieldRadius, true); + } + } public static void getShields(Map map) { From 65adbb708e3cc343e73fa9092516fe79eb52cc1d Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 30 Nov 2023 00:00:43 +0600 Subject: [PATCH 16/19] VEF.CompShieldField-based shield suppression compatibility (not tested yet) --- .../Compatibility/VanillaExpandedFramework.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Source/CombatExtended/Compatibility/VanillaExpandedFramework.cs b/Source/CombatExtended/Compatibility/VanillaExpandedFramework.cs index bbe5a8c331..a8f138f267 100644 --- a/Source/CombatExtended/Compatibility/VanillaExpandedFramework.cs +++ b/Source/CombatExtended/Compatibility/VanillaExpandedFramework.cs @@ -26,7 +26,26 @@ IEnumerable IPatch.GetCompatList() void IPatch.Install() { BlockerRegistry.RegisterCheckForCollisionCallback(CheckIntercept); + BlockerRegistry.RegisterShieldZonesCallback(ShieldZonesCallback); } + + private IEnumerable> ShieldZonesCallback(Thing pawnToSuppress) + { + IEnumerable interceptors = CompShieldField.ListerShieldGensActiveIn(pawnToSuppress.Map).ToList(); + if (!interceptors.Any()) + { + yield break; + } + foreach (var interceptor in interceptors) + { + if (!interceptor.CanFunction) + { + continue; + } + yield return GenRadial.RadialCellsAround(interceptor.HostThing.Position, interceptor.ShieldRadius, true); + } + } + private static bool CheckIntercept(ProjectileCE projectile, IntVec3 cell, Thing launcher) { if (projectile.def.projectile.flyOverhead) From 247e1bc5f1d03eff3918062e78b54c64df0da82e Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 30 Nov 2023 00:19:09 +0600 Subject: [PATCH 17/19] Missing type fix --- Source/CombatExtended/Compatibility/Rimatomics.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/CombatExtended/Compatibility/Rimatomics.cs b/Source/CombatExtended/Compatibility/Rimatomics.cs index 40b4b5afb7..d894714815 100644 --- a/Source/CombatExtended/Compatibility/Rimatomics.cs +++ b/Source/CombatExtended/Compatibility/Rimatomics.cs @@ -154,6 +154,7 @@ private static IEnumerable> ShieldZonesCallback(Thing pawnT { Map map = pawnToSuppress.Map; getShields(map); + List> result = new List>(); foreach (CompRimatomicsShield shield in shields) { if (!shield.Active || shield.ShieldState != ShieldState.Active) @@ -167,8 +168,9 @@ private static IEnumerable> ShieldZonesCallback(Thing pawnT } int fieldRadius = (int)shield.Radius; - yield return GenRadial.RadialCellsAround(shield.parent.Position, fieldRadius, true); + result.Add(GenRadial.RadialCellsAround(shield.parent.Position, fieldRadius, true)); } + return result; } public static void getShields(Map map) From 9a1dc295fc895aab67442731a5a9db77c89fe4e0 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 30 Nov 2023 00:20:47 +0600 Subject: [PATCH 18/19] ED Shields missing fix --- Source/CombatExtended/Compatibility/EDShields.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/CombatExtended/Compatibility/EDShields.cs b/Source/CombatExtended/Compatibility/EDShields.cs index 833cc19b88..c317515e2d 100644 --- a/Source/CombatExtended/Compatibility/EDShields.cs +++ b/Source/CombatExtended/Compatibility/EDShields.cs @@ -162,6 +162,7 @@ private static IEnumerable> ShieldZonesCallback(Thing pawnT { Map map = pawnToSuppress.Map; getShields(map); + List> result = new List>(); foreach (Building building in shields) { var shield = building as Building_Shield; @@ -178,8 +179,9 @@ private static IEnumerable> ShieldZonesCallback(Thing pawnT } //Is there no shields that doesn't intercept ingoing friendly projectiles? int fieldRadius = (int)generator.FieldRadius_Active(); - yield return GenRadial.RadialCellsAround(shield.Position, fieldRadius, true); + result.Add(GenRadial.RadialCellsAround(shield.Position, fieldRadius, true)); } + return result; } } From 465ab52d2aa2a52234b7bd43951247a2b00f5bce Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 30 Nov 2023 00:22:43 +0600 Subject: [PATCH 19/19] VEF missing type fix --- .../Compatibility/VanillaExpandedFramework.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/CombatExtended/Compatibility/VanillaExpandedFramework.cs b/Source/CombatExtended/Compatibility/VanillaExpandedFramework.cs index a8f138f267..a3d939db83 100644 --- a/Source/CombatExtended/Compatibility/VanillaExpandedFramework.cs +++ b/Source/CombatExtended/Compatibility/VanillaExpandedFramework.cs @@ -32,9 +32,10 @@ void IPatch.Install() private IEnumerable> ShieldZonesCallback(Thing pawnToSuppress) { IEnumerable interceptors = CompShieldField.ListerShieldGensActiveIn(pawnToSuppress.Map).ToList(); + List> result = new List>(); if (!interceptors.Any()) { - yield break; + return result; } foreach (var interceptor in interceptors) { @@ -42,8 +43,9 @@ private IEnumerable> ShieldZonesCallback(Thing pawnToSuppre { continue; } - yield return GenRadial.RadialCellsAround(interceptor.HostThing.Position, interceptor.ShieldRadius, true); + result.Add(GenRadial.RadialCellsAround(interceptor.HostThing.Position, interceptor.ShieldRadius, true)); } + return result; } private static bool CheckIntercept(ProjectileCE projectile, IntVec3 cell, Thing launcher)