From 1752cf0ef2ef2bcf3a5a5fab0f7af1135526edb7 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sat, 27 Jul 2024 23:23:51 +0600 Subject: [PATCH 001/127] Comps for CIWS (used my comps from vanilla CIWS - https://github.com/MaxDorob/HAETAE_CIWS) --- .../CombatExtended/Comps/CompCIWS.cs | 140 +++++++++++++++++ .../Comps/CompCIWSProjectile.cs | 40 +++++ .../CombatExtended/Comps/CompCIWSSkyfaller.cs | 37 +++++ .../CombatExtended/Comps/CompCIWSTarget.cs | 141 ++++++++++++++++++ 4 files changed, 358 insertions(+) create mode 100644 Source/CombatExtended/CombatExtended/Comps/CompCIWS.cs create mode 100644 Source/CombatExtended/CombatExtended/Comps/CompCIWSProjectile.cs create mode 100644 Source/CombatExtended/CombatExtended/Comps/CompCIWSSkyfaller.cs create mode 100644 Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWS.cs new file mode 100644 index 0000000000..513363fac0 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWS.cs @@ -0,0 +1,140 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using UnityEngine.SocialPlatforms; +using Verse; +using Verse.Sound; + +namespace CombatExtended +{ + public abstract class CompCIWS : ThingComp + { + #region Caching + protected static Dictionary> CIWS = new Dictionary>(); + + public override void PostSpawnSetup(bool respawningAfterLoad) + { + base.PostSpawnSetup(respawningAfterLoad); + if (parent.Map == null) + { + return; + } + if (!CIWS.TryGetValue(parent.Map, out var targetList)) + { + CIWS[parent.Map] = targetList = new List(); + } + targetList.Add(Turret); + + //IgnoredDefs ??= Props.Ignored.Union(Mod.Settings?.settings?.FirstOrDefault(x => x.ciws == parent.def)?.IgnoredDefs ?? Enumerable.Empty()).ToList(); + } + public override void PostDeSpawn(Map map) + { + base.PostDeSpawn(map); + if (CIWS.TryGetValue(map, out var targetList)) + { + targetList.Remove(Turret); + } + } + #endregion + protected bool holdFire; + public IEnumerable IgnoredDefs { get; private set; } + public Building_TurretGun Turret => parent as Building_TurretGun; + public CompProperties_CIWS Props => props as CompProperties_CIWS; + public virtual Verb Verb => Turret.GunCompEq.PrimaryVerb; + public abstract bool HasTarget { get; } + protected abstract string HoldLabel { get; } + protected abstract string HoldDesc { get; } + protected virtual string HoldIcon => "UI/Commands/HoldFire"; + public override void PostExposeData() + { + base.PostExposeData(); + Scribe_Values.Look(ref holdFire, nameof(holdFire), false); + } + public override IEnumerable CompGetGizmosExtra() + { + foreach (var gizmo in base.CompGetGizmosExtra()) + { + yield return gizmo; + } + if (Turret.CanToggleHoldFire) + { + yield return new Command_Toggle + { + defaultLabel = HoldLabel.Translate(), + defaultDesc = HoldDesc.Translate(), + icon = ContentFinder.Get(HoldIcon, true), + hotKey = KeyBindingDefOf.Misc6, + toggleAction = delegate () + { + this.holdFire = !this.holdFire; + if (this.holdFire && HasTarget) + { + Turret.ResetForcedTarget(); + } + }, + isActive = (() => this.holdFire) + }; + } + } + public virtual bool Active => !holdFire && Turret.Active; + } + public abstract class CompCIWS : CompCIWS where TargetType : Thing + { + + public override void CompTick() + { + base.CompTick(); + + if (parent.IsHashIntervalTick(10) && Active && Verb.state != VerbState.Bursting && Turret.burstCooldownTicksLeft <= 0 && TryFindNewTarget(out var target)) + { + Turret.currentTargetInt = target; + Turret.BeginBurst(); + Turret.Top.TurretTopTick(); + } + } + public virtual bool TryFindNewTarget(out LocalTargetInfo target) + { + float range = this.Verb.verbProps.range; + var _target = Targets.Where(x => Props.Interceptable(x.def) && !IgnoredDefs.Contains(x.def)).Where(x => !IsFriendlyTo(x)).FirstOrDefault(t => + { + if (CIWS[parent.Map].Any(turret => turret.currentTargetInt.Thing == t) || CIWSProjectile.ProjectilesAt(parent.Map).Any(x => x.intendedTarget.Thing == t)) + { + return false; + } + float num = this.Verb.verbProps.EffectiveMinRange(t, this.parent); + var intersectionPoint = t.TryGetComp()?.CalculatePointForPreemptiveFire(Verb.GetProjectile(), parent.DrawPos, (int)Verb.verbProps.warmupTime) ?? t.CalculatePointForPreemptiveFire(Verb.GetProjectile(), parent.DrawPos, (int)Verb.verbProps.warmupTime); + if (!intersectionPoint.IsValid) + { + return false; + } + float num2 = intersectionPoint.DistanceToSquared(this.parent.Position); + return num2 > num * num && num2 < range * range; + }); + if (_target != null) + { + target = _target; + return true; + } + target = null; + return false; + } + protected virtual bool IsFriendlyTo(TargetType thing) => ((!thing.TryGetComp()?.Props.alwaysIntercept) ?? false) && !thing.HostileTo(parent); + public abstract IEnumerable Targets { get; } + } + + public abstract class CompProperties_CIWS : CompProperties + { + public List ignored = new List(); + public IEnumerable Ignored => ignored; + public virtual bool Interceptable(ThingDef targetDef) => true; + + private IEnumerable allTargets; + + public IEnumerable AllTargets => allTargets ??= InitAllTargets(); + protected abstract IEnumerable InitAllTargets(); + } +} diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSProjectile.cs new file mode 100644 index 0000000000..f1d6078bea --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSProjectile.cs @@ -0,0 +1,40 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; +using static HarmonyLib.Code; + +namespace CombatExtended +{ + public class CompCIWSProjectile : CompCIWS + { + protected override string HoldDesc => "HoldCloseInProjectilesFireDesc"; + protected override string HoldLabel => "HoldCloseInProjectilesFire"; + public new CompProperties_CIWSProjectile Props => props as CompProperties_CIWSProjectile; + + public override IEnumerable Targets => parent.Map?.listerThings.ThingsInGroup(ThingRequestGroup.Projectile).OfType() ?? Array.Empty(); + + public override Verb Verb + { + get + { + return Turret.GunCompEq.AllVerbs.OfType().FirstOrDefault() ?? base.Verb; + } + } + protected override bool IsFriendlyTo(Projectile thing) => base.IsFriendlyTo(thing) && !thing.Launcher.HostileTo(parent); + public override bool HasTarget => Turret.currentTargetInt.Thing is Projectile; + } + public class CompProperties_CIWSProjectile : CompProperties_CIWS + { + public CompProperties_CIWSProjectile() + { + this.compClass = typeof(CompCIWSProjectile); + } + public override bool Interceptable(ThingDef targetDef) => targetDef.projectile.speed < maximumSpeed && targetDef.projectile.flyOverhead && base.Interceptable(targetDef); + public float maximumSpeed = 80; + protected override IEnumerable InitAllTargets() => DefDatabase.AllDefsListForReading.Where(x => x.projectile != null && x.projectile.flyOverhead && x.projectile.speed < maximumSpeed); + } +} diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSSkyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSSkyfaller.cs new file mode 100644 index 0000000000..42a50c8170 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSSkyfaller.cs @@ -0,0 +1,37 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace CombatExtended +{ + public class CompCIWSSkyfaller : CompCIWS + { + protected override string HoldDesc => "HoldSkyfallerFireDesc"; + protected override string HoldLabel => "HoldSkyfallerFire"; + public override IEnumerable Targets => parent.Map?.listerThings.ThingsInGroup(Verse.ThingRequestGroup.ActiveDropPod).OfType().Union(CompCIWSTarget.Targets(parent.Map).OfType()); + + public override Verb Verb + { + get + { + return Turret.GunCompEq.AllVerbs.OfType().FirstOrDefault() ?? base.Verb; + } + } + protected override bool IsFriendlyTo(Skyfaller thing) => base.IsFriendlyTo(thing) && Utils.ContainedThings(thing).All(x => !x.HostileTo(parent)); + public override bool HasTarget => Turret.currentTargetInt.Thing is Skyfaller; + + } + public class CompProperties_CIWSSkyfaller : CompProperties_CIWS + { + public CompProperties_CIWSSkyfaller() + { + this.compClass = typeof(CompCIWSSkyfaller); + } + protected override IEnumerable InitAllTargets() => DefDatabase.AllDefsListForReading.Where(x => (typeof(Skyfaller).IsAssignableFrom(x.thingClass) && x.HasComp()) || typeof(IActiveDropPod).IsAssignableFrom(x.thingClass)); + } +} diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs new file mode 100644 index 0000000000..5c219cffd8 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs @@ -0,0 +1,141 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; +using Verse.Sound; + +namespace CombatExtended +{ + public class CompCIWSTarget : ThingComp + { + protected static Dictionary> CIWSTargets = new Dictionary>(); + public static IEnumerable Targets(Map map) + { + CIWSTargets.TryGetValue(map, out var targets); + return targets ?? Enumerable.Empty(); + } + + public CompProperties_CIWSTarget Props => props as CompProperties_CIWSTarget; + + public override void PostSpawnSetup(bool respawningAfterLoad) + { + base.PostSpawnSetup(respawningAfterLoad); + if (parent.Map == null) + { + return; + } + if (!CIWSTargets.TryGetValue(parent.Map, out var targetList)) + { + CIWSTargets[parent.Map] = targetList = new List(); + } + targetList.Add(parent); + } + public override void PostDeSpawn(Map map) + { + base.PostDeSpawn(map); + if (CIWSTargets.TryGetValue(map, out var targetList)) + { + targetList.Remove(parent); + if (targetList.Count <= 0) + { + CIWSTargets.Remove(map); + } + } + } + public virtual void OnImpact(Projectile projectile, DamageInfo dinfo) + { + parent.Position = projectile.Position; + if (parent is IThingHolder pod) + { + var containedThings = Utils.ContainedThings(pod).ToList(); + + foreach (var thing in containedThings) + { + if (thing is Building) + { + var leavingList = new List(); + GenLeaving.DoLeavingsFor(thing, parent.Map, DestroyMode.KillFinalize, CellRect.CenteredOn(parent.Position, thing.def.size), listOfLeavingsOut: leavingList); + continue; + } + TryDropThing(thing, projectile.Map, projectile.Position); + if (thing is Pawn pawn) + { + pawn.TakeDamage(dinfo); + if (!pawn.Dead) + { + pawn.Kill(dinfo); + } + } + else + { + thing.HitPoints = Rand.RangeInclusive(1, thing.MaxHitPoints); + } + + } + } + if (!Props.impacted.NullOrUndefined()) + { + Props.impacted.PlayOneShot(new TargetInfo(parent.DrawPos.ToIntVec3(), parent.Map)); + } + parent.Destroy(DestroyMode.Vanish); + } + private Thing TryDropThing(Thing thing, Map map, IntVec3 position) + { + var contents = (parent as IActiveDropPod)?.Contents; + Rot4 rot = (contents?.setRotation != null) ? contents.setRotation.Value : Rot4.North; + if (contents?.moveItemsAsideBeforeSpawning ?? false) + { + GenSpawn.CheckMoveItemsAside(parent.Position, rot, thing.def, map); + } + Thing thing2; + if (contents?.spawnWipeMode == null) + { + GenPlace.TryPlaceThing(thing, position, map, ThingPlaceMode.Near, out thing2, delegate (Thing placedThing, int count) + { + if (Find.TickManager.TicksGame < 1200 && TutorSystem.TutorialMode && placedThing.def.category == ThingCategory.Item) + { + Find.TutorialState.AddStartingItem(placedThing); + } + }, null, rot); + } + else if (contents?.setRotation != null) + { + thing2 = GenSpawn.Spawn(thing, position, map, contents.setRotation.Value, contents.spawnWipeMode.Value, false, false); + } + else + { + thing2 = GenSpawn.Spawn(thing, position, map, contents.spawnWipeMode.Value); + } + Pawn pawn = thing2 as Pawn; + if (pawn != null) + { + if (pawn.RaceProps.Humanlike) + { + TaleRecorder.RecordTale(TaleDefOf.LandedInPod, new object[] + { + pawn + }); + } + } + return thing2; + } + public virtual IntVec3 CalculatePointForPreemptiveFire(ThingDef projectile, Vector3 source, int tickOffset = 0) + { + return parent.CalculatePointForPreemptiveFire(projectile, source, tickOffset); + } + + } + public class CompProperties_CIWSTarget : CompProperties + { + public CompProperties_CIWSTarget() + { + compClass = typeof(CompCIWSTarget); + } + public SoundDef impacted; + public bool alwaysIntercept; + } +} From 898c4a913f14e0317cd127c1b0a1b50abec8e342 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sat, 27 Jul 2024 23:25:42 +0600 Subject: [PATCH 002/127] Different projectile def for CIWS-targets --- Source/CombatExtended/CombatExtended/Defs/AmmoLink.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Defs/AmmoLink.cs b/Source/CombatExtended/CombatExtended/Defs/AmmoLink.cs index d4fb57ee19..ffbf7aee48 100644 --- a/Source/CombatExtended/CombatExtended/Defs/AmmoLink.cs +++ b/Source/CombatExtended/CombatExtended/Defs/AmmoLink.cs @@ -13,15 +13,18 @@ public class AmmoLink { public AmmoDef ammo; public ThingDef projectile; + private ThingDef projectileCIWS; public AmmoLink() { } - public AmmoLink(AmmoDef ammo, ThingDef projectile) + public AmmoLink(AmmoDef ammo, ThingDef projectile, ThingDef CIWSProjectile = null) { this.ammo = ammo; this.projectile = projectile; + this.projectileCIWS = CIWSProjectile; } + public ThingDef CIWSProjectile => projectileCIWS ?? projectile; public void LoadDataFromXmlCustom(XmlNode xmlRoot) { if (xmlRoot.ChildNodes.Count != 1) From d7115a0ddd8aa859bd5f68b705a5eaa457d7aeb7 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sun, 28 Jul 2024 00:56:22 +0600 Subject: [PATCH 003/127] Moved some code to base class --- .../CombatExtended/Projectiles/BulletCE.cs | 24 ++----------------- .../Projectiles/ProjectileCE.cs | 18 ++++++++++++++ 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/BulletCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/BulletCE.cs index ba690a7966..56e1edda48 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/BulletCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/BulletCE.cs @@ -21,16 +21,7 @@ public class BulletCE : ProjectileCE public static RulePackDef Shelling => shellingDamageEvent ?? (shellingDamageEvent = DefDatabase.GetNamed("DamageEvent_Shelling")); - public virtual float PenetrationAmount - { - get - { - var projectilePropsCE = (ProjectilePropertiesCE)def.projectile; - var isSharpDmg = def.projectile.damageDef.armorCategory == DamageArmorCategoryDefOf.Sharp; - return (equipment?.GetStatValue(StatDefOf.RangedWeapon_DamageMultiplier) ?? 1f) * (isSharpDmg ? projectilePropsCE.armorPenetrationSharp : projectilePropsCE.armorPenetrationBlunt); - } - } - + private void LogImpact(Thing hitThing, out LogEntry_DamageResult logEntry) { var ed = equipmentDef ?? ThingDef.Named("Gun_Autopistol"); @@ -64,20 +55,9 @@ public override void Impact(Thing hitThing) if (hitThing != null) { // launcher being the pawn equipping the weapon, not the weapon itself - float damageAmountBase = DamageAmount; var projectilePropsCE = (ProjectilePropertiesCE)def.projectile; - var isSharpDmg = def.projectile.damageDef.armorCategory == DamageArmorCategoryDefOf.Sharp; - var penetration = PenetrationAmount; var damDefCE = def.projectile.damageDef.GetModExtension() ?? new DamageDefExtensionCE(); - var dinfo = new DamageInfo( - def.projectile.damageDef, - damageAmountBase, - penetration, //Armor Penetration - ExactRotation.eulerAngles.y, - launcher, - null, - def, - instigatorGuilty: InstigatorGuilty); + var dinfo = DamageInfo; // Set impact height BodyPartDepth partDepth = damDefCE.harmOnlyOutsideLayers ? BodyPartDepth.Outside : BodyPartDepth.Undefined; diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index ee3cd03a43..37ed394277 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -93,6 +93,24 @@ public virtual float DamageAmount return ((float)this.damageAmount) * (shotSpeed * shotSpeed) / (initialSpeed * initialSpeed); } } + public virtual float PenetrationAmount + { + get + { + var projectilePropsCE = (ProjectilePropertiesCE)def.projectile; + var isSharpDmg = def.projectile.damageDef.armorCategory == DamageArmorCategoryDefOf.Sharp; + return (equipment?.GetStatValue(StatDefOf.RangedWeapon_DamageMultiplier) ?? 1f) * (isSharpDmg ? projectilePropsCE.armorPenetrationSharp : projectilePropsCE.armorPenetrationBlunt); + } + } + public virtual DamageInfo DamageInfo => new DamageInfo( + def.projectile.damageDef, + DamageAmount, + PenetrationAmount, //Armor Penetration + ExactRotation.eulerAngles.y, + launcher, + null, + def, + instigatorGuilty: InstigatorGuilty); /// /// Reference to the weapon that fired this projectile, may be null. From e085a99381e2200787bb026401c9d5432424cd75 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sun, 28 Jul 2024 21:31:34 +0600 Subject: [PATCH 004/127] Projectile movement improvments --- .../Projectiles/ProjectileCE.cs | 62 +++++++++++-------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 37ed394277..bd5b70c81b 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -171,20 +171,10 @@ public virtual float Height #endregion #region Position - protected virtual Vector2 Vec2Position(float ticks = -1f) + protected virtual Vector2 Vec2Position(int ticks = -1) { - Log.ErrorOnce("Vec2Position(float) is deprecated and will be removed in 1.5", 50021); - if (ticks < 0) - { - return Vec2Position(); + return Vector2.Lerp(origin, Destination, (ticks < 0 ? FlightTicks : ticks) / startingTicksToImpact); } - return Vector2.Lerp(origin, Destination, ticks / startingTicksToImpact); - } - protected virtual Vector2 Vec2Position() - { - return Vector2.Lerp(origin, Destination, FlightTicks / startingTicksToImpact); - } - private Vector3 exactPosition; /// @@ -1078,7 +1068,26 @@ protected void ApplySuppression(Pawn pawn, float suppressionMultiplier = 1f) // If anyone wants to override how projectiles move, this can be made virtual. // For now, it is non-virtual for performance. - protected Vector3 MoveForward() + public Vector3 MoveForward(ref Vector3 velocity, ref float shotSpeed, ref int flightTicks) + { + flightTicks++; + if (lerpPosition) + { + return LerpedMoveForward(flightTicks); + } + else + { + return NonLerpedMoveForward(ref velocity, ref shotSpeed); + } + + } + protected virtual Vector3 LerpedMoveForward(int flightTicks) + { + var v = Vec2Position(flightTicks); + return new Vector3(v.x, GetHeightAtTicks(flightTicks), v.y); + + } + protected virtual Vector3 NonLerpedMoveForward(ref Vector3 velocity, ref float shotSpeed) { Vector3 curPosition = ExactPosition; float sr = shotRotation * Mathf.Deg2Rad + 3.14159f / 2.0f; @@ -1095,12 +1104,12 @@ protected Vector3 MoveForward() initialSpeed = sspt; } Vector3 newPosition = curPosition + velocity; - Accelerate(); + Accelerate(ref velocity, ref shotSpeed); return newPosition; } // This can also be made virtual, and would be the ideal entry point for guided ammunition and rockets. - protected void Accelerate() + protected void Accelerate(ref Vector3 velocity, ref float shotSpeed) { float crossSectionalArea = radius; crossSectionalArea *= crossSectionalArea * 3.14159f; @@ -1117,6 +1126,17 @@ protected void Accelerate() shotSpeed = velocity.magnitude; } + public IEnumerable NextPositions() + { + int flightTicks = FlightTicks; + float shotSpeed = this.shotSpeed; + Vector3 velocity = this.velocity; + for (int ticksToImpact = this.ticksToImpact - 1; ticksToImpact >= 0; ticksToImpact--) + { + yield return MoveForward(ref velocity, ref shotSpeed, ref flightTicks); + } + } + #region Tick/Draw public override void Tick() { @@ -1127,17 +1147,7 @@ public override void Tick() } LastPos = ExactPosition; ticksToImpact--; - FlightTicks++; - Vector3 nextPosition; - if (lerpPosition) - { - var v = Vec2Position(); - nextPosition = new Vector3(v.x, GetHeightAtTicks(FlightTicks), v.y); - } - else - { - nextPosition = MoveForward(); - } + Vector3 nextPosition = MoveForward(ref velocity, ref shotSpeed, ref FlightTicks); if (!nextPosition.InBounds(Map)) { if (globalTargetInfo.IsValid) From f686568da27ab3ae64e80508a4b863f46223e8f3 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sun, 28 Jul 2024 21:32:54 +0600 Subject: [PATCH 005/127] Virtual check collision between --- .../CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index bd5b70c81b..e2d75cc89d 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -698,7 +698,7 @@ protected bool CheckIntercept(Thing interceptorThing, CompProjectileInterceptor } //Removed minimum collision distance - protected bool CheckForCollisionBetween() + protected virtual bool CheckForCollisionBetween() { bool collided = false; Map localMap = this.Map; // Saving the map in case CheckCellForCollision->...->Impact destroys the projectile, thus setting this.Map to null From 3cf9ab586ff819fc5a6139e380e136b1d5454843 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sun, 28 Jul 2024 21:33:28 +0600 Subject: [PATCH 006/127] Moved unused calculations to Init --- .../CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index e2d75cc89d..346773a363 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -1090,9 +1090,9 @@ protected virtual Vector3 LerpedMoveForward(int flightTicks) protected virtual Vector3 NonLerpedMoveForward(ref Vector3 velocity, ref float shotSpeed) { Vector3 curPosition = ExactPosition; - float sr = shotRotation * Mathf.Deg2Rad + 3.14159f / 2.0f; if (!kinit) { + float sr = shotRotation * Mathf.Deg2Rad + 3.14159f / 2.0f; kinit = true; var projectileProperties = def.projectile as ProjectilePropertiesCE; ballisticCoefficient = projectileProperties.ballisticCoefficient.RandomInRange; From 793cda2a76d4ff937886957b9a4e19fcb7ad98b6 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sun, 11 Aug 2024 19:51:50 +0600 Subject: [PATCH 007/127] Invoking OnImpact of CIWSTarget --- .../CombatExtended/Comps/CompCIWSTarget.cs | 12 +++--------- .../CombatExtended/Projectiles/ProjectileCE.cs | 5 +++++ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs index 5c219cffd8..85622712f6 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs @@ -46,12 +46,12 @@ public override void PostDeSpawn(Map map) } } } - public virtual void OnImpact(Projectile projectile, DamageInfo dinfo) + public virtual void OnImpact(ProjectileCE projectile, DamageInfo dinfo) { parent.Position = projectile.Position; if (parent is IThingHolder pod) { - var containedThings = Utils.ContainedThings(pod).ToList(); + var containedThings = pod.ContainedThings().ToList(); foreach (var thing in containedThings) { @@ -94,14 +94,8 @@ private Thing TryDropThing(Thing thing, Map map, IntVec3 position) Thing thing2; if (contents?.spawnWipeMode == null) { - GenPlace.TryPlaceThing(thing, position, map, ThingPlaceMode.Near, out thing2, delegate (Thing placedThing, int count) - { - if (Find.TickManager.TicksGame < 1200 && TutorSystem.TutorialMode && placedThing.def.category == ThingCategory.Item) - { - Find.TutorialState.AddStartingItem(placedThing); + GenPlace.TryPlaceThing(thing, position, map, ThingPlaceMode.Near, out thing2, null, null, rot); } - }, null, rot); - } else if (contents?.setRotation != null) { thing2 = GenSpawn.Spawn(thing, position, map, contents.setRotation.Value, contents.spawnWipeMode.Value, false, false); diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 346773a363..d5c0b2afb6 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -1498,6 +1498,11 @@ public virtual void Impact(Thing hitThing) } } + var compCIWSTarget = hitThing?.TryGetComp(); + if (compCIWSTarget != null) + { + compCIWSTarget.OnImpact(this, DamageInfo); + } Destroy(); } #endregion From 87b8ab32b0fbcf9683afb8289189a028034237f2 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sun, 11 Aug 2024 19:53:41 +0600 Subject: [PATCH 008/127] Moved moving-forward code to ProjectilePropertiesCE --- .../Projectiles/ProjectileCE.cs | 72 ++------------- .../Projectiles/ProjectilePropertiesCE.cs | 87 ++++++++++++++++++- 2 files changed, 91 insertions(+), 68 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index d5c0b2afb6..9523e23a05 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -171,10 +171,6 @@ public virtual float Height #endregion #region Position - protected virtual Vector2 Vec2Position(int ticks = -1) - { - return Vector2.Lerp(origin, Destination, (ticks < 0 ? FlightTicks : ticks) / startingTicksToImpact); - } private Vector3 exactPosition; /// @@ -1066,74 +1062,16 @@ protected void ApplySuppression(Pawn pawn, float suppressionMultiplier = 1f) } } - // If anyone wants to override how projectiles move, this can be made virtual. - // For now, it is non-virtual for performance. - public Vector3 MoveForward(ref Vector3 velocity, ref float shotSpeed, ref int flightTicks) - { - flightTicks++; - if (lerpPosition) - { - return LerpedMoveForward(flightTicks); - } - else - { - return NonLerpedMoveForward(ref velocity, ref shotSpeed); - } - - } - protected virtual Vector3 LerpedMoveForward(int flightTicks) - { - var v = Vec2Position(flightTicks); - return new Vector3(v.x, GetHeightAtTicks(flightTicks), v.y); - - } - protected virtual Vector3 NonLerpedMoveForward(ref Vector3 velocity, ref float shotSpeed) - { - Vector3 curPosition = ExactPosition; - if (!kinit) - { - float sr = shotRotation * Mathf.Deg2Rad + 3.14159f / 2.0f; - kinit = true; - var projectileProperties = def.projectile as ProjectilePropertiesCE; - ballisticCoefficient = projectileProperties.ballisticCoefficient.RandomInRange; - mass = projectileProperties.mass.RandomInRange; - radius = projectileProperties.diameter.RandomInRange / 2000; - gravity = projectileProperties.Gravity; - float sspt = shotSpeed / GenTicks.TicksPerRealSecond; - velocity = new Vector3(Mathf.Cos(sr) * Mathf.Cos(shotAngle) * sspt, Mathf.Sin(shotAngle) * sspt, Mathf.Sin(sr) * Mathf.Cos(shotAngle) * sspt); - initialSpeed = sspt; - } - Vector3 newPosition = curPosition + velocity; - Accelerate(ref velocity, ref shotSpeed); - return newPosition; - } - - // This can also be made virtual, and would be the ideal entry point for guided ammunition and rockets. - protected void Accelerate(ref Vector3 velocity, ref float shotSpeed) - { - float crossSectionalArea = radius; - crossSectionalArea *= crossSectionalArea * 3.14159f; - // 2.5f is half the mass of 1m² x 1cell of air. - var q = 2.5f * shotSpeed * shotSpeed; - var dragForce = q * crossSectionalArea / ballisticCoefficient; - // F = mA - // A = F / m - var a = (float)((-dragForce / (float)mass)); - var normalized = velocity.normalized; - velocity.x += a * normalized.x; - velocity.y += a * normalized.y - (float)(1 / ballisticCoefficient) * (float)gravity / GenTicks.TicksPerRealSecond; - velocity.z += a * normalized.z; - shotSpeed = velocity.magnitude; - } + - public IEnumerable NextPositions() + public virtual IEnumerable NextPositions() { int flightTicks = FlightTicks; float shotSpeed = this.shotSpeed; Vector3 velocity = this.velocity; for (int ticksToImpact = this.ticksToImpact - 1; ticksToImpact >= 0; ticksToImpact--) { - yield return MoveForward(ref velocity, ref shotSpeed, ref flightTicks); + yield return (def.projectile as ProjectilePropertiesCE).MoveForward(shotRotation, shotAngle, origin, Destination, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref exactPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref FlightTicks); } } @@ -1147,7 +1085,7 @@ public override void Tick() } LastPos = ExactPosition; ticksToImpact--; - Vector3 nextPosition = MoveForward(ref velocity, ref shotSpeed, ref FlightTicks); + Vector3 nextPosition = (def.projectile as ProjectilePropertiesCE).MoveForward(shotRotation, shotAngle, origin, Destination, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref exactPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref FlightTicks); if (!nextPosition.InBounds(Map)) { if (globalTargetInfo.IsValid) @@ -1413,7 +1351,7 @@ public virtual void Impact(Thing hitThing) var suppressThings = new List(); float dangerAmount = 0f; - var dir = new float?(origin.AngleTo(Vec2Position())); + var dir = new float?(origin.AngleTo((def.projectile as ProjectilePropertiesCE).Vec2Position(origin, Destination, startingTicksToImpact, FlightTicks))); // Opt-out for things without explosionRadius if (def.projectile.explosionRadius > 0f) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs index 3a55f3ae30..f0a9607bcf 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -56,6 +56,91 @@ public class ProjectilePropertiesCE : ProjectileProperties public float aimHeightOffset = 0; public float empShieldBreakChance = 1f; + public float collideDistance = 1f; + public float impactChance = 1f; + public float Gravity => CE_Utility.GravityConst * gravityFactor; + #region Moving methods + public virtual Vector2 Vec2Position(Vector2 origin, Vector2 destination, float startingTicksToImpact, int ticks) + { + return Vector2.Lerp(origin, destination, ticks / startingTicksToImpact); + } + public Vector3 MoveForward(float shotRotation, + float shotAngle, + Vector2 origin, + Vector2 destination, + float startingTicksToImpact, + float shotHeight, + ref bool kinit, + ref Vector3 velocity, + ref float shotSpeed, + ref Vector3 curPosition, + ref float mass, + ref float ballisticCoefficient, + ref float radius, + ref float gravity, + ref float initialSpeed, + ref int flightTicks) + { + flightTicks++; + if (lerpPosition) + { + return LerpedMoveForward(origin, destination, startingTicksToImpact, shotHeight, shotSpeed, shotAngle, flightTicks); + } + else + { + return NonLerpedMoveForward(shotRotation, shotAngle, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed); + } + + } + protected Vector3 LerpedMoveForward(Vector2 origin, Vector2 destination, float startingTicksToImpact, float shotHeight, float shotSpeed, float shotAngle, int ticks) + { + var v = Vec2Position(origin, destination, startingTicksToImpact, ticks); + return new Vector3(v.x, GetHeightAtTicks(shotHeight, shotSpeed, shotAngle, ticks), v.y); + + } + protected virtual Vector3 NonLerpedMoveForward(float shotRotation, float shotAngle, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed) + { + if (!kinit) + { + float sr = shotRotation * Mathf.Deg2Rad + 3.14159f / 2.0f; + kinit = true; + ballisticCoefficient = this.ballisticCoefficient.RandomInRange; + mass = this.mass.RandomInRange; + radius = diameter.RandomInRange / 2000; + gravity = Gravity; + float sspt = shotSpeed / GenTicks.TicksPerRealSecond; + velocity = new Vector3(Mathf.Cos(sr) * Mathf.Cos(shotAngle) * sspt, Mathf.Sin(shotAngle) * sspt, Mathf.Sin(sr) * Mathf.Cos(shotAngle) * sspt); + initialSpeed = sspt; + } + Vector3 newPosition = curPosition + velocity; + Accelerate(radius, ballisticCoefficient, mass, gravity, ref velocity, ref shotSpeed); + return newPosition; + } + + // This can also be made virtual, and would be the ideal entry point for guided ammunition and rockets. + protected void Accelerate(float radius, float ballisticCoefficient, float mass, float gravity, ref Vector3 velocity, ref float shotSpeed) + { + float crossSectionalArea = radius; + crossSectionalArea *= crossSectionalArea * 3.14159f; + // 2.5f is half the mass of 1m² x 1cell of air. + var q = 2.5f * shotSpeed * shotSpeed; + var dragForce = q * crossSectionalArea / ballisticCoefficient; + // F = mA + // A = F / m + var a = (float)((-dragForce / (float)mass)); + var normalized = velocity.normalized; + velocity.x += a * normalized.x; + velocity.y += a * normalized.y - (float)(1 / ballisticCoefficient) * (float)gravity / GenTicks.TicksPerRealSecond; + velocity.z += a * normalized.z; + shotSpeed = velocity.magnitude; + } + + protected float GetHeightAtTicks(float shotHeight, float shotSpeed, float shotAngle, int ticks) + { + var seconds = ((float)ticks) / GenTicks.TicksPerRealSecond; + return (float)Math.Round(shotHeight + shotSpeed * Mathf.Sin(shotAngle) * seconds - (CE_Utility.GravityConst * seconds * seconds) / 2f, 3); + } + #endregion } } From 5c7a14b3794a1eaafc92cbc679061dcd402b6847 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sun, 11 Aug 2024 21:42:18 +0600 Subject: [PATCH 009/127] Moved NextPositions to ProjectilePropetiesCE --- .../Projectiles/ProjectileCE.cs | 13 --------- .../Projectiles/ProjectilePropertiesCE.cs | 28 +++++++++++++++++++ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 9523e23a05..8c7908baa4 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -1062,19 +1062,6 @@ protected void ApplySuppression(Pawn pawn, float suppressionMultiplier = 1f) } } - - - public virtual IEnumerable NextPositions() - { - int flightTicks = FlightTicks; - float shotSpeed = this.shotSpeed; - Vector3 velocity = this.velocity; - for (int ticksToImpact = this.ticksToImpact - 1; ticksToImpact >= 0; ticksToImpact--) - { - yield return (def.projectile as ProjectilePropertiesCE).MoveForward(shotRotation, shotAngle, origin, Destination, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref exactPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref FlightTicks); - } - } - #region Tick/Draw public override void Tick() { diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs index f0a9607bcf..1b71baafa5 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs @@ -5,6 +5,10 @@ using RimWorld; using Verse; using UnityEngine; +using Rimatomics; +using static UnityEngine.UI.CanvasScaler; +using static UnityEngine.UI.Image; +using System.Security.Cryptography; namespace CombatExtended { @@ -141,6 +145,30 @@ protected float GetHeightAtTicks(float shotHeight, float shotSpeed, float shotAn var seconds = ((float)ticks) / GenTicks.TicksPerRealSecond; return (float)Math.Round(shotHeight + shotSpeed * Mathf.Sin(shotAngle) * seconds - (CE_Utility.GravityConst * seconds * seconds) / 2f, 3); } + + public virtual IEnumerable NextPositions(float shotRotation, + float shotAngle, + Vector2 origin, + Vector2 destination, + float startingTicksToImpact, + float shotHeight, + bool kinit, + Vector3 velocity, + float shotSpeed, + Vector3 curPosition, + float mass, + float ballisticCoefficient, + float radius, + float gravity, + float initialSpeed, + int flightTicks, + int ticksToImpact) + { + for (; ticksToImpact >= 0; ticksToImpact--) + { + yield return MoveForward(shotRotation, shotAngle, origin, destination, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); + } + } #endregion } } From f7c929d103e4501a296f542b764d6f3c527648de Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 15 Aug 2024 19:16:09 +0600 Subject: [PATCH 010/127] Returned NextPositions to ProjectileCE --- .../CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 8c7908baa4..cd63cafb31 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -1062,6 +1062,8 @@ protected void ApplySuppression(Pawn pawn, float suppressionMultiplier = 1f) } } + public virtual IEnumerable NextPositions => (def.projectile as ProjectilePropertiesCE).NextPositions(shotRotation, shotAngle, origin, Destination, startingTicksToImpact, shotHeight, kinit, velocity, shotSpeed, ExactPosition, mass, ballisticCoefficient, radius, gravity, initialSpeed, FlightTicks); + #region Tick/Draw public override void Tick() { From 10ae25193f4c2f2b7caabc2e759daf51687a5fdb Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 16 Aug 2024 00:13:23 +0600 Subject: [PATCH 011/127] 2D segments intersection check --- .../CombatExtended/CE_Utility.cs | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/Source/CombatExtended/CombatExtended/CE_Utility.cs b/Source/CombatExtended/CombatExtended/CE_Utility.cs index 2c319e90b7..fb4c96fbe0 100644 --- a/Source/CombatExtended/CombatExtended/CE_Utility.cs +++ b/Source/CombatExtended/CombatExtended/CE_Utility.cs @@ -1452,6 +1452,35 @@ public static float DistanceToSegment(this Vector3 point, Vector3 lineStart, Vec return Mathf.Sqrt(dx * dx + dz * dz); } + /// + /// Finds intersection point for two segments + /// + /// First point of first segment + /// Second point of first segment + /// First point of second segment + /// Second point of second segment + /// Intersection point or + /// True if intersects, false if not + public static bool TryFindIntersectionPoint(Vector2 A, Vector2 B, Vector2 C, Vector2 D, out Vector2 result) + { + float x1 = A.x, y1 = A.y, x2 = B.x, y2 = B.y, x3 = C.x, y3 = C.y, x4 = D.x, y4 = D.y; + var det = ((x4 - x3) * (y2 - y1) - (y4 - y3) * (x2 - x1)); + if (Mathf.Abs(det) < 0.0000001f) + { + result = Vector2.negativeInfinity; + return false; + } + var alpha = ((x4 - x3) * (y3 - y1) - (y4 - y3) * (x3 - x1)) / det; + var beta = ((x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1)) / det; + if (alpha < 0.0f || alpha > 1.0f || beta < 0.0f || beta > 1.0f) + { + result = Vector2.negativeInfinity; + return false; + } + result = new Vector2(x1 + alpha * (x2 - x1), y1 + alpha * (y2 - y1)); + return true; + } + public static Vector3 ToVec3Gridified(this Vector3 originalVec3) { Vector2 tempVec2 = new Vector2(originalVec3.normalized.x, originalVec3.normalized.z); @@ -1611,5 +1640,38 @@ public static Pawn GetRandomWorldPawn(this Faction faction, bool capableOfCombat } public static FactionStrengthTracker GetStrengthTracker(this Faction faction) => Find.World.GetComponent().GetFactionTracker(faction); + + internal static IEnumerable ContainedThings(this IThingHolder thingHolder) + { + if (thingHolder == null) + { + yield break; + } + var heldThings = thingHolder.GetDirectlyHeldThings(); + if (heldThings != null) + { + foreach (var thing in heldThings) + { + if (thing is IThingHolder childThingHolder && (thing is Skyfaller || thing is IActiveDropPod)) + { + foreach (var childThing in ContainedThings(childThingHolder)) + { + yield return childThing; + } + if (thing is IActiveDropPod dropPod) + { + foreach (var childThing in ContainedThings(dropPod.Contents)) + { + yield return childThing; + } + } + } + else if (thing != null) + { + yield return thing; + } + } + } + } } } From 343c4cda55702c12b15baf368253de0e406649f8 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 16 Aug 2024 00:13:47 +0600 Subject: [PATCH 012/127] NextPosition Changes --- .../CombatExtended/Projectiles/ProjectilePropertiesCE.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs index 1b71baafa5..68ee601274 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs @@ -150,7 +150,7 @@ public virtual IEnumerable NextPositions(float shotRotation, float shotAngle, Vector2 origin, Vector2 destination, - float startingTicksToImpact, + float ticksToImpact, float shotHeight, bool kinit, Vector3 velocity, @@ -161,12 +161,11 @@ public virtual IEnumerable NextPositions(float shotRotation, float radius, float gravity, float initialSpeed, - int flightTicks, - int ticksToImpact) + int flightTicks) { for (; ticksToImpact >= 0; ticksToImpact--) { - yield return MoveForward(shotRotation, shotAngle, origin, destination, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); + yield return MoveForward(shotRotation, shotAngle, origin, destination, ticksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); } } #endregion From c9d620cb34b3e2881233d2669917db5b6fe7f560 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 16 Aug 2024 00:14:19 +0600 Subject: [PATCH 013/127] Initial commit for CIWS verb --- .../CombatExtended/Verbs/Verb_ShootCE_CIWS.cs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs new file mode 100644 index 0000000000..b47767a521 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs @@ -0,0 +1,33 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace CombatExtended +{ + public class Verb_ShootCE_CIWS : Verb_ShootCE + { + protected int maximumPredectionTicks = 40; + public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine) + { + var targetComp = targ.Thing?.TryGetComp(); + if (targetComp != null) + { + + } + if (targ.Thing is Skyfaller skyfaller) + { + + } + if (targ.Thing is ProjectileCE projectile) + { + + } + return base.TryFindCEShootLineFromTo(root, targ, out resultingLine); + } + } +} From b4b8bd1ac6b40d485ea87169d3a2a9c285ca65b6 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 16 Aug 2024 00:25:58 +0600 Subject: [PATCH 014/127] Initial commit for CIWS projectile and turret --- .../Projectiles/ProjectileCE_CIWS.cs | 65 +++++++++++++++++++ .../CombatExtended/Things/Building_CIWS_CE.cs | 53 +++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs create mode 100644 Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs new file mode 100644 index 0000000000..406a6689e0 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs @@ -0,0 +1,65 @@ +using Mono.Unix.Native; +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; +using Verse.Sound; + +namespace CombatExtended +{ + internal class ProjectileCE_CIWS : ProjectileCE + { + #region Caching + protected static Dictionary> CIWSProjectiles = new Dictionary>(); + public static IEnumerable ProjectilesAt(Map map) + { + CIWSProjectiles.TryGetValue(map, out var targets); + return targets ?? Enumerable.Empty(); + } + + public override void SpawnSetup(Map map, bool respawningAfterLoad) + { + base.SpawnSetup(map, respawningAfterLoad); + if (map == null) + { + return; + } + if (!CIWSProjectiles.TryGetValue(map, out var targetList)) + { + CIWSProjectiles[map] = targetList = new List(); + } + targetList.Add(this); + } + public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish) + { + Map map = Map; + base.DeSpawn(mode); + if (CIWSProjectiles.TryGetValue(map, out var targetList)) + { + targetList.Remove(this); + if (targetList.Count <= 0) + { + CIWSProjectiles.Remove(map); + } + } + } + #endregion + + public virtual float CollideDistance => (def.projectile as ProjectilePropertiesCE)?.collideDistance ?? 1f; + public virtual float ImpactChance => (def.projectile as ProjectilePropertiesCE)?.impactChance ?? 1f; + public override void Tick() + { + ticksToImpact++; //do not allow it hit zero + base.Tick(); + TryCollideWith(intendedTargetThing); + } + protected override bool CheckForCollisionBetween() + { + return false; + } + } +} diff --git a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs new file mode 100644 index 0000000000..bac30364dd --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace CombatExtended +{ + public class Building_CIWS_CE : Building_TurretGunCE + { + IEnumerable ciws; + public IEnumerable CIWS => ciws ??= this.GetComps().ToList(); + + public override Verb AttackVerb + { + get + { + foreach (var ciws in CIWS) + { + if (ciws.HasTarget) + { + var verb = ciws.Verb; + if (verb != null) + { + return verb; + } + } + } + return base.AttackVerb; + } + } + public override void DrawExtraSelectionOverlays() + { + base.DrawExtraSelectionOverlays(); + foreach (var verb in GunCompEq.AllVerbs.Except(AttackVerb)) + { + float range = verb.verbProps.range; + if (range < 90f) + { + GenDraw.DrawRadiusRing(base.Position, range); + } + float num = verb.verbProps.EffectiveMinRange(true); + if (num < 90f && num > 0.1f) + { + GenDraw.DrawRadiusRing(base.Position, num); + } + } + + } + } +} From ed04020e83fb4192993302914ff4ba63efaf94a5 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 16 Aug 2024 00:26:51 +0600 Subject: [PATCH 015/127] Name fix --- .../CombatExtended/CombatExtended/Comps/CompCIWSProjectile.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSProjectile.cs index f1d6078bea..8985fa9fa0 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSProjectile.cs @@ -21,7 +21,7 @@ public override Verb Verb { get { - return Turret.GunCompEq.AllVerbs.OfType().FirstOrDefault() ?? base.Verb; + return Turret.GunCompEq.AllVerbs.OfType().FirstOrDefault() ?? base.Verb; } } protected override bool IsFriendlyTo(Projectile thing) => base.IsFriendlyTo(thing) && !thing.Launcher.HostileTo(parent); From 45f241c1efe9772c6d03627a42bd668cba807b1e Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 16 Aug 2024 00:28:56 +0600 Subject: [PATCH 016/127] Another name fix --- .../CombatExtended/CombatExtended/Comps/CompCIWSSkyfaller.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSSkyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSSkyfaller.cs index 42a50c8170..d8eae050e8 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSSkyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSSkyfaller.cs @@ -19,10 +19,10 @@ public override Verb Verb { get { - return Turret.GunCompEq.AllVerbs.OfType().FirstOrDefault() ?? base.Verb; + return Turret.GunCompEq.AllVerbs.OfType().FirstOrDefault() ?? base.Verb; } } - protected override bool IsFriendlyTo(Skyfaller thing) => base.IsFriendlyTo(thing) && Utils.ContainedThings(thing).All(x => !x.HostileTo(parent)); + protected override bool IsFriendlyTo(Skyfaller thing) => base.IsFriendlyTo(thing) && thing.ContainedThings().All(x => !x.HostileTo(parent)); public override bool HasTarget => Turret.currentTargetInt.Thing is Skyfaller; } From 6b84eb7cfe96d1725c029165ab8b724fe1bd442d Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 16 Aug 2024 00:29:38 +0600 Subject: [PATCH 017/127] Temp CalculatePointForPreemptiveFire --- .../CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs index 85622712f6..5d5c3dd3c5 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs @@ -95,7 +95,7 @@ private Thing TryDropThing(Thing thing, Map map, IntVec3 position) if (contents?.spawnWipeMode == null) { GenPlace.TryPlaceThing(thing, position, map, ThingPlaceMode.Near, out thing2, null, null, rot); - } + } else if (contents?.setRotation != null) { thing2 = GenSpawn.Spawn(thing, position, map, contents.setRotation.Value, contents.spawnWipeMode.Value, false, false); @@ -117,9 +117,10 @@ private Thing TryDropThing(Thing thing, Map map, IntVec3 position) } return thing2; } - public virtual IntVec3 CalculatePointForPreemptiveFire(ThingDef projectile, Vector3 source, int tickOffset = 0) + public virtual bool CalculatePointForPreemptiveFire(ThingDef projectile, Vector3 source, out Vector3 result, int tickOffset = 0) { - return parent.CalculatePointForPreemptiveFire(projectile, source, tickOffset); + result = Vector3.zero; + return true; } } From afc44589c23062ec795b21d6a5d403d84d345270 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 16 Aug 2024 04:43:13 +0600 Subject: [PATCH 018/127] Improved base ciws tick --- .../CombatExtended/Comps/CompCIWS.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWS.cs index 513363fac0..1b498cb2a0 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWS.cs @@ -92,25 +92,31 @@ public override void CompTick() if (parent.IsHashIntervalTick(10) && Active && Verb.state != VerbState.Bursting && Turret.burstCooldownTicksLeft <= 0 && TryFindNewTarget(out var target)) { Turret.currentTargetInt = target; - Turret.BeginBurst(); - Turret.Top.TurretTopTick(); + //Turret.BeginBurst(); + //Turret.Top.TurretTopTick(); } } public virtual bool TryFindNewTarget(out LocalTargetInfo target) { + if (!(Verb is Verb_LaunchProjectileCE)) + { + target = LocalTargetInfo.Invalid; + return false; + } float range = this.Verb.verbProps.range; var _target = Targets.Where(x => Props.Interceptable(x.def) && !IgnoredDefs.Contains(x.def)).Where(x => !IsFriendlyTo(x)).FirstOrDefault(t => { - if (CIWS[parent.Map].Any(turret => turret.currentTargetInt.Thing == t) || CIWSProjectile.ProjectilesAt(parent.Map).Any(x => x.intendedTarget.Thing == t)) + var verb = Verb as Verb_LaunchProjectileCE; + if (CIWS[parent.Map].Any(turret => turret.currentTargetInt.Thing == t) || ProjectileCE_CIWS.ProjectilesAt(parent.Map).Any(x => x.intendedTarget.Thing == t)) { return false; } - float num = this.Verb.verbProps.EffectiveMinRange(t, this.parent); - var intersectionPoint = t.TryGetComp()?.CalculatePointForPreemptiveFire(Verb.GetProjectile(), parent.DrawPos, (int)Verb.verbProps.warmupTime) ?? t.CalculatePointForPreemptiveFire(Verb.GetProjectile(), parent.DrawPos, (int)Verb.verbProps.warmupTime); - if (!intersectionPoint.IsValid) + float num = verb.verbProps.EffectiveMinRange(t, this.parent); + if (!verb.TryFindCEShootLineFromTo(parent.Position, t, out var shootLine)) { return false; } + var intersectionPoint = shootLine.Dest; float num2 = intersectionPoint.DistanceToSquared(this.parent.Position); return num2 > num * num && num2 < range * range; }); From 5746b9213f3bd7339d734e81ac117728d2377d44 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 16 Aug 2024 04:48:24 +0600 Subject: [PATCH 019/127] TryFindShotLine for projectile --- .../CombatExtended/Verbs/Verb_ShootCE_CIWS.cs | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs index b47767a521..5bc4d6e1ec 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs @@ -25,7 +25,43 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ } if (targ.Thing is ProjectileCE projectile) { - + var instant = Projectile.projectile is ProjectilePropertiesCE projectilePropertiesCE && projectilePropertiesCE.isInstant; + if (instant) + { + resultingLine = new ShootLine(root, projectile.Position); + return true; + } + int i = 1; + if (projectile.def.projectile is ProjectilePropertiesCE target_ProjectilePropeties && Projectile.projectile is ProjectilePropertiesCE CIWS_ProjectilePropeties) + { + var targetPos1 = new Vector2(projectile.Position.x, projectile.Position.z); + foreach (var pos in projectile.NextPositions.Skip(1)) + { + if (i > maximumPredectionTicks) + { + break; + } + var report = ShiftVecReportFor(pos.ToIntVec3()); + ShiftTarget(report); + var originV3 = Shooter.Position.ToVector3Shifted(); + Vector2 originV2 = new Vector2(originV3.x, originV3.z), destinationV2 = new Vector2(pos.x, pos.z); + var positions = CIWS_ProjectilePropeties.NextPositions(shotRotation, shotAngle, originV2, destinationV2, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).Skip(i - 1).Take(2).ToList(); + if (positions.Count < 2) + { + resultingLine = default(ShootLine); + return false; + } + Vector2 ciwsPos1 = new Vector2(positions.First().x, positions.First().z), ciwsPos2 = new Vector2(positions.Last().x, positions.Last().z), targetPos2 = new Vector2(pos.x, pos.z); + + if (CE_Utility.TryFindIntersectionPoint(ciwsPos1, ciwsPos2, targetPos1, targetPos2, out var point)) + { + resultingLine = new ShootLine(Shooter.Position, point.ToVector3().ToIntVec3()); + return true; + } + targetPos1 = targetPos2; + i++; + } + } } return base.TryFindCEShootLineFromTo(root, targ, out resultingLine); } From 725c3dbf37c8494147f14c94cc9a391f5974079b Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 31 Oct 2024 13:24:13 +0600 Subject: [PATCH 020/127] Moved PenetrationAmount to ProjectileCE again --- .../CombatExtended/Projectiles/BulletCE.cs | 13 ------------- .../CombatExtended/Projectiles/ProjectileCE.cs | 5 ++++- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/BulletCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/BulletCE.cs index 10de688e0c..cdf97821a7 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/BulletCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/BulletCE.cs @@ -21,19 +21,6 @@ public class BulletCE : ProjectileCE public static RulePackDef Shelling => shellingDamageEvent ?? (shellingDamageEvent = DefDatabase.GetNamed("DamageEvent_Shelling")); - public virtual float PenetrationAmount - { - get - { - var projectilePropsCE = (ProjectilePropertiesCE)def.projectile; - var isSharpDmg = def.projectile.damageDef.armorCategory == DamageArmorCategoryDefOf.Sharp; - - float penetrationAmount = (equipment?.GetStatValue(StatDefOf.RangedWeapon_DamageMultiplier) ?? 1f) * (isSharpDmg ? projectilePropsCE.armorPenetrationSharp : projectilePropsCE.armorPenetrationBlunt); - - return lerpPosition ? penetrationAmount : penetrationAmount * RemainingKineticEnergyPct; - } - } - private void LogImpact(Thing hitThing, out LogEntry_DamageResult logEntry) { var ed = equipmentDef ?? ThingDef.Named("Gun_Autopistol"); diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index a88946cec7..e68d4f9b23 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -103,7 +103,10 @@ public virtual float PenetrationAmount { var projectilePropsCE = (ProjectilePropertiesCE)def.projectile; var isSharpDmg = def.projectile.damageDef.armorCategory == DamageArmorCategoryDefOf.Sharp; - return (equipment?.GetStatValue(StatDefOf.RangedWeapon_DamageMultiplier) ?? 1f) * (isSharpDmg ? projectilePropsCE.armorPenetrationSharp : projectilePropsCE.armorPenetrationBlunt); + + float penetrationAmount = (equipment?.GetStatValue(StatDefOf.RangedWeapon_DamageMultiplier) ?? 1f) * (isSharpDmg ? projectilePropsCE.armorPenetrationSharp : projectilePropsCE.armorPenetrationBlunt); + + return lerpPosition ? penetrationAmount : penetrationAmount * RemainingKineticEnergyPct; } } public virtual DamageInfo DamageInfo => new DamageInfo( From c2d470491c9bd8fca1b8fc80dd0de8b08adc6579 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 31 Oct 2024 13:48:25 +0600 Subject: [PATCH 021/127] Moved "MoveForward" logic to ProjectilePropetiesCE again --- .../Projectiles/ProjectileCE.cs | 51 +------------------ .../Projectiles/ProjectilePropertiesCE.cs | 20 +++++--- 2 files changed, 16 insertions(+), 55 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index e68d4f9b23..4e9c87a97b 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -1081,57 +1081,10 @@ protected void ApplySuppression(Pawn pawn, float suppressionMultiplier = 1f) } } - // If anyone wants to override how projectiles move, this can be made virtual. - // For now, it is non-virtual for performance. - protected Vector3 MoveForward() - { - Vector3 curPosition = ExactPosition; - float sr = shotRotation * Mathf.Deg2Rad + 3.14159f / 2.0f; - if (!kinit) - { - kinit = true; - var projectileProperties = def.projectile as ProjectilePropertiesCE; - ballisticCoefficient = projectileProperties.ballisticCoefficient.RandomInRange; - mass = projectileProperties.mass.RandomInRange; - radius = projectileProperties.diameter.RandomInRange / 2000; - gravity = projectileProperties.Gravity; - float sspt = shotSpeed / GenTicks.TicksPerRealSecond; - velocity = new Vector3(Mathf.Cos(sr) * Mathf.Cos(shotAngle) * sspt, Mathf.Sin(shotAngle) * sspt, Mathf.Sin(sr) * Mathf.Cos(shotAngle) * sspt); - initialSpeed = sspt; - } - Accelerate(); - Vector3 newPosition = curPosition + velocity; - shotSpeed = velocity.magnitude; - return newPosition; - } - // This is the ideal entry point for guided ammunition and rockets. - protected virtual void Accelerate() - { - AffectedByDrag(); - AffectedByGravity(); - } - protected void AffectedByGravity() - { - velocity.y -= gravity / GenTicks.TicksPerRealSecond; - } - - protected void AffectedByDrag() - { - float crossSectionalArea = radius; - crossSectionalArea *= crossSectionalArea * 3.14159f; - // 2.5f is half the mass of 1m² x 1cell of air. - var q = 2.5f * shotSpeed * shotSpeed; - var dragForce = q * crossSectionalArea / ballisticCoefficient; - // F = mA - // A = F / m - var a = (float)-dragForce / mass; - var normalized = velocity.normalized; - velocity.x += a * normalized.x; - velocity.y += a * normalized.y; - velocity.z += a * normalized.z; - } + // This is the ideal entry point for guided ammunition and rockets. + public virtual IEnumerable NextPositions => (def.projectile as ProjectilePropertiesCE).NextPositions(shotRotation, shotAngle, origin, Destination, startingTicksToImpact, shotHeight, kinit, velocity, shotSpeed, ExactPosition, mass, ballisticCoefficient, radius, gravity, initialSpeed, FlightTicks); #region Tick/Draw diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs index a3b477a648..985f6b4930 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs @@ -127,8 +127,18 @@ protected virtual Vector3 NonLerpedMoveForward(float shotRotation, float shotAng return newPosition; } - // This can also be made virtual, and would be the ideal entry point for guided ammunition and rockets. - protected void Accelerate(float radius, float ballisticCoefficient, float mass, float gravity, ref Vector3 velocity, ref float shotSpeed) + protected virtual void Accelerate(float radius, float ballisticCoefficient, float mass, float gravity, ref Vector3 velocity, ref float shotSpeed) + { + AffectedByDrag(radius, shotSpeed, ballisticCoefficient, mass, ref velocity); + AffectedByGravity(gravity, ref velocity); + } + + protected void AffectedByGravity(float gravity, ref Vector3 velocity) + { + velocity.y -= gravity / GenTicks.TicksPerRealSecond; + } + + protected void AffectedByDrag(float radius, float shotSpeed, float ballisticCoefficient, float mass, ref Vector3 velocity) { float crossSectionalArea = radius; crossSectionalArea *= crossSectionalArea * 3.14159f; @@ -137,14 +147,12 @@ protected void Accelerate(float radius, float ballisticCoefficient, float mass, var dragForce = q * crossSectionalArea / ballisticCoefficient; // F = mA // A = F / m - var a = (float)((-dragForce / (float)mass)); + var a = (float)-dragForce / mass; var normalized = velocity.normalized; velocity.x += a * normalized.x; - velocity.y += a * normalized.y - (float)(1 / ballisticCoefficient) * (float)gravity / GenTicks.TicksPerRealSecond; + velocity.y += a * normalized.y; velocity.z += a * normalized.z; - shotSpeed = velocity.magnitude; } - protected float GetHeightAtTicks(float shotHeight, float shotSpeed, float shotAngle, int ticks) { var seconds = ((float)ticks) / GenTicks.TicksPerRealSecond; From d23f77df6a9f0a5786076f68f7e15cbfac8dbd25 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 31 Oct 2024 16:44:27 +0600 Subject: [PATCH 022/127] CompCIWSTarget targeting method call Count warmup time when trying to predict position Not tested yet (as well as everything else about CIWS) --- .../CombatExtended/Verbs/Verb_ShootCE_CIWS.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs index 5bc4d6e1ec..c116d8d7df 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs @@ -14,16 +14,20 @@ public class Verb_ShootCE_CIWS : Verb_ShootCE protected int maximumPredectionTicks = 40; public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine) { + var originV3 = Shooter.Position.ToVector3Shifted(); var targetComp = targ.Thing?.TryGetComp(); + var ticksToSkip = (int)verbProps.warmupTime; if (targetComp != null) { - + var result = targetComp.CalculatePointForPreemptiveFire(Projectile, originV3, out var targetPos, ticksToSkip); + resultingLine = new ShootLine(originV3.ToIntVec3(), targetPos.ToIntVec3()); + return result; } - if (targ.Thing is Skyfaller skyfaller) + else if (targ.Thing is Skyfaller skyfaller) { } - if (targ.Thing is ProjectileCE projectile) + else if (targ.Thing is ProjectileCE projectile) { var instant = Projectile.projectile is ProjectilePropertiesCE projectilePropertiesCE && projectilePropertiesCE.isInstant; if (instant) @@ -35,7 +39,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ if (projectile.def.projectile is ProjectilePropertiesCE target_ProjectilePropeties && Projectile.projectile is ProjectilePropertiesCE CIWS_ProjectilePropeties) { var targetPos1 = new Vector2(projectile.Position.x, projectile.Position.z); - foreach (var pos in projectile.NextPositions.Skip(1)) + foreach (var pos in projectile.NextPositions.Skip(ticksToSkip)) { if (i > maximumPredectionTicks) { @@ -43,7 +47,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ } var report = ShiftVecReportFor(pos.ToIntVec3()); ShiftTarget(report); - var originV3 = Shooter.Position.ToVector3Shifted(); + Vector2 originV2 = new Vector2(originV3.x, originV3.z), destinationV2 = new Vector2(pos.x, pos.z); var positions = CIWS_ProjectilePropeties.NextPositions(shotRotation, shotAngle, originV2, destinationV2, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).Skip(i - 1).Take(2).ToList(); if (positions.Count < 2) From 315718dd24269a437bad093545e05814b058f139 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 31 Oct 2024 16:52:18 +0600 Subject: [PATCH 023/127] selecting CIWS projectile if possible for CIWS verbs --- .../Projectiles/ProjectilePropertiesCE.cs | 1 + .../CombatExtended/Verbs/Verb_ShootCE_CIWS.cs | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs index 985f6b4930..5700cf056d 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs @@ -69,6 +69,7 @@ public class ProjectilePropertiesCE : ProjectileProperties public float impactChance = 1f; public float Gravity => CE_Utility.GravityConst * gravityFactor; + public ThingDef CIWSVersion; #region Moving methods public virtual Vector2 Vec2Position(Vector2 origin, Vector2 destination, float startingTicksToImpact, int ticks) { diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs index c116d8d7df..c4c903046d 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs @@ -11,6 +11,16 @@ namespace CombatExtended { public class Verb_ShootCE_CIWS : Verb_ShootCE { + public override ThingDef Projectile + { + get + { + var result = base.Projectile; + var ciwsVersion = (result?.projectile as ProjectilePropertiesCE)?.CIWSVersion; + return ciwsVersion ?? result; + } + } + protected int maximumPredectionTicks = 40; public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine) { From 663856314cb75e1c07cda5e3dfee6d5ccb67ee10 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 31 Oct 2024 17:04:55 +0600 Subject: [PATCH 024/127] Warning about wrong projectile --- .../CombatExtended/Verbs/Verb_ShootCE_CIWS.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs index c4c903046d..1257d33866 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs @@ -17,6 +17,10 @@ public override ThingDef Projectile { var result = base.Projectile; var ciwsVersion = (result?.projectile as ProjectilePropertiesCE)?.CIWSVersion; + if (ciwsVersion == null && typeof(ProjectileCE_CIWS).IsAssignableFrom(result.thingClass)) + { + Log.WarningOnce($"{result} is not a CIWS projectile and the projectile does not have the CIWS version specified in its properties. Must be on-ground projectile used for CIWS", result.GetHashCode()); + } return ciwsVersion ?? result; } } @@ -57,7 +61,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ } var report = ShiftVecReportFor(pos.ToIntVec3()); ShiftTarget(report); - + Vector2 originV2 = new Vector2(originV3.x, originV3.z), destinationV2 = new Vector2(pos.x, pos.z); var positions = CIWS_ProjectilePropeties.NextPositions(shotRotation, shotAngle, originV2, destinationV2, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).Skip(i - 1).Take(2).ToList(); if (positions.Count < 2) From 4da40bd88f3b4e13824579325105c3cf30dacf77 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 31 Oct 2024 22:27:37 +0600 Subject: [PATCH 025/127] Comp -> Verb MultiVerb turret --- .../CombatExtended/Comps/CompCIWS.cs | 146 ------------------ .../CombatExtended/Comps/VerbCIWS.cs | 99 ++++++++++++ ...IWSProjectile.cs => VerbCIWSProjectile.cs} | 22 +-- ...pCIWSSkyfaller.cs => VerbCIWSSkyfaller.cs} | 22 +-- .../CombatExtended/ITargetSearcher.cs | 14 ++ .../CombatExtended/Things/Building_CIWS_CE.cs | 53 +++---- .../Things/Building_Turret_MultiVerbs.cs | 61 ++++++++ .../CombatExtended/TurretTracker.cs | 16 +- 8 files changed, 223 insertions(+), 210 deletions(-) delete mode 100644 Source/CombatExtended/CombatExtended/Comps/CompCIWS.cs create mode 100644 Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs rename Source/CombatExtended/CombatExtended/Comps/{CompCIWSProjectile.cs => VerbCIWSProjectile.cs} (55%) rename Source/CombatExtended/CombatExtended/Comps/{CompCIWSSkyfaller.cs => VerbCIWSSkyfaller.cs} (56%) create mode 100644 Source/CombatExtended/CombatExtended/ITargetSearcher.cs create mode 100644 Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWS.cs deleted file mode 100644 index 1b498cb2a0..0000000000 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWS.cs +++ /dev/null @@ -1,146 +0,0 @@ -using RimWorld; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using UnityEngine.SocialPlatforms; -using Verse; -using Verse.Sound; - -namespace CombatExtended -{ - public abstract class CompCIWS : ThingComp - { - #region Caching - protected static Dictionary> CIWS = new Dictionary>(); - - public override void PostSpawnSetup(bool respawningAfterLoad) - { - base.PostSpawnSetup(respawningAfterLoad); - if (parent.Map == null) - { - return; - } - if (!CIWS.TryGetValue(parent.Map, out var targetList)) - { - CIWS[parent.Map] = targetList = new List(); - } - targetList.Add(Turret); - - //IgnoredDefs ??= Props.Ignored.Union(Mod.Settings?.settings?.FirstOrDefault(x => x.ciws == parent.def)?.IgnoredDefs ?? Enumerable.Empty()).ToList(); - } - public override void PostDeSpawn(Map map) - { - base.PostDeSpawn(map); - if (CIWS.TryGetValue(map, out var targetList)) - { - targetList.Remove(Turret); - } - } - #endregion - protected bool holdFire; - public IEnumerable IgnoredDefs { get; private set; } - public Building_TurretGun Turret => parent as Building_TurretGun; - public CompProperties_CIWS Props => props as CompProperties_CIWS; - public virtual Verb Verb => Turret.GunCompEq.PrimaryVerb; - public abstract bool HasTarget { get; } - protected abstract string HoldLabel { get; } - protected abstract string HoldDesc { get; } - protected virtual string HoldIcon => "UI/Commands/HoldFire"; - public override void PostExposeData() - { - base.PostExposeData(); - Scribe_Values.Look(ref holdFire, nameof(holdFire), false); - } - public override IEnumerable CompGetGizmosExtra() - { - foreach (var gizmo in base.CompGetGizmosExtra()) - { - yield return gizmo; - } - if (Turret.CanToggleHoldFire) - { - yield return new Command_Toggle - { - defaultLabel = HoldLabel.Translate(), - defaultDesc = HoldDesc.Translate(), - icon = ContentFinder.Get(HoldIcon, true), - hotKey = KeyBindingDefOf.Misc6, - toggleAction = delegate () - { - this.holdFire = !this.holdFire; - if (this.holdFire && HasTarget) - { - Turret.ResetForcedTarget(); - } - }, - isActive = (() => this.holdFire) - }; - } - } - public virtual bool Active => !holdFire && Turret.Active; - } - public abstract class CompCIWS : CompCIWS where TargetType : Thing - { - - public override void CompTick() - { - base.CompTick(); - - if (parent.IsHashIntervalTick(10) && Active && Verb.state != VerbState.Bursting && Turret.burstCooldownTicksLeft <= 0 && TryFindNewTarget(out var target)) - { - Turret.currentTargetInt = target; - //Turret.BeginBurst(); - //Turret.Top.TurretTopTick(); - } - } - public virtual bool TryFindNewTarget(out LocalTargetInfo target) - { - if (!(Verb is Verb_LaunchProjectileCE)) - { - target = LocalTargetInfo.Invalid; - return false; - } - float range = this.Verb.verbProps.range; - var _target = Targets.Where(x => Props.Interceptable(x.def) && !IgnoredDefs.Contains(x.def)).Where(x => !IsFriendlyTo(x)).FirstOrDefault(t => - { - var verb = Verb as Verb_LaunchProjectileCE; - if (CIWS[parent.Map].Any(turret => turret.currentTargetInt.Thing == t) || ProjectileCE_CIWS.ProjectilesAt(parent.Map).Any(x => x.intendedTarget.Thing == t)) - { - return false; - } - float num = verb.verbProps.EffectiveMinRange(t, this.parent); - if (!verb.TryFindCEShootLineFromTo(parent.Position, t, out var shootLine)) - { - return false; - } - var intersectionPoint = shootLine.Dest; - float num2 = intersectionPoint.DistanceToSquared(this.parent.Position); - return num2 > num * num && num2 < range * range; - }); - if (_target != null) - { - target = _target; - return true; - } - target = null; - return false; - } - protected virtual bool IsFriendlyTo(TargetType thing) => ((!thing.TryGetComp()?.Props.alwaysIntercept) ?? false) && !thing.HostileTo(parent); - public abstract IEnumerable Targets { get; } - } - - public abstract class CompProperties_CIWS : CompProperties - { - public List ignored = new List(); - public IEnumerable Ignored => ignored; - public virtual bool Interceptable(ThingDef targetDef) => true; - - private IEnumerable allTargets; - - public IEnumerable AllTargets => allTargets ??= InitAllTargets(); - protected abstract IEnumerable InitAllTargets(); - } -} diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs new file mode 100644 index 0000000000..0dc89f3935 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -0,0 +1,99 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using UnityEngine.SocialPlatforms; +using Verse; +using Verse.Sound; + +namespace CombatExtended +{ + public abstract class VerbCIWS : Verb_ShootCE_CIWS, ITargetSearcher + { + + protected bool holdFire; + public IEnumerable IgnoredDefs { get; private set; } + public Building_TurretGun Turret => Caster as Building_TurretGun; + public VerbProperties_CIWS Props => verbProps as VerbProperties_CIWS; + protected abstract string HoldLabel { get; } + protected abstract string HoldDesc { get; } + protected virtual string HoldIcon => "UI/Commands/HoldFire"; + + //public override IEnumerable CompGetGizmosExtra() + //{ + // foreach (var gizmo in base.CompGetGizmosExtra()) + // { + // yield return gizmo; + // } + // if (Turret.CanToggleHoldFire) + // { + // yield return new Command_Toggle + // { + // defaultLabel = HoldLabel.Translate(), + // defaultDesc = HoldDesc.Translate(), + // icon = ContentFinder.Get(HoldIcon, true), + // hotKey = KeyBindingDefOf.Misc6, + // toggleAction = delegate () + // { + // this.holdFire = !this.holdFire; + // if (this.holdFire && HasTarget) + // { + // Turret.ResetForcedTarget(); + // } + // }, + // isActive = (() => this.holdFire) + // }; + // } + //} + public virtual bool Active => !holdFire && Turret.Active; + public abstract bool TryFindNewTarget(out LocalTargetInfo target); + } + public abstract class VerbCIWS : VerbCIWS where TargetType : Thing + { + + public override bool TryFindNewTarget(out LocalTargetInfo target) + { + float range = this.verbProps.range; + var _target = Targets.Where(x => Props.Interceptable(x.def) && !IgnoredDefs.Contains(x.def)).Where(x => !IsFriendlyTo(x)).FirstOrDefault(t => + { + var verb = this; + if (Caster.Map.GetComponent().CIWS.Any(turret => turret.currentTargetInt.Thing == t) || ProjectileCE_CIWS.ProjectilesAt(Caster.Map).Any(x => x.intendedTarget.Thing == t)) + { + return false; + } + float num = verb.verbProps.EffectiveMinRange(t, this.Caster); + if (!verb.TryFindCEShootLineFromTo(Caster.Position, t, out var shootLine)) + { + return false; + } + var intersectionPoint = shootLine.Dest; + float num2 = intersectionPoint.DistanceToSquared(Caster.Position); + return num2 > num * num && num2 < range * range; + }); + if (_target != null) + { + target = _target; + return true; + } + target = null; + return false; + } + protected virtual bool IsFriendlyTo(TargetType thing) => ((!thing.TryGetComp()?.Props.alwaysIntercept) ?? false) && !thing.HostileTo(Caster); + public abstract IEnumerable Targets { get; } + } + + public abstract class VerbProperties_CIWS : VerbPropertiesCE + { + public List ignored = new List(); + public IEnumerable Ignored => ignored; + public virtual bool Interceptable(ThingDef targetDef) => true; + + private IEnumerable allTargets; + + public IEnumerable AllTargets => allTargets ??= InitAllTargets(); + protected abstract IEnumerable InitAllTargets(); + } +} diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs similarity index 55% rename from Source/CombatExtended/CombatExtended/Comps/CompCIWSProjectile.cs rename to Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 8985fa9fa0..c665e09084 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -5,33 +5,25 @@ using System.Text; using System.Threading.Tasks; using Verse; -using static HarmonyLib.Code; namespace CombatExtended { - public class CompCIWSProjectile : CompCIWS + public class VerbCIWSProjectile : VerbCIWS { protected override string HoldDesc => "HoldCloseInProjectilesFireDesc"; protected override string HoldLabel => "HoldCloseInProjectilesFire"; - public new CompProperties_CIWSProjectile Props => props as CompProperties_CIWSProjectile; + public new CompProperties_CIWSProjectile Props => verbProps as CompProperties_CIWSProjectile; - public override IEnumerable Targets => parent.Map?.listerThings.ThingsInGroup(ThingRequestGroup.Projectile).OfType() ?? Array.Empty(); + public override IEnumerable Targets => Caster.Map?.listerThings.ThingsInGroup(ThingRequestGroup.Projectile).OfType() ?? Array.Empty(); - public override Verb Verb - { - get - { - return Turret.GunCompEq.AllVerbs.OfType().FirstOrDefault() ?? base.Verb; - } - } - protected override bool IsFriendlyTo(Projectile thing) => base.IsFriendlyTo(thing) && !thing.Launcher.HostileTo(parent); - public override bool HasTarget => Turret.currentTargetInt.Thing is Projectile; + protected override bool IsFriendlyTo(Projectile thing) => base.IsFriendlyTo(thing) && !thing.Launcher.HostileTo(Caster); + public override bool ValidateTarget(LocalTargetInfo targetInfo, bool showMessages) => Turret.currentTargetInt.Thing is Projectile; } - public class CompProperties_CIWSProjectile : CompProperties_CIWS + public class CompProperties_CIWSProjectile : VerbProperties_CIWS { public CompProperties_CIWSProjectile() { - this.compClass = typeof(CompCIWSProjectile); + this.verbClass = typeof(VerbCIWSProjectile); } public override bool Interceptable(ThingDef targetDef) => targetDef.projectile.speed < maximumSpeed && targetDef.projectile.flyOverhead && base.Interceptable(targetDef); public float maximumSpeed = 80; diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSSkyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs similarity index 56% rename from Source/CombatExtended/CombatExtended/Comps/CompCIWSSkyfaller.cs rename to Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs index d8eae050e8..81fa753745 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSSkyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs @@ -9,28 +9,22 @@ namespace CombatExtended { - public class CompCIWSSkyfaller : CompCIWS + public class VerbCIWSSkyfaller : VerbCIWS { protected override string HoldDesc => "HoldSkyfallerFireDesc"; protected override string HoldLabel => "HoldSkyfallerFire"; - public override IEnumerable Targets => parent.Map?.listerThings.ThingsInGroup(Verse.ThingRequestGroup.ActiveDropPod).OfType().Union(CompCIWSTarget.Targets(parent.Map).OfType()); + public override IEnumerable Targets => Caster.Map?.listerThings.ThingsInGroup(Verse.ThingRequestGroup.ActiveDropPod).OfType().Union(CompCIWSTarget.Targets(Caster.Map).OfType()); - public override Verb Verb - { - get - { - return Turret.GunCompEq.AllVerbs.OfType().FirstOrDefault() ?? base.Verb; - } - } - protected override bool IsFriendlyTo(Skyfaller thing) => base.IsFriendlyTo(thing) && thing.ContainedThings().All(x => !x.HostileTo(parent)); - public override bool HasTarget => Turret.currentTargetInt.Thing is Skyfaller; + + protected override bool IsFriendlyTo(Skyfaller thing) => base.IsFriendlyTo(thing) && thing.ContainedThings().All(x => !x.HostileTo(Caster)); + public override bool ValidateTarget(LocalTargetInfo targetInfo, bool showMessages) => Turret.currentTargetInt.Thing is Skyfaller; } - public class CompProperties_CIWSSkyfaller : CompProperties_CIWS + public class VerbProperties_CIWSSkyfaller : VerbProperties_CIWS { - public CompProperties_CIWSSkyfaller() + public VerbProperties_CIWSSkyfaller() { - this.compClass = typeof(CompCIWSSkyfaller); + this.verbClass = typeof(VerbCIWSSkyfaller); } protected override IEnumerable InitAllTargets() => DefDatabase.AllDefsListForReading.Where(x => (typeof(Skyfaller).IsAssignableFrom(x.thingClass) && x.HasComp()) || typeof(IActiveDropPod).IsAssignableFrom(x.thingClass)); } diff --git a/Source/CombatExtended/CombatExtended/ITargetSearcher.cs b/Source/CombatExtended/CombatExtended/ITargetSearcher.cs new file mode 100644 index 0000000000..663c8dfe6d --- /dev/null +++ b/Source/CombatExtended/CombatExtended/ITargetSearcher.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace CombatExtended +{ + public interface ITargetSearcher + { + bool TryFindNewTarget(out LocalTargetInfo target); + } +} diff --git a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs index bac30364dd..c01528c88d 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs @@ -1,4 +1,6 @@ -using System; +using Mono.Unix.Native; +using RimWorld; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -8,46 +10,29 @@ namespace CombatExtended { - public class Building_CIWS_CE : Building_TurretGunCE + public class Building_CIWS_CE : Building_Turret_MultiVerbs { - IEnumerable ciws; - public IEnumerable CIWS => ciws ??= this.GetComps().ToList(); + #region Caching - public override Verb AttackVerb + public override void SpawnSetup(Map map, bool respawningAfterLoad) { - get - { - foreach (var ciws in CIWS) - { - if (ciws.HasTarget) - { - var verb = ciws.Verb; - if (verb != null) - { - return verb; - } - } - } - return base.AttackVerb; - } + base.SpawnSetup(map, respawningAfterLoad); + map.GetComponent().Register(this); + } + public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish) + { + Map.GetComponent()?.Unregister(this); + base.DeSpawn(mode); } - public override void DrawExtraSelectionOverlays() + #endregion + + IEnumerable IgnoredDefs { - base.DrawExtraSelectionOverlays(); - foreach (var verb in GunCompEq.AllVerbs.Except(AttackVerb)) + get { - float range = verb.verbProps.range; - if (range < 90f) - { - GenDraw.DrawRadiusRing(base.Position, range); - } - float num = verb.verbProps.EffectiveMinRange(true); - if (num < 90f && num > 0.1f) - { - GenDraw.DrawRadiusRing(base.Position, num); - } + Log.WarningOnce("IgnoredDefs not implemented yet", 82469265); + return Enumerable.Empty(); } - } } } diff --git a/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs b/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs new file mode 100644 index 0000000000..fba1572521 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace CombatExtended +{ + public class Building_Turret_MultiVerbs : Building_TurretGunCE + { + public override Verb AttackVerb + { + get + { + if (CurrentTarget.IsValid) + { + foreach (var verb in GunCompEq.AllVerbs) + { + if (verb.ValidateTarget(CurrentTarget, false)) + { + return verb; + } + } + } + + return base.AttackVerb; + } + } + IEnumerable cachedVerbsWithTargetSearcher; + protected IEnumerable VerbsWithTargetSearcher => cachedVerbsWithTargetSearcher ??= GunCompEq.AllVerbs.OfType(); + public override void DrawExtraSelectionOverlays() + { + base.DrawExtraSelectionOverlays(); + foreach (var verb in GunCompEq.AllVerbs.Except(AttackVerb)) + { + float range = verb.verbProps.range; + if (range < 90f) + { + GenDraw.DrawRadiusRing(base.Position, range); + } + float num = verb.verbProps.EffectiveMinRange(true); + if (num < 90f && num > 0.1f) + { + GenDraw.DrawRadiusRing(base.Position, num); + } + } + } + public override LocalTargetInfo TryFindNewTarget() + { + foreach (var verb in VerbsWithTargetSearcher) + { + if (verb.TryFindNewTarget(out var target)) + { + return target; + } + } + return base.TryFindNewTarget(); + } + } +} diff --git a/Source/CombatExtended/CombatExtended/TurretTracker.cs b/Source/CombatExtended/CombatExtended/TurretTracker.cs index 2aca9951f7..f251298f5d 100644 --- a/Source/CombatExtended/CombatExtended/TurretTracker.cs +++ b/Source/CombatExtended/CombatExtended/TurretTracker.cs @@ -10,6 +10,7 @@ namespace CombatExtended public class TurretTracker : MapComponent { public HashSet Turrets = new HashSet(); + public HashSet CIWS = new HashSet(); public TurretTracker(Map map) : base(map) { @@ -22,7 +23,13 @@ public void Register(Building_Turret t) Turrets.Add(t); } } - + public void Register(Building_CIWS_CE ciws) + { + if (!CIWS.Contains(ciws)) + { + CIWS.Add(ciws); + } + } public void Unregister(Building_Turret t) { if (Turrets.Contains(t)) @@ -30,6 +37,13 @@ public void Unregister(Building_Turret t) Turrets.Remove(t); } } + public void Unregister(Building_CIWS_CE ciws) + { + if (CIWS.Contains(ciws)) + { + CIWS.Remove(ciws); + } + } // Returns the closest turret to `position` on the which matches the criteria set in `validator` public Thing ClosestTurret(IntVec3 position, PathEndMode pathEndMode, TraverseParms parms, float maxDist, From ee992cf79fe3e89039f60c9625b7b16d94c5c30c Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 31 Oct 2024 22:30:41 +0600 Subject: [PATCH 026/127] IgnoredDefs changes --- Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs | 5 ++--- .../CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs | 2 +- .../CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs | 1 + 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index 0dc89f3935..d7c2eb517d 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -15,8 +15,7 @@ public abstract class VerbCIWS : Verb_ShootCE_CIWS, ITargetSearcher { protected bool holdFire; - public IEnumerable IgnoredDefs { get; private set; } - public Building_TurretGun Turret => Caster as Building_TurretGun; + public VerbProperties_CIWS Props => verbProps as VerbProperties_CIWS; protected abstract string HoldLabel { get; } protected abstract string HoldDesc { get; } @@ -57,7 +56,7 @@ public abstract class VerbCIWS : VerbCIWS where TargetType : Thing public override bool TryFindNewTarget(out LocalTargetInfo target) { float range = this.verbProps.range; - var _target = Targets.Where(x => Props.Interceptable(x.def) && !IgnoredDefs.Contains(x.def)).Where(x => !IsFriendlyTo(x)).FirstOrDefault(t => + var _target = Targets.Where(x => Props.Interceptable(x.def) && !Turret.IgnoredDefs.Contains(x.def)).Where(x => !IsFriendlyTo(x)).FirstOrDefault(t => { var verb = this; if (Caster.Map.GetComponent().CIWS.Any(turret => turret.currentTargetInt.Thing == t) || ProjectileCE_CIWS.ProjectilesAt(Caster.Map).Any(x => x.intendedTarget.Thing == t)) diff --git a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs index c01528c88d..1fc565ac5e 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs @@ -26,7 +26,7 @@ public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish) } #endregion - IEnumerable IgnoredDefs + public IEnumerable IgnoredDefs { get { diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs index 1257d33866..d976709355 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs @@ -11,6 +11,7 @@ namespace CombatExtended { public class Verb_ShootCE_CIWS : Verb_ShootCE { + public Building_CIWS_CE Turret => Caster as Building_CIWS_CE; public override ThingDef Projectile { get From e6007a795a69c976eebcb3458ccade047e8a5ea5 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 31 Oct 2024 22:44:47 +0600 Subject: [PATCH 027/127] Projectile -> ProjectileCE --- .../CombatExtended/Comps/VerbCIWSProjectile.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index c665e09084..dee519e69d 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -8,15 +8,15 @@ namespace CombatExtended { - public class VerbCIWSProjectile : VerbCIWS + public class VerbCIWSProjectile : VerbCIWS { protected override string HoldDesc => "HoldCloseInProjectilesFireDesc"; protected override string HoldLabel => "HoldCloseInProjectilesFire"; public new CompProperties_CIWSProjectile Props => verbProps as CompProperties_CIWSProjectile; - public override IEnumerable Targets => Caster.Map?.listerThings.ThingsInGroup(ThingRequestGroup.Projectile).OfType() ?? Array.Empty(); + public override IEnumerable Targets => Caster.Map?.listerThings.ThingsInGroup(ThingRequestGroup.Projectile).OfType() ?? Array.Empty(); - protected override bool IsFriendlyTo(Projectile thing) => base.IsFriendlyTo(thing) && !thing.Launcher.HostileTo(Caster); + protected override bool IsFriendlyTo(ProjectileCE thing) => base.IsFriendlyTo(thing) && !thing.launcher.HostileTo(Caster); public override bool ValidateTarget(LocalTargetInfo targetInfo, bool showMessages) => Turret.currentTargetInt.Thing is Projectile; } public class CompProperties_CIWSProjectile : VerbProperties_CIWS From ffc8f51b51d07f01a0148f71a69029e185a128b6 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 31 Oct 2024 22:49:56 +0600 Subject: [PATCH 028/127] Validate target moved to base class --- Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs | 1 + Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs | 1 - Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index d7c2eb517d..3473c29d63 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -82,6 +82,7 @@ public override bool TryFindNewTarget(out LocalTargetInfo target) } protected virtual bool IsFriendlyTo(TargetType thing) => ((!thing.TryGetComp()?.Props.alwaysIntercept) ?? false) && !thing.HostileTo(Caster); public abstract IEnumerable Targets { get; } + public override bool ValidateTarget(LocalTargetInfo target, bool showMessages = true) => target.Thing is TargetType && base.ValidateTarget(target, showMessages); } public abstract class VerbProperties_CIWS : VerbPropertiesCE diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index dee519e69d..9e7f5a706b 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -17,7 +17,6 @@ public class VerbCIWSProjectile : VerbCIWS public override IEnumerable Targets => Caster.Map?.listerThings.ThingsInGroup(ThingRequestGroup.Projectile).OfType() ?? Array.Empty(); protected override bool IsFriendlyTo(ProjectileCE thing) => base.IsFriendlyTo(thing) && !thing.launcher.HostileTo(Caster); - public override bool ValidateTarget(LocalTargetInfo targetInfo, bool showMessages) => Turret.currentTargetInt.Thing is Projectile; } public class CompProperties_CIWSProjectile : VerbProperties_CIWS { diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs index 81fa753745..b3be76e4f8 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs @@ -17,7 +17,6 @@ public class VerbCIWSSkyfaller : VerbCIWS protected override bool IsFriendlyTo(Skyfaller thing) => base.IsFriendlyTo(thing) && thing.ContainedThings().All(x => !x.HostileTo(Caster)); - public override bool ValidateTarget(LocalTargetInfo targetInfo, bool showMessages) => Turret.currentTargetInt.Thing is Skyfaller; } public class VerbProperties_CIWSSkyfaller : VerbProperties_CIWS From c082f99fa524852b009bc73cf979ea5ba40e092d Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 31 Oct 2024 23:43:27 +0600 Subject: [PATCH 029/127] Moved projectile code --- .../Comps/VerbCIWSProjectile.cs | 60 +++++++++++++++++++ .../CombatExtended/Verbs/Verb_ShootCE_CIWS.cs | 47 +-------------- 2 files changed, 62 insertions(+), 45 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 9e7f5a706b..37a967640b 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -4,7 +4,9 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using UnityEngine; using Verse; +using static UnityEngine.UI.Image; namespace CombatExtended { @@ -17,6 +19,64 @@ public class VerbCIWSProjectile : VerbCIWS public override IEnumerable Targets => Caster.Map?.listerThings.ThingsInGroup(ThingRequestGroup.Projectile).OfType() ?? Array.Empty(); protected override bool IsFriendlyTo(ProjectileCE thing) => base.IsFriendlyTo(thing) && !thing.launcher.HostileTo(Caster); + public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo target, out ShootLine resultingLine) + { + if (base.TryFindCEShootLineFromTo(root, target, out resultingLine)) + { + return true; + } + if (!(target.Thing is ProjectileCE targetProjectile)) + { + return false; + } + var originV3 = Caster.Position.ToVector3Shifted(); + var ticksToSkip = (int)verbProps.warmupTime; + var instant = Projectile.projectile is ProjectilePropertiesCE CIWSProjectilePropertiesCE && CIWSProjectilePropertiesCE.isInstant; + if (instant) + { + var to = targetProjectile.NextPositions.Skip(ticksToSkip).FirstOrFallback(Vector3.negativeInfinity); + if (to == Vector3.negativeInfinity) + { + resultingLine = default; + return false; + } + resultingLine = new ShootLine(originV3.ToIntVec3(), to.ToIntVec3()); + return true; + } + int i = 1; + if (targetProjectile.def.projectile is ProjectilePropertiesCE targetProjectileProperties && Projectile.projectile is ProjectilePropertiesCE CIWS_ProjectileProperties) + { + var targetPos1 = new Vector2(targetProjectile.Position.x, targetProjectile.Position.z); + foreach (var pos in targetProjectile.NextPositions.Skip(ticksToSkip)) + { + if (i > maximumPredectionTicks) + { + break; + } + var report = ShiftVecReportFor(pos.ToIntVec3()); + ShiftTarget(report); + + Vector2 originV2 = new Vector2(originV3.x, originV3.z), destinationV2 = new Vector2(pos.x, pos.z); + var positions = CIWS_ProjectileProperties.NextPositions(shotRotation, shotAngle, originV2, destinationV2, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).Skip(i - 1).Take(2).ToList(); + if (positions.Count < 2) + { + resultingLine = default(ShootLine); + return false; + } + Vector2 ciwsPos1 = new Vector2(positions.First().x, positions.First().z), ciwsPos2 = new Vector2(positions.Last().x, positions.Last().z), targetPos2 = new Vector2(pos.x, pos.z); + + if (CE_Utility.TryFindIntersectionPoint(ciwsPos1, ciwsPos2, targetPos1, targetPos2, out var point)) + { + resultingLine = new ShootLine(Shooter.Position, point.ToVector3().ToIntVec3()); + return true; + } + targetPos1 = targetPos2; + i++; + } + } + resultingLine = default; + return false; + } } public class CompProperties_CIWSProjectile : VerbProperties_CIWS { diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs index d976709355..7262ab6d31 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs @@ -37,51 +37,8 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ var result = targetComp.CalculatePointForPreemptiveFire(Projectile, originV3, out var targetPos, ticksToSkip); resultingLine = new ShootLine(originV3.ToIntVec3(), targetPos.ToIntVec3()); return result; - } - else if (targ.Thing is Skyfaller skyfaller) - { - - } - else if (targ.Thing is ProjectileCE projectile) - { - var instant = Projectile.projectile is ProjectilePropertiesCE projectilePropertiesCE && projectilePropertiesCE.isInstant; - if (instant) - { - resultingLine = new ShootLine(root, projectile.Position); - return true; - } - int i = 1; - if (projectile.def.projectile is ProjectilePropertiesCE target_ProjectilePropeties && Projectile.projectile is ProjectilePropertiesCE CIWS_ProjectilePropeties) - { - var targetPos1 = new Vector2(projectile.Position.x, projectile.Position.z); - foreach (var pos in projectile.NextPositions.Skip(ticksToSkip)) - { - if (i > maximumPredectionTicks) - { - break; - } - var report = ShiftVecReportFor(pos.ToIntVec3()); - ShiftTarget(report); - - Vector2 originV2 = new Vector2(originV3.x, originV3.z), destinationV2 = new Vector2(pos.x, pos.z); - var positions = CIWS_ProjectilePropeties.NextPositions(shotRotation, shotAngle, originV2, destinationV2, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).Skip(i - 1).Take(2).ToList(); - if (positions.Count < 2) - { - resultingLine = default(ShootLine); - return false; - } - Vector2 ciwsPos1 = new Vector2(positions.First().x, positions.First().z), ciwsPos2 = new Vector2(positions.Last().x, positions.Last().z), targetPos2 = new Vector2(pos.x, pos.z); - - if (CE_Utility.TryFindIntersectionPoint(ciwsPos1, ciwsPos2, targetPos1, targetPos2, out var point)) - { - resultingLine = new ShootLine(Shooter.Position, point.ToVector3().ToIntVec3()); - return true; - } - targetPos1 = targetPos2; - i++; - } - } - } + } + return base.TryFindCEShootLineFromTo(root, targ, out resultingLine); } } From b40bea4be89ef1d0f7675123eed755e0bd1c70a2 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 1 Nov 2024 00:18:59 +0600 Subject: [PATCH 030/127] One more check --- Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index 3473c29d63..71c064e57f 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -13,9 +13,9 @@ namespace CombatExtended { public abstract class VerbCIWS : Verb_ShootCE_CIWS, ITargetSearcher { - + protected bool holdFire; - + public VerbProperties_CIWS Props => verbProps as VerbProperties_CIWS; protected abstract string HoldLabel { get; } protected abstract string HoldDesc { get; } @@ -82,7 +82,7 @@ public override bool TryFindNewTarget(out LocalTargetInfo target) } protected virtual bool IsFriendlyTo(TargetType thing) => ((!thing.TryGetComp()?.Props.alwaysIntercept) ?? false) && !thing.HostileTo(Caster); public abstract IEnumerable Targets { get; } - public override bool ValidateTarget(LocalTargetInfo target, bool showMessages = true) => target.Thing is TargetType && base.ValidateTarget(target, showMessages); + public override bool ValidateTarget(LocalTargetInfo target, bool showMessages = true) => target.Thing is TargetType && TryFindCEShootLineFromTo(Caster.Position, target, out _) && base.ValidateTarget(target, showMessages); } public abstract class VerbProperties_CIWS : VerbPropertiesCE From b55d9d118b2fb58133b7bc71d5f7969d2d6b8842 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 1 Nov 2024 15:03:59 +0600 Subject: [PATCH 031/127] Another rename --- .../CombatExtended/Comps/VerbCIWSProjectile.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 37a967640b..64eb02fd03 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -14,7 +14,7 @@ public class VerbCIWSProjectile : VerbCIWS { protected override string HoldDesc => "HoldCloseInProjectilesFireDesc"; protected override string HoldLabel => "HoldCloseInProjectilesFire"; - public new CompProperties_CIWSProjectile Props => verbProps as CompProperties_CIWSProjectile; + public new VerbProperties_CIWSProjectile Props => verbProps as VerbProperties_CIWSProjectile; public override IEnumerable Targets => Caster.Map?.listerThings.ThingsInGroup(ThingRequestGroup.Projectile).OfType() ?? Array.Empty(); @@ -78,9 +78,9 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ return false; } } - public class CompProperties_CIWSProjectile : VerbProperties_CIWS + public class VerbProperties_CIWSProjectile : VerbProperties_CIWS { - public CompProperties_CIWSProjectile() + public VerbProperties_CIWSProjectile() { this.verbClass = typeof(VerbCIWSProjectile); } From 269efab5b5a94db4b567bae7addfe58fda4ff467 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 1 Nov 2024 20:36:12 +0600 Subject: [PATCH 032/127] Active verb selecting --- .../Things/Building_Turret_MultiVerbs.cs | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs b/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs index fba1572521..68d30886b8 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs @@ -9,33 +9,30 @@ namespace CombatExtended { public class Building_Turret_MultiVerbs : Building_TurretGunCE { + + public override void ExposeData() + { + base.ExposeData(); + Scribe_References.Look(ref activeVerb, nameof(activeVerb)); + } + + Verb activeVerb; public override Verb AttackVerb { get { - if (CurrentTarget.IsValid) - { - foreach (var verb in GunCompEq.AllVerbs) - { - if (verb.ValidateTarget(CurrentTarget, false)) - { - return verb; - } - } - } - - return base.AttackVerb; + return activeVerb ?? GunCompEq.AllVerbs.FirstOrDefault(x=>x.state == VerbState.Bursting) ?? base.AttackVerb; } } IEnumerable cachedVerbsWithTargetSearcher; - protected IEnumerable VerbsWithTargetSearcher => cachedVerbsWithTargetSearcher ??= GunCompEq.AllVerbs.OfType(); + protected IEnumerable VerbsWithTargetSearcher => cachedVerbsWithTargetSearcher ??= GunCompEq.AllVerbs.OfType().ToList(); public override void DrawExtraSelectionOverlays() { base.DrawExtraSelectionOverlays(); foreach (var verb in GunCompEq.AllVerbs.Except(AttackVerb)) { float range = verb.verbProps.range; - if (range < 90f) + if (range < 120f) { GenDraw.DrawRadiusRing(base.Position, range); } @@ -52,10 +49,22 @@ public override LocalTargetInfo TryFindNewTarget() { if (verb.TryFindNewTarget(out var target)) { + activeVerb = (Verb)verb; return target; } } return base.TryFindNewTarget(); } + + public override void ResetCurrentTarget() + { + base.ResetCurrentTarget(); + activeVerb = null; + } + public override void ResetForcedTarget() + { + base.ResetForcedTarget(); + activeVerb = null; + } } } From 0a6db24b31e056514d4cdadd933333b146c7fab6 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 1 Nov 2024 20:37:13 +0600 Subject: [PATCH 033/127] PrimaryVerb -> AttackVerb --- .../CombatExtended/Things/Building_TurretGunCE.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Things/Building_TurretGunCE.cs b/Source/CombatExtended/CombatExtended/Things/Building_TurretGunCE.cs index 5f343ed786..35e6f1cbda 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_TurretGunCE.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_TurretGunCE.cs @@ -336,7 +336,7 @@ public override void Tick() //Autoreload code and IsReloading check if (Active && (this.mannableComp == null || this.mannableComp.MannedNow) && base.Spawned && !(isReloading && WarmingUp)) { this.GunCompEq.verbTracker.VerbsTick(); - if (!IsStunned && this.GunCompEq.PrimaryVerb.state != VerbState.Bursting) + if (!IsStunned && AttackVerb.state != VerbState.Bursting) { if (this.WarmingUp) { @@ -796,7 +796,7 @@ public virtual void ResetForcedTarget() // Core method } } - public void ResetCurrentTarget() // Core method + public virtual void ResetCurrentTarget() // Core method { this.currentTargetInt = LocalTargetInfo.Invalid; this.burstWarmupTicksLeft = 0; From 29f2db27000314ba4f67eedb99ca7f9991f6b577 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 1 Nov 2024 22:38:30 +0600 Subject: [PATCH 034/127] Corrected check --- Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs index 7262ab6d31..15501e3ebb 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs @@ -18,7 +18,7 @@ public override ThingDef Projectile { var result = base.Projectile; var ciwsVersion = (result?.projectile as ProjectilePropertiesCE)?.CIWSVersion; - if (ciwsVersion == null && typeof(ProjectileCE_CIWS).IsAssignableFrom(result.thingClass)) + if (ciwsVersion == null && !typeof(ProjectileCE_CIWS).IsAssignableFrom(result.thingClass)) { Log.WarningOnce($"{result} is not a CIWS projectile and the projectile does not have the CIWS version specified in its properties. Must be on-ground projectile used for CIWS", result.GetHashCode()); } From 62a2671b2e55b8e2db29c67d012367222c8e46bb Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sat, 2 Nov 2024 18:45:54 +0600 Subject: [PATCH 035/127] Not calling base findLine --- .../CombatExtended/Verbs/Verb_ShootCE_CIWS.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs index 15501e3ebb..ab24875c64 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs @@ -37,9 +37,10 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ var result = targetComp.CalculatePointForPreemptiveFire(Projectile, originV3, out var targetPos, ticksToSkip); resultingLine = new ShootLine(originV3.ToIntVec3(), targetPos.ToIntVec3()); return result; - } - - return base.TryFindCEShootLineFromTo(root, targ, out resultingLine); + } + resultingLine = default; + return false; } + } } From 95befe3f35e1b4a9e416e92b337477fdcf0eb726 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sat, 2 Nov 2024 18:48:48 +0600 Subject: [PATCH 036/127] Seconds -> ticks --- .../CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 64eb02fd03..388bb9de6b 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -30,7 +30,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ return false; } var originV3 = Caster.Position.ToVector3Shifted(); - var ticksToSkip = (int)verbProps.warmupTime; + var ticksToSkip = verbProps.warmupTime.SecondsToTicks(); var instant = Projectile.projectile is ProjectilePropertiesCE CIWSProjectilePropertiesCE && CIWSProjectilePropertiesCE.isInstant; if (instant) { From de887b67000d03caeaf9ca42d99d3ee59d361db7 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Mon, 4 Nov 2024 22:46:55 +0600 Subject: [PATCH 037/127] Fixed reneder issue with shells --- .../CombatExtended/Projectiles/ProjectilePropertiesCE.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs index 5700cf056d..bf8f3295e5 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs @@ -157,7 +157,7 @@ protected void AffectedByDrag(float radius, float shotSpeed, float ballisticCoef protected float GetHeightAtTicks(float shotHeight, float shotSpeed, float shotAngle, int ticks) { var seconds = ((float)ticks) / GenTicks.TicksPerRealSecond; - return (float)Math.Round(shotHeight + shotSpeed * Mathf.Sin(shotAngle) * seconds - (CE_Utility.GravityConst * seconds * seconds) / 2f, 3); + return (float)Math.Round(shotHeight + shotSpeed * Mathf.Sin(shotAngle) * seconds - (Gravity * seconds * seconds) / 2f, 3); } public virtual IEnumerable NextPositions(float shotRotation, From acc4576bdc7b7ffddcb324684d6469d8b21096c8 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Tue, 5 Nov 2024 12:08:24 +0600 Subject: [PATCH 038/127] Do not return target for deafult CIWS target --- Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs index 5d5c3dd3c5..1a2f04bb05 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs @@ -120,7 +120,7 @@ private Thing TryDropThing(Thing thing, Map map, IntVec3 position) public virtual bool CalculatePointForPreemptiveFire(ThingDef projectile, Vector3 source, out Vector3 result, int tickOffset = 0) { result = Vector3.zero; - return true; + return false; } } From 3a7be1250add7b0fcd406258d4205fdd3c6dd214 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Tue, 5 Nov 2024 13:33:42 +0600 Subject: [PATCH 039/127] ExactPosToDrawPos method --- .../CombatExtended/Projectiles/ProjectileCE.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 4e9c87a97b..c58af1ec8e 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -208,16 +208,20 @@ public Vector3 ExactMinusLastPos } } - public override Vector3 DrawPos + public virtual Vector3 ExactPosToDrawPos(Vector3 exactPosition) { - get - { - var sh = Mathf.Max(0f, (ExactPosition.y) * 0.84f); + var sh = Mathf.Max(0f, (exactPosition.y) * 0.84f); if (FlightTicks < ticksToTruePosition) { sh *= (float)FlightTicks / ticksToTruePosition; } - return new Vector3(ExactPosition.x, def.Altitude, ExactPosition.z + sh); + return new Vector3(exactPosition.x, def.Altitude, exactPosition.z + sh); + } + public override Vector3 DrawPos + { + get + { + return ExactPosToDrawPos(ExactPosition); } } From 8cc5b29b6de9eb86ba85bc2ab753651e3e373db0 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Tue, 5 Nov 2024 13:34:22 +0600 Subject: [PATCH 040/127] Corrected projectile targeting --- .../CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 388bb9de6b..249a8cbd51 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -47,7 +47,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ if (targetProjectile.def.projectile is ProjectilePropertiesCE targetProjectileProperties && Projectile.projectile is ProjectilePropertiesCE CIWS_ProjectileProperties) { var targetPos1 = new Vector2(targetProjectile.Position.x, targetProjectile.Position.z); - foreach (var pos in targetProjectile.NextPositions.Skip(ticksToSkip)) + foreach (var pos in targetProjectile.NextPositions.Skip(ticksToSkip).Select(x => targetProjectile.ExactPosToDrawPos(x))) { if (i > maximumPredectionTicks) { From 25e3a957aea7a6017b4befba5b98f3edbdf826d3 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Tue, 5 Nov 2024 13:41:53 +0600 Subject: [PATCH 041/127] Moved warmup ticks to property --- .../Verbs/Verb_LaunchProjectileCE.cs | 35 +++++++++++++++++++ .../CombatExtended/Verbs/Verb_ShootCE.cs | 12 +------ 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index b77b26fccd..8223d08626 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -1192,6 +1192,41 @@ protected float GetMinCollisionDistance(float targetDistance) public virtual void VerbTickCE() { } + public int BurstWarmupTicksLeft + { + get + { + if (caster is Building_TurretGunCE turret) + { + return turret.burstWarmupTicksLeft; + + } + else if (this.WarmupStance != null) + { + return this.WarmupStance.ticksLeft; + } + Log.Error("Verb caster is not a turret and does not have a WarmupStance"); + return -1; + } + set + { + if (caster is Building_TurretGunCE turret) + { + if (turret.burstWarmupTicksLeft > 0) //Turrets call beginBurst() when starting to fire a burst, and when starting the final aiming part of an aimed shot. We only want apply changes to warmup. + { + turret.burstWarmupTicksLeft = value; + } + } + else if (this.WarmupStance != null) + { + this.WarmupStance.ticksLeft = value; + } + else + { + Log.Error("Verb caster is not a turret and does not have a WarmupStance"); + } + } + } #region Line of Sight Utility diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs index fdae41ceb4..f10d8dd77c 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs @@ -349,17 +349,7 @@ public override void RecalculateWarmupTicks() if (reduction < 1.0f) { - if (caster is Building_TurretGunCE turret) - { - if (turret.burstWarmupTicksLeft > 0) //Turrets call beginBurst() when starting to fire a burst, and when starting the final aiming part of an aimed shot. We only want apply changes to warmup. - { - turret.burstWarmupTicksLeft = (int)(turret.burstWarmupTicksLeft * reduction); - } - } - else if (this.WarmupStance != null) - { - this.WarmupStance.ticksLeft = (int)(this.WarmupStance.ticksLeft * reduction); - } + this.BurstWarmupTicksLeft = (int)(BurstWarmupTicksLeft * reduction); } } From 043ee1302620a8071bb82ede03297a953b96d3cd Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 6 Nov 2024 12:18:28 +0600 Subject: [PATCH 042/127] Corrected skip ticks (not sure if it's needed cuz it's always 0) --- .../CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 249a8cbd51..2f2bab3096 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -30,7 +30,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ return false; } var originV3 = Caster.Position.ToVector3Shifted(); - var ticksToSkip = verbProps.warmupTime.SecondsToTicks(); + var ticksToSkip = this.BurstWarmupTicksLeft; var instant = Projectile.projectile is ProjectilePropertiesCE CIWSProjectilePropertiesCE && CIWSProjectilePropertiesCE.isInstant; if (instant) { @@ -68,6 +68,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ if (CE_Utility.TryFindIntersectionPoint(ciwsPos1, ciwsPos2, targetPos1, targetPos2, out var point)) { resultingLine = new ShootLine(Shooter.Position, point.ToVector3().ToIntVec3()); + Shooter.Map.debugDrawer.FlashLine(Shooter.Position, point.ToVector3().ToIntVec3(), 100, SimpleColor.Red); return true; } targetPos1 = targetPos2; From 177b34596fd94bfbc1807e3d200f17202ca0ce00 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 6 Nov 2024 12:19:13 +0600 Subject: [PATCH 043/127] Test CIWS turret --- Defs/Ammo/Advanced/8x35mmCharged.xml | 18 +++++ Defs/ThingDefs_Buildings/Building_CIWS.xml | 59 +++++++++++++++++ Defs/ThingDefs_Misc/Weapons_CIWS.xml | 76 ++++++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 Defs/ThingDefs_Buildings/Building_CIWS.xml create mode 100644 Defs/ThingDefs_Misc/Weapons_CIWS.xml diff --git a/Defs/Ammo/Advanced/8x35mmCharged.xml b/Defs/Ammo/Advanced/8x35mmCharged.xml index 8c72f76624..70907d6378 100644 --- a/Defs/Ammo/Advanced/8x35mmCharged.xml +++ b/Defs/Ammo/Advanced/8x35mmCharged.xml @@ -97,6 +97,7 @@ Bullet_8x35mmCharged + Bullet_8x35mmChargedCIWS 19
  • @@ -142,6 +143,23 @@ + + Bullet_8x35mmChargedCIWS + CombatExtended.ProjectileCE_CIWS + + + 19 + +
  • + Bomb_Secondary + 6 +
  • +
    + 16 + 57.6 +
    +
    + diff --git a/Defs/ThingDefs_Buildings/Building_CIWS.xml b/Defs/ThingDefs_Buildings/Building_CIWS.xml new file mode 100644 index 0000000000..d643d42267 --- /dev/null +++ b/Defs/ThingDefs_Buildings/Building_CIWS.xml @@ -0,0 +1,59 @@ + + + + + + + CIWS_Blaster + CombatExtended.Building_CIWS_CE + + 8 + + Things/Building/Turrets/MachineGunBase + + (0.27,0.25,0.27) + (0,0,0) + + + UI/Icons/Turrets/ChargeBlaster_uiIcon + + 23000 + 150 + 20 + 25 + 0.75 + 1.25 + 0.5 + + Spacer + +
  • + CompPowerTrader + 400 +
  • +
    + Automatic turret equipped with a charge blaster. + + 125 + 40 + 6 + 1 + + + Gun_CIWSBlasterTurret + true + + CE_AutoTurrets + +
  • PlaceWorker_TurretTop
  • +
  • PlaceWorker_ShowTurretRadius
  • +
    + +
  • CE_ChargeTurret
  • +
    + MinifiedThing +
    + + + +
    \ No newline at end of file diff --git a/Defs/ThingDefs_Misc/Weapons_CIWS.xml b/Defs/ThingDefs_Misc/Weapons_CIWS.xml new file mode 100644 index 0000000000..286db6fc1c --- /dev/null +++ b/Defs/ThingDefs_Misc/Weapons_CIWS.xml @@ -0,0 +1,76 @@ + + + + + + + Gun_CIWSBlasterTurret + + + Things/Building/Turrets/BlasterTurret_Top + Graphic_Single + + Charge blaster attached to a turret mount. + Interact_ChargeRifle + + 1 + 0.06 + 0.86 + 0.36 + 10 + + +
  • + 0.90 + CombatExtended.Verb_ShootCE + true + Bullet_8x35mmCharged + 1.3 + 55 + 5 + 10 + Shot_ChargeBlaster + GunTail_Heavy + 9 + Mounted +
  • +
  • + CombatExtended.VerbCIWSProjectile + 0.90 + true + Bullet_8x35mmCharged + 0.4 + 105 + 5 + 10 + Shot_ChargeBlaster + GunTail_Heavy + 9 + Mounted +
  • +
  • + CombatExtended.VerbCIWSSkyfaller + 0.90 + true + Bullet_8x35mmCharged + 0.4 + 105 + 5 + 10 + Shot_ChargeBlaster + GunTail_Heavy + 9 + Mounted +
  • +
    + +
  • + 100 + 7.8 + AmmoSet_8x35mmCharged +
  • +
    +
    + + +
    \ No newline at end of file From a3f4c65911eabceeaf124d3f848ca9d314997a7b Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 6 Nov 2024 13:43:07 +0600 Subject: [PATCH 044/127] Splited CompCIWSTarget to targeting and impact handle comps --- .../Comps/CompCIWSImpactHandler.cs | 98 +++++++++++++++++ .../CombatExtended/Comps/CompCIWSTarget.cs | 100 ++++-------------- .../CombatExtended/Comps/VerbCIWS.cs | 18 +++- .../CombatExtended/Comps/VerbCIWSSkyfaller.cs | 4 +- .../CombatExtended/Verbs/Verb_ShootCE_CIWS.cs | 9 -- 5 files changed, 136 insertions(+), 93 deletions(-) create mode 100644 Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs new file mode 100644 index 0000000000..73cf7d9fa6 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs @@ -0,0 +1,98 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; +using Verse.Sound; + +namespace CombatExtended +{ + public class CompCIWSImpactHandler : ThingComp + { + public CompProperties_CIWSImpactHandler Props => props as CompProperties_CIWSImpactHandler; + + public virtual void OnImpact(ProjectileCE projectile, DamageInfo dinfo) + { + parent.Position = projectile.Position; + if (parent is IThingHolder pod) + { + var containedThings = pod.ContainedThings().ToList(); + + foreach (var thing in containedThings) + { + if (thing is Building) + { + var leavingList = new List(); + GenLeaving.DoLeavingsFor(thing, parent.Map, DestroyMode.KillFinalize, CellRect.CenteredOn(parent.Position, thing.def.size), listOfLeavingsOut: leavingList); + continue; + } + TryDropThing(thing, projectile.Map, projectile.Position); + if (thing is Pawn pawn) + { + pawn.TakeDamage(dinfo); + if (!pawn.Dead) + { + pawn.Kill(dinfo); + } + } + else + { + thing.HitPoints = Rand.RangeInclusive(1, thing.MaxHitPoints); + } + + } + } + if (!Props.impacted.NullOrUndefined()) + { + Props.impacted.PlayOneShot(new TargetInfo(parent.DrawPos.ToIntVec3(), parent.Map)); + } + parent.Destroy(DestroyMode.Vanish); + } + private Thing TryDropThing(Thing thing, Map map, IntVec3 position) + { + var contents = (parent as IActiveDropPod)?.Contents; + Rot4 rot = (contents?.setRotation != null) ? contents.setRotation.Value : Rot4.North; + if (contents?.moveItemsAsideBeforeSpawning ?? false) + { + GenSpawn.CheckMoveItemsAside(parent.Position, rot, thing.def, map); + } + Thing thing2; + if (contents?.spawnWipeMode == null) + { + GenPlace.TryPlaceThing(thing, position, map, ThingPlaceMode.Near, out thing2, null, null, rot); + } + else if (contents?.setRotation != null) + { + thing2 = GenSpawn.Spawn(thing, position, map, contents.setRotation.Value, contents.spawnWipeMode.Value, false, false); + } + else + { + thing2 = GenSpawn.Spawn(thing, position, map, contents.spawnWipeMode.Value); + } + Pawn pawn = thing2 as Pawn; + if (pawn != null) + { + if (pawn.RaceProps.Humanlike) + { + TaleRecorder.RecordTale(TaleDefOf.LandedInPod, new object[] + { + pawn + }); + } + } + return thing2; + } + + } + public class CompProperties_CIWSImpactHandler : CompProperties + { + public CompProperties_CIWSImpactHandler() + { + compClass = typeof(CompCIWSImpactHandler); + } + public SoundDef impacted; + } +} diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs index 1a2f04bb05..f7ac321ca6 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs @@ -6,11 +6,13 @@ using System.Threading.Tasks; using UnityEngine; using Verse; -using Verse.Sound; namespace CombatExtended { - public class CompCIWSTarget : ThingComp + /// + /// Base class for third-party mods compatibility (if their skyfallers\projectiles needs custom targeting logic) + /// + public abstract class CompCIWSTarget : ThingComp { protected static Dictionary> CIWSTargets = new Dictionary>(); public static IEnumerable Targets(Map map) @@ -18,6 +20,10 @@ public static IEnumerable Targets(Map map) CIWSTargets.TryGetValue(map, out var targets); return targets ?? Enumerable.Empty(); } + public static IEnumerable Targets(Map map) where T : CompCIWSTarget + { + return Targets(map).Where(x=>x.HasComp()); + } public CompProperties_CIWSTarget Props => props as CompProperties_CIWSTarget; @@ -46,91 +52,23 @@ public override void PostDeSpawn(Map map) } } } - public virtual void OnImpact(ProjectileCE projectile, DamageInfo dinfo) - { - parent.Position = projectile.Position; - if (parent is IThingHolder pod) - { - var containedThings = pod.ContainedThings().ToList(); - - foreach (var thing in containedThings) - { - if (thing is Building) - { - var leavingList = new List(); - GenLeaving.DoLeavingsFor(thing, parent.Map, DestroyMode.KillFinalize, CellRect.CenteredOn(parent.Position, thing.def.size), listOfLeavingsOut: leavingList); - continue; - } - TryDropThing(thing, projectile.Map, projectile.Position); - if (thing is Pawn pawn) - { - pawn.TakeDamage(dinfo); - if (!pawn.Dead) - { - pawn.Kill(dinfo); - } - } - else - { - thing.HitPoints = Rand.RangeInclusive(1, thing.MaxHitPoints); - } - - } - } - if (!Props.impacted.NullOrUndefined()) - { - Props.impacted.PlayOneShot(new TargetInfo(parent.DrawPos.ToIntVec3(), parent.Map)); - } - parent.Destroy(DestroyMode.Vanish); - } - private Thing TryDropThing(Thing thing, Map map, IntVec3 position) + public abstract bool IsFriendlyTo(Thing thing); + public abstract bool CalculatePointForPreemptiveFire(ThingDef projectile, Vector3 source, out Vector3 result, int tickOffset = 0); + } + public class CompProperties_CIWSTarget : CompProperties + { + public CompProperties_CIWSTarget(){} + public override IEnumerable ConfigErrors(ThingDef parentDef) { - var contents = (parent as IActiveDropPod)?.Contents; - Rot4 rot = (contents?.setRotation != null) ? contents.setRotation.Value : Rot4.North; - if (contents?.moveItemsAsideBeforeSpawning ?? false) + foreach (var item in base.ConfigErrors(parentDef)) { - GenSpawn.CheckMoveItemsAside(parent.Position, rot, thing.def, map); + yield return item; } - Thing thing2; - if (contents?.spawnWipeMode == null) + if (!compClass.IsAssignableFrom(typeof(CompCIWSTarget))) { - GenPlace.TryPlaceThing(thing, position, map, ThingPlaceMode.Near, out thing2, null, null, rot); + yield return "compClass must be the heir to class " + nameof(CompCIWSTarget); } - else if (contents?.setRotation != null) - { - thing2 = GenSpawn.Spawn(thing, position, map, contents.setRotation.Value, contents.spawnWipeMode.Value, false, false); - } - else - { - thing2 = GenSpawn.Spawn(thing, position, map, contents.spawnWipeMode.Value); - } - Pawn pawn = thing2 as Pawn; - if (pawn != null) - { - if (pawn.RaceProps.Humanlike) - { - TaleRecorder.RecordTale(TaleDefOf.LandedInPod, new object[] - { - pawn - }); - } - } - return thing2; - } - public virtual bool CalculatePointForPreemptiveFire(ThingDef projectile, Vector3 source, out Vector3 result, int tickOffset = 0) - { - result = Vector3.zero; - return false; - } - - } - public class CompProperties_CIWSTarget : CompProperties - { - public CompProperties_CIWSTarget() - { - compClass = typeof(CompCIWSTarget); } - public SoundDef impacted; public bool alwaysIntercept; } } diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index 71c064e57f..731518bb2c 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -80,10 +80,26 @@ public override bool TryFindNewTarget(out LocalTargetInfo target) target = null; return false; } - protected virtual bool IsFriendlyTo(TargetType thing) => ((!thing.TryGetComp()?.Props.alwaysIntercept) ?? false) && !thing.HostileTo(Caster); + protected virtual bool IsFriendlyTo(TargetType thing) => !thing.HostileTo(Caster); public abstract IEnumerable Targets { get; } public override bool ValidateTarget(LocalTargetInfo target, bool showMessages = true) => target.Thing is TargetType && TryFindCEShootLineFromTo(Caster.Position, target, out _) && base.ValidateTarget(target, showMessages); } + public abstract class VerbCIWS_Comp : VerbCIWS where TargetType : CompCIWSTarget + { + public override IEnumerable Targets => CompCIWSTarget.Targets(Caster.Map); + protected override bool IsFriendlyTo(Thing thing) => thing.TryGetComp()?.IsFriendlyTo(thing) ?? base.IsFriendlyTo(thing); + public override bool ValidateTarget(LocalTargetInfo target, bool showMessages = true) => target.HasThing && target.Thing.HasComp() && base.ValidateTarget(target, showMessages); + public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine) + { + if (targ.Thing?.TryGetComp()?.CalculatePointForPreemptiveFire(Projectile, root.ToVector3Shifted(), out var result, BurstWarmupTicksLeft) ?? false) + { + resultingLine = new ShootLine(root, result.ToIntVec3()); + return true; + } + resultingLine = default; + return false; + } + } public abstract class VerbProperties_CIWS : VerbPropertiesCE { diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs index b3be76e4f8..603d17669c 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs @@ -13,7 +13,7 @@ public class VerbCIWSSkyfaller : VerbCIWS { protected override string HoldDesc => "HoldSkyfallerFireDesc"; protected override string HoldLabel => "HoldSkyfallerFire"; - public override IEnumerable Targets => Caster.Map?.listerThings.ThingsInGroup(Verse.ThingRequestGroup.ActiveDropPod).OfType().Union(CompCIWSTarget.Targets(Caster.Map).OfType()); + public override IEnumerable Targets => Caster.Map?.listerThings.ThingsInGroup(Verse.ThingRequestGroup.ActiveDropPod).OfType(); protected override bool IsFriendlyTo(Skyfaller thing) => base.IsFriendlyTo(thing) && thing.ContainedThings().All(x => !x.HostileTo(Caster)); @@ -25,6 +25,6 @@ public VerbProperties_CIWSSkyfaller() { this.verbClass = typeof(VerbCIWSSkyfaller); } - protected override IEnumerable InitAllTargets() => DefDatabase.AllDefsListForReading.Where(x => (typeof(Skyfaller).IsAssignableFrom(x.thingClass) && x.HasComp()) || typeof(IActiveDropPod).IsAssignableFrom(x.thingClass)); + protected override IEnumerable InitAllTargets() => DefDatabase.AllDefsListForReading.Where(x => (typeof(Skyfaller).IsAssignableFrom(x.thingClass) && typeof(IActiveDropPod).IsAssignableFrom(x.thingClass))); } } diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs index ab24875c64..14898ae4dd 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs @@ -29,15 +29,6 @@ public override ThingDef Projectile protected int maximumPredectionTicks = 40; public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine) { - var originV3 = Shooter.Position.ToVector3Shifted(); - var targetComp = targ.Thing?.TryGetComp(); - var ticksToSkip = (int)verbProps.warmupTime; - if (targetComp != null) - { - var result = targetComp.CalculatePointForPreemptiveFire(Projectile, originV3, out var targetPos, ticksToSkip); - resultingLine = new ShootLine(originV3.ToIntVec3(), targetPos.ToIntVec3()); - return result; - } resultingLine = default; return false; } From 0889401f2957b2fd1841b30b43418081e9e9a280 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 6 Nov 2024 14:00:20 +0600 Subject: [PATCH 045/127] Splited impact logic --- .../Comps/CompCIWSImpactHandler.cs | 64 +-------------- .../Comps/CompCIWSImpactHandler_Skyfaller.cs | 82 +++++++++++++++++++ 2 files changed, 83 insertions(+), 63 deletions(-) create mode 100644 Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs index 73cf7d9fa6..06b7d16a0e 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs @@ -17,75 +17,13 @@ public class CompCIWSImpactHandler : ThingComp public virtual void OnImpact(ProjectileCE projectile, DamageInfo dinfo) { parent.Position = projectile.Position; - if (parent is IThingHolder pod) - { - var containedThings = pod.ContainedThings().ToList(); - - foreach (var thing in containedThings) - { - if (thing is Building) - { - var leavingList = new List(); - GenLeaving.DoLeavingsFor(thing, parent.Map, DestroyMode.KillFinalize, CellRect.CenteredOn(parent.Position, thing.def.size), listOfLeavingsOut: leavingList); - continue; - } - TryDropThing(thing, projectile.Map, projectile.Position); - if (thing is Pawn pawn) - { - pawn.TakeDamage(dinfo); - if (!pawn.Dead) - { - pawn.Kill(dinfo); - } - } - else - { - thing.HitPoints = Rand.RangeInclusive(1, thing.MaxHitPoints); - } - - } - } if (!Props.impacted.NullOrUndefined()) { Props.impacted.PlayOneShot(new TargetInfo(parent.DrawPos.ToIntVec3(), parent.Map)); } parent.Destroy(DestroyMode.Vanish); } - private Thing TryDropThing(Thing thing, Map map, IntVec3 position) - { - var contents = (parent as IActiveDropPod)?.Contents; - Rot4 rot = (contents?.setRotation != null) ? contents.setRotation.Value : Rot4.North; - if (contents?.moveItemsAsideBeforeSpawning ?? false) - { - GenSpawn.CheckMoveItemsAside(parent.Position, rot, thing.def, map); - } - Thing thing2; - if (contents?.spawnWipeMode == null) - { - GenPlace.TryPlaceThing(thing, position, map, ThingPlaceMode.Near, out thing2, null, null, rot); - } - else if (contents?.setRotation != null) - { - thing2 = GenSpawn.Spawn(thing, position, map, contents.setRotation.Value, contents.spawnWipeMode.Value, false, false); - } - else - { - thing2 = GenSpawn.Spawn(thing, position, map, contents.spawnWipeMode.Value); - } - Pawn pawn = thing2 as Pawn; - if (pawn != null) - { - if (pawn.RaceProps.Humanlike) - { - TaleRecorder.RecordTale(TaleDefOf.LandedInPod, new object[] - { - pawn - }); - } - } - return thing2; - } - + } public class CompProperties_CIWSImpactHandler : CompProperties { diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs new file mode 100644 index 0000000000..ff4fff2018 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs @@ -0,0 +1,82 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse.Sound; +using Verse; + +namespace CombatExtended +{ + public class CompCIWSImpactHandler_Skyfaller : CompCIWSImpactHandler + { + public override void OnImpact(ProjectileCE projectile, DamageInfo dinfo) + { + if (parent is IThingHolder pod) + { + var containedThings = pod.ContainedThings().ToList(); + + foreach (var thing in containedThings) + { + if (thing is Building) + { + var leavingList = new List(); + GenLeaving.DoLeavingsFor(thing, parent.Map, DestroyMode.KillFinalize, CellRect.CenteredOn(parent.Position, thing.def.size), listOfLeavingsOut: leavingList); + continue; + } + TryDropThing(thing, projectile.Map, projectile.Position); + if (thing is Pawn pawn) + { + pawn.TakeDamage(dinfo); + if (!pawn.Dead) + { + pawn.Kill(dinfo); + } + } + else + { + thing.HitPoints = Rand.RangeInclusive(1, thing.MaxHitPoints); + } + + } + } + base.OnImpact(projectile, dinfo); + + } + private Thing TryDropThing(Thing thing, Map map, IntVec3 position) + { + var contents = (parent as IActiveDropPod)?.Contents; + Rot4 rot = (contents?.setRotation != null) ? contents.setRotation.Value : Rot4.North; + if (contents?.moveItemsAsideBeforeSpawning ?? false) + { + GenSpawn.CheckMoveItemsAside(parent.Position, rot, thing.def, map); + } + Thing thing2; + if (contents?.spawnWipeMode == null) + { + GenPlace.TryPlaceThing(thing, position, map, ThingPlaceMode.Near, out thing2, null, null, rot); + } + else if (contents?.setRotation != null) + { + thing2 = GenSpawn.Spawn(thing, position, map, contents.setRotation.Value, contents.spawnWipeMode.Value, false, false); + } + else + { + thing2 = GenSpawn.Spawn(thing, position, map, contents.spawnWipeMode.Value); + } + Pawn pawn = thing2 as Pawn; + if (pawn != null) + { + if (pawn.RaceProps.Humanlike) + { + TaleRecorder.RecordTale(TaleDefOf.LandedInPod, new object[] + { + pawn + }); + } + } + return thing2; + } + } +} From dac14992398db8e972e4b0c9b450d52c25f38f34 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 6 Nov 2024 16:41:49 +0600 Subject: [PATCH 046/127] Access modifier --- .../CombatExtended/Projectiles/ProjectileCE_CIWS.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs index 406a6689e0..f9610fd672 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs @@ -11,7 +11,7 @@ namespace CombatExtended { - internal class ProjectileCE_CIWS : ProjectileCE + public class ProjectileCE_CIWS : ProjectileCE { #region Caching protected static Dictionary> CIWSProjectiles = new Dictionary>(); From 1248f5ce56c8c4a966648e23118b5f5f34a0434e Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 6 Nov 2024 16:50:27 +0600 Subject: [PATCH 047/127] Collision logic --- .../CombatExtended/Comps/CompCIWSTarget.cs | 10 +++++++ .../Projectiles/ProjectileCE_CIWS.cs | 27 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs index f7ac321ca6..65135d8ff5 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs @@ -54,6 +54,16 @@ public override void PostDeSpawn(Map map) } public abstract bool IsFriendlyTo(Thing thing); public abstract bool CalculatePointForPreemptiveFire(ThingDef projectile, Vector3 source, out Vector3 result, int tickOffset = 0); + + /// + /// Checks if projectile can intersect with this object + /// + /// Can the projectile collide with parent. Null if should use original logic + public virtual bool? CanCollideWith(ProjectileCE_CIWS projectileCE_CIWS, out float dist) + { + dist = -1f; + return null; + } } public class CompProperties_CIWSTarget : CompProperties { diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs index f9610fd672..44895615af 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs @@ -57,6 +57,33 @@ public override void Tick() base.Tick(); TryCollideWith(intendedTargetThing); } + protected override bool CanCollideWith(Thing thing, out float dist) + { + dist = 0f; + if (!Rand.Chance(ImpactChance)) + { + return false; + } + var ciwsTargetCompResult = thing.TryGetComp()?.CanCollideWith(this, out dist); + if (ciwsTargetCompResult != null) + { + return ciwsTargetCompResult.Value; + } + dist = (thing.DrawPos.Yto0() - this.DrawPos.Yto0()).MagnitudeHorizontalSquared(); + var collideDistance = CollideDistance; + if (dist < collideDistance * collideDistance) + { + dist = Mathf.Sqrt(dist); + return true; + } + return false; + + } + public override void Impact(Thing hitThing) + { + hitThing?.TryGetComp()?.OnImpact(this, DamageInfo); + base.Impact(hitThing); + } protected override bool CheckForCollisionBetween() { return false; From 01b9b93047e9c7f8c06b02d94998ad862f7ff8c6 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 6 Nov 2024 17:12:50 +0600 Subject: [PATCH 048/127] Virtual CanCollideWith --- .../CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index c58af1ec8e..690cb8eebb 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -924,7 +924,7 @@ protected virtual bool TryCollideWithRoof(IntVec3 cell) Impact(null); return true; } - protected bool CanCollideWith(Thing thing, out float dist) + protected virtual bool CanCollideWith(Thing thing, out float dist) { dist = -1f; if (globalTargetInfo.IsValid) From 5d5c713d980dcb97fdf80336c5ddf40f0e74fe8b Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 6 Nov 2024 20:42:26 +0600 Subject: [PATCH 049/127] Removed CIWS code from base projectile --- .../CombatExtended/Projectiles/ProjectileCE.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 690cb8eebb..6430cdeb1f 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -1457,11 +1457,6 @@ public virtual void Impact(Thing hitThing) } } - var compCIWSTarget = hitThing?.TryGetComp(); - if (compCIWSTarget != null) - { - compCIWSTarget.OnImpact(this, DamageInfo); - } Destroy(); } #endregion From 96e7fccc88f8f51da8dd3ba01340ea976a92c0b2 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 6 Nov 2024 20:43:21 +0600 Subject: [PATCH 050/127] Additional check (not sure if'll help) --- .../CombatExtended/Projectiles/ProjectileCE_CIWS.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs index 44895615af..2f02715087 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs @@ -60,6 +60,10 @@ public override void Tick() protected override bool CanCollideWith(Thing thing, out float dist) { dist = 0f; + if (thing.Destroyed) + { + return false; + } if (!Rand.Chance(ImpactChance)) { return false; From 70e129e03960a26831b7409473eee61ed5666a2d Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 6 Nov 2024 20:52:22 +0600 Subject: [PATCH 051/127] Revert "Different projectile def for CIWS-targets" This reverts commit 898c4a913f14e0317cd127c1b0a1b50abec8e342. --- Source/CombatExtended/CombatExtended/Defs/AmmoLink.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Defs/AmmoLink.cs b/Source/CombatExtended/CombatExtended/Defs/AmmoLink.cs index ffbf7aee48..d4fb57ee19 100644 --- a/Source/CombatExtended/CombatExtended/Defs/AmmoLink.cs +++ b/Source/CombatExtended/CombatExtended/Defs/AmmoLink.cs @@ -13,18 +13,15 @@ public class AmmoLink { public AmmoDef ammo; public ThingDef projectile; - private ThingDef projectileCIWS; public AmmoLink() { } - public AmmoLink(AmmoDef ammo, ThingDef projectile, ThingDef CIWSProjectile = null) + public AmmoLink(AmmoDef ammo, ThingDef projectile) { this.ammo = ammo; this.projectile = projectile; - this.projectileCIWS = CIWSProjectile; } - public ThingDef CIWSProjectile => projectileCIWS ?? projectile; public void LoadDataFromXmlCustom(XmlNode xmlRoot) { if (xmlRoot.ChildNodes.Count != 1) From be59f6413f28695625870dfbef6adf2a34c69ecc Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 7 Nov 2024 01:55:58 +0600 Subject: [PATCH 052/127] Projectile targeting fix --- .../CombatExtended/CE_Utility.cs | 14 +++++++++++ .../CombatExtended/CollisionVertical.cs | 7 +++++- .../Comps/VerbCIWSProjectile.cs | 7 ++++-- .../Verbs/Verb_LaunchProjectileCE.cs | 23 +++++++++++++++---- 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/CE_Utility.cs b/Source/CombatExtended/CombatExtended/CE_Utility.cs index ce3054b84a..2957058406 100644 --- a/Source/CombatExtended/CombatExtended/CE_Utility.cs +++ b/Source/CombatExtended/CombatExtended/CE_Utility.cs @@ -1680,5 +1680,19 @@ internal static IEnumerable ContainedThings(this IThingHolder thingHolder } } } + internal static T ElementAtOrLast(this IEnumerable enumerable, int index) + { + var source = enumerable.GetEnumerator(); + T current = source.Current; + for (int i = 0; i < index; i++) + { + if (!source.MoveNext()) + { + break; + } + current = source.Current; + } + return current; + } } } diff --git a/Source/CombatExtended/CombatExtended/CollisionVertical.cs b/Source/CombatExtended/CombatExtended/CollisionVertical.cs index 0f01f33692..18e5f33780 100644 --- a/Source/CombatExtended/CombatExtended/CollisionVertical.cs +++ b/Source/CombatExtended/CombatExtended/CollisionVertical.cs @@ -67,7 +67,12 @@ private static void CalculateHeightRange(Thing thing, out FloatRange heightRange shotHeight = fillPercent; return; } - + if (thing is ProjectileCE projectile) + { + heightRange = new FloatRange(projectile.Height); + shotHeight = projectile.Height; + return; + } float collisionHeight = 0f; float shotHeightOffset = 0; float heightAdjust = CETrenches.GetHeightAdjust(thing.Position, thing.Map); diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 2f2bab3096..1a920f9d5a 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -29,6 +29,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ { return false; } + var midBurst = numShotsFired > 0; var originV3 = Caster.Position.ToVector3Shifted(); var ticksToSkip = this.BurstWarmupTicksLeft; var instant = Projectile.projectile is ProjectilePropertiesCE CIWSProjectilePropertiesCE && CIWSProjectilePropertiesCE.isInstant; @@ -44,6 +45,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ return true; } int i = 1; + var report = ShiftVecReportFor((LocalTargetInfo)targetProjectile); if (targetProjectile.def.projectile is ProjectilePropertiesCE targetProjectileProperties && Projectile.projectile is ProjectilePropertiesCE CIWS_ProjectileProperties) { var targetPos1 = new Vector2(targetProjectile.Position.x, targetProjectile.Position.z); @@ -53,8 +55,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ { break; } - var report = ShiftVecReportFor(pos.ToIntVec3()); - ShiftTarget(report); + ShiftTarget(report, false, instant, midBurst, i); Vector2 originV2 = new Vector2(originV3.x, originV3.z), destinationV2 = new Vector2(pos.x, pos.z); var positions = CIWS_ProjectileProperties.NextPositions(shotRotation, shotAngle, originV2, destinationV2, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).Skip(i - 1).Take(2).ToList(); @@ -69,6 +70,8 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ { resultingLine = new ShootLine(Shooter.Position, point.ToVector3().ToIntVec3()); Shooter.Map.debugDrawer.FlashLine(Shooter.Position, point.ToVector3().ToIntVec3(), 100, SimpleColor.Red); + + this.sinceTicks = i; return true; } targetPos1 = targetPos2; diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index 8223d08626..621acf80f3 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -31,6 +31,7 @@ public class Verb_LaunchProjectileCE : Verb // Targeting factors private float estimatedTargDist = -1; // Stores estimate target distance for each burst, so each burst shot uses the same protected int numShotsFired = 0; // Stores how many shots were fired for purposes of recoil + protected int sinceTicks = 0; // Angle in Vector2(degrees, radians) protected Vector2 newTargetLoc = new Vector2(0, 0); @@ -351,7 +352,7 @@ public override void WarmupComplete() /// /// Shifts the original target position in accordance with target leading, range estimation and weather/lighting effects /// - public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalOnly = false, bool isInstant = false, bool midBurst = false) + public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalOnly = false, bool isInstant = false, bool midBurst = false, int sinceTicks = 0) { if (!calculateMechanicalOnly) { @@ -363,7 +364,16 @@ public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalO // On first shot of burst do a range estimate estimatedTargDist = report.GetRandDist(); } - Vector3 v = report.target.Thing?.TrueCenter() ?? report.target.Cell.ToVector3Shifted(); //report.targetPawn != null ? report.targetPawn.DrawPos + report.targetPawn.Drawer.leaner.LeanOffset * 0.5f : report.target.Cell.ToVector3Shifted(); + Vector3 v; + if (report.target.Thing is ProjectileCE projectile) + { + v = projectile.ExactPosToDrawPos(projectile.NextPositions.ElementAtOrLast(sinceTicks)); + } + else + { + v = report.target.Thing?.TrueCenter() ?? report.target.Cell.ToVector3Shifted(); //report.targetPawn != null ? report.targetPawn.DrawPos + report.targetPawn.Drawer.leaner.LeanOffset * 0.5f : report.target.Cell.ToVector3Shifted(); + } + if (report.targetPawn != null) { v += report.targetPawn.Drawer.leaner.LeanOffset * 0.5f; @@ -401,7 +411,11 @@ public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalO var coverRange = new CollisionVertical(report.cover).HeightRange; //Get " " cover, assume it is the edifice // Projectiles with flyOverhead target the surface in front of the target - if (Projectile.projectile.flyOverhead) + if (currentTarget.Thing is ProjectileCE) + { + targetHeight = v.y; + } + else if (Projectile.projectile.flyOverhead) { targetHeight = coverRange.max; } @@ -995,6 +1009,7 @@ public override bool TryStartCastOn(LocalTargetInfo castTarg, LocalTargetInfo de public override bool TryCastShot() { Retarget(); + sinceTicks = 0; repeating = true; doRetarget = true; storedShotReduction = null; @@ -1080,7 +1095,7 @@ public override bool TryCastShot() ProjectileCE projectile = (ProjectileCE)ThingMaker.MakeThing(Projectile, null); GenSpawn.Spawn(projectile, shootLine.Source, caster.Map); - ShiftTarget(report, pelletMechanicsOnly, instant, midBurst); + ShiftTarget(report, pelletMechanicsOnly, instant, midBurst, sinceTicks); //New aiming algorithm projectile.canTargetSelf = false; From 8d9b63048bdda87902c03e1b97af09ffd995136b Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 7 Nov 2024 01:57:59 +0600 Subject: [PATCH 053/127] XML - Impact handler for bullets --- Defs/Ammo/AmmoBases.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Defs/Ammo/AmmoBases.xml b/Defs/Ammo/AmmoBases.xml index e35cc0ac7e..ff29ddde5d 100644 --- a/Defs/Ammo/AmmoBases.xml +++ b/Defs/Ammo/AmmoBases.xml @@ -90,6 +90,11 @@ true + +
  • + CombatExtended.CompCIWSImpactHandler_Projectile +
  • +
    From 2866d225fa997eb958a74925c6e46d195f115dc6 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 7 Nov 2024 01:58:18 +0600 Subject: [PATCH 054/127] Missing class --- .../Comps/CompCIWSImpactHandler_Projectile.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Projectile.cs diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Projectile.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Projectile.cs new file mode 100644 index 0000000000..fd7f5696c1 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Projectile.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace CombatExtended +{ + public class CompCIWSImpactHandler_Projectile : CompCIWSImpactHandler + { + public override void OnImpact(ProjectileCE projectile, DamageInfo dinfo) + { + base.OnImpact(projectile, dinfo); + } + } +} From a30bbc72650013d4d3904a5363e8d6d38a3ebaac Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 7 Nov 2024 11:50:23 +0600 Subject: [PATCH 055/127] Moved trajectory code to special worker --- .../Comps/VerbCIWSProjectile.cs | 2 +- .../Projectiles/ProjectileCE.cs | 10 +- .../Projectiles/ProjectilePropertiesCE.cs | 133 +++--------------- .../BallisticsTrajectoryWorker.cs | 46 ++++++ .../TrajectoryWorkers/BaseTrajectoryWorker.cs | 61 ++++++++ .../LerpedTrajectoryWorker.cs | 29 ++++ .../SmartRocketTrajectoryWorker.cs | 22 +++ 7 files changed, 186 insertions(+), 117 deletions(-) create mode 100644 Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs create mode 100644 Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs create mode 100644 Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs create mode 100644 Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 1a920f9d5a..712eab39b1 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -58,7 +58,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ ShiftTarget(report, false, instant, midBurst, i); Vector2 originV2 = new Vector2(originV3.x, originV3.z), destinationV2 = new Vector2(pos.x, pos.z); - var positions = CIWS_ProjectileProperties.NextPositions(shotRotation, shotAngle, originV2, destinationV2, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).Skip(i - 1).Take(2).ToList(); + var positions = CIWS_ProjectileProperties.TrajectoryWorker.NextPositions(targetProjectile, shotRotation, shotAngle, CIWS_ProjectileProperties.Gravity, originV2, Shooter.Position.ToVector3(), destinationV2, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).Skip(i - 1).Take(2).ToList(); if (positions.Count < 2) { resultingLine = default(ShootLine); diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 6430cdeb1f..41e2416f7b 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -1087,9 +1087,10 @@ protected void ApplySuppression(Pawn pawn, float suppressionMultiplier = 1f) - // This is the ideal entry point for guided ammunition and rockets. + + public virtual IEnumerable NextPositions => TrajectoryWorker.NextPositions(intendedTarget, shotRotation, shotAngle, GravityFactor, origin, exactPosition, Destination, startingTicksToImpact, shotHeight, kinit, velocity, shotSpeed, ExactPosition, mass, ballisticCoefficient, radius, gravity, initialSpeed, FlightTicks); + protected Vector3 MoveForward() => TrajectoryWorker.MoveForward(intendedTarget, shotRotation, shotAngle, GravityFactor, origin, ExactPosition, ref Destination, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref exactPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref FlightTicks); - public virtual IEnumerable NextPositions => (def.projectile as ProjectilePropertiesCE).NextPositions(shotRotation, shotAngle, origin, Destination, startingTicksToImpact, shotHeight, kinit, velocity, shotSpeed, ExactPosition, mass, ballisticCoefficient, radius, gravity, initialSpeed, FlightTicks); #region Tick/Draw public override void Tick() @@ -1101,7 +1102,7 @@ public override void Tick() } LastPos = ExactPosition; ticksToImpact--; - Vector3 nextPosition = (def.projectile as ProjectilePropertiesCE).MoveForward(shotRotation, shotAngle, origin, Destination, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref exactPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref FlightTicks); + Vector3 nextPosition = MoveForward(); if (!nextPosition.InBounds(Map)) { if (globalTargetInfo.IsValid) @@ -1372,7 +1373,7 @@ public virtual void Impact(Thing hitThing) var suppressThings = new List(); float dangerAmount = 0f; - var dir = new float?(origin.AngleTo((def.projectile as ProjectilePropertiesCE).Vec2Position(origin, Destination, startingTicksToImpact, FlightTicks))); + var dir = new float?(origin.AngleTo(new Vector2(ExactPosition.x, ExactPosition.z))); // Opt-out for things without explosionRadius if (def.projectile.explosionRadius > 0f) @@ -1462,6 +1463,7 @@ public virtual void Impact(Thing hitThing) #endregion #region Ballistics + public BaseTrajectoryWorker TrajectoryWorker => (def.projectile as ProjectilePropertiesCE).TrajectoryWorker; /// /// Calculated rounding to three decimales the output of h0 + v * sin(a0) * t - g/2 * t^2 with {h0 -> shotHeight, v -> shotSpeed, a0 -> shotAngle, t -> ticks/GenTicks.TicksPerRealSecond, g -> GravityFactor}. Called roughly each tick for impact checks and for drawing. /// diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs index bf8f3295e5..0036e56810 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs @@ -5,10 +5,8 @@ using RimWorld; using Verse; using UnityEngine; -using Rimatomics; -using static UnityEngine.UI.CanvasScaler; using static UnityEngine.UI.Image; -using System.Security.Cryptography; + namespace CombatExtended { @@ -70,118 +68,29 @@ public class ProjectilePropertiesCE : ProjectileProperties public float Gravity => CE_Utility.GravityConst * gravityFactor; public ThingDef CIWSVersion; - #region Moving methods - public virtual Vector2 Vec2Position(Vector2 origin, Vector2 destination, float startingTicksToImpact, int ticks) - { - return Vector2.Lerp(origin, destination, ticks / startingTicksToImpact); - } - public Vector3 MoveForward(float shotRotation, - float shotAngle, - Vector2 origin, - Vector2 destination, - float startingTicksToImpact, - float shotHeight, - ref bool kinit, - ref Vector3 velocity, - ref float shotSpeed, - ref Vector3 curPosition, - ref float mass, - ref float ballisticCoefficient, - ref float radius, - ref float gravity, - ref float initialSpeed, - ref int flightTicks) - { - flightTicks++; - if (lerpPosition) - { - return LerpedMoveForward(origin, destination, startingTicksToImpact, shotHeight, shotSpeed, shotAngle, flightTicks); - } - else - { - return NonLerpedMoveForward(shotRotation, shotAngle, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed); - } - - } - protected Vector3 LerpedMoveForward(Vector2 origin, Vector2 destination, float startingTicksToImpact, float shotHeight, float shotSpeed, float shotAngle, int ticks) - { - var v = Vec2Position(origin, destination, startingTicksToImpact, ticks); - return new Vector3(v.x, GetHeightAtTicks(shotHeight, shotSpeed, shotAngle, ticks), v.y); - - } - protected virtual Vector3 NonLerpedMoveForward(float shotRotation, float shotAngle, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed) - { - if (!kinit) - { - float sr = shotRotation * Mathf.Deg2Rad + 3.14159f / 2.0f; - kinit = true; - ballisticCoefficient = this.ballisticCoefficient.RandomInRange; - mass = this.mass.RandomInRange; - radius = diameter.RandomInRange / 2000; - gravity = Gravity; - float sspt = shotSpeed / GenTicks.TicksPerRealSecond; - velocity = new Vector3(Mathf.Cos(sr) * Mathf.Cos(shotAngle) * sspt, Mathf.Sin(shotAngle) * sspt, Mathf.Sin(sr) * Mathf.Cos(shotAngle) * sspt); - initialSpeed = sspt; - } - Vector3 newPosition = curPosition + velocity; - Accelerate(radius, ballisticCoefficient, mass, gravity, ref velocity, ref shotSpeed); - return newPosition; - } - - protected virtual void Accelerate(float radius, float ballisticCoefficient, float mass, float gravity, ref Vector3 velocity, ref float shotSpeed) - { - AffectedByDrag(radius, shotSpeed, ballisticCoefficient, mass, ref velocity); - AffectedByGravity(gravity, ref velocity); - } - - protected void AffectedByGravity(float gravity, ref Vector3 velocity) + public System.Type trajectoryWorker; + private BaseTrajectoryWorker trajectoryWorkerInt; + public BaseTrajectoryWorker TrajectoryWorker { - velocity.y -= gravity / GenTicks.TicksPerRealSecond; - } - - protected void AffectedByDrag(float radius, float shotSpeed, float ballisticCoefficient, float mass, ref Vector3 velocity) - { - float crossSectionalArea = radius; - crossSectionalArea *= crossSectionalArea * 3.14159f; - // 2.5f is half the mass of 1m² x 1cell of air. - var q = 2.5f * shotSpeed * shotSpeed; - var dragForce = q * crossSectionalArea / ballisticCoefficient; - // F = mA - // A = F / m - var a = (float)-dragForce / mass; - var normalized = velocity.normalized; - velocity.x += a * normalized.x; - velocity.y += a * normalized.y; - velocity.z += a * normalized.z; - } - protected float GetHeightAtTicks(float shotHeight, float shotSpeed, float shotAngle, int ticks) - { - var seconds = ((float)ticks) / GenTicks.TicksPerRealSecond; - return (float)Math.Round(shotHeight + shotSpeed * Mathf.Sin(shotAngle) * seconds - (Gravity * seconds * seconds) / 2f, 3); - } - - public virtual IEnumerable NextPositions(float shotRotation, - float shotAngle, - Vector2 origin, - Vector2 destination, - float ticksToImpact, - float shotHeight, - bool kinit, - Vector3 velocity, - float shotSpeed, - Vector3 curPosition, - float mass, - float ballisticCoefficient, - float radius, - float gravity, - float initialSpeed, - int flightTicks) - { - for (; ticksToImpact >= 0; ticksToImpact--) + get { - yield return MoveForward(shotRotation, shotAngle, origin, destination, ticksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); + if (trajectoryWorkerInt == null) + { + if (trajectoryWorker != null) + { + trajectoryWorkerInt = (BaseTrajectoryWorker)Activator.CreateInstance(trajectoryWorker); + } + else if (lerpPosition) + { + trajectoryWorkerInt = new LerpedTrajectoryWorker(); + } + else + { + trajectoryWorkerInt = new BallisticsTrajectoryWorker(); + } + } + return trajectoryWorkerInt; } } - #endregion } } diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs new file mode 100644 index 0000000000..e55b174992 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace CombatExtended +{ + public class BallisticsTrajectoryWorker : BaseTrajectoryWorker + { + public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int flightTicks) + { + Accelerate(radius, ballisticCoefficient, mass, gravity, ref velocity, ref shotSpeed); + shotSpeed = velocity.magnitude; + return exactPosition + velocity; + } + protected virtual void Accelerate(float radius, float ballisticCoefficient, float mass, float gravity, ref Vector3 velocity, ref float shotSpeed) + { + AffectedByDrag(radius, shotSpeed, ballisticCoefficient, mass, ref velocity); + AffectedByGravity(gravity, ref velocity); + } + + protected void AffectedByGravity(float gravity, ref Vector3 velocity) + { + velocity.y -= gravity / GenTicks.TicksPerRealSecond; + } + + protected void AffectedByDrag(float radius, float shotSpeed, float ballisticCoefficient, float mass, ref Vector3 velocity) + { + float crossSectionalArea = radius; + crossSectionalArea *= crossSectionalArea * 3.14159f; + // 2.5f is half the mass of 1m² x 1cell of air. + var q = 2.5f * shotSpeed * shotSpeed; + var dragForce = q * crossSectionalArea / ballisticCoefficient; + // F = mA + // A = F / m + var a = (float)-dragForce / mass; + var normalized = velocity.normalized; + velocity.x += a * normalized.x; + velocity.y += a * normalized.y; + velocity.z += a * normalized.z; + } + } +} diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs new file mode 100644 index 0000000000..ddc7753b9f --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace CombatExtended +{ + public abstract class BaseTrajectoryWorker + { + public abstract Vector3 MoveForward( + LocalTargetInfo currentTarget, + float shotRotation, + float shotAngle, + float gravityFactor, + Vector2 origin, + Vector3 exactPosition, + ref Vector2 destination, + float startingTicksToImpact, + float shotHeight, + ref bool kinit, + ref Vector3 velocity, + ref float shotSpeed, + ref Vector3 curPosition, + ref float mass, + ref float ballisticCoefficient, + ref float radius, + ref float gravity, + ref float initialSpeed, + ref int flightTicks + ); + public virtual IEnumerable NextPositions( + LocalTargetInfo currentTarget, + float shotRotation, + float shotAngle, + float gravityFactor, + Vector2 origin, + Vector3 exactPosition, + Vector2 destination, + float ticksToImpact, + float shotHeight, + bool kinit, + Vector3 velocity, + float shotSpeed, + Vector3 curPosition, + float mass, + float ballisticCoefficient, + float radius, + float gravity, + float initialSpeed, + int flightTicks) + { + for (; ticksToImpact >= 0; ticksToImpact--) + { + yield return MoveForward(currentTarget, shotRotation, shotAngle, gravityFactor, origin, exactPosition, ref destination, ticksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); + } + } + } +} diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs new file mode 100644 index 0000000000..b59bcb54da --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace CombatExtended +{ + public class LerpedTrajectoryWorker : BaseTrajectoryWorker + { + public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int ticks) + { + ticks++; + var v = Vec2Position(origin, destination, startingTicksToImpact, ticks); + return new Vector3(v.x, GetHeightAtTicks(shotHeight, shotSpeed, shotAngle, ticks, gravityFactor), v.y); + } + protected float GetHeightAtTicks(float shotHeight, float shotSpeed, float shotAngle, int ticks, float gravityFactor) + { + var seconds = ((float)ticks) / GenTicks.TicksPerRealSecond; + return (float)Math.Round(shotHeight + shotSpeed * Mathf.Sin(shotAngle) * seconds - (gravityFactor * seconds * seconds) / 2f, 3); + } + public Vector2 Vec2Position(Vector2 origin, Vector2 destination, float startingTicksToImpact, int ticks) + { + return Vector2.Lerp(origin, destination, ticks / startingTicksToImpact); + } + } +} diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs new file mode 100644 index 0000000000..0f6228b1f4 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace CombatExtended +{ + public class SmartRocketTrajectoryWorker : BallisticsTrajectoryWorker + { + public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int flightTicks) + { + if (currentTarget.HasThing) + { + velocity = Vector3.RotateTowards(velocity, currentTarget.Thing.DrawPos, 360, 0); //Rotate rocket towards target. Not sure how it should work, haven't tested it yet + } + return base.MoveForward(currentTarget, shotRotation, shotAngle, gravityFactor, origin, exactPosition, ref destination, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); + } + } +} From b60ad5bf2f0e4f881f7a7c842138c5409cea979a Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 7 Nov 2024 12:26:32 +0600 Subject: [PATCH 056/127] Debug things --- .../CombatExtended/Comps/VerbCIWS.cs | 18 +++++++++++++++++- .../CombatExtended/Comps/VerbCIWSProjectile.cs | 6 +++++- .../CombatExtended/Projectiles/ProjectileCE.cs | 15 +++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index 731518bb2c..f121740802 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -13,7 +13,7 @@ namespace CombatExtended { public abstract class VerbCIWS : Verb_ShootCE_CIWS, ITargetSearcher { - + protected bool debug; protected bool holdFire; public VerbProperties_CIWS Props => verbProps as VerbProperties_CIWS; @@ -49,6 +49,22 @@ public abstract class VerbCIWS : Verb_ShootCE_CIWS, ITargetSearcher //} public virtual bool Active => !holdFire && Turret.Active; public abstract bool TryFindNewTarget(out LocalTargetInfo target); + public virtual void ShowTrajectories() + { + if (lastShootLine != null) + { + Caster.Map.debugDrawer.FlashLine(lastShootLine.Value.source, lastShootLine.Value.Dest, 60, SimpleColor.Green); + } + } + public override bool TryCastShot() + { + var result = base.TryCastShot(); + if (result && debug) + { + ShowTrajectories(); + } + return result; + } } public abstract class VerbCIWS : VerbCIWS where TargetType : Thing { diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 712eab39b1..09f8ba7d55 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -69,7 +69,6 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ if (CE_Utility.TryFindIntersectionPoint(ciwsPos1, ciwsPos2, targetPos1, targetPos2, out var point)) { resultingLine = new ShootLine(Shooter.Position, point.ToVector3().ToIntVec3()); - Shooter.Map.debugDrawer.FlashLine(Shooter.Position, point.ToVector3().ToIntVec3(), 100, SimpleColor.Red); this.sinceTicks = i; return true; @@ -81,6 +80,11 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ resultingLine = default; return false; } + public override void ShowTrajectories() + { + base.ShowTrajectories(); + (currentTarget.Thing as ProjectileCE)?.DrawNextPositions(); + } } public class VerbProperties_CIWSProjectile : VerbProperties_CIWS { diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 41e2416f7b..ddd090fe81 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -1464,6 +1464,21 @@ public virtual void Impact(Thing hitThing) #region Ballistics public BaseTrajectoryWorker TrajectoryWorker => (def.projectile as ProjectilePropertiesCE).TrajectoryWorker; + + public void DrawNextPositions() + { + if (Map == null) + { + return; + } + var previous = ExactPosition; + foreach (var next in NextPositions) + { + Map.debugDrawer.FlashLine(previous.ToIntVec3(), next.ToIntVec3(), 70, SimpleColor.Orange); + Map.debugDrawer.FlashLine(ExactPosToDrawPos(previous).ToIntVec3(), ExactPosToDrawPos(next).ToIntVec3(), 70, SimpleColor.Red); + previous = next; + } + } /// /// Calculated rounding to three decimales the output of h0 + v * sin(a0) * t - g/2 * t^2 with {h0 -> shotHeight, v -> shotSpeed, a0 -> shotAngle, t -> ticks/GenTicks.TicksPerRealSecond, g -> GravityFactor}. Called roughly each tick for impact checks and for drawing. /// From dbbd4c2b50830f737c80c546be1b168c6d67d58b Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 7 Nov 2024 22:59:33 +0600 Subject: [PATCH 057/127] Another ballistic changes --- .../Comps/VerbCIWSProjectile.cs | 5 ++-- .../Projectiles/ProjectileCE.cs | 23 ++++++++----------- .../BallisticsTrajectoryWorker.cs | 2 +- .../TrajectoryWorkers/BaseTrajectoryWorker.cs | 15 +++++++++++- .../LerpedTrajectoryWorker.cs | 2 +- .../SmartRocketTrajectoryWorker.cs | 4 ++-- .../Verbs/Verb_LaunchProjectileCE.cs | 4 ++-- 7 files changed, 33 insertions(+), 22 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 09f8ba7d55..4207069a68 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -49,8 +49,9 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ if (targetProjectile.def.projectile is ProjectilePropertiesCE targetProjectileProperties && Projectile.projectile is ProjectilePropertiesCE CIWS_ProjectileProperties) { var targetPos1 = new Vector2(targetProjectile.Position.x, targetProjectile.Position.z); - foreach (var pos in targetProjectile.NextPositions.Skip(ticksToSkip).Select(x => targetProjectile.ExactPosToDrawPos(x))) + foreach (var exactPos in targetProjectile.NextPositions.Skip(ticksToSkip)) { + var pos = targetProjectile.TrajectoryWorker.ExactPosToDrawPos(exactPos, targetProjectile.FlightTicks + ticksToSkip + i - 1, (targetProjectile.def.projectile as ProjectilePropertiesCE).TickToTruePos, targetProjectile.def.Altitude); if (i > maximumPredectionTicks) { break; @@ -58,7 +59,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ ShiftTarget(report, false, instant, midBurst, i); Vector2 originV2 = new Vector2(originV3.x, originV3.z), destinationV2 = new Vector2(pos.x, pos.z); - var positions = CIWS_ProjectileProperties.TrajectoryWorker.NextPositions(targetProjectile, shotRotation, shotAngle, CIWS_ProjectileProperties.Gravity, originV2, Shooter.Position.ToVector3(), destinationV2, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).Skip(i - 1).Take(2).ToList(); + var positions = CIWS_ProjectileProperties.TrajectoryWorker.NextPositions(targetProjectile, shotRotation, shotAngle, CIWS_ProjectileProperties.Gravity, originV2, Shooter.Position.ToVector3(), destinationV2, maximumPredectionTicks, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).Skip(i - 1).Take(2).ToList(); if (positions.Count < 2) { resultingLine = default(ShootLine); diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index ddd090fe81..80687eed6c 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -208,20 +208,12 @@ public Vector3 ExactMinusLastPos } } - public virtual Vector3 ExactPosToDrawPos(Vector3 exactPosition) - { - var sh = Mathf.Max(0f, (exactPosition.y) * 0.84f); - if (FlightTicks < ticksToTruePosition) - { - sh *= (float)FlightTicks / ticksToTruePosition; - } - return new Vector3(exactPosition.x, def.Altitude, exactPosition.z + sh); - } + public override Vector3 DrawPos { get { - return ExactPosToDrawPos(ExactPosition); + return TrajectoryWorker.ExactPosToDrawPos(ExactPosition, FlightTicks, ticksToTruePosition, def.Altitude); } } @@ -1088,8 +1080,8 @@ protected void ApplySuppression(Pawn pawn, float suppressionMultiplier = 1f) - public virtual IEnumerable NextPositions => TrajectoryWorker.NextPositions(intendedTarget, shotRotation, shotAngle, GravityFactor, origin, exactPosition, Destination, startingTicksToImpact, shotHeight, kinit, velocity, shotSpeed, ExactPosition, mass, ballisticCoefficient, radius, gravity, initialSpeed, FlightTicks); - protected Vector3 MoveForward() => TrajectoryWorker.MoveForward(intendedTarget, shotRotation, shotAngle, GravityFactor, origin, ExactPosition, ref Destination, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref exactPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref FlightTicks); + public virtual IEnumerable NextPositions => TrajectoryWorker.NextPositions(intendedTarget, shotRotation, shotAngle, GravityFactor, origin, exactPosition, Destination, ticksToImpact, startingTicksToImpact, shotHeight, kinit, velocity, shotSpeed, ExactPosition, mass, ballisticCoefficient, radius, gravity, initialSpeed, FlightTicks); + protected Vector3 MoveForward() => TrajectoryWorker.MoveForward(intendedTarget, shotRotation, shotAngle, GravityFactor, origin, ExactPosition, ref Destination, ticksToImpact, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref exactPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref FlightTicks); #region Tick/Draw @@ -1472,11 +1464,16 @@ public void DrawNextPositions() return; } var previous = ExactPosition; + int sinceTicks = 1; foreach (var next in NextPositions) { Map.debugDrawer.FlashLine(previous.ToIntVec3(), next.ToIntVec3(), 70, SimpleColor.Orange); - Map.debugDrawer.FlashLine(ExactPosToDrawPos(previous).ToIntVec3(), ExactPosToDrawPos(next).ToIntVec3(), 70, SimpleColor.Red); + Map.debugDrawer.FlashLine( + TrajectoryWorker.ExactPosToDrawPos(next, FlightTicks + sinceTicks, (def.projectile as ProjectilePropertiesCE).TickToTruePos, def.Altitude).ToIntVec3(), + TrajectoryWorker.ExactPosToDrawPos(previous, FlightTicks + sinceTicks -1, (def.projectile as ProjectilePropertiesCE).TickToTruePos, def.Altitude).ToIntVec3() + , 70, SimpleColor.Red); previous = next; + sinceTicks++; } } /// diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs index e55b174992..74ea3eac26 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs @@ -10,7 +10,7 @@ namespace CombatExtended { public class BallisticsTrajectoryWorker : BaseTrajectoryWorker { - public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int flightTicks) + public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float ticksToImpact, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int flightTicks) { Accelerate(radius, ballisticCoefficient, mass, gravity, ref velocity, ref shotSpeed); shotSpeed = velocity.magnitude; diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs index ddc7753b9f..be261a6493 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using UnityEngine; @@ -18,6 +19,7 @@ public abstract Vector3 MoveForward( Vector2 origin, Vector3 exactPosition, ref Vector2 destination, + float tickToImpact, float startingTicksToImpact, float shotHeight, ref bool kinit, @@ -40,6 +42,7 @@ public virtual IEnumerable NextPositions( Vector3 exactPosition, Vector2 destination, float ticksToImpact, + float startingTicksToImpact, float shotHeight, bool kinit, Vector3 velocity, @@ -54,8 +57,18 @@ public virtual IEnumerable NextPositions( { for (; ticksToImpact >= 0; ticksToImpact--) { - yield return MoveForward(currentTarget, shotRotation, shotAngle, gravityFactor, origin, exactPosition, ref destination, ticksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); + Log.Message($"{ticksToImpact}, {flightTicks}"); + yield return MoveForward(currentTarget, shotRotation, shotAngle, gravityFactor, origin, exactPosition, ref destination, ticksToImpact, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); + } + } + public virtual Vector3 ExactPosToDrawPos(Vector3 exactPosition, int FlightTicks, int ticksToTruePosition, float altitude) + { + var sh = Mathf.Max(0f, (exactPosition.y) * 0.84f); + if (FlightTicks < ticksToTruePosition) + { + sh *= (float)FlightTicks / ticksToTruePosition; } + return new Vector3(exactPosition.x, altitude, exactPosition.z + sh); } } } diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs index b59bcb54da..df16520055 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs @@ -10,7 +10,7 @@ namespace CombatExtended { public class LerpedTrajectoryWorker : BaseTrajectoryWorker { - public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int ticks) + public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float tickToImpact, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int ticks) { ticks++; var v = Vec2Position(origin, destination, startingTicksToImpact, ticks); diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs index 0f6228b1f4..a4f5ad7c85 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs @@ -10,13 +10,13 @@ namespace CombatExtended { public class SmartRocketTrajectoryWorker : BallisticsTrajectoryWorker { - public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int flightTicks) + public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float tickToImpact, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int flightTicks) { if (currentTarget.HasThing) { velocity = Vector3.RotateTowards(velocity, currentTarget.Thing.DrawPos, 360, 0); //Rotate rocket towards target. Not sure how it should work, haven't tested it yet } - return base.MoveForward(currentTarget, shotRotation, shotAngle, gravityFactor, origin, exactPosition, ref destination, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); + return base.MoveForward(currentTarget, shotRotation, shotAngle, gravityFactor, origin, exactPosition, ref destination, tickToImpact, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); } } } diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index 621acf80f3..51b5b2e687 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -367,7 +367,7 @@ public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalO Vector3 v; if (report.target.Thing is ProjectileCE projectile) { - v = projectile.ExactPosToDrawPos(projectile.NextPositions.ElementAtOrLast(sinceTicks)); + v = projectile.TrajectoryWorker.ExactPosToDrawPos(projectile.NextPositions.ElementAtOrLast(sinceTicks), projectile.FlightTicks + sinceTicks, (projectile.def.projectile as ProjectilePropertiesCE).TickToTruePos, projectile.def.Altitude); } else { @@ -584,7 +584,7 @@ public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalO } } angleRadians += lastShotAngle; - } + } // ----------------------------------- STEP 4: Mechanical variation From 3fcdf6709e4476a975af2cceed2fb1341d05539b Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 8 Nov 2024 00:14:00 +0600 Subject: [PATCH 058/127] Some manipulations with tick offset --- .../CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 4207069a68..f4ef99b9f7 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -59,7 +59,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ ShiftTarget(report, false, instant, midBurst, i); Vector2 originV2 = new Vector2(originV3.x, originV3.z), destinationV2 = new Vector2(pos.x, pos.z); - var positions = CIWS_ProjectileProperties.TrajectoryWorker.NextPositions(targetProjectile, shotRotation, shotAngle, CIWS_ProjectileProperties.Gravity, originV2, Shooter.Position.ToVector3(), destinationV2, maximumPredectionTicks, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).Skip(i - 1).Take(2).ToList(); + var positions = CIWS_ProjectileProperties.TrajectoryWorker.NextPositions(targetProjectile, shotRotation, shotAngle, CIWS_ProjectileProperties.Gravity, originV2, Shooter.Position.ToVector3(), destinationV2, maximumPredectionTicks, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).Skip(i + 1).Take(2).ToList(); if (positions.Count < 2) { resultingLine = default(ShootLine); From f1152d5023a83cc71c6647e2349540154aea8e2f Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 8 Nov 2024 00:14:25 +0600 Subject: [PATCH 059/127] Draw CIWS projectile exactly where it is --- .../CombatExtended/Projectiles/ProjectileCE_CIWS.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs index 2f02715087..a0720b2fc6 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs @@ -83,6 +83,7 @@ protected override bool CanCollideWith(Thing thing, out float dist) return false; } + public override Vector3 DrawPos => ExactPosition.WithY(def.Altitude); public override void Impact(Thing hitThing) { hitThing?.TryGetComp()?.OnImpact(this, DamageInfo); From 14464e1d7f7906d2a6287620911a20ae67981b76 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 8 Nov 2024 00:15:07 +0600 Subject: [PATCH 060/127] Fixed turret not using default verb --- .../CombatExtended/Things/Building_Turret_MultiVerbs.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs b/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs index 68d30886b8..6c6a44416a 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs @@ -45,6 +45,7 @@ public override void DrawExtraSelectionOverlays() } public override LocalTargetInfo TryFindNewTarget() { + activeVerb = null; foreach (var verb in VerbsWithTargetSearcher) { if (verb.TryFindNewTarget(out var target)) From 79afc9d992b1432e94b16e61c2a206b08d989eb8 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 8 Nov 2024 00:27:59 +0600 Subject: [PATCH 061/127] TurretTop rotation fix --- .../CombatExtended/Things/Building_CIWS_CE.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs index 1fc565ac5e..56b33a51ab 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs @@ -34,5 +34,13 @@ public IEnumerable IgnoredDefs return Enumerable.Empty(); } } + public override void Tick() + { + base.Tick(); + if (CurrentTarget.IsValid && CurrentTarget.HasThing) + { + this.top.CurRotation = (CurrentTarget.Thing.DrawPos - this.DrawPos).AngleFlat(); + } + } } } From f6fb81de258e711d34295a6f588c72e42ddfd302 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 8 Nov 2024 00:38:29 +0600 Subject: [PATCH 062/127] Impact and vfx position fix --- .../CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs | 1 - .../CombatExtended/Comps/CompCIWSImpactHandler_Projectile.cs | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs index 06b7d16a0e..bc4d35e3d6 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs @@ -16,7 +16,6 @@ public class CompCIWSImpactHandler : ThingComp public virtual void OnImpact(ProjectileCE projectile, DamageInfo dinfo) { - parent.Position = projectile.Position; if (!Props.impacted.NullOrUndefined()) { Props.impacted.PlayOneShot(new TargetInfo(parent.DrawPos.ToIntVec3(), parent.Map)); diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Projectile.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Projectile.cs index fd7f5696c1..f4663c2cd8 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Projectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Projectile.cs @@ -11,6 +11,7 @@ public class CompCIWSImpactHandler_Projectile : CompCIWSImpactHandler { public override void OnImpact(ProjectileCE projectile, DamageInfo dinfo) { + projectile.ExactPosition = parent.DrawPos; base.OnImpact(projectile, dinfo); } } From 576961e756152a788042206b7f3ea74876264543 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 8 Nov 2024 20:33:50 +0600 Subject: [PATCH 063/127] Draw pos of skyfallers --- .../CombatExtended/CombatExtended/CE_Utility.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Source/CombatExtended/CombatExtended/CE_Utility.cs b/Source/CombatExtended/CombatExtended/CE_Utility.cs index 2957058406..64ab983792 100644 --- a/Source/CombatExtended/CombatExtended/CE_Utility.cs +++ b/Source/CombatExtended/CombatExtended/CE_Utility.cs @@ -1694,5 +1694,20 @@ internal static T ElementAtOrLast(this IEnumerable enumerable, int index) } return current; } + public static Vector3 DrawPosSinceTicks(this Skyfaller thing, int ticksAmount) + { + thing.ticksToImpact -= ticksAmount; + var result = thing.DrawPos; + thing.ticksToImpact += ticksAmount; + return result; + } + public static IEnumerable DrawPositions(this Skyfaller skyfaller) + { + int max = skyfaller.ticksToImpact; + for (int i = 1; i <= max; i++) + { + yield return skyfaller.DrawPosSinceTicks(i); + } + } } } From e69476f3b35c49365930a06f4f78512708a6b58e Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 8 Nov 2024 20:36:03 +0600 Subject: [PATCH 064/127] Code reuse for skyfallers --- .../CombatExtended/Comps/VerbCIWS.cs | 88 +++++++++++++++++++ .../Comps/VerbCIWSProjectile.cs | 73 +++------------ .../CombatExtended/Comps/VerbCIWSSkyfaller.cs | 5 ++ .../Projectiles/ProjectileCE.cs | 2 +- 4 files changed, 105 insertions(+), 63 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index f121740802..2820badc39 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -56,6 +56,32 @@ public virtual void ShowTrajectories() Caster.Map.debugDrawer.FlashLine(lastShootLine.Value.source, lastShootLine.Value.Dest, 60, SimpleColor.Green); } } + protected (Vector2 firstPos, Vector2 secondPos) PositionOfCIWSProjectile(int sinceTicks, Vector2 destination, bool drawPos = false) + { + var firstPos = Caster.Position.ToVector3Shifted(); + var secondPos = firstPos; + var originV3 = firstPos; + var originV2 = new Vector2(originV3.x, originV3.z); + var enumeration = projectilePropsCE.TrajectoryWorker.NextPositions(currentTarget, shotRotation, shotAngle, projectilePropsCE.Gravity, originV2, this.Caster.Position.ToVector3Shifted(), destination, maximumPredectionTicks, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).GetEnumerator(); + for (int i = 1; i <= sinceTicks; i++) + { + firstPos = secondPos; + + if (!enumeration.MoveNext()) + { + break; + } + secondPos = enumeration.Current; + + } + if (drawPos) + { + firstPos = projectilePropsCE.TrajectoryWorker.ExactPosToDrawPos(firstPos, sinceTicks - 1, projectilePropsCE.TickToTruePos, Projectile.Altitude); + secondPos = projectilePropsCE.TrajectoryWorker.ExactPosToDrawPos(secondPos, sinceTicks, projectilePropsCE.TickToTruePos, Projectile.Altitude); + } + return (new Vector2(firstPos.x, firstPos.z), new Vector2(secondPos.x, secondPos.z)); + } + public override bool TryCastShot() { var result = base.TryCastShot(); @@ -99,6 +125,68 @@ public override bool TryFindNewTarget(out LocalTargetInfo target) protected virtual bool IsFriendlyTo(TargetType thing) => !thing.HostileTo(Caster); public abstract IEnumerable Targets { get; } public override bool ValidateTarget(LocalTargetInfo target, bool showMessages = true) => target.Thing is TargetType && TryFindCEShootLineFromTo(Caster.Position, target, out _) && base.ValidateTarget(target, showMessages); + protected abstract IEnumerable TargetNextPositions(TargetType target); + public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targetInfo, out ShootLine resultingLine) + { + if (base.TryFindCEShootLineFromTo(root, targetInfo, out resultingLine)) + { + return true; + } + if (!(targetInfo.Thing is TargetType target)) + { + return false; + } + var midBurst = numShotsFired > 0; + var originV3 = Caster.Position.ToVector3Shifted(); + var ticksToSkip = this.BurstWarmupTicksLeft; + var instant = projectilePropsCE.isInstant; + if (instant) + { + var to = TargetNextPositions(target).Skip(ticksToSkip).FirstOrFallback(Vector3.negativeInfinity); + if (to == Vector3.negativeInfinity) + { + resultingLine = default; + return false; + } + resultingLine = new ShootLine(originV3.ToIntVec3(), to.ToIntVec3()); + return true; + } + int i = 1; + var report = ShiftVecReportFor(targetInfo); + + var targetPos1 = new Vector2(target.DrawPos.x, target.DrawPos.z); + foreach (var pos in TargetNextPositions(target).Skip(ticksToSkip)) + { + if (i > maximumPredectionTicks) + { + break; + } + ShiftTarget(report, false, instant, midBurst, i); + + Vector2 originV2 = new Vector2(originV3.x, originV3.z), destinationV2 = new Vector2(pos.x, pos.z); + + var positions = PositionOfCIWSProjectile(i, destinationV2); + if (positions.firstPos == positions.secondPos) + { + resultingLine = default(ShootLine); + return false; + } + Vector2 ciwsPos1 = positions.firstPos, ciwsPos2 = positions.secondPos, targetPos2 = new Vector2(pos.x, pos.z); + + if (CE_Utility.TryFindIntersectionPoint(ciwsPos1, ciwsPos2, targetPos1, targetPos2, out var point)) + { + resultingLine = new ShootLine(Shooter.Position, point.ToVector3().ToIntVec3()); + + this.sinceTicks = i; + return true; + } + targetPos1 = targetPos2; + i++; + + } + resultingLine = default; + return false; + } } public abstract class VerbCIWS_Comp : VerbCIWS where TargetType : CompCIWSTarget { diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index f4ef99b9f7..4cbd673511 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -19,73 +19,22 @@ public class VerbCIWSProjectile : VerbCIWS public override IEnumerable Targets => Caster.Map?.listerThings.ThingsInGroup(ThingRequestGroup.Projectile).OfType() ?? Array.Empty(); protected override bool IsFriendlyTo(ProjectileCE thing) => base.IsFriendlyTo(thing) && !thing.launcher.HostileTo(Caster); - public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo target, out ShootLine resultingLine) - { - if (base.TryFindCEShootLineFromTo(root, target, out resultingLine)) - { - return true; - } - if (!(target.Thing is ProjectileCE targetProjectile)) - { - return false; - } - var midBurst = numShotsFired > 0; - var originV3 = Caster.Position.ToVector3Shifted(); - var ticksToSkip = this.BurstWarmupTicksLeft; - var instant = Projectile.projectile is ProjectilePropertiesCE CIWSProjectilePropertiesCE && CIWSProjectilePropertiesCE.isInstant; - if (instant) - { - var to = targetProjectile.NextPositions.Skip(ticksToSkip).FirstOrFallback(Vector3.negativeInfinity); - if (to == Vector3.negativeInfinity) - { - resultingLine = default; - return false; - } - resultingLine = new ShootLine(originV3.ToIntVec3(), to.ToIntVec3()); - return true; - } - int i = 1; - var report = ShiftVecReportFor((LocalTargetInfo)targetProjectile); - if (targetProjectile.def.projectile is ProjectilePropertiesCE targetProjectileProperties && Projectile.projectile is ProjectilePropertiesCE CIWS_ProjectileProperties) - { - var targetPos1 = new Vector2(targetProjectile.Position.x, targetProjectile.Position.z); - foreach (var exactPos in targetProjectile.NextPositions.Skip(ticksToSkip)) - { - var pos = targetProjectile.TrajectoryWorker.ExactPosToDrawPos(exactPos, targetProjectile.FlightTicks + ticksToSkip + i - 1, (targetProjectile.def.projectile as ProjectilePropertiesCE).TickToTruePos, targetProjectile.def.Altitude); - if (i > maximumPredectionTicks) - { - break; - } - ShiftTarget(report, false, instant, midBurst, i); - - Vector2 originV2 = new Vector2(originV3.x, originV3.z), destinationV2 = new Vector2(pos.x, pos.z); - var positions = CIWS_ProjectileProperties.TrajectoryWorker.NextPositions(targetProjectile, shotRotation, shotAngle, CIWS_ProjectileProperties.Gravity, originV2, Shooter.Position.ToVector3(), destinationV2, maximumPredectionTicks, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).Skip(i + 1).Take(2).ToList(); - if (positions.Count < 2) - { - resultingLine = default(ShootLine); - return false; - } - Vector2 ciwsPos1 = new Vector2(positions.First().x, positions.First().z), ciwsPos2 = new Vector2(positions.Last().x, positions.Last().z), targetPos2 = new Vector2(pos.x, pos.z); - - if (CE_Utility.TryFindIntersectionPoint(ciwsPos1, ciwsPos2, targetPos1, targetPos2, out var point)) - { - resultingLine = new ShootLine(Shooter.Position, point.ToVector3().ToIntVec3()); - - this.sinceTicks = i; - return true; - } - targetPos1 = targetPos2; - i++; - } - } - resultingLine = default; - return false; - } + public override void ShowTrajectories() { base.ShowTrajectories(); (currentTarget.Thing as ProjectileCE)?.DrawNextPositions(); } + + protected override IEnumerable TargetNextPositions(ProjectileCE target) + { + int tickOffset = 1; + foreach (var exactPos in target.NextPositions) + { + yield return target.TrajectoryWorker.ExactPosToDrawPos(exactPos, target.FlightTicks + tickOffset, target.ticksToTruePosition, target.def.Altitude); + tickOffset++; + } + } } public class VerbProperties_CIWSProjectile : VerbProperties_CIWS { diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs index 603d17669c..ebb2ea2b68 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs @@ -18,6 +18,11 @@ public class VerbCIWSSkyfaller : VerbCIWS protected override bool IsFriendlyTo(Skyfaller thing) => base.IsFriendlyTo(thing) && thing.ContainedThings().All(x => !x.HostileTo(Caster)); + protected override IEnumerable TargetNextPositions(Skyfaller target) + { + return target.DrawPositions(); + } + } public class VerbProperties_CIWSSkyfaller : VerbProperties_CIWS { diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 80687eed6c..c021f3ed5e 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -38,7 +38,7 @@ public abstract class ProjectileCE : ThingWithComps #endregion #region Drawing - protected int ticksToTruePosition; + public int ticksToTruePosition; #endregion #region Origin destination From 82bfe0b443eaf1231e7ec7f83b2fe1cff7098552 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 8 Nov 2024 21:18:38 +0600 Subject: [PATCH 065/127] Overrided ShiftTarget variable calculations --- .../Comps/VerbCIWSProjectile.cs | 16 + .../CombatExtended/Comps/VerbCIWSSkyfaller.cs | 16 + .../Verbs/Verb_LaunchProjectileCE.cs | 341 +++++++++--------- 3 files changed, 203 insertions(+), 170 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 4cbd673511..27dca0b382 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -26,6 +26,22 @@ public override void ShowTrajectories() (currentTarget.Thing as ProjectileCE)?.DrawNextPositions(); } + public override Vector3 GetTargetLoc(LocalTargetInfo tagret, int sinceTicks) + { + if (tagret.Thing is ProjectileCE projectile) + { + return projectile.TrajectoryWorker.ExactPosToDrawPos(projectile.NextPositions.ElementAtOrLast(sinceTicks), projectile.FlightTicks + sinceTicks, (projectile.def.projectile as ProjectilePropertiesCE).TickToTruePos, projectile.def.Altitude); + } + return base.GetTargetLoc(tagret, sinceTicks); + } + public override float GetTargetHeight(LocalTargetInfo target, Thing cover, bool roofed, Vector3 targetLoc, int sinceTicks) + { + if (target.Thing is ProjectileCE projectile) + { + return targetLoc.y; + } + return base.GetTargetHeight(target, cover, roofed, targetLoc, sinceTicks); + } protected override IEnumerable TargetNextPositions(ProjectileCE target) { int tickOffset = 1; diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs index ebb2ea2b68..ec0d3dd758 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs @@ -22,6 +22,22 @@ protected override IEnumerable TargetNextPositions(Skyfaller target) { return target.DrawPositions(); } + public override Vector3 GetTargetLoc(LocalTargetInfo target, int sinceTicks) + { + if (target.Thing is Skyfaller skyfaller) + { + return skyfaller.DrawPosSinceTicks(sinceTicks); + } + return base.GetTargetLoc(target, sinceTicks); + } + public override float GetTargetHeight(LocalTargetInfo target, Thing cover, bool roofed, Vector3 targetLoc, int sinceTicks) + { + if (target.Thing is Skyfaller skyfaller) + { + return 0.5f * (skyfaller.ticksToImpact - sinceTicks); + } + return base.GetTargetHeight(target, cover, roofed, targetLoc, sinceTicks); + } } public class VerbProperties_CIWSSkyfaller : VerbProperties_CIWS diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index 51b5b2e687..d46bd551bc 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -349,229 +349,230 @@ public override void WarmupComplete() ); } - /// - /// Shifts the original target position in accordance with target leading, range estimation and weather/lighting effects - /// - public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalOnly = false, bool isInstant = false, bool midBurst = false, int sinceTicks = 0) + public virtual Vector3 GetTargetLoc(LocalTargetInfo target, int sinceTicks) { - if (!calculateMechanicalOnly) - { - Vector3 u = caster.TrueCenter(); - sourceLoc.Set(u.x, u.z); + return target.Thing?.TrueCenter() ?? target.Cell.ToVector3Shifted(); //report.targetPawn != null ? report.targetPawn.DrawPos + report.targetPawn.Drawer.leaner.LeanOffset * 0.5f : report.target.Cell.ToVector3Shifted(); + } + public virtual float GetTargetHeight(LocalTargetInfo target, Thing cover, bool roofed, Vector3 targetLoc, int sinceTicks) + { + float targetHeight = 0f; - if (numShotsFired == 0) - { - // On first shot of burst do a range estimate - estimatedTargDist = report.GetRandDist(); - } - Vector3 v; - if (report.target.Thing is ProjectileCE projectile) + var coverRange = new CollisionVertical(cover).HeightRange; //Get " " cover, assume it is the edifice + + // Projectiles with flyOverhead target the surface in front of the target + if (Projectile.projectile.flyOverhead) + { + targetHeight = coverRange.max; + } + else + { + var victimVert = new CollisionVertical(currentTarget.Thing); + var targetRange = victimVert.HeightRange; //Get lower and upper heights of the target + if (targetRange.min < coverRange.max) //Some part of the target is hidden behind some cover { - v = projectile.TrajectoryWorker.ExactPosToDrawPos(projectile.NextPositions.ElementAtOrLast(sinceTicks), projectile.FlightTicks + sinceTicks, (projectile.def.projectile as ProjectilePropertiesCE).TickToTruePos, projectile.def.Altitude); + // - It is possible for targetRange.max < coverRange.max, technically, in which case the shooter will never hit until the cover is gone. + // - This should be checked for in LoS -NIA + targetRange.min = coverRange.max; + + // Target fully hidden, shift aim upwards if we're doing suppressive fire + if (targetRange.max <= coverRange.max && (CompFireModes?.CurrentAimMode == AimMode.SuppressFire || VerbPropsCE.ignorePartialLoSBlocker)) + { + targetRange.max = coverRange.max * 2; + } } - else + else if (currentTarget.Thing is Pawn Victim) { - v = report.target.Thing?.TrueCenter() ?? report.target.Cell.ToVector3Shifted(); //report.targetPawn != null ? report.targetPawn.DrawPos + report.targetPawn.Drawer.leaner.LeanOffset * 0.5f : report.target.Cell.ToVector3Shifted(); - } + targetRange.min = victimVert.BottomHeight; + targetRange.max = victimVert.MiddleHeight; - if (report.targetPawn != null) - { - v += report.targetPawn.Drawer.leaner.LeanOffset * 0.5f; - } + bool AppropiateAimMode = CompFireModes?.CurrentAimMode != AimMode.SuppressFire; - newTargetLoc.Set(v.x, v.z); + bool IsAccurate = (ShootingAccuracy >= 2.45f) | isTurretMannable; - // ----------------------------------- STEP 1: Actual location + Shift for visibility - //FIXME : GetRandCircularVec may be causing recoil to be unnoticeable - each next shot in the burst has a new random circular vector around the target. - newTargetLoc += report.GetRandCircularVec(); + if (IsAccurate) + { + if (((CasterPawn?.Faction ?? Caster.Faction) == Faction.OfPlayer) && + (CompFireModes?.targetMode != TargettingMode.automatic)) + { + if (AppropiateAimMode) + { + if (CompFireModes?.targetMode == TargettingMode.head) + { + // Aim upper thoraxic to head + targetRange.min = victimVert.MiddleHeight; + targetRange.max = victimVert.Max; + } + else if (CompFireModes?.targetMode == TargettingMode.legs) + { + // Aim legs to lower abdomen + targetRange.min = victimVert.Min; + targetRange.max = victimVert.BottomHeight; + } + else + { + // Aim center mass + targetRange.min = victimVert.BottomHeight; + targetRange.max = victimVert.MiddleHeight; + } + } + } + else + { + if ((Victim?.kindDef?.RaceProps?.Humanlike ?? false)) + { + if (AppropiateAimMode) + { + #region Finding highest protection apparel on legs, head and torso - // ----------------------------------- STEP 2: Estimated shot to hit location + Func funcArmor = x => (x?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f); - newTargetLoc = sourceLoc + (newTargetLoc - sourceLoc).normalized * estimatedTargDist; + var Torso = Victim.health.hediffSet.GetNotMissingParts().Where(X => X.IsCorePart).First(); - // Lead a moving target - if (!isInstant) - { + var TorsoArmors = (Victim?.apparel?.WornApparel?.FindAll(F => F.def.apparel.CoversBodyPart(Torso)) ?? null); - newTargetLoc += report.GetRandLeadVec(); - } + Apparel TorsoArmor = TorsoArmors.MaxByWithFallback(funcArmor); - // ----------------------------------- STEP 3: Recoil, Skewing, Skill checks, Cover calculations + var Head = Victim.health.hediffSet.GetNotMissingParts().Where(X => X.def.defName == "Head").FirstOrFallback(Torso); - rotationDegrees = 0f; - angleRadians = 0f; + var Helmets = (Victim?.apparel?.WornApparel?.FindAll(F => F.def.apparel.CoversBodyPart(Head)) ?? null); - GetSwayVec(ref rotationDegrees, ref angleRadians); - GetRecoilVec(ref rotationDegrees, ref angleRadians); + Apparel Helmet = Helmets.MaxByWithFallback(funcArmor); - // Height difference calculations for ShotAngle - float targetHeight = 0f; + var Leg = Victim.health.hediffSet.GetNotMissingParts().Where(X => X.def.defName == "Leg").FirstOrFallback(Torso); - var coverRange = new CollisionVertical(report.cover).HeightRange; //Get " " cover, assume it is the edifice + var LegArmors = (Victim?.apparel?.WornApparel?.FindAll(F => F.def.apparel.CoversBodyPart(Leg)) ?? null); - // Projectiles with flyOverhead target the surface in front of the target - if (currentTarget.Thing is ProjectileCE) - { - targetHeight = v.y; - } - else if (Projectile.projectile.flyOverhead) - { - targetHeight = coverRange.max; - } - else - { - var victimVert = new CollisionVertical(currentTarget.Thing); - var targetRange = victimVert.HeightRange; //Get lower and upper heights of the target - if (targetRange.min < coverRange.max) //Some part of the target is hidden behind some cover - { - // - It is possible for targetRange.max < coverRange.max, technically, in which case the shooter will never hit until the cover is gone. - // - This should be checked for in LoS -NIA - targetRange.min = coverRange.max; + Apparel LegArmor = LegArmors.MaxByWithFallback(funcArmor); + #endregion - // Target fully hidden, shift aim upwards if we're doing suppressive fire - if (targetRange.max <= coverRange.max && (CompFireModes?.CurrentAimMode == AimMode.SuppressFire || VerbPropsCE.ignorePartialLoSBlocker)) - { - targetRange.max = coverRange.max * 2; - } - } - else if (currentTarget.Thing is Pawn Victim) - { - targetRange.min = victimVert.BottomHeight; - targetRange.max = victimVert.MiddleHeight; + #region get CompAmmo's Current ammo projectile - bool AppropiateAimMode = CompFireModes?.CurrentAimMode != AimMode.SuppressFire; + var ProjCE = (ProjectilePropertiesCE)compAmmo?.CurAmmoProjectile?.projectile ?? null; - bool IsAccurate = (ShootingAccuracy >= 2.45f) | isTurretMannable; + #endregion + #region checks for whether the pawn can penetrate armor, which armor is stronger, etc - if (IsAccurate) - { - if (((CasterPawn?.Faction ?? Caster.Faction) == Faction.OfPlayer) && - (CompFireModes?.targetMode != TargettingMode.automatic)) - { - if (AppropiateAimMode) - { - if (CompFireModes?.targetMode == TargettingMode.head) + var TargetedBodyPartArmor = TorsoArmor; + + bool flagTorsoArmor = ((TorsoArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f) >= (Helmet?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0f)); + + bool flag2 = ((ProjCE?.armorPenetrationSharp ?? 0f) >= (TorsoArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f)); + //Headshots do too little damage too often, so if the pawn can penetrate torso armor, they should aim at it + if ((flagTorsoArmor && !flag2)) + { + TargetedBodyPartArmor = Helmet; + } + //Leg armor is artificially increased in calculation so pawns will prefer headshots over leg shots even with medium strength helmets + bool flag3 = (TargetedBodyPartArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0f) >= ((LegArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0f) + 4f); + + //bool for whether the pawn can penetrate helmet + bool flag4 = ((ProjCE?.armorPenetrationSharp ?? 0f) >= (Helmet?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f)); + + //if the pawn can penetrate the helmet or torso armor there's no need to aim for legs + if (flag3 && (!flag4) && (!flag2)) + { + TargetedBodyPartArmor = LegArmor; + } + #endregion + + + #region choose shot height based on TargetedBodyPartArmor + if (TargetedBodyPartArmor == Helmet) { - // Aim upper thoraxic to head targetRange.min = victimVert.MiddleHeight; targetRange.max = victimVert.Max; } - else if (CompFireModes?.targetMode == TargettingMode.legs) + else if (TargetedBodyPartArmor == LegArmor) { - // Aim legs to lower abdomen targetRange.min = victimVert.Min; targetRange.max = victimVert.BottomHeight; } - else - { - // Aim center mass - targetRange.min = victimVert.BottomHeight; - targetRange.max = victimVert.MiddleHeight; - } - } - } - else - { - if ((Victim?.kindDef?.RaceProps?.Humanlike ?? false)) - { - if (AppropiateAimMode) - { - #region Finding highest protection apparel on legs, head and torso - - Func funcArmor = x => (x?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f); - - var Torso = Victim.health.hediffSet.GetNotMissingParts().Where(X => X.IsCorePart).First(); - - var TorsoArmors = (Victim?.apparel?.WornApparel?.FindAll(F => F.def.apparel.CoversBodyPart(Torso)) ?? null); - - Apparel TorsoArmor = TorsoArmors.MaxByWithFallback(funcArmor); + #endregion - var Head = Victim.health.hediffSet.GetNotMissingParts().Where(X => X.def.defName == "Head").FirstOrFallback(Torso); - var Helmets = (Victim?.apparel?.WornApparel?.FindAll(F => F.def.apparel.CoversBodyPart(Head)) ?? null); - - Apparel Helmet = Helmets.MaxByWithFallback(funcArmor); - - var Leg = Victim.health.hediffSet.GetNotMissingParts().Where(X => X.def.defName == "Leg").FirstOrFallback(Torso); + } + else // Shooting at non-humanlike, go for headshots + { + targetRange.min = victimVert.MiddleHeight; + targetRange.max = victimVert.Max; + } + } - var LegArmors = (Victim?.apparel?.WornApparel?.FindAll(F => F.def.apparel.CoversBodyPart(Leg)) ?? null); + } - Apparel LegArmor = LegArmors.MaxByWithFallback(funcArmor); - #endregion + } - #region get CompAmmo's Current ammo projectile - var ProjCE = (ProjectilePropertiesCE)compAmmo?.CurAmmoProjectile?.projectile ?? null; + } - #endregion + targetHeight = targetRange.Average; + if (projectilePropsCE != null) + { + targetHeight += projectilePropsCE.aimHeightOffset; + } + if (targetHeight > CollisionVertical.WallCollisionHeight && roofed) + { + targetHeight = CollisionVertical.WallCollisionHeight; + } + } + return targetHeight; + } - #region checks for whether the pawn can penetrate armor, which armor is stronger, etc + /// + /// Shifts the original target position in accordance with target leading, range estimation and weather/lighting effects + /// + public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalOnly = false, bool isInstant = false, bool midBurst = false, int sinceTicks = 0) + { + if (!calculateMechanicalOnly) + { + Vector3 u = caster.TrueCenter(); + sourceLoc.Set(u.x, u.z); - var TargetedBodyPartArmor = TorsoArmor; + if (numShotsFired == 0) + { + // On first shot of burst do a range estimate + estimatedTargDist = report.GetRandDist(); + } + Vector3 v = GetTargetLoc(report.target, sinceTicks); + - bool flagTorsoArmor = ((TorsoArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f) >= (Helmet?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0f)); + if (report.targetPawn != null) + { + v += report.targetPawn.Drawer.leaner.LeanOffset * 0.5f; + } - bool flag2 = ((ProjCE?.armorPenetrationSharp ?? 0f) >= (TorsoArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f)); - //Headshots do too little damage too often, so if the pawn can penetrate torso armor, they should aim at it - if ((flagTorsoArmor && !flag2)) - { - TargetedBodyPartArmor = Helmet; - } - //Leg armor is artificially increased in calculation so pawns will prefer headshots over leg shots even with medium strength helmets - bool flag3 = (TargetedBodyPartArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0f) >= ((LegArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0f) + 4f); + newTargetLoc.Set(v.x, v.z); - //bool for whether the pawn can penetrate helmet - bool flag4 = ((ProjCE?.armorPenetrationSharp ?? 0f) >= (Helmet?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f)); + // ----------------------------------- STEP 1: Actual location + Shift for visibility - //if the pawn can penetrate the helmet or torso armor there's no need to aim for legs - if (flag3 && (!flag4) && (!flag2)) - { - TargetedBodyPartArmor = LegArmor; - } - #endregion + //FIXME : GetRandCircularVec may be causing recoil to be unnoticeable - each next shot in the burst has a new random circular vector around the target. + newTargetLoc += report.GetRandCircularVec(); + // ----------------------------------- STEP 2: Estimated shot to hit location - #region choose shot height based on TargetedBodyPartArmor - if (TargetedBodyPartArmor == Helmet) - { - targetRange.min = victimVert.MiddleHeight; - targetRange.max = victimVert.Max; - } - else if (TargetedBodyPartArmor == LegArmor) - { - targetRange.min = victimVert.Min; - targetRange.max = victimVert.BottomHeight; - } - #endregion + newTargetLoc = sourceLoc + (newTargetLoc - sourceLoc).normalized * estimatedTargDist; + // Lead a moving target + if (!isInstant) + { - } - else // Shooting at non-humanlike, go for headshots - { - targetRange.min = victimVert.MiddleHeight; - targetRange.max = victimVert.Max; - } - } + newTargetLoc += report.GetRandLeadVec(); + } - } + // ----------------------------------- STEP 3: Recoil, Skewing, Skill checks, Cover calculations - } + rotationDegrees = 0f; + angleRadians = 0f; + GetSwayVec(ref rotationDegrees, ref angleRadians); + GetRecoilVec(ref rotationDegrees, ref angleRadians); - } + // Height difference calculations for ShotAngle + + var targetHeight = GetTargetHeight(report.target, report.cover, report.roofed, v, sinceTicks); - targetHeight = targetRange.Average; - if (projectilePropsCE != null) - { - targetHeight += projectilePropsCE.aimHeightOffset; - } - if (targetHeight > CollisionVertical.WallCollisionHeight && report.roofed) - { - targetHeight = CollisionVertical.WallCollisionHeight; - } - } if (!midBurst) { if (projectilePropsCE.isInstant) @@ -584,7 +585,7 @@ public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalO } } angleRadians += lastShotAngle; - } + } // ----------------------------------- STEP 4: Mechanical variation From 5e49c86750ef0a45f27abc7d6a820773a49bd704 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 8 Nov 2024 21:20:35 +0600 Subject: [PATCH 066/127] Removed log --- .../Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs index be261a6493..4b02ee0c37 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs @@ -57,7 +57,6 @@ public virtual IEnumerable NextPositions( { for (; ticksToImpact >= 0; ticksToImpact--) { - Log.Message($"{ticksToImpact}, {flightTicks}"); yield return MoveForward(currentTarget, shotRotation, shotAngle, gravityFactor, origin, exactPosition, ref destination, ticksToImpact, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); } } From 085f5d89186b56bcdf7f67a0a17462219e6170f0 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 8 Nov 2024 22:58:19 +0600 Subject: [PATCH 067/127] Unlocked rotation for CIWS --- Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs | 1 + .../CombatExtended/Verbs/Verb_LaunchProjectileCE.cs | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index 2820badc39..89e39c7581 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -48,6 +48,7 @@ public abstract class VerbCIWS : Verb_ShootCE_CIWS, ITargetSearcher // } //} public virtual bool Active => !holdFire && Turret.Active; + protected override bool LockRotationAndAngle => false; public abstract bool TryFindNewTarget(out LocalTargetInfo target); public virtual void ShowTrajectories() { diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index d46bd551bc..9cd3278a27 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -519,11 +519,12 @@ public virtual float GetTargetHeight(LocalTargetInfo target, Thing cover, bool r } return targetHeight; } + protected virtual bool LockRotationAndAngle => numShotsFired > 0; /// /// Shifts the original target position in accordance with target leading, range estimation and weather/lighting effects /// - public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalOnly = false, bool isInstant = false, bool midBurst = false, int sinceTicks = 0) + public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalOnly = false, bool isInstant = false, int sinceTicks = 0) { if (!calculateMechanicalOnly) { @@ -573,7 +574,7 @@ public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalO var targetHeight = GetTargetHeight(report.target, report.cover, report.roofed, v, sinceTicks); - if (!midBurst) + if (!LockRotationAndAngle) { if (projectilePropsCE.isInstant) { @@ -594,7 +595,7 @@ public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalO // ----------------------------------- STEP 5: Finalization var w = (newTargetLoc - sourceLoc); - if (!midBurst) + if (!LockRotationAndAngle) { lastShotRotation = -90 + Mathf.Rad2Deg * Mathf.Atan2(w.y, w.x); } @@ -1096,7 +1097,7 @@ public override bool TryCastShot() ProjectileCE projectile = (ProjectileCE)ThingMaker.MakeThing(Projectile, null); GenSpawn.Spawn(projectile, shootLine.Source, caster.Map); - ShiftTarget(report, pelletMechanicsOnly, instant, midBurst, sinceTicks); + ShiftTarget(report, pelletMechanicsOnly, instant, sinceTicks); //New aiming algorithm projectile.canTargetSelf = false; From 2d4eeba950d2c8976e1444f230575519d8f3307e Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 14 Nov 2024 23:00:35 +0600 Subject: [PATCH 068/127] Moved GetFlightTime and DistanceTraveled to trajecory worker Unclamped Vec2Position --- .../CombatExtended/Projectiles/ProjectileCE.cs | 10 +++------- .../TrajectoryWorkers/BallisticsTrajectoryWorker.cs | 8 ++++++++ .../TrajectoryWorkers/BaseTrajectoryWorker.cs | 3 +++ .../TrajectoryWorkers/LerpedTrajectoryWorker.cs | 11 ++++++++++- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index c021f3ed5e..3f4d1b01be 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -590,7 +590,7 @@ public virtual void Launch(Thing launcher, Vector2 origin, Thing equipment = nul var info = SoundInfo.InMap(this, MaintenanceType.PerTick); ambientSustainer = def.projectile.soundAmbient.TrySpawnSustainer(info); } - this.startingTicksToImpact = GetFlightTime() * GenTicks.TicksPerRealSecond; + this.startingTicksToImpact = TrajectoryWorker.GetFlightTime(shotAngle, shotSpeed, GravityFactor, shotHeight) * GenTicks.TicksPerRealSecond; this.ticksToImpact = Mathf.CeilToInt(this.startingTicksToImpact); this.ExactPosition = this.LastPos = new Vector3(origin.x, shotHeight, origin.y); @@ -1494,11 +1494,7 @@ protected float GetHeightAtTicks(int ticks) /// Shot angle in radians off the ground. /// Height from which the projectile is fired in vertical cells. /// Time in seconds that the projectile will take to traverse the given arc. - protected float GetFlightTime() - { - //Calculates quadratic formula (g/2)t^2 + (-v_0y)t + (y-y0) for {g -> gravity, v_0y -> vSin, y -> 0, y0 -> shotHeight} to find t in fractional ticks where height equals zero. - return (Mathf.Sin(shotAngle) * shotSpeed + Mathf.Sqrt(Mathf.Pow(Mathf.Sin(shotAngle) * shotSpeed, 2f) + 2f * GravityFactor * shotHeight)) / GravityFactor; - } + /// /// Calculates the range reachable with a projectile of speed velocity fired at angle from height shotHeight. Does not take into account air resistance. @@ -1507,7 +1503,7 @@ protected float GetFlightTime() /// Shot angle in radians off the ground. /// Height from which the projectile is fired in vertical cells. /// Distance in cells that the projectile will fly at the given arc. - protected float DistanceTraveled => CE_Utility.MaxProjectileRange(shotHeight, shotSpeed, shotAngle, GravityFactor); + protected float DistanceTraveled => TrajectoryWorker.DistanceTraveled(shotHeight, shotSpeed, shotAngle, GravityFactor); /// /// Calculates the shot angle necessary to reach range with a projectile of speed velocity at a height difference of heightDifference, returning either the upper or lower arc in radians. Does not take into account air resistance. diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs index 74ea3eac26..d71f53495f 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs @@ -10,6 +10,14 @@ namespace CombatExtended { public class BallisticsTrajectoryWorker : BaseTrajectoryWorker { + public override float DistanceTraveled(float shotHeight, float shotSpeed, float shotAngle, float GravityFactor) + { + throw new NotImplementedException(); + } + public override float GetFlightTime(float shotAngle, float shotSpeed, float GravityFactor, float shotHeight) + { + throw new NotImplementedException(); + } public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float ticksToImpact, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int flightTicks) { Accelerate(radius, ballisticCoefficient, mass, gravity, ref velocity, ref shotSpeed); diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs index 4b02ee0c37..4c7e28ae8d 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs @@ -11,6 +11,7 @@ namespace CombatExtended { public abstract class BaseTrajectoryWorker { + public abstract float DistanceTraveled(float shotHeight, float shotSpeed, float shotAngle, float GravityFactor); public abstract Vector3 MoveForward( LocalTargetInfo currentTarget, float shotRotation, @@ -69,5 +70,7 @@ public virtual Vector3 ExactPosToDrawPos(Vector3 exactPosition, int FlightTicks, } return new Vector3(exactPosition.x, altitude, exactPosition.z + sh); } + public virtual Vector2 Destination(Vector2 origin, float shotRotation, float shotHeight, float shotSpeed, float shotAngle, float GravityFactor) => origin + Vector2.up.RotatedBy(shotRotation) * DistanceTraveled(shotHeight, shotSpeed, shotAngle, GravityFactor); + public abstract float GetFlightTime(float shotAngle, float shotSpeed, float GravityFactor, float shotHeight); } } diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs index df16520055..a7e727b2c1 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs @@ -10,6 +10,15 @@ namespace CombatExtended { public class LerpedTrajectoryWorker : BaseTrajectoryWorker { + public override float DistanceTraveled(float shotHeight, float shotSpeed, float shotAngle, float GravityFactor) + { + return CE_Utility.MaxProjectileRange(shotHeight, shotSpeed, shotAngle, GravityFactor); + } + public override float GetFlightTime(float shotAngle, float shotSpeed, float GravityFactor, float shotHeight) + { + //Calculates quadratic formula (g/2)t^2 + (-v_0y)t + (y-y0) for {g -> gravity, v_0y -> vSin, y -> 0, y0 -> shotHeight} to find t in fractional ticks where height equals zero. + return (Mathf.Sin(shotAngle) * shotSpeed + Mathf.Sqrt(Mathf.Pow(Mathf.Sin(shotAngle) * shotSpeed, 2f) + 2f * GravityFactor * shotHeight)) / GravityFactor; + } public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float tickToImpact, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int ticks) { ticks++; @@ -23,7 +32,7 @@ protected float GetHeightAtTicks(float shotHeight, float shotSpeed, float shotAn } public Vector2 Vec2Position(Vector2 origin, Vector2 destination, float startingTicksToImpact, int ticks) { - return Vector2.Lerp(origin, destination, ticks / startingTicksToImpact); + return Vector2.LerpUnclamped(origin, destination, ticks / startingTicksToImpact); } } } From ee6f093edeee5b957199fa158b9290ed780b9024 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 15 Nov 2024 00:03:00 +0600 Subject: [PATCH 069/127] Moved some calculations to separate methods Removed sinceTicks --- .../CombatExtended/Comps/VerbCIWS.cs | 6 + .../Comps/VerbCIWSProjectile.cs | 4 +- .../Verbs/Verb_LaunchProjectileCE.cs | 141 +++++++++++------- 3 files changed, 97 insertions(+), 54 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index 89e39c7581..54929985e8 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -92,6 +92,12 @@ public override bool TryCastShot() } return result; } + protected override bool KeepBurstOnNoShootLine(bool suppressing, out ShootLine shootLine) + { + shootLine = lastShootLine.HasValue ? lastShootLine.Value : default; + return !currentTarget.ThingDestroyed; + } + } public abstract class VerbCIWS : VerbCIWS where TargetType : Thing { diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 27dca0b382..4b0e3507b0 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -34,13 +34,13 @@ public override Vector3 GetTargetLoc(LocalTargetInfo tagret, int sinceTicks) } return base.GetTargetLoc(tagret, sinceTicks); } - public override float GetTargetHeight(LocalTargetInfo target, Thing cover, bool roofed, Vector3 targetLoc, int sinceTicks) + public override float GetTargetHeight(LocalTargetInfo target, Thing cover, bool roofed, Vector3 targetLoc) { if (target.Thing is ProjectileCE projectile) { return targetLoc.y; } - return base.GetTargetHeight(target, cover, roofed, targetLoc, sinceTicks); + return base.GetTargetHeight(target, cover, roofed, targetLoc); } protected override IEnumerable TargetNextPositions(ProjectileCE target) { diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index 9cd3278a27..7387b0d998 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -31,7 +31,6 @@ public class Verb_LaunchProjectileCE : Verb // Targeting factors private float estimatedTargDist = -1; // Stores estimate target distance for each burst, so each burst shot uses the same protected int numShotsFired = 0; // Stores how many shots were fired for purposes of recoil - protected int sinceTicks = 0; // Angle in Vector2(degrees, radians) protected Vector2 newTargetLoc = new Vector2(0, 0); @@ -353,7 +352,7 @@ public virtual Vector3 GetTargetLoc(LocalTargetInfo target, int sinceTicks) { return target.Thing?.TrueCenter() ?? target.Cell.ToVector3Shifted(); //report.targetPawn != null ? report.targetPawn.DrawPos + report.targetPawn.Drawer.leaner.LeanOffset * 0.5f : report.target.Cell.ToVector3Shifted(); } - public virtual float GetTargetHeight(LocalTargetInfo target, Thing cover, bool roofed, Vector3 targetLoc, int sinceTicks) + public virtual float GetTargetHeight(LocalTargetInfo target, Thing cover, bool roofed, Vector3 targetLoc) { float targetHeight = 0f; @@ -524,7 +523,7 @@ public virtual float GetTargetHeight(LocalTargetInfo target, Thing cover, bool r /// /// Shifts the original target position in accordance with target leading, range estimation and weather/lighting effects /// - public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalOnly = false, bool isInstant = false, int sinceTicks = 0) + public virtual void ShiftTarget(ShiftVecReport report, Vector3 v, bool calculateMechanicalOnly = false, bool isInstant = false) { if (!calculateMechanicalOnly) { @@ -536,7 +535,6 @@ public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalO // On first shot of burst do a range estimate estimatedTargDist = report.GetRandDist(); } - Vector3 v = GetTargetLoc(report.target, sinceTicks); if (report.targetPawn != null) @@ -572,19 +570,12 @@ public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalO // Height difference calculations for ShotAngle - var targetHeight = GetTargetHeight(report.target, report.cover, report.roofed, v, sinceTicks); + var targetHeight = GetTargetHeight(report.target, report.cover, report.roofed, v); if (!LockRotationAndAngle) { - if (projectilePropsCE.isInstant) - { - lastShotAngle = Mathf.Atan2(targetHeight - ShotHeight, (newTargetLoc - sourceLoc).magnitude); + lastShotAngle = ShotAngle(u.WithY(ShotHeight), newTargetLoc.ToVector3().WithY(targetHeight)); } - else - { - lastShotAngle = ProjectileCE.GetShotAngle(ShotSpeed, (newTargetLoc - sourceLoc).magnitude, targetHeight - ShotHeight, Projectile.projectile.flyOverhead, projectilePropsCE.Gravity); - } - } angleRadians += lastShotAngle; } @@ -594,16 +585,49 @@ public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalO Vector2 spreadVec = (projectilePropsCE.isInstant && projectilePropsCE.damageFalloff) ? new Vector2(0, 0) : report.GetRandSpreadVec(); // ----------------------------------- STEP 5: Finalization - var w = (newTargetLoc - sourceLoc); if (!LockRotationAndAngle) { - lastShotRotation = -90 + Mathf.Rad2Deg * Mathf.Atan2(w.y, w.x); + lastShotRotation = ShotRotation(newTargetLoc.ToVector3()); } shotRotation = (lastShotRotation + rotationDegrees + spreadVec.x) % 360; shotAngle = angleRadians + spreadVec.y * Mathf.Deg2Rad; distance = (newTargetLoc - sourceLoc).magnitude; } - + protected float ShotAngle(Vector3 targetPos) + { + return ShotAngle(caster.TrueCenter().WithY(ShotHeight), targetPos); + } + /// + /// Shot angle in radians + /// + /// Source shot, including shot height + /// Target position, including target height + /// angle in radians + protected virtual float ShotAngle(Vector3 source, Vector3 targetPos) + { + var targetHeight = targetPos.y; + if (projectilePropsCE.isInstant) + { + return Mathf.Atan2(targetHeight - ShotHeight, (newTargetLoc - sourceLoc).magnitude); + } + else + { + return ProjectileCE.GetShotAngle(ShotSpeed, (newTargetLoc - sourceLoc).magnitude, targetHeight - ShotHeight, Projectile.projectile.flyOverhead, projectilePropsCE.Gravity); + } + } + protected float ShotRotation(Vector3 targetPos) + { + return ShotRotation(Caster.TrueCenter(), targetPos); + } + /// + /// Rotation in degrees + /// + /// rotation in degrees + protected virtual float ShotRotation(Vector3 source, Vector3 targetPos) + { + var w = targetPos - source; + return -90 + Mathf.Rad2Deg * Mathf.Atan2(w.z, w.x); + } /// /// Calculates the amount of recoil at a given point in a burst, up to a maximum /// @@ -640,7 +664,10 @@ public void GetSwayVec(ref float rotation, ref float angle) public virtual ShiftVecReport ShiftVecReportFor(LocalTargetInfo target) { - IntVec3 targetCell = target.Cell; + return ShiftVecReportFor(target, target.Cell); + } + public virtual ShiftVecReport ShiftVecReportFor(LocalTargetInfo target, IntVec3 targetCell) + { ShiftVecReport report = new ShiftVecReport(); report.target = target; @@ -782,7 +809,10 @@ private bool GetHighestCoverAndSmokeForTarget(LocalTargetInfo target, out Thing for (int i = 0; i < endCell; i++) { var cell = cells[i]; - + if (!cell.InBounds(map)) + { + continue; + } if (cell.AdjacentTo8Way(caster.Position)) { continue; @@ -1003,7 +1033,43 @@ public override bool TryStartCastOn(LocalTargetInfo castTarg, LocalTargetInfo de return startedCasting; } - + protected virtual bool KeepBurstOnNoShootLine(bool suppressing, out ShootLine shootLine) + { + shootLine = (ShootLine)lastShootLine; + if (LockRotationAndAngle) // Case 2,3,6,7 + { + if (VerbPropsCE.interruptibleBurst && !suppressing) // Case 2, 6 + { + return false; + } + // Case 3, 7 + if (lastShootLine == null) + { + return false; + } + shootLine = (ShootLine)lastShootLine; + currentTarget = new LocalTargetInfo(lastTargetPos); + } + else // case 4,5,8 + { + if (suppressing) // case 4,5 + { + if (currentTarget.IsValid && !currentTarget.ThingDestroyed) + { + lastShootLine = shootLine = new ShootLine(caster.Position, currentTarget.Cell); + } + else + { + return false; + } + } + else + { + return false; + } + } + return true; + } /// /// Fires a projectile using the new aiming system /// @@ -1011,7 +1077,6 @@ public override bool TryStartCastOn(LocalTargetInfo castTarg, LocalTargetInfo de public override bool TryCastShot() { Retarget(); - sinceTicks = 0; repeating = true; doRetarget = true; storedShotReduction = null; @@ -1039,39 +1104,11 @@ public override bool TryCastShot() } else // We cannot hit the current target { - if (midBurst) // Case 2,3,6,7 - { - if (props.interruptibleBurst && !suppressing) // Case 2, 6 - { - return false; - } - // Case 3, 7 - if (lastShootLine == null) - { - return false; - } - shootLine = (ShootLine)lastShootLine; - currentTarget = new LocalTargetInfo(lastTargetPos); - } - else // case 4,5,8 - { - if (suppressing) // case 4,5 - { - if (currentTarget.IsValid && !currentTarget.ThingDestroyed) - { - lastShootLine = shootLine = new ShootLine(caster.Position, currentTarget.Cell); - } - else + if (!KeepBurstOnNoShootLine(suppressing, out shootLine)) { return false; } } - else - { - return false; - } - } - } if (projectilePropsCE.pelletCount < 1) { Log.Error(EquipmentSource.LabelCap + " tried firing with pelletCount less than 1."); @@ -1089,15 +1126,15 @@ public override bool TryCastShot() spreadDegrees = (EquipmentSource?.GetStatValue(CE_StatDefOf.ShotSpread) ?? 0) * pprop.spreadMult; aperatureSize = 0.03f; } - - ShiftVecReport report = ShiftVecReportFor(currentTarget); + Vector3 targetLoc = currentTarget.Thing is Pawn ? currentTarget.Thing.TrueCenter() : shootLine.Dest.ToVector3Shifted(); + ShiftVecReport report = ShiftVecReportFor(currentTarget, targetLoc.ToIntVec3()); bool pelletMechanicsOnly = false; for (int i = 0; i < projectilePropsCE.pelletCount; i++) { ProjectileCE projectile = (ProjectileCE)ThingMaker.MakeThing(Projectile, null); GenSpawn.Spawn(projectile, shootLine.Source, caster.Map); - ShiftTarget(report, pelletMechanicsOnly, instant, sinceTicks); + ShiftTarget(report, targetLoc, pelletMechanicsOnly, instant); //New aiming algorithm projectile.canTargetSelf = false; From bdaa20f62fbeeb8aed723e90741873735f7c9c09 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 15 Nov 2024 00:16:46 +0600 Subject: [PATCH 070/127] Trajectory worker with exactpos drawing --- Defs/Ammo/Advanced/8x35mmCharged.xml | 1 + .../Projectiles/ProjectileCE_CIWS.cs | 2 +- .../LerpedTrajectoryWorker_ExactPosDrawing.cs | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker_ExactPosDrawing.cs diff --git a/Defs/Ammo/Advanced/8x35mmCharged.xml b/Defs/Ammo/Advanced/8x35mmCharged.xml index 70907d6378..33a0ef3256 100644 --- a/Defs/Ammo/Advanced/8x35mmCharged.xml +++ b/Defs/Ammo/Advanced/8x35mmCharged.xml @@ -157,6 +157,7 @@ 16 57.6 + CombatExtended.LerpedTrajectoryWorker_ExactPosDrawing diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs index a0720b2fc6..a4bfc3c489 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs @@ -83,7 +83,7 @@ protected override bool CanCollideWith(Thing thing, out float dist) return false; } - public override Vector3 DrawPos => ExactPosition.WithY(def.Altitude); + public override void Impact(Thing hitThing) { hitThing?.TryGetComp()?.OnImpact(this, DamageInfo); diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker_ExactPosDrawing.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker_ExactPosDrawing.cs new file mode 100644 index 0000000000..e3691429be --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker_ExactPosDrawing.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace CombatExtended +{ + public class LerpedTrajectoryWorker_ExactPosDrawing : LerpedTrajectoryWorker + { + public override Vector3 ExactPosToDrawPos(Vector3 exactPosition, int FlightTicks, int ticksToTruePosition, float altitude) + { + return exactPosition.WithY(altitude); + } + } +} From 5423f86bd647b2f4368cc6e84cd2ae6a997687a2 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 15 Nov 2024 00:43:00 +0600 Subject: [PATCH 071/127] Do not aim if CIWS --- Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs | 1 + Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index 54929985e8..3d1b3183c5 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -47,6 +47,7 @@ public abstract class VerbCIWS : Verb_ShootCE_CIWS, ITargetSearcher // }; // } //} + protected override bool ShouldAim => false; public virtual bool Active => !holdFire && Turret.Active; protected override bool LockRotationAndAngle => false; public abstract bool TryFindNewTarget(out LocalTargetInfo target); diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs index f10d8dd77c..98f0df99aa 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs @@ -51,7 +51,7 @@ public override int ShotsPerBurst } } - private bool ShouldAim + protected virtual bool ShouldAim { get { From 42dfe71a4f52c41de551c1ca8460e2cd057c9699 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 15 Nov 2024 00:46:42 +0600 Subject: [PATCH 072/127] ImpactSomething condition property --- .../CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs | 4 ++-- .../CombatExtended/Projectiles/ProjectileCE_CIWS.cs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 3f4d1b01be..92cb4a12d6 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -1083,7 +1083,7 @@ protected void ApplySuppression(Pawn pawn, float suppressionMultiplier = 1f) public virtual IEnumerable NextPositions => TrajectoryWorker.NextPositions(intendedTarget, shotRotation, shotAngle, GravityFactor, origin, exactPosition, Destination, ticksToImpact, startingTicksToImpact, shotHeight, kinit, velocity, shotSpeed, ExactPosition, mass, ballisticCoefficient, radius, gravity, initialSpeed, FlightTicks); protected Vector3 MoveForward() => TrajectoryWorker.MoveForward(intendedTarget, shotRotation, shotAngle, GravityFactor, origin, ExactPosition, ref Destination, ticksToImpact, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref exactPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref FlightTicks); - + protected virtual bool ShouldCollideWithSomething => (lerpPosition && ticksToImpact <= 0) || ExactPosition.y <= 0f; #region Tick/Draw public override void Tick() { @@ -1139,7 +1139,7 @@ public override void Tick() def.projectile.soundImpactAnticipate.PlayOneShot(this); } //TODO : It appears that the final steps in the arc (past ticksToImpact == 0) don't CheckForCollisionBetween. - if ((lerpPosition && ticksToImpact <= 0) || nextPosition.y <= 0f) + if (ShouldCollideWithSomething) { ImpactSomething(); return; diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs index a4bfc3c489..b228a2edd3 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs @@ -84,6 +84,7 @@ protected override bool CanCollideWith(Thing thing, out float dist) } + protected override bool ShouldCollideWithSomething => ExactPosition.y <= 0f; public override void Impact(Thing hitThing) { hitThing?.TryGetComp()?.OnImpact(this, DamageInfo); From 842b1b5f3336e8edaf289cb31927ef2c47b3c827 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 15 Nov 2024 01:16:25 +0600 Subject: [PATCH 073/127] Original ShiftTarget --- .../Verbs/Verb_LaunchProjectileCE.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index 7387b0d998..ccd657dc43 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -519,6 +519,10 @@ public virtual float GetTargetHeight(LocalTargetInfo target, Thing cover, bool r return targetHeight; } protected virtual bool LockRotationAndAngle => numShotsFired > 0; + public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalOnly = false, bool isInstant = false, bool midBurst = false) + { + ShiftTarget(report, report.target.Thing?.TrueCenter() ?? report.target.Cell.ToVector3Shifted(), calculateMechanicalOnly, isInstant); + } /// /// Shifts the original target position in accordance with target leading, range estimation and weather/lighting effects @@ -535,7 +539,7 @@ public virtual void ShiftTarget(ShiftVecReport report, Vector3 v, bool calculate // On first shot of burst do a range estimate estimatedTargDist = report.GetRandDist(); } - + if (report.targetPawn != null) { @@ -569,13 +573,13 @@ public virtual void ShiftTarget(ShiftVecReport report, Vector3 v, bool calculate GetRecoilVec(ref rotationDegrees, ref angleRadians); // Height difference calculations for ShotAngle - + var targetHeight = GetTargetHeight(report.target, report.cover, report.roofed, v); if (!LockRotationAndAngle) { lastShotAngle = ShotAngle(u.WithY(ShotHeight), newTargetLoc.ToVector3().WithY(targetHeight)); - } + } angleRadians += lastShotAngle; } @@ -1105,10 +1109,10 @@ public override bool TryCastShot() else // We cannot hit the current target { if (!KeepBurstOnNoShootLine(suppressing, out shootLine)) - { - return false; - } - } + { + return false; + } + } if (projectilePropsCE.pelletCount < 1) { Log.Error(EquipmentSource.LabelCap + " tried firing with pelletCount less than 1."); From 66fccb2713a0583802d5c928a200dcbb2880cc0a Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 15 Nov 2024 13:22:30 +0600 Subject: [PATCH 074/127] Angle and rotation now calculated w/o ShiftReport --- .../CombatExtended/Comps/VerbCIWS.cs | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index 3d1b3183c5..ebd992edf1 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -58,13 +58,18 @@ public virtual void ShowTrajectories() Caster.Map.debugDrawer.FlashLine(lastShootLine.Value.source, lastShootLine.Value.Dest, 60, SimpleColor.Green); } } - protected (Vector2 firstPos, Vector2 secondPos) PositionOfCIWSProjectile(int sinceTicks, Vector2 destination, bool drawPos = false) + protected (Vector2 firstPos, Vector2 secondPos) PositionOfCIWSProjectile(int sinceTicks, Vector3 targetPos, bool drawPos = false) { var firstPos = Caster.Position.ToVector3Shifted(); var secondPos = firstPos; var originV3 = firstPos; var originV2 = new Vector2(originV3.x, originV3.z); - var enumeration = projectilePropsCE.TrajectoryWorker.NextPositions(currentTarget, shotRotation, shotAngle, projectilePropsCE.Gravity, originV2, this.Caster.Position.ToVector3Shifted(), destination, maximumPredectionTicks, maximumPredectionTicks, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).GetEnumerator(); + var shotAngle = ShotAngle(targetPos); + var shotRotation = ShotRotation(targetPos); + + var destination = projectilePropsCE.TrajectoryWorker.Destination(originV2, shotRotation, ShotHeight, ShotSpeed, shotAngle, projectilePropsCE.Gravity); + var flightTime = projectilePropsCE.TrajectoryWorker.GetFlightTime(shotAngle, ShotSpeed, projectilePropsCE.Gravity, ShotHeight) * GenTicks.TicksPerRealSecond; + var enumeration = projectilePropsCE.TrajectoryWorker.NextPositions(currentTarget, shotRotation, shotAngle, projectilePropsCE.Gravity, originV2, this.Caster.Position.ToVector3Shifted(), destination, (int)flightTime, flightTime, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).GetEnumerator(); for (int i = 1; i <= sinceTicks; i++) { firstPos = secondPos; @@ -160,7 +165,6 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ return true; } int i = 1; - var report = ShiftVecReportFor(targetInfo); var targetPos1 = new Vector2(target.DrawPos.x, target.DrawPos.z); foreach (var pos in TargetNextPositions(target).Skip(ticksToSkip)) @@ -169,23 +173,21 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ { break; } - ShiftTarget(report, false, instant, midBurst, i); - Vector2 originV2 = new Vector2(originV3.x, originV3.z), destinationV2 = new Vector2(pos.x, pos.z); + Vector2 originV2 = new Vector2(originV3.x, originV3.z); - var positions = PositionOfCIWSProjectile(i, destinationV2); - if (positions.firstPos == positions.secondPos) - { - resultingLine = default(ShootLine); - return false; - } + var positions = PositionOfCIWSProjectile(i, pos, true); + //if (positions.firstPos == positions.secondPos) //Not sure why, but sometimes this code drops calculations on i = 1 + //{ + // resultingLine = default(ShootLine); + // return false; + //} Vector2 ciwsPos1 = positions.firstPos, ciwsPos2 = positions.secondPos, targetPos2 = new Vector2(pos.x, pos.z); if (CE_Utility.TryFindIntersectionPoint(ciwsPos1, ciwsPos2, targetPos1, targetPos2, out var point)) { - resultingLine = new ShootLine(Shooter.Position, point.ToVector3().ToIntVec3()); + resultingLine = new ShootLine(Shooter.Position, new IntVec3((int)point.x, (int)pos.y, (int)point.y)); - this.sinceTicks = i; return true; } targetPos1 = targetPos2; From 73f5a1851cb068cb85364d2fd02254ad982e9a87 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 15 Nov 2024 13:23:40 +0600 Subject: [PATCH 075/127] Corrected ticksToSkip calculations --- Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index ebd992edf1..083138cb31 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -151,7 +151,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ } var midBurst = numShotsFired > 0; var originV3 = Caster.Position.ToVector3Shifted(); - var ticksToSkip = this.BurstWarmupTicksLeft; + var ticksToSkip = (Caster as Building_TurretGunCE)?.CurrentTarget.IsValid ?? CurrentTarget.IsValid ? this.BurstWarmupTicksLeft : VerbPropsCE.warmupTime.SecondsToTicks(); var instant = projectilePropsCE.isInstant; if (instant) { From 3da4d58b298c46b30d119cc007590fbefab5124a Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 15 Nov 2024 13:24:42 +0600 Subject: [PATCH 076/127] Shot rotation now use variable instead of field --- .../CombatExtended/Verbs/Verb_LaunchProjectileCE.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index ccd657dc43..099f35de03 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -610,6 +610,7 @@ protected float ShotAngle(Vector3 targetPos) protected virtual float ShotAngle(Vector3 source, Vector3 targetPos) { var targetHeight = targetPos.y; + var newTargetLoc = new Vector2(targetPos.x, targetPos.z); if (projectilePropsCE.isInstant) { return Mathf.Atan2(targetHeight - ShotHeight, (newTargetLoc - sourceLoc).magnitude); From 40566551566bd3851e6dba1e2f8bd0ffba5d4041 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 15 Nov 2024 13:25:53 +0600 Subject: [PATCH 077/127] Target projectile height included --- .../CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 4b0e3507b0..cbb2ac079c 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -6,7 +6,6 @@ using System.Threading.Tasks; using UnityEngine; using Verse; -using static UnityEngine.UI.Image; namespace CombatExtended { @@ -47,7 +46,7 @@ protected override IEnumerable TargetNextPositions(ProjectileCE target) int tickOffset = 1; foreach (var exactPos in target.NextPositions) { - yield return target.TrajectoryWorker.ExactPosToDrawPos(exactPos, target.FlightTicks + tickOffset, target.ticksToTruePosition, target.def.Altitude); + yield return target.TrajectoryWorker.ExactPosToDrawPos(exactPos, target.FlightTicks + tickOffset, target.ticksToTruePosition, target.def.Altitude).WithY(exactPos.y); tickOffset++; } } From bc15746a5b697fad2a36c170d62b0bcc757c97ea Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 15 Nov 2024 13:52:12 +0600 Subject: [PATCH 078/127] Parameters change --- .../CombatExtended/Comps/VerbCIWSSkyfaller.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs index ec0d3dd758..71e750225b 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs @@ -30,13 +30,13 @@ public override Vector3 GetTargetLoc(LocalTargetInfo target, int sinceTicks) } return base.GetTargetLoc(target, sinceTicks); } - public override float GetTargetHeight(LocalTargetInfo target, Thing cover, bool roofed, Vector3 targetLoc, int sinceTicks) + public override float GetTargetHeight(LocalTargetInfo target, Thing cover, bool roofed, Vector3 targetLoc) { if (target.Thing is Skyfaller skyfaller) { - return 0.5f * (skyfaller.ticksToImpact - sinceTicks); + return 0.5f * (skyfaller.ticksToImpact); } - return base.GetTargetHeight(target, cover, roofed, targetLoc, sinceTicks); + return base.GetTargetHeight(target, cover, roofed, targetLoc); } } From b053b7607beee4d9f96932bb2889e5eb04b4baaa Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sun, 17 Nov 2024 02:11:07 +0600 Subject: [PATCH 079/127] Aim CIWS-trajectory point instead of intersection point --- Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index 083138cb31..c1be9fbd3c 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -184,9 +184,10 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ //} Vector2 ciwsPos1 = positions.firstPos, ciwsPos2 = positions.secondPos, targetPos2 = new Vector2(pos.x, pos.z); - if (CE_Utility.TryFindIntersectionPoint(ciwsPos1, ciwsPos2, targetPos1, targetPos2, out var point)) + if (CE_Utility.TryFindIntersectionPoint(ciwsPos1, ciwsPos2, targetPos1, targetPos2, out _)) { resultingLine = new ShootLine(Shooter.Position, new IntVec3((int)point.x, (int)pos.y, (int)point.y)); + resultingLine = new ShootLine(Shooter.Position, new IntVec3((int)pos.x, (int)pos.y, (int)pos.y)); return true; } From e7bca9d1fce63582f03b6208e80be4a368a1bfba Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sun, 17 Nov 2024 02:13:03 +0600 Subject: [PATCH 080/127] Moved GetTargetHeight to base class Fixed Skyfaller targeting --- .../CombatExtended/Comps/VerbCIWS.cs | 8 ++++++++ .../Comps/VerbCIWSProjectile.cs | 16 --------------- .../CombatExtended/Comps/VerbCIWSSkyfaller.cs | 20 ++----------------- 3 files changed, 10 insertions(+), 34 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index c1be9fbd3c..6a386a3465 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -198,6 +198,14 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ resultingLine = default; return false; } + public override float GetTargetHeight(LocalTargetInfo target, Thing cover, bool roofed, Vector3 targetLoc) + { + if (target.Thing is TargetType targ) + { + return targetLoc.y; + } + return base.GetTargetHeight(target, cover, roofed, targetLoc); + } } public abstract class VerbCIWS_Comp : VerbCIWS where TargetType : CompCIWSTarget { diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index cbb2ac079c..5a39faa553 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -25,22 +25,6 @@ public override void ShowTrajectories() (currentTarget.Thing as ProjectileCE)?.DrawNextPositions(); } - public override Vector3 GetTargetLoc(LocalTargetInfo tagret, int sinceTicks) - { - if (tagret.Thing is ProjectileCE projectile) - { - return projectile.TrajectoryWorker.ExactPosToDrawPos(projectile.NextPositions.ElementAtOrLast(sinceTicks), projectile.FlightTicks + sinceTicks, (projectile.def.projectile as ProjectilePropertiesCE).TickToTruePos, projectile.def.Altitude); - } - return base.GetTargetLoc(tagret, sinceTicks); - } - public override float GetTargetHeight(LocalTargetInfo target, Thing cover, bool roofed, Vector3 targetLoc) - { - if (target.Thing is ProjectileCE projectile) - { - return targetLoc.y; - } - return base.GetTargetHeight(target, cover, roofed, targetLoc); - } protected override IEnumerable TargetNextPositions(ProjectileCE target) { int tickOffset = 1; diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs index 71e750225b..8c19061f49 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs @@ -15,28 +15,12 @@ public class VerbCIWSSkyfaller : VerbCIWS protected override string HoldLabel => "HoldSkyfallerFire"; public override IEnumerable Targets => Caster.Map?.listerThings.ThingsInGroup(Verse.ThingRequestGroup.ActiveDropPod).OfType(); - + protected override bool IsFriendlyTo(Skyfaller thing) => base.IsFriendlyTo(thing) && thing.ContainedThings().All(x => !x.HostileTo(Caster)); protected override IEnumerable TargetNextPositions(Skyfaller target) { - return target.DrawPositions(); - } - public override Vector3 GetTargetLoc(LocalTargetInfo target, int sinceTicks) - { - if (target.Thing is Skyfaller skyfaller) - { - return skyfaller.DrawPosSinceTicks(sinceTicks); - } - return base.GetTargetLoc(target, sinceTicks); - } - public override float GetTargetHeight(LocalTargetInfo target, Thing cover, bool roofed, Vector3 targetLoc) - { - if (target.Thing is Skyfaller skyfaller) - { - return 0.5f * (skyfaller.ticksToImpact); - } - return base.GetTargetHeight(target, cover, roofed, targetLoc); + return target.DrawPositions().Select(x => x.WithY(45f)); } } From a4c8d457c00f76a0ce321db308e24c14b95beb82 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sun, 17 Nov 2024 02:13:31 +0600 Subject: [PATCH 081/127] Skyfaller impact handler patch --- Patches/Core/Skyfallers/SkyfallerBase.xml | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Patches/Core/Skyfallers/SkyfallerBase.xml diff --git a/Patches/Core/Skyfallers/SkyfallerBase.xml b/Patches/Core/Skyfallers/SkyfallerBase.xml new file mode 100644 index 0000000000..fbe625b425 --- /dev/null +++ b/Patches/Core/Skyfallers/SkyfallerBase.xml @@ -0,0 +1,24 @@ + + + + + + + Defs/ThingDef[@Name="SkyfallerBase"]/comps + + Defs/ThingDef[@Name="SkyfallerBase"] + + + + + + + + Defs/ThingDef[@Name="SkyfallerBase"]/comps + +
  • + CombatExtended.CompCIWSImpactHandler_Skyfaller +
  • +
    +
    +
    \ No newline at end of file From 5bd107f686ca51a982372b9fc50b54bf3d6db0b1 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sun, 17 Nov 2024 02:16:39 +0600 Subject: [PATCH 082/127] Returning more accurate position from TryFindCEShootLineFromTo (can be reverted I guess tho) --- .../CombatExtended/Comps/VerbCIWS.cs | 15 +++++++++------ .../Verbs/Verb_LaunchProjectileCE.cs | 17 ++++++++++------- .../CombatExtended/Verbs/Verb_ShootCE_CIWS.cs | 3 ++- .../Harmony/Harmony_Verb_LaunchProjectileCE.cs | 2 +- .../SOS2Compat/SOS2Compat/Verb_ShootShipCE.cs | 2 +- 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index 6a386a3465..10d563fdcc 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -119,7 +119,7 @@ public override bool TryFindNewTarget(out LocalTargetInfo target) return false; } float num = verb.verbProps.EffectiveMinRange(t, this.Caster); - if (!verb.TryFindCEShootLineFromTo(Caster.Position, t, out var shootLine)) + if (!verb.TryFindCEShootLineFromTo(Caster.Position, t, out var shootLine, out var targetPos)) { return false; } @@ -137,11 +137,11 @@ public override bool TryFindNewTarget(out LocalTargetInfo target) } protected virtual bool IsFriendlyTo(TargetType thing) => !thing.HostileTo(Caster); public abstract IEnumerable Targets { get; } - public override bool ValidateTarget(LocalTargetInfo target, bool showMessages = true) => target.Thing is TargetType && TryFindCEShootLineFromTo(Caster.Position, target, out _) && base.ValidateTarget(target, showMessages); + public override bool ValidateTarget(LocalTargetInfo target, bool showMessages = true) => target.Thing is TargetType && TryFindCEShootLineFromTo(Caster.Position, target, out _, out _) && base.ValidateTarget(target, showMessages); protected abstract IEnumerable TargetNextPositions(TargetType target); - public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targetInfo, out ShootLine resultingLine) + public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targetInfo, out ShootLine resultingLine, out Vector3 targetPos) { - if (base.TryFindCEShootLineFromTo(root, targetInfo, out resultingLine)) + if (base.TryFindCEShootLineFromTo(root, targetInfo, out resultingLine, out targetPos)) { return true; } @@ -186,7 +186,8 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ if (CE_Utility.TryFindIntersectionPoint(ciwsPos1, ciwsPos2, targetPos1, targetPos2, out _)) { - resultingLine = new ShootLine(Shooter.Position, new IntVec3((int)point.x, (int)pos.y, (int)point.y)); + targetPos = pos; + resultingLine = new ShootLine(Shooter.Position, new IntVec3((int)pos.x, (int)pos.y, (int)pos.y)); return true; @@ -212,14 +213,16 @@ public abstract class VerbCIWS_Comp : VerbCIWS where TargetTy public override IEnumerable Targets => CompCIWSTarget.Targets(Caster.Map); protected override bool IsFriendlyTo(Thing thing) => thing.TryGetComp()?.IsFriendlyTo(thing) ?? base.IsFriendlyTo(thing); public override bool ValidateTarget(LocalTargetInfo target, bool showMessages = true) => target.HasThing && target.Thing.HasComp() && base.ValidateTarget(target, showMessages); - public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine) + public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine, out Vector3 targetPos) { if (targ.Thing?.TryGetComp()?.CalculatePointForPreemptiveFire(Projectile, root.ToVector3Shifted(), out var result, BurstWarmupTicksLeft) ?? false) { + targetPos = result; resultingLine = new ShootLine(root, result.ToIntVec3()); return true; } resultingLine = default; + targetPos = default; return false; } } diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index 099f35de03..9dc8ac33d6 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -948,7 +948,7 @@ public virtual bool CanHitTargetFrom(IntVec3 root, LocalTargetInfo targ, out str } // Check for line of sight ShootLine shootLine; - if (!TryFindCEShootLineFromTo(root, targ, out shootLine)) + if (!TryFindCEShootLineFromTo(root, targ, out shootLine, out _)) { float lengthHorizontalSquared = (root - targ.Cell).LengthHorizontalSquared; if (lengthHorizontalSquared > EffectiveRange * EffectiveRange) @@ -1103,7 +1103,7 @@ public override bool TryCastShot() // 6: Interruptible -> stop shooting // 7: Not interruptible -> shoot along previous line // 8: else -> stop - if (TryFindCEShootLineFromTo(caster.Position, currentTarget, out var shootLine)) // Case 1 + if (TryFindCEShootLineFromTo(caster.Position, currentTarget, out var shootLine, out var targetLoc)) // Case 1 { lastShootLine = shootLine; } @@ -1131,7 +1131,7 @@ public override bool TryCastShot() spreadDegrees = (EquipmentSource?.GetStatValue(CE_StatDefOf.ShotSpread) ?? 0) * pprop.spreadMult; aperatureSize = 0.03f; } - Vector3 targetLoc = currentTarget.Thing is Pawn ? currentTarget.Thing.TrueCenter() : shootLine.Dest.ToVector3Shifted(); + ShiftVecReport report = ShiftVecReportFor(currentTarget, targetLoc.ToIntVec3()); bool pelletMechanicsOnly = false; for (int i = 0; i < projectilePropsCE.pelletCount; i++) @@ -1300,8 +1300,9 @@ public int BurstWarmupTicksLeft private new List tempLeanShootSources = new List(); - public virtual bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine) + public virtual bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine, out Vector3 targetPos) { + targetPos = targ.Thing is Pawn ? targ.Thing.TrueCenter() : targ.Cell.ToVector3Shifted(); if (targ.HasThing && targ.Thing.Map != caster.Map) { resultingLine = default(ShootLine); @@ -1309,20 +1310,20 @@ public virtual bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, } if (EffectiveRange <= ShootTuning.MeleeRange) // If this verb has a MAX range up to melee range (NOT a MIN RANGE!) { - resultingLine = new ShootLine(root, targ.Cell); + resultingLine = new ShootLine(root, targetPos.ToIntVec3()); return ReachabilityImmediate.CanReachImmediate(root, targ, caster.Map, PathEndMode.Touch, null); } CellRect cellRect = (!targ.HasThing) ? CellRect.SingleCell(targ.Cell) : targ.Thing.OccupiedRect(); float num = cellRect.ClosestDistSquaredTo(root); if (num > EffectiveRange * EffectiveRange || num < verbProps.minRange * verbProps.minRange) { - resultingLine = new ShootLine(root, targ.Cell); + resultingLine = new ShootLine(root, targetPos.ToIntVec3()); return false; } //if (!this.verbProps.NeedsLineOfSight) This method doesn't consider the currently loaded projectile if (Projectile.projectile.flyOverhead) { - resultingLine = new ShootLine(root, targ.Cell); + resultingLine = new ShootLine(root, targetPos.ToIntVec3()); return true; } @@ -1339,6 +1340,7 @@ public virtual bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, if (CanHitFromCellIgnoringRange(shotSource, targ, out dest)) { + targetPos = dest.ToVector3Shifted(); resultingLine = new ShootLine(root, dest); return true; } @@ -1353,6 +1355,7 @@ public virtual bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, var leanPosOffset = (leanLoc - root).ToVector3() * leanOffset; if (CanHitFromCellIgnoringRange(shotSource + leanPosOffset, targ, out dest)) { + targetPos = dest.ToVector3Shifted(); resultingLine = new ShootLine(leanLoc, dest); return true; } diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs index 14898ae4dd..a051fbafad 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs @@ -27,8 +27,9 @@ public override ThingDef Projectile } protected int maximumPredectionTicks = 40; - public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine) + public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine, out Vector3 targetPos) { + targetPos = default(Vector3); resultingLine = default; return false; } diff --git a/Source/CombatExtended/Harmony/Harmony_Verb_LaunchProjectileCE.cs b/Source/CombatExtended/Harmony/Harmony_Verb_LaunchProjectileCE.cs index 5a420c2a43..ab51ac8912 100644 --- a/Source/CombatExtended/Harmony/Harmony_Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/Harmony/Harmony_Verb_LaunchProjectileCE.cs @@ -16,7 +16,7 @@ internal static bool Prefix(Verb __instance, ref bool __result, IntVec3 root, Lo { if (__instance is Verb_LaunchProjectileCE launchVerbCE) { - __result = (launchVerbCE as Verb_LaunchProjectileCE).TryFindCEShootLineFromTo(root, targ, out resultingLine); + __result = (launchVerbCE as Verb_LaunchProjectileCE).TryFindCEShootLineFromTo(root, targ, out resultingLine, out _); return false; } return true; diff --git a/Source/SOS2Compat/SOS2Compat/Verb_ShootShipCE.cs b/Source/SOS2Compat/SOS2Compat/Verb_ShootShipCE.cs index 1ec3453598..8e9aa3f1bc 100644 --- a/Source/SOS2Compat/SOS2Compat/Verb_ShootShipCE.cs +++ b/Source/SOS2Compat/SOS2Compat/Verb_ShootShipCE.cs @@ -93,7 +93,7 @@ public override bool TryCastShot() // 6: Interruptible -> stop shooting // 7: Not interruptible -> shoot along previous line // 8: else -> stop - if (TryFindCEShootLineFromTo(caster.Position, currentTarget, out var shootLine)) // Case 1 + if (TryFindCEShootLineFromTo(caster.Position, currentTarget, out var shootLine, out var targetPos)) // Case 1 { lastShootLine = shootLine; } From c0694fdb6374f072c77f9cf9bcb3dd173d88b7ac Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Mon, 18 Nov 2024 04:04:46 +0600 Subject: [PATCH 083/127] Corrected shoot position if no shootLine found --- .../CombatExtended/Verbs/Verb_LaunchProjectileCE.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index 9dc8ac33d6..0e4e516aef 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -55,6 +55,7 @@ public class Verb_LaunchProjectileCE : Verb private bool shootingAtDowned = false; private LocalTargetInfo lastTarget = null; protected IntVec3 lastTargetPos = IntVec3.Invalid; + protected Vector3 lastExactPos = Vector3.negativeInfinity; protected float lastShotAngle; protected float lastShotRotation; @@ -1054,6 +1055,7 @@ protected virtual bool KeepBurstOnNoShootLine(bool suppressing, out ShootLine sh } shootLine = (ShootLine)lastShootLine; currentTarget = new LocalTargetInfo(lastTargetPos); + lastExactPos = lastTargetPos.ToVector3Shifted(); } else // case 4,5,8 { @@ -1062,6 +1064,7 @@ protected virtual bool KeepBurstOnNoShootLine(bool suppressing, out ShootLine sh if (currentTarget.IsValid && !currentTarget.ThingDestroyed) { lastShootLine = shootLine = new ShootLine(caster.Position, currentTarget.Cell); + lastExactPos = currentTarget.Cell.ToVector3Shifted(); } else { @@ -1106,6 +1109,7 @@ public override bool TryCastShot() if (TryFindCEShootLineFromTo(caster.Position, currentTarget, out var shootLine, out var targetLoc)) // Case 1 { lastShootLine = shootLine; + lastExactPos = targetLoc; } else // We cannot hit the current target { @@ -1139,7 +1143,7 @@ public override bool TryCastShot() ProjectileCE projectile = (ProjectileCE)ThingMaker.MakeThing(Projectile, null); GenSpawn.Spawn(projectile, shootLine.Source, caster.Map); - ShiftTarget(report, targetLoc, pelletMechanicsOnly, instant); + ShiftTarget(report, lastExactPos, pelletMechanicsOnly, instant); //New aiming algorithm projectile.canTargetSelf = false; From 719332d9671467e7638244dff2b8f78b3bae2545 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Tue, 19 Nov 2024 03:11:05 +0600 Subject: [PATCH 084/127] Hold fire for CIWS --- Defs/ThingDefs_Misc/Weapons_CIWS.xml | 6 ++ .../CombatExtended/Comps/CompVerbDisabler.cs | 38 +++++++++++ .../CombatExtended/Comps/VerbCIWS.cs | 66 +++++++++---------- .../Comps/VerbCIWSProjectile.cs | 2 - .../CombatExtended/Comps/VerbCIWSSkyfaller.cs | 2 - .../CombatExtended/IVerbDisableable.cs | 17 +++++ .../Things/Building_Turret_MultiVerbs.cs | 21 +++++- 7 files changed, 112 insertions(+), 40 deletions(-) create mode 100644 Source/CombatExtended/CombatExtended/Comps/CompVerbDisabler.cs create mode 100644 Source/CombatExtended/CombatExtended/IVerbDisableable.cs diff --git a/Defs/ThingDefs_Misc/Weapons_CIWS.xml b/Defs/ThingDefs_Misc/Weapons_CIWS.xml index 286db6fc1c..0e1ef49e59 100644 --- a/Defs/ThingDefs_Misc/Weapons_CIWS.xml +++ b/Defs/ThingDefs_Misc/Weapons_CIWS.xml @@ -47,6 +47,8 @@ GunTail_Heavy 9 Mounted + HoldCloseInProjectilesFire + HoldCloseInProjectilesFireDesc
  • CombatExtended.VerbCIWSSkyfaller @@ -61,6 +63,7 @@ GunTail_Heavy 9 Mounted + HoldCloseInSkyfallersFire
  • @@ -69,6 +72,9 @@ 7.8 AmmoSet_8x35mmCharged +
  • + CombatExtended.CompVerbDisabler +
  • diff --git a/Source/CombatExtended/CombatExtended/Comps/CompVerbDisabler.cs b/Source/CombatExtended/CombatExtended/Comps/CompVerbDisabler.cs new file mode 100644 index 0000000000..67466ae447 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Comps/CompVerbDisabler.cs @@ -0,0 +1,38 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Verse; + +namespace CombatExtended +{ + public class CompVerbDisabler : ThingComp + { + public override IEnumerable CompGetGizmosExtra() + { + foreach (var gizmo in base.CompGetGizmosExtra()) + { + yield return gizmo; + } + var verbs = parent.GetComp()?.AllVerbs.OfType(); + if (verbs != null) + { + foreach (var verb in verbs) + { + var command = new Command_Toggle() + { + defaultDesc = verb.HoldFireDesc.Translate(), + defaultLabel = verb.HoldFireLabel.Translate(), + icon = verb.HoldFireIcon, + isActive = () => verb.HoldFire, + toggleAction = () => verb.HoldFire = !verb.HoldFire, + + }; + yield return command; + } + } + } + } +} diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index 10d563fdcc..85cbc5d380 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -6,49 +6,34 @@ using System.Threading.Tasks; using UnityEngine; using UnityEngine.SocialPlatforms; +using UnityEngine.UI; using Verse; using Verse.Sound; namespace CombatExtended { - public abstract class VerbCIWS : Verb_ShootCE_CIWS, ITargetSearcher + public abstract class VerbCIWS : Verb_ShootCE_CIWS, ITargetSearcher, IVerbDisableable { protected bool debug; - protected bool holdFire; + protected Texture2D icon; + public virtual bool HoldFire { get; set; } public VerbProperties_CIWS Props => verbProps as VerbProperties_CIWS; - protected abstract string HoldLabel { get; } - protected abstract string HoldDesc { get; } - protected virtual string HoldIcon => "UI/Commands/HoldFire"; - - //public override IEnumerable CompGetGizmosExtra() - //{ - // foreach (var gizmo in base.CompGetGizmosExtra()) - // { - // yield return gizmo; - // } - // if (Turret.CanToggleHoldFire) - // { - // yield return new Command_Toggle - // { - // defaultLabel = HoldLabel.Translate(), - // defaultDesc = HoldDesc.Translate(), - // icon = ContentFinder.Get(HoldIcon, true), - // hotKey = KeyBindingDefOf.Misc6, - // toggleAction = delegate () - // { - // this.holdFire = !this.holdFire; - // if (this.holdFire && HasTarget) - // { - // Turret.ResetForcedTarget(); - // } - // }, - // isActive = (() => this.holdFire) - // }; - // } - //} + public virtual string HoldFireLabel => Props.holdFireLabel; + public virtual string HoldFireDesc => Props.holdFireDesc; + public virtual Texture2D HoldFireIcon + { + get + { + if (icon == null) + { + icon = ContentFinder.Get(Props.holdFireIcon); + } + return icon; + } + } protected override bool ShouldAim => false; - public virtual bool Active => !holdFire && Turret.Active; + public virtual bool Active => !HoldFire && Turret.Active; protected override bool LockRotationAndAngle => false; public abstract bool TryFindNewTarget(out LocalTargetInfo target); public virtual void ShowTrajectories() @@ -102,14 +87,22 @@ protected override bool KeepBurstOnNoShootLine(bool suppressing, out ShootLine s { shootLine = lastShootLine.HasValue ? lastShootLine.Value : default; return !currentTarget.ThingDestroyed; - } - + } + public override bool Available() + { + return Active && base.Available(); + } } public abstract class VerbCIWS : VerbCIWS where TargetType : Thing { public override bool TryFindNewTarget(out LocalTargetInfo target) { + if (!Active) + { + target = LocalTargetInfo.Invalid; + return false; + } float range = this.verbProps.range; var _target = Targets.Where(x => Props.Interceptable(x.def) && !Turret.IgnoredDefs.Contains(x.def)).Where(x => !IsFriendlyTo(x)).FirstOrDefault(t => { @@ -229,6 +222,9 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ public abstract class VerbProperties_CIWS : VerbPropertiesCE { + public string holdFireIcon = "UI/Commands/HoldFire"; + public string holdFireLabel = "HoldFire"; + public string holdFireDesc; public List ignored = new List(); public IEnumerable Ignored => ignored; public virtual bool Interceptable(ThingDef targetDef) => true; diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs index 5a39faa553..5b2bbb1d11 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs @@ -11,8 +11,6 @@ namespace CombatExtended { public class VerbCIWSProjectile : VerbCIWS { - protected override string HoldDesc => "HoldCloseInProjectilesFireDesc"; - protected override string HoldLabel => "HoldCloseInProjectilesFire"; public new VerbProperties_CIWSProjectile Props => verbProps as VerbProperties_CIWSProjectile; public override IEnumerable Targets => Caster.Map?.listerThings.ThingsInGroup(ThingRequestGroup.Projectile).OfType() ?? Array.Empty(); diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs index 8c19061f49..c6767da0e6 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs @@ -11,8 +11,6 @@ namespace CombatExtended { public class VerbCIWSSkyfaller : VerbCIWS { - protected override string HoldDesc => "HoldSkyfallerFireDesc"; - protected override string HoldLabel => "HoldSkyfallerFire"; public override IEnumerable Targets => Caster.Map?.listerThings.ThingsInGroup(Verse.ThingRequestGroup.ActiveDropPod).OfType(); diff --git a/Source/CombatExtended/CombatExtended/IVerbDisableable.cs b/Source/CombatExtended/CombatExtended/IVerbDisableable.cs new file mode 100644 index 0000000000..5077665fc1 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/IVerbDisableable.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; + +namespace CombatExtended +{ + public interface IVerbDisableable + { + bool HoldFire { get; set; } + string HoldFireLabel { get; } + string HoldFireDesc { get; } + Texture2D HoldFireIcon { get; } + } +} diff --git a/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs b/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs index 6c6a44416a..d8bc521758 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs @@ -1,4 +1,5 @@ -using System; +using RimWorld; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -67,5 +68,23 @@ public override void ResetForcedTarget() base.ResetForcedTarget(); activeVerb = null; } + public override IEnumerable GetGizmos() + { + foreach (var gizmo in base.GetGizmos()) + { + yield return gizmo; + } + if (PlayerControlled) + { + var disablerComp = Gun.TryGetComp(); + if (disablerComp != null) + { + foreach (var gizmo in disablerComp.CompGetGizmosExtra()) + { + yield return gizmo; + } + } + } + } } } From 49cbf31fb4ef47ad8c83f201625b7073e9145c65 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Tue, 19 Nov 2024 03:25:49 +0600 Subject: [PATCH 085/127] Targeting by CompCIWSTarget + CompCIWSTarget_Skyfaller (not tested) --- .../CombatExtended/Comps/CompCIWSTarget.cs | 2 +- .../Comps/CompCIWSTarget_Skyfaller.cs | 27 +++++++++++++++++++ .../CombatExtended/Comps/VerbCIWS.cs | 12 ++------- .../Verbs/VerbCIWS_CompSkyfaller.cs | 12 +++++++++ 4 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget_Skyfaller.cs create mode 100644 Source/CombatExtended/CombatExtended/Verbs/VerbCIWS_CompSkyfaller.cs diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs index 65135d8ff5..c82623a9f7 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs @@ -53,7 +53,7 @@ public override void PostDeSpawn(Map map) } } public abstract bool IsFriendlyTo(Thing thing); - public abstract bool CalculatePointForPreemptiveFire(ThingDef projectile, Vector3 source, out Vector3 result, int tickOffset = 0); + public abstract IEnumerable NextPositions { get; } /// /// Checks if projectile can intersect with this object diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget_Skyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget_Skyfaller.cs new file mode 100644 index 0000000000..8a2b70ef89 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget_Skyfaller.cs @@ -0,0 +1,27 @@ +using RimWorld; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace CombatExtended +{ + public class CompCIWSTarget_Skyfaller : CompCIWSTarget + { + public override IEnumerable NextPositions + { + get + { + return (parent as Skyfaller).DrawPositions().Select(x => x.WithY(45f)); + } + } + + public override bool IsFriendlyTo(Thing caster) + { + return (parent as Skyfaller).ContainedThings().All(x => !x.HostileTo(caster)); + } + } +} diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs index 85cbc5d380..47c439e208 100644 --- a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs @@ -206,17 +206,9 @@ public abstract class VerbCIWS_Comp : VerbCIWS where TargetTy public override IEnumerable Targets => CompCIWSTarget.Targets(Caster.Map); protected override bool IsFriendlyTo(Thing thing) => thing.TryGetComp()?.IsFriendlyTo(thing) ?? base.IsFriendlyTo(thing); public override bool ValidateTarget(LocalTargetInfo target, bool showMessages = true) => target.HasThing && target.Thing.HasComp() && base.ValidateTarget(target, showMessages); - public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine, out Vector3 targetPos) + protected override IEnumerable TargetNextPositions(Thing target) { - if (targ.Thing?.TryGetComp()?.CalculatePointForPreemptiveFire(Projectile, root.ToVector3Shifted(), out var result, BurstWarmupTicksLeft) ?? false) - { - targetPos = result; - resultingLine = new ShootLine(root, result.ToIntVec3()); - return true; - } - resultingLine = default; - targetPos = default; - return false; + return target.TryGetComp().NextPositions; } } diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS_CompSkyfaller.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS_CompSkyfaller.cs new file mode 100644 index 0000000000..255bad1837 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS_CompSkyfaller.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CombatExtended +{ + public class VerbCIWS_CompSkyfaller : VerbCIWS_Comp + { + } +} From 8b32cc71153c376eb26c63e4b87f1b150403cc3a Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Tue, 19 Nov 2024 03:27:10 +0600 Subject: [PATCH 086/127] Changed folder of verbs --- Source/CombatExtended/CombatExtended/{Comps => Verbs}/VerbCIWS.cs | 0 .../CombatExtended/{Comps => Verbs}/VerbCIWSProjectile.cs | 0 .../CombatExtended/{Comps => Verbs}/VerbCIWSSkyfaller.cs | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename Source/CombatExtended/CombatExtended/{Comps => Verbs}/VerbCIWS.cs (100%) rename Source/CombatExtended/CombatExtended/{Comps => Verbs}/VerbCIWSProjectile.cs (100%) rename Source/CombatExtended/CombatExtended/{Comps => Verbs}/VerbCIWSSkyfaller.cs (100%) diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs similarity index 100% rename from Source/CombatExtended/CombatExtended/Comps/VerbCIWS.cs rename to Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs similarity index 100% rename from Source/CombatExtended/CombatExtended/Comps/VerbCIWSProjectile.cs rename to Source/CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs diff --git a/Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSSkyfaller.cs similarity index 100% rename from Source/CombatExtended/CombatExtended/Comps/VerbCIWSSkyfaller.cs rename to Source/CombatExtended/CombatExtended/Verbs/VerbCIWSSkyfaller.cs From 369e91a2f516b0c770566a81595bfb65b18f9749 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 20 Nov 2024 00:28:03 +0600 Subject: [PATCH 087/127] Ignored defs --- Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs | 2 +- Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs index 56b33a51ab..c82d3ab2c7 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs @@ -26,7 +26,7 @@ public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish) } #endregion - public IEnumerable IgnoredDefs + public IEnumerable IgnoredDefsSettings { get { diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs index 47c439e208..2c26a2946f 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs @@ -104,7 +104,7 @@ public override bool TryFindNewTarget(out LocalTargetInfo target) return false; } float range = this.verbProps.range; - var _target = Targets.Where(x => Props.Interceptable(x.def) && !Turret.IgnoredDefs.Contains(x.def)).Where(x => !IsFriendlyTo(x)).FirstOrDefault(t => + var _target = Targets.Where(x => Props.Interceptable(x.def) && !Props.Ignored.Contains(x.def) && !Turret.IgnoredDefsSettings.Contains(x.def)).Where(x => !IsFriendlyTo(x)).FirstOrDefault(t => { var verb = this; if (Caster.Map.GetComponent().CIWS.Any(turret => turret.currentTargetInt.Thing == t) || ProjectileCE_CIWS.ProjectilesAt(Caster.Map).Any(x => x.intendedTarget.Thing == t)) From 8f6032b57e83facd53c0fcee538a9e09b26a114d Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 20 Nov 2024 00:32:38 +0600 Subject: [PATCH 088/127] Effecter --- .../CombatExtended/Comps/CompCIWSImpactHandler.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs index bc4d35e3d6..c068b69174 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs @@ -20,6 +20,10 @@ public virtual void OnImpact(ProjectileCE projectile, DamageInfo dinfo) { Props.impacted.PlayOneShot(new TargetInfo(parent.DrawPos.ToIntVec3(), parent.Map)); } + if (Props.impactEffecter != null) + { + Props.impactEffecter.Spawn(parent.DrawPos.ToIntVec3(), parent.Map); + } parent.Destroy(DestroyMode.Vanish); } @@ -31,5 +35,6 @@ public CompProperties_CIWSImpactHandler() compClass = typeof(CompCIWSImpactHandler); } public SoundDef impacted; + public EffecterDef impactEffecter; } } From 0553cca577ec5d5cdb8e32ec5c4ef02c635473d6 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 21 Nov 2024 03:27:17 +0600 Subject: [PATCH 089/127] CIWS settings dialog --- Languages/English/Keyed/Keys.xml | 6 + Languages/Russian/Keyed/Keys.xml | 7 + .../Dialog_ManageCIWSTargets.cs | 141 ++++++++++++++++++ .../CombatExtended/Things/Building_CIWS_CE.cs | 26 +++- 4 files changed, 177 insertions(+), 3 deletions(-) create mode 100644 Source/CombatExtended/CombatExtended/Dialog_ManageCIWSTargets.cs diff --git a/Languages/English/Keyed/Keys.xml b/Languages/English/Keyed/Keys.xml index df82f099bd..c622630e75 100644 --- a/Languages/English/Keyed/Keys.xml +++ b/Languages/English/Keyed/Keys.xml @@ -176,5 +176,11 @@ Shield coverage Body parts protected from ranged and melee attacks by the shield. + + + Copy + Paste + Available targets + Ignored targets \ No newline at end of file diff --git a/Languages/Russian/Keyed/Keys.xml b/Languages/Russian/Keyed/Keys.xml index 276b1c8fd8..1dcabe3754 100644 --- a/Languages/Russian/Keyed/Keys.xml +++ b/Languages/Russian/Keyed/Keys.xml @@ -134,4 +134,11 @@ + + + Копировать + Вставить + Доступные цели + Игнорировать + \ No newline at end of file diff --git a/Source/CombatExtended/CombatExtended/Dialog_ManageCIWSTargets.cs b/Source/CombatExtended/CombatExtended/Dialog_ManageCIWSTargets.cs new file mode 100644 index 0000000000..98c2325a97 --- /dev/null +++ b/Source/CombatExtended/CombatExtended/Dialog_ManageCIWSTargets.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Verse; + +namespace CombatExtended.CombatExtended +{ + [StaticConstructorOnStartup] + public class Dialog_ManageCIWSTargets : Window + { + static IList copied = new List(); + + private readonly IList availableTargets; + private readonly IList ignored; + + private const float BufferArea = 16f, TextOffset = 6f, RowHeight = 30f, ElementsHeight = 26f; + private IList filteredAvailableTargets; + private Vector2 scrollPosition; + private Vector2 scrollPosition2; + private static Texture2D _darkBackground = SolidColorMaterials.NewSolidColorTexture(0f, 0f, 0f, .2f); + private string searchString; + + public override Vector2 InitialSize + { + get + { + return new Vector2(1000, 700); + } + } + private string SearchString + { + get => searchString; + set + { + if (searchString != value) + { + searchString = value; + ResetFilterCollection(); + } + } + } + public Dialog_ManageCIWSTargets(IList availableTargets, IList ignored) : base() + { + this.availableTargets = availableTargets; + this.ignored = ignored; + } + + void ResetFilterCollection() + { + var collection = availableTargets.Except(ignored); + if (!string.IsNullOrWhiteSpace(SearchString)) + { + collection = collection.Where(x => x.label.IndexOf(SearchString, StringComparison.OrdinalIgnoreCase) >= 0); + } + filteredAvailableTargets = collection.ToList(); + } + + public override void DoWindowContents(Rect inRect) + { + + inRect = new Rect(inRect.x, inRect.y + BufferArea, inRect.width, inRect.height - BufferArea); + var y = inRect.y; + Rect labelRect = new Rect(inRect.width / 2, y, inRect.width / 2, ElementsHeight); + Rect label2Rect = new Rect(inRect.x + BufferArea, y, inRect.width / 2, ElementsHeight); + + + + Widgets.Label(labelRect, "CIWSSettings_AvailableTargets".Translate()); + Widgets.Label(label2Rect, "CIWSSettings_IgnoredTargets".Translate()); + + y += ElementsHeight + BufferArea; + + Rect searchBarRect = new Rect(inRect.width / 2 + TextOffset, y, inRect.width / 2 - BufferArea * 3, ElementsHeight); + Rect copyRect = new Rect(inRect.x + BufferArea, y, 46f, ElementsHeight); + Rect pasteRect = new Rect(copyRect.xMax + BufferArea, y, 46f, ElementsHeight); + + + SearchString = Widgets.TextArea(searchBarRect, SearchString); + if (Widgets.ButtonText(copyRect, "CIWSSettings_Copy".Translate())) + { + copied = ignored.ToList(); + } + if (Widgets.ButtonText(pasteRect, "CIWSSettings_Paste".Translate())) + { + ignored.Clear(); + foreach (var item in copied) + { + ignored.Add(item); + } + ResetFilterCollection(); + } + + y += ElementsHeight + BufferArea; + + Rect outRect = new Rect(inRect.width / 2, y, inRect.width / 2 - BufferArea, inRect.height - y - BufferArea); + Rect viewRect = new Rect(outRect.x, outRect.y, outRect.width - 32f, filteredAvailableTargets.Count * RowHeight); + GUI.DrawTexture(outRect, _darkBackground); + Widgets.BeginScrollView(outRect, ref scrollPosition2, viewRect, true); + for (int i = 0; i < filteredAvailableTargets.Count; i++) + { + ThingDef target = filteredAvailableTargets[i]; + Rect allowedDefRect = new Rect(viewRect.x, viewRect.y + (RowHeight * i), viewRect.width, RowHeight); + if (i % 2 == 0) + { + GUI.DrawTexture(allowedDefRect, _darkBackground); + } + allowedDefRect = new Rect(allowedDefRect.x + TextOffset, allowedDefRect.y, allowedDefRect.width - TextOffset, allowedDefRect.height); + if (Widgets.ButtonText(allowedDefRect, target.label, false, false, true)) + { + ignored.Add(target); + ResetFilterCollection(); + } + } + Widgets.EndScrollView(); + outRect = new Rect(inRect.x + BufferArea, y, inRect.width / 2 - BufferArea * 2, inRect.height - y - BufferArea); + viewRect = new Rect(outRect.x, outRect.y, outRect.width - 32f, ignored.Count * RowHeight); + GUI.DrawTexture(outRect, _darkBackground); + Widgets.BeginScrollView(outRect, ref scrollPosition, viewRect, true); + for (int i = 0; i < ignored.Count; i++) + { + var s = ignored[i]; + Rect ignoredDefRect = new Rect(viewRect.x, viewRect.y + (RowHeight * i), viewRect.width, RowHeight); + if (i % 2 == 0) + { + GUI.DrawTexture(ignoredDefRect, _darkBackground); + } + ignoredDefRect = new Rect(ignoredDefRect.x + TextOffset, ignoredDefRect.y, ignoredDefRect.width - TextOffset, ignoredDefRect.height); + if (Widgets.ButtonText(ignoredDefRect, s.label, false, false, true)) + { + ignored.Remove(s); + ResetFilterCollection(); + } + } + Widgets.EndScrollView(); + } + } +} diff --git a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs index c82d3ab2c7..0b9abc89dd 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs @@ -1,4 +1,5 @@ -using Mono.Unix.Native; +using CombatExtended.CombatExtended; +using Mono.Unix.Native; using RimWorld; using System; using System.Collections.Generic; @@ -26,12 +27,31 @@ public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish) } #endregion + public override void ExposeData() + { + base.ExposeData(); + Scribe_Collections.Look(ref ignoredDefs, nameof(ignoredDefs)); + } + + public override IEnumerable GetGizmos() + { + foreach (var gizmo in base.GetGizmos()) + { + yield return gizmo; + } + yield return new Command_Action() + { + action = () => Find.WindowStack.Add(new Dialog_ManageCIWSTargets(GunCompEq.AllVerbs.OfType().SelectMany(x=>x.Props.AllTargets).Distinct().ToList(), ignoredDefs)), + defaultLabel = "Dialog_ManageCIWS".Translate(), + }; + } + + private List ignoredDefs = new List(); public IEnumerable IgnoredDefsSettings { get { - Log.WarningOnce("IgnoredDefs not implemented yet", 82469265); - return Enumerable.Empty(); + return ignoredDefs ??= new List(); } } public override void Tick() From 7c4c72a358d8e35e4cf7af92b7a8fbe995d60813 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 22 Nov 2024 03:37:45 +0600 Subject: [PATCH 090/127] Fixed non-lerped moving (not sure if even worked before). non lerped CIWS projecitles works bad tho --- .../Projectiles/ProjectileCE.cs | 7 +++- .../BallisticsTrajectoryWorker.cs | 16 ++++----- .../TrajectoryWorkers/BaseTrajectoryWorker.cs | 35 +++++++++++++++++-- .../LerpedTrajectoryWorker.cs | 9 ----- .../CombatExtended/Verbs/VerbCIWS.cs | 5 +-- 5 files changed, 48 insertions(+), 24 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 92cb4a12d6..7864ba1464 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -567,6 +567,10 @@ public virtual void Launch(Thing launcher, Vector2 origin, float shotAngle, floa this.castShadow = props.castShadow; this.lerpPosition = props.lerpPosition; this.GravityFactor = props.Gravity; + ballisticCoefficient = props.ballisticCoefficient.RandomInRange; + mass = props.mass.RandomInRange; + radius = props.diameter.RandomInRange / 2000; // half the diameter and mm -> m + } if (shotHeight >= CollisionVertical.WallCollisionHeight && Position.Roofed(launcher.Map)) { @@ -581,6 +585,7 @@ public virtual void Launch(Thing launcher, Vector2 origin, Thing equipment = nul this.origin = origin; this.OriginIV3 = new IntVec3(origin); this.Destination = origin + Vector2.up.RotatedBy(shotRotation) * DistanceTraveled; + velocity = TrajectoryWorker.GetVelocity(shotSpeed, shotRotation, shotAngle); this.equipment = equipment; //For explosives/bullets, equipmentDef is important equipmentDef = (equipment != null) ? equipment.def : null; @@ -1470,7 +1475,7 @@ public void DrawNextPositions() Map.debugDrawer.FlashLine(previous.ToIntVec3(), next.ToIntVec3(), 70, SimpleColor.Orange); Map.debugDrawer.FlashLine( TrajectoryWorker.ExactPosToDrawPos(next, FlightTicks + sinceTicks, (def.projectile as ProjectilePropertiesCE).TickToTruePos, def.Altitude).ToIntVec3(), - TrajectoryWorker.ExactPosToDrawPos(previous, FlightTicks + sinceTicks -1, (def.projectile as ProjectilePropertiesCE).TickToTruePos, def.Altitude).ToIntVec3() + TrajectoryWorker.ExactPosToDrawPos(previous, FlightTicks + sinceTicks - 1, (def.projectile as ProjectilePropertiesCE).TickToTruePos, def.Altitude).ToIntVec3() , 70, SimpleColor.Red); previous = next; sinceTicks++; diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs index d71f53495f..d1a9ea85b5 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs @@ -10,18 +10,11 @@ namespace CombatExtended { public class BallisticsTrajectoryWorker : BaseTrajectoryWorker { - public override float DistanceTraveled(float shotHeight, float shotSpeed, float shotAngle, float GravityFactor) - { - throw new NotImplementedException(); - } - public override float GetFlightTime(float shotAngle, float shotSpeed, float GravityFactor, float shotHeight) - { - throw new NotImplementedException(); - } public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float ticksToImpact, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int flightTicks) { + flightTicks++; Accelerate(radius, ballisticCoefficient, mass, gravity, ref velocity, ref shotSpeed); - shotSpeed = velocity.magnitude; + shotSpeed = GetSpeed(velocity); return exactPosition + velocity; } protected virtual void Accelerate(float radius, float ballisticCoefficient, float mass, float gravity, ref Vector3 velocity, ref float shotSpeed) @@ -32,6 +25,7 @@ protected virtual void Accelerate(float radius, float ballisticCoefficient, floa protected void AffectedByGravity(float gravity, ref Vector3 velocity) { + var original = velocity; velocity.y -= gravity / GenTicks.TicksPerRealSecond; } @@ -50,5 +44,9 @@ protected void AffectedByDrag(float radius, float shotSpeed, float ballisticCoef velocity.y += a * normalized.y; velocity.z += a * normalized.z; } + public override Vector3 ExactPosToDrawPos(Vector3 exactPosition, int FlightTicks, int ticksToTruePosition, float altitude) + { + return exactPosition.WithY(altitude); + } } } diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs index 4c7e28ae8d..f686e01864 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs @@ -11,7 +11,6 @@ namespace CombatExtended { public abstract class BaseTrajectoryWorker { - public abstract float DistanceTraveled(float shotHeight, float shotSpeed, float shotAngle, float GravityFactor); public abstract Vector3 MoveForward( LocalTargetInfo currentTarget, float shotRotation, @@ -58,7 +57,7 @@ public virtual IEnumerable NextPositions( { for (; ticksToImpact >= 0; ticksToImpact--) { - yield return MoveForward(currentTarget, shotRotation, shotAngle, gravityFactor, origin, exactPosition, ref destination, ticksToImpact, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); + yield return exactPosition = MoveForward(currentTarget, shotRotation, shotAngle, gravityFactor, origin, exactPosition, ref destination, ticksToImpact, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); } } public virtual Vector3 ExactPosToDrawPos(Vector3 exactPosition, int FlightTicks, int ticksToTruePosition, float altitude) @@ -71,6 +70,36 @@ public virtual Vector3 ExactPosToDrawPos(Vector3 exactPosition, int FlightTicks, return new Vector3(exactPosition.x, altitude, exactPosition.z + sh); } public virtual Vector2 Destination(Vector2 origin, float shotRotation, float shotHeight, float shotSpeed, float shotAngle, float GravityFactor) => origin + Vector2.up.RotatedBy(shotRotation) * DistanceTraveled(shotHeight, shotSpeed, shotAngle, GravityFactor); - public abstract float GetFlightTime(float shotAngle, float shotSpeed, float GravityFactor, float shotHeight); + public virtual float DistanceTraveled(float shotHeight, float shotSpeed, float shotAngle, float GravityFactor) + { + return CE_Utility.MaxProjectileRange(shotHeight, shotSpeed, shotAngle, GravityFactor); + } + public virtual float GetFlightTime(float shotAngle, float shotSpeed, float GravityFactor, float shotHeight) + { + //Calculates quadratic formula (g/2)t^2 + (-v_0y)t + (y-y0) for {g -> gravity, v_0y -> vSin, y -> 0, y0 -> shotHeight} to find t in fractional ticks where height equals zero. + return (Mathf.Sin(shotAngle) * shotSpeed + Mathf.Sqrt(Mathf.Pow(Mathf.Sin(shotAngle) * shotSpeed, 2f) + 2f * GravityFactor * shotHeight)) / GravityFactor; + } + + public virtual float GetSpeed(Vector3 velocity) + { + return velocity.magnitude; + } + + public virtual Vector3 GetVelocity(float shotSpeed, Vector3 origin, Vector3 destination) + { + return (destination - origin).normalized * shotSpeed / GenTicks.TicksPerRealSecond; + } + /// + /// Get initial velocity + /// + /// speed + /// rotation in degrees + /// angle in radians + /// + public virtual Vector3 GetVelocity(float shotSpeed, float rotation, float angle) + { + angle = angle * Mathf.Rad2Deg; // transform to degrees + return Vector2.up.RotatedBy(rotation).ToVector3().RotatedBy(angle) * shotSpeed / GenTicks.TicksPerRealSecond; + } } } diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs index a7e727b2c1..1c2a652b7f 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs @@ -10,15 +10,6 @@ namespace CombatExtended { public class LerpedTrajectoryWorker : BaseTrajectoryWorker { - public override float DistanceTraveled(float shotHeight, float shotSpeed, float shotAngle, float GravityFactor) - { - return CE_Utility.MaxProjectileRange(shotHeight, shotSpeed, shotAngle, GravityFactor); - } - public override float GetFlightTime(float shotAngle, float shotSpeed, float GravityFactor, float shotHeight) - { - //Calculates quadratic formula (g/2)t^2 + (-v_0y)t + (y-y0) for {g -> gravity, v_0y -> vSin, y -> 0, y0 -> shotHeight} to find t in fractional ticks where height equals zero. - return (Mathf.Sin(shotAngle) * shotSpeed + Mathf.Sqrt(Mathf.Pow(Mathf.Sin(shotAngle) * shotSpeed, 2f) + 2f * GravityFactor * shotHeight)) / GravityFactor; - } public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float tickToImpact, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int ticks) { ticks++; diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs index 2c26a2946f..ba9a46f35d 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs @@ -14,7 +14,7 @@ namespace CombatExtended { public abstract class VerbCIWS : Verb_ShootCE_CIWS, ITargetSearcher, IVerbDisableable { - protected bool debug; + protected bool debug = true; protected Texture2D icon; public virtual bool HoldFire { get; set; } @@ -54,7 +54,8 @@ public virtual void ShowTrajectories() var destination = projectilePropsCE.TrajectoryWorker.Destination(originV2, shotRotation, ShotHeight, ShotSpeed, shotAngle, projectilePropsCE.Gravity); var flightTime = projectilePropsCE.TrajectoryWorker.GetFlightTime(shotAngle, ShotSpeed, projectilePropsCE.Gravity, ShotHeight) * GenTicks.TicksPerRealSecond; - var enumeration = projectilePropsCE.TrajectoryWorker.NextPositions(currentTarget, shotRotation, shotAngle, projectilePropsCE.Gravity, originV2, this.Caster.Position.ToVector3Shifted(), destination, (int)flightTime, flightTime, ShotHeight, false, Vector3.zero, ShotSpeed, originV3, -1f, -1f, -1f, -1f, ShotSpeed, 0).GetEnumerator(); + var initialVelocity = projectilePropsCE.TrajectoryWorker.GetVelocity(ShotSpeed, shotRotation, shotAngle); + var enumeration = projectilePropsCE.TrajectoryWorker.NextPositions(currentTarget, shotRotation, shotAngle, projectilePropsCE.Gravity, originV2, this.Caster.Position.ToVector3Shifted(), destination, (int)flightTime, flightTime, ShotHeight, false, initialVelocity, ShotSpeed, originV3, projectilePropsCE.mass.max, projectilePropsCE.ballisticCoefficient.max, projectilePropsCE.diameter.max / 2000, projectilePropsCE.Gravity, ShotSpeed, 0).GetEnumerator(); for (int i = 1; i <= sinceTicks; i++) { firstPos = secondPos; From 414eb6fb4c39e4b5b0aaf5c2bea5eee2778078f5 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Tue, 26 Nov 2024 01:45:24 +0600 Subject: [PATCH 091/127] Moved rotation and angle calculations to trajectory worker --- .../Projectiles/ProjectileCE.cs | 21 +--------- .../TrajectoryWorkers/BaseTrajectoryWorker.cs | 39 +++++++++++++++++++ .../Verbs/Verb_LaunchProjectileCE.cs | 11 +----- .../WorldObjects/TravelingShell.cs | 12 +++--- ...mony_CompAbilityEffect_LaunchProjectile.cs | 24 +++--------- 5 files changed, 52 insertions(+), 55 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 7864ba1464..51cfc13b77 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -1510,26 +1510,7 @@ protected float GetHeightAtTicks(int ticks) /// Distance in cells that the projectile will fly at the given arc. protected float DistanceTraveled => TrajectoryWorker.DistanceTraveled(shotHeight, shotSpeed, shotAngle, GravityFactor); - /// - /// Calculates the shot angle necessary to reach range with a projectile of speed velocity at a height difference of heightDifference, returning either the upper or lower arc in radians. Does not take into account air resistance. - /// - /// Projectile velocity in cells per second. - /// Cells between shooter and target. - /// Difference between initial shot height and target height in vertical cells. - /// Whether to take the lower (False) or upper (True) arc angle. - /// Arc angle in radians off the ground. - public static float GetShotAngle(float velocity, float range, float heightDifference, bool flyOverhead, float gravity) - { - float squareRootCheck = Mathf.Sqrt(Mathf.Pow(velocity, 4f) - gravity * (gravity * Mathf.Pow(range, 2f) + 2f * heightDifference * Mathf.Pow(velocity, 2f))); - if (float.IsNaN(squareRootCheck)) - { - //Target is too far to hit with given velocity/range/gravity params - //set firing angle for maximum distance - Log.Warning("[CE] Tried to fire projectile to unreachable target cell, truncating to maximum distance."); - return 45.0f * Mathf.Deg2Rad; - } - return Mathf.Atan((Mathf.Pow(velocity, 2f) + (flyOverhead ? 1f : -1f) * squareRootCheck) / (gravity * range)); - } + #endregion protected static Material[] GetShadowMaterial(Graphic_Collection g) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs index f686e01864..7db3b7beab 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs @@ -101,5 +101,44 @@ public virtual Vector3 GetVelocity(float shotSpeed, float rotation, float angle) angle = angle * Mathf.Rad2Deg; // transform to degrees return Vector2.up.RotatedBy(rotation).ToVector3().RotatedBy(angle) * shotSpeed / GenTicks.TicksPerRealSecond; } + + /// + /// Shot angle in radians + /// + /// Source shot, including shot height + /// Target position, including target height + /// angle in radians + public virtual float ShotAngle(ProjectilePropertiesCE projectilePropsCE, Vector3 source, Vector3 targetPos, float? velocity = null) + { + var targetHeight = targetPos.y; + var shotHeight = source.y; + var newTargetLoc = new Vector2(targetPos.x, targetPos.z); + var sourceV2 = new Vector2(source.x, source.z); + if (projectilePropsCE.isInstant) + { + return Mathf.Atan2(targetHeight - shotHeight, (newTargetLoc - sourceV2).magnitude); + } + else + { + var _velocity = velocity ?? projectilePropsCE.speed; + var gravity = projectilePropsCE.Gravity; + var heightDifference = targetHeight - shotHeight; + var range = (newTargetLoc - sourceV2).magnitude; + float squareRootCheck = Mathf.Sqrt(Mathf.Pow(_velocity, 4f) - gravity * (gravity * Mathf.Pow(range, 2f) + 2f * heightDifference * Mathf.Pow(_velocity, 2f))); + if (float.IsNaN(squareRootCheck)) + { + //Target is too far to hit with given velocity/range/gravity params + //set firing angle for maximum distance + Log.Warning("[CE] Tried to fire projectile to unreachable target cell, truncating to maximum distance."); + return 45.0f * Mathf.Deg2Rad; + } + return Mathf.Atan((Mathf.Pow(_velocity, 2f) + (projectilePropsCE.flyOverhead ? 1f : -1f) * squareRootCheck) / (gravity * range)); + } + } + public virtual float ShotRotation(ProjectilePropertiesCE projectilePropertiesCE, Vector3 source, Vector3 targetPos) + { + var w = targetPos - source; + return ( - 90 + Mathf.Rad2Deg * Mathf.Atan2(w.z, w.x)) % 360; + } } } diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index 0e4e516aef..b2d0c01c0a 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -610,16 +610,7 @@ protected float ShotAngle(Vector3 targetPos) /// angle in radians protected virtual float ShotAngle(Vector3 source, Vector3 targetPos) { - var targetHeight = targetPos.y; - var newTargetLoc = new Vector2(targetPos.x, targetPos.z); - if (projectilePropsCE.isInstant) - { - return Mathf.Atan2(targetHeight - ShotHeight, (newTargetLoc - sourceLoc).magnitude); - } - else - { - return ProjectileCE.GetShotAngle(ShotSpeed, (newTargetLoc - sourceLoc).magnitude, targetHeight - ShotHeight, Projectile.projectile.flyOverhead, projectilePropsCE.Gravity); - } + return projectilePropsCE.TrajectoryWorker.ShotAngle(projectilePropsCE, source, targetPos); } protected float ShotRotation(Vector3 targetPos) { diff --git a/Source/CombatExtended/CombatExtended/WorldObjects/TravelingShell.cs b/Source/CombatExtended/CombatExtended/WorldObjects/TravelingShell.cs index ce5a108318..01ca8b45d4 100644 --- a/Source/CombatExtended/CombatExtended/WorldObjects/TravelingShell.cs +++ b/Source/CombatExtended/CombatExtended/WorldObjects/TravelingShell.cs @@ -151,20 +151,18 @@ private bool TryShell(WorldObject worldObject) private void LaunchProjectile(IntVec3 sourceCell, LocalTargetInfo target, Map map, float shotSpeed = 20, float shotHeight = 200) { - IntVec3 targetCell = target.Cell; - Vector2 source = new Vector2(sourceCell.x, sourceCell.z); - Vector2 destination = new Vector2(targetCell.x, targetCell.z); - Vector2 w = (destination - source); + Vector3 source = new Vector3(sourceCell.x, shotHeight, sourceCell.z); + Vector3 targetPos = target.Cell.ToVector3Shifted(); ProjectileCE projectile = (ProjectileCE)ThingMaker.MakeThing(shellDef); ProjectilePropertiesCE pprops = projectile.def.projectile as ProjectilePropertiesCE; - float shotRotation = (-90 + Mathf.Rad2Deg * Mathf.Atan2(w.y, w.x)) % 360; - float shotAngle = ProjectileCE.GetShotAngle(shotSpeed, (destination - source).magnitude, -shotHeight, false, pprops.Gravity); + float shotRotation = pprops.TrajectoryWorker.ShotRotation(pprops, source, targetPos); + float shotAngle = pprops.TrajectoryWorker.ShotAngle(pprops, source, targetPos, shotSpeed); projectile.canTargetSelf = false; projectile.Position = sourceCell; projectile.SpawnSetup(map, false); - projectile.Launch(launcher, source, shotAngle, shotRotation, shotHeight, shotSpeed); + projectile.Launch(launcher, new Vector2(source.x, source.z), shotAngle, shotRotation, shotHeight, shotSpeed); //projectile.cameraShakingInit = Rand.Range(0f, 2f); } diff --git a/Source/CombatExtended/Harmony/Harmony_CompAbilityEffect_LaunchProjectile.cs b/Source/CombatExtended/Harmony/Harmony_CompAbilityEffect_LaunchProjectile.cs index 55bc11d5cc..ad41171f69 100644 --- a/Source/CombatExtended/Harmony/Harmony_CompAbilityEffect_LaunchProjectile.cs +++ b/Source/CombatExtended/Harmony/Harmony_CompAbilityEffect_LaunchProjectile.cs @@ -24,26 +24,14 @@ internal static bool Prefix(CompAbilityEffect_LaunchProjectile __instance, Local if (projectileDef.projectile is ProjectilePropertiesCE ppce) { Pawn pawn = __instance.parent.pawn; - var u = pawn.TrueCenter(); - var sourceLoc = new Vector2(); - sourceLoc.Set(u.x, u.z); - var targetLocation = new Vector2(); + var u = pawn.TrueCenter().WithY((new CollisionVertical(pawn)).shotHeight); + var targetPos = target.Thing != null ? target.Thing.TrueCenter() : target.Cell.ToVector3Shifted(); + targetPos = targetPos.WithY((new CollisionVertical(target.Thing)).shotHeight); - if (target.HasThing) - { - targetLocation.Set(target.Thing.TrueCenter().x, target.Thing.TrueCenter().z); - } - else - { - targetLocation.Set(target.Cell.ToIntVec2.x, target.Cell.ToIntVec2.z); - } - var w = (targetLocation - sourceLoc); - float shotRotation = (-90 + Mathf.Rad2Deg * Mathf.Atan2(w.y, w.x)) % 360; - - var targetVert = new CollisionVertical(target.Thing); - var angle = ProjectileCE.GetShotAngle(ppce.speed, (target.Cell - pawn.Position).LengthHorizontal, targetVert.HeightRange.Average - 1, ppce.flyOverhead, ppce.Gravity); - CE_Utility.LaunchProjectileCE(projectileDef, sourceLoc, target, pawn, angle, shotRotation, 1, ppce.speed); + var angle = ppce.TrajectoryWorker.ShotAngle(ppce, u, targetPos); + float shotRotation = ppce.TrajectoryWorker.ShotRotation(ppce, u, targetPos); + CE_Utility.LaunchProjectileCE(projectileDef, new Vector2(u.x, u.z), target, pawn, angle, shotRotation, u.y, ppce.speed); return false; } } From 9fafa61a88935625ef3478bea832df966f00d767 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Tue, 26 Nov 2024 01:48:29 +0600 Subject: [PATCH 092/127] Some optimizations --- .../CombatExtended/Verbs/VerbCIWS.cs | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs index ba9a46f35d..6a9c562978 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs @@ -131,30 +131,32 @@ public override bool TryFindNewTarget(out LocalTargetInfo target) } protected virtual bool IsFriendlyTo(TargetType thing) => !thing.HostileTo(Caster); public abstract IEnumerable Targets { get; } - public override bool ValidateTarget(LocalTargetInfo target, bool showMessages = true) => target.Thing is TargetType && TryFindCEShootLineFromTo(Caster.Position, target, out _, out _) && base.ValidateTarget(target, showMessages); + //public override bool ValidateTarget(LocalTargetInfo target, bool showMessages = true) => target.Thing is TargetType && TryFindCEShootLineFromTo(Caster.Position, target, out _, out _) && base.ValidateTarget(target, showMessages); protected abstract IEnumerable TargetNextPositions(TargetType target); public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targetInfo, out ShootLine resultingLine, out Vector3 targetPos) { - if (base.TryFindCEShootLineFromTo(root, targetInfo, out resultingLine, out targetPos)) - { - return true; - } + if (!(targetInfo.Thing is TargetType target)) { + resultingLine = default; + targetPos = default; return false; } var midBurst = numShotsFired > 0; var originV3 = Caster.Position.ToVector3Shifted(); var ticksToSkip = (Caster as Building_TurretGunCE)?.CurrentTarget.IsValid ?? CurrentTarget.IsValid ? this.BurstWarmupTicksLeft : VerbPropsCE.warmupTime.SecondsToTicks(); var instant = projectilePropsCE.isInstant; + var maxDistSqr = Props.range * Props.range; if (instant) { var to = TargetNextPositions(target).Skip(ticksToSkip).FirstOrFallback(Vector3.negativeInfinity); if (to == Vector3.negativeInfinity) { resultingLine = default; + targetPos = default; return false; } + targetPos = to; resultingLine = new ShootLine(originV3.ToIntVec3(), to.ToIntVec3()); return true; } @@ -163,9 +165,9 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ var targetPos1 = new Vector2(target.DrawPos.x, target.DrawPos.z); foreach (var pos in TargetNextPositions(target).Skip(ticksToSkip)) { - if (i > maximumPredectionTicks) + if ((pos - originV3).MagnitudeHorizontalSquared() > maxDistSqr) { - break; + continue; } Vector2 originV2 = new Vector2(originV3.x, originV3.z); @@ -188,9 +190,13 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ } targetPos1 = targetPos2; i++; - + if (i > maximumPredectionTicks) + { + break; + } } resultingLine = default; + targetPos = default; return false; } public override float GetTargetHeight(LocalTargetInfo target, Thing cover, bool roofed, Vector3 targetLoc) From 4064638f8ee81578e3046d7b92f14d4773ee29c2 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 27 Nov 2024 23:56:57 +0600 Subject: [PATCH 093/127] Small mortar fix --- .../CombatExtended/Verbs/Verb_LaunchProjectileCE.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index b2d0c01c0a..e02a6f4f8b 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -610,7 +610,7 @@ protected float ShotAngle(Vector3 targetPos) /// angle in radians protected virtual float ShotAngle(Vector3 source, Vector3 targetPos) { - return projectilePropsCE.TrajectoryWorker.ShotAngle(projectilePropsCE, source, targetPos); + return projectilePropsCE.TrajectoryWorker.ShotAngle(projectilePropsCE, source, targetPos, ShotSpeed); } protected float ShotRotation(Vector3 targetPos) { From 994dc3deb690bb38f1850eed7db6458bfb7e1318 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 27 Nov 2024 23:58:49 +0600 Subject: [PATCH 094/127] Speed gain --- .../CombatExtended/Projectiles/ProjectileCE.cs | 4 ++-- .../Projectiles/ProjectilePropertiesCE.cs | 1 + .../BallisticsTrajectoryWorker.cs | 16 +++++++++++++--- .../TrajectoryWorkers/BaseTrajectoryWorker.cs | 6 +++++- .../TrajectoryWorkers/LerpedTrajectoryWorker.cs | 2 +- .../SmartRocketTrajectoryWorker.cs | 12 ++++++++---- .../CombatExtended/Verbs/VerbCIWS.cs | 2 +- 7 files changed, 31 insertions(+), 12 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 51cfc13b77..b1798d37fc 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -1085,8 +1085,8 @@ protected void ApplySuppression(Pawn pawn, float suppressionMultiplier = 1f) - public virtual IEnumerable NextPositions => TrajectoryWorker.NextPositions(intendedTarget, shotRotation, shotAngle, GravityFactor, origin, exactPosition, Destination, ticksToImpact, startingTicksToImpact, shotHeight, kinit, velocity, shotSpeed, ExactPosition, mass, ballisticCoefficient, radius, gravity, initialSpeed, FlightTicks); - protected Vector3 MoveForward() => TrajectoryWorker.MoveForward(intendedTarget, shotRotation, shotAngle, GravityFactor, origin, ExactPosition, ref Destination, ticksToImpact, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref exactPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref FlightTicks); + public virtual IEnumerable NextPositions => TrajectoryWorker.NextPositions(intendedTarget, shotRotation, shotAngle, GravityFactor, origin, exactPosition, Destination, ticksToImpact, startingTicksToImpact, shotHeight, kinit, velocity, shotSpeed, ExactPosition, mass, ballisticCoefficient, radius, gravity, initialSpeed, (def.projectile as ProjectilePropertiesCE).speedGain, (def.projectile as ProjectilePropertiesCE).speed, FlightTicks); + protected Vector3 MoveForward() => TrajectoryWorker.MoveForward(intendedTarget, shotRotation, shotAngle, GravityFactor, origin, ExactPosition, ref Destination, ticksToImpact, startingTicksToImpact, shotHeight, (def.projectile as ProjectilePropertiesCE).speedGain, (def.projectile as ProjectilePropertiesCE).speed, ref kinit, ref velocity, ref shotSpeed, ref exactPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref FlightTicks); protected virtual bool ShouldCollideWithSomething => (lerpPosition && ticksToImpact <= 0) || ExactPosition.y <= 0f; #region Tick/Draw diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs index 0036e56810..28ac998c31 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs @@ -15,6 +15,7 @@ public class ProjectilePropertiesCE : ProjectileProperties public TravelingShellProperties shellingProps; // public float armorPenetration = 0; + public float speedGain = 0f; public int pelletCount = 1; public float spreadMult = 1; public List secondaryDamage = new List(); diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs index d1a9ea85b5..b3378a5222 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BallisticsTrajectoryWorker.cs @@ -10,17 +10,27 @@ namespace CombatExtended { public class BallisticsTrajectoryWorker : BaseTrajectoryWorker { - public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float ticksToImpact, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int flightTicks) + public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float tickToImpact, float startingTicksToImpact, float shotHeight, float speedGain, float maxSpeed, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int flightTicks) { flightTicks++; - Accelerate(radius, ballisticCoefficient, mass, gravity, ref velocity, ref shotSpeed); + Accelerate(currentTarget, radius, ballisticCoefficient, mass, gravity, speedGain, maxSpeed, exactPosition, ref velocity, ref shotSpeed); shotSpeed = GetSpeed(velocity); return exactPosition + velocity; } - protected virtual void Accelerate(float radius, float ballisticCoefficient, float mass, float gravity, ref Vector3 velocity, ref float shotSpeed) + protected virtual void Accelerate(LocalTargetInfo currentTarget, float radius, float ballisticCoefficient, float mass, float gravity, float speedGain, float maxSpeed, Vector3 exactPosition, ref Vector3 velocity, ref float shotSpeed) { AffectedByDrag(radius, shotSpeed, ballisticCoefficient, mass, ref velocity); AffectedByGravity(gravity, ref velocity); + ReactiveAcceleration(currentTarget, speedGain, maxSpeed, exactPosition, ref velocity, ref shotSpeed); + } + + protected virtual void ReactiveAcceleration(LocalTargetInfo currentTarget, float speedGain, float maxSpeed, Vector3 exactPosition, ref Vector3 velocity, ref float shotSpeed) + { + var speedChange = Mathf.Min(maxSpeed - shotSpeed, speedGain); + if (speedChange > 0.001f) + { + velocity = velocity + GetVelocity(speedChange, Vector3.zero, velocity); + } } protected void AffectedByGravity(float gravity, ref Vector3 velocity) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs index 7db3b7beab..832cb188b6 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs @@ -22,6 +22,8 @@ public abstract Vector3 MoveForward( float tickToImpact, float startingTicksToImpact, float shotHeight, + float speedGain, + float maxSpeed, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, @@ -53,11 +55,13 @@ public virtual IEnumerable NextPositions( float radius, float gravity, float initialSpeed, + float speedGain, + float maxSpeed, int flightTicks) { for (; ticksToImpact >= 0; ticksToImpact--) { - yield return exactPosition = MoveForward(currentTarget, shotRotation, shotAngle, gravityFactor, origin, exactPosition, ref destination, ticksToImpact, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); + yield return exactPosition = MoveForward(currentTarget, shotRotation, shotAngle, gravityFactor, origin, exactPosition, ref destination, ticksToImpact, startingTicksToImpact, shotHeight, speedGain, maxSpeed, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); } } public virtual Vector3 ExactPosToDrawPos(Vector3 exactPosition, int FlightTicks, int ticksToTruePosition, float altitude) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs index 1c2a652b7f..4079e694f4 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/LerpedTrajectoryWorker.cs @@ -10,7 +10,7 @@ namespace CombatExtended { public class LerpedTrajectoryWorker : BaseTrajectoryWorker { - public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float tickToImpact, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int ticks) + public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float tickToImpact, float startingTicksToImpact, float shotHeight, float speedGain, float maxSpeed, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int ticks) { ticks++; var v = Vec2Position(origin, destination, startingTicksToImpact, ticks); diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs index a4f5ad7c85..9f548e8785 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs @@ -10,13 +10,17 @@ namespace CombatExtended { public class SmartRocketTrajectoryWorker : BallisticsTrajectoryWorker { - public override Vector3 MoveForward(LocalTargetInfo currentTarget, float shotRotation, float shotAngle, float gravityFactor, Vector2 origin, Vector3 exactPosition, ref Vector2 destination, float tickToImpact, float startingTicksToImpact, float shotHeight, ref bool kinit, ref Vector3 velocity, ref float shotSpeed, ref Vector3 curPosition, ref float mass, ref float ballisticCoefficient, ref float radius, ref float gravity, ref float initialSpeed, ref int flightTicks) + protected override void ReactiveAcceleration(LocalTargetInfo currentTarget, float speedGain, float maxSpeed, Vector3 exactPosition, ref Vector3 velocity, ref float shotSpeed) { - if (currentTarget.HasThing) + if (currentTarget.ThingDestroyed) { - velocity = Vector3.RotateTowards(velocity, currentTarget.Thing.DrawPos, 360, 0); //Rotate rocket towards target. Not sure how it should work, haven't tested it yet + base.ReactiveAcceleration(currentTarget, speedGain, maxSpeed, exactPosition, ref velocity, ref shotSpeed); + return; } - return base.MoveForward(currentTarget, shotRotation, shotAngle, gravityFactor, origin, exactPosition, ref destination, tickToImpact, startingTicksToImpact, shotHeight, ref kinit, ref velocity, ref shotSpeed, ref curPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref flightTicks); + var targetPos = currentTarget.Thing?.DrawPos ?? currentTarget.Cell.ToVector3Shifted(); + var velocityChange = GetVelocity(speedGain, exactPosition, targetPos); + shotSpeed = Mathf.Min(shotSpeed + speedGain, maxSpeed); + velocity = GetVelocity(shotSpeed, Vector3.zero, velocity + velocityChange); } } } diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs index 6a9c562978..04210888b5 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs @@ -55,7 +55,7 @@ public virtual void ShowTrajectories() var destination = projectilePropsCE.TrajectoryWorker.Destination(originV2, shotRotation, ShotHeight, ShotSpeed, shotAngle, projectilePropsCE.Gravity); var flightTime = projectilePropsCE.TrajectoryWorker.GetFlightTime(shotAngle, ShotSpeed, projectilePropsCE.Gravity, ShotHeight) * GenTicks.TicksPerRealSecond; var initialVelocity = projectilePropsCE.TrajectoryWorker.GetVelocity(ShotSpeed, shotRotation, shotAngle); - var enumeration = projectilePropsCE.TrajectoryWorker.NextPositions(currentTarget, shotRotation, shotAngle, projectilePropsCE.Gravity, originV2, this.Caster.Position.ToVector3Shifted(), destination, (int)flightTime, flightTime, ShotHeight, false, initialVelocity, ShotSpeed, originV3, projectilePropsCE.mass.max, projectilePropsCE.ballisticCoefficient.max, projectilePropsCE.diameter.max / 2000, projectilePropsCE.Gravity, ShotSpeed, 0).GetEnumerator(); + var enumeration = projectilePropsCE.TrajectoryWorker.NextPositions(currentTarget, shotRotation, shotAngle, projectilePropsCE.Gravity, originV2, this.Caster.Position.ToVector3Shifted(), destination, (int)flightTime, flightTime, ShotHeight, false, initialVelocity, ShotSpeed, originV3, projectilePropsCE.mass.max, projectilePropsCE.ballisticCoefficient.max, projectilePropsCE.diameter.max / 2000, projectilePropsCE.Gravity, ShotSpeed, projectilePropsCE.speedGain, projectilePropsCE.speed, 0).GetEnumerator(); for (int i = 1; i <= sinceTicks; i++) { firstPos = secondPos; From e2b55f620e3e345a15a0284843ddc1bbdd0abeca Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 28 Nov 2024 00:00:00 +0600 Subject: [PATCH 095/127] Fixed prediction --- Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs index 04210888b5..1b635b4ba3 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs @@ -165,8 +165,11 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ var targetPos1 = new Vector2(target.DrawPos.x, target.DrawPos.z); foreach (var pos in TargetNextPositions(target).Skip(ticksToSkip)) { + var targetPos2 = new Vector2(pos.x, pos.z); if ((pos - originV3).MagnitudeHorizontalSquared() > maxDistSqr) { + targetPos1 = targetPos2; + i++; continue; } @@ -178,7 +181,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ // resultingLine = default(ShootLine); // return false; //} - Vector2 ciwsPos1 = positions.firstPos, ciwsPos2 = positions.secondPos, targetPos2 = new Vector2(pos.x, pos.z); + Vector2 ciwsPos1 = positions.firstPos, ciwsPos2 = positions.secondPos; if (CE_Utility.TryFindIntersectionPoint(ciwsPos1, ciwsPos2, targetPos1, targetPos2, out _)) { From d096114734109f858c2f42c4f36e96aa2091a9cb Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Thu, 28 Nov 2024 00:01:05 +0600 Subject: [PATCH 096/127] Direct shooting version --- .../CombatExtended/Verbs/VerbCIWS.cs | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs index 1b635b4ba3..199c83551b 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs @@ -1,4 +1,5 @@ -using RimWorld; +using ProjectRimFactory.AutoMachineTool; +using RimWorld; using System; using System.Collections.Generic; using System.Linq; @@ -142,11 +143,24 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ targetPos = default; return false; } - var midBurst = numShotsFired > 0; + var maxDistSqr = Props.range * Props.range; var originV3 = Caster.Position.ToVector3Shifted(); + if (!Props.tryPredict) + { + if ((originV3 - target.DrawPos).MagnitudeHorizontalSquared() > maxDistSqr) + { + resultingLine = default; + targetPos = default; + return false; + } + var y = TargetNextPositions(target).FirstOrDefault().y; + targetPos = target.DrawPos; + resultingLine = new ShootLine(Shooter.Position, new IntVec3((int)targetPos.x, (int)y, (int)targetPos.z)); + return true; + } + var midBurst = numShotsFired > 0; var ticksToSkip = (Caster as Building_TurretGunCE)?.CurrentTarget.IsValid ?? CurrentTarget.IsValid ? this.BurstWarmupTicksLeft : VerbPropsCE.warmupTime.SecondsToTicks(); var instant = projectilePropsCE.isInstant; - var maxDistSqr = Props.range * Props.range; if (instant) { var to = TargetNextPositions(target).Skip(ticksToSkip).FirstOrFallback(Vector3.negativeInfinity); @@ -224,6 +238,7 @@ protected override IEnumerable TargetNextPositions(Thing target) public abstract class VerbProperties_CIWS : VerbPropertiesCE { + public bool tryPredict = true; public string holdFireIcon = "UI/Commands/HoldFire"; public string holdFireLabel = "HoldFire"; public string holdFireDesc; From 8e3e10648d8587ff4080805754fe1d24cd65af2c Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 29 Nov 2024 00:13:57 +0600 Subject: [PATCH 097/127] Rotation fix --- .../CombatExtended/Projectiles/ProjectileCE.cs | 10 +++++----- .../CombatExtended/Projectiles/ProjectileCE_CIWS.cs | 8 ++++++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index b1798d37fc..47ad525fc2 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -208,7 +208,7 @@ public Vector3 ExactMinusLastPos } } - + public override Vector3 DrawPos { get @@ -247,7 +247,7 @@ public Ray ShotLine /// /// Based on equations of motion /// - public Quaternion DrawRotation + public virtual Quaternion DrawRotation { get { @@ -729,7 +729,7 @@ protected virtual bool CheckForCollisionBetween() if (CheckIntercept(list[i], list[i].TryGetComp())) { landed = true; - this.Impact(null); + InterceptProjectile(list[i], ExactPosition, def.projectile.flyOverhead); return true; } } @@ -1087,7 +1087,7 @@ protected void ApplySuppression(Pawn pawn, float suppressionMultiplier = 1f) public virtual IEnumerable NextPositions => TrajectoryWorker.NextPositions(intendedTarget, shotRotation, shotAngle, GravityFactor, origin, exactPosition, Destination, ticksToImpact, startingTicksToImpact, shotHeight, kinit, velocity, shotSpeed, ExactPosition, mass, ballisticCoefficient, radius, gravity, initialSpeed, (def.projectile as ProjectilePropertiesCE).speedGain, (def.projectile as ProjectilePropertiesCE).speed, FlightTicks); protected Vector3 MoveForward() => TrajectoryWorker.MoveForward(intendedTarget, shotRotation, shotAngle, GravityFactor, origin, ExactPosition, ref Destination, ticksToImpact, startingTicksToImpact, shotHeight, (def.projectile as ProjectilePropertiesCE).speedGain, (def.projectile as ProjectilePropertiesCE).speed, ref kinit, ref velocity, ref shotSpeed, ref exactPosition, ref mass, ref ballisticCoefficient, ref radius, ref gravity, ref initialSpeed, ref FlightTicks); - + protected virtual bool ShouldCollideWithSomething => (lerpPosition && ticksToImpact <= 0) || ExactPosition.y <= 0f; #region Tick/Draw public override void Tick() @@ -1499,7 +1499,7 @@ protected float GetHeightAtTicks(int ticks) /// Shot angle in radians off the ground. /// Height from which the projectile is fired in vertical cells. /// Time in seconds that the projectile will take to traverse the given arc. - + /// /// Calculates the range reachable with a projectile of speed velocity fired at angle from height shotHeight. Does not take into account air resistance. diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs index b228a2edd3..d54ae9ae47 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs @@ -84,6 +84,14 @@ protected override bool CanCollideWith(Thing thing, out float dist) } + public override Quaternion DrawRotation + { + get + { + return Quaternion.LookRotation((NextPositions.FirstOrDefault() - ExactPosition).Yto0()); + } + } + protected override bool ShouldCollideWithSomething => ExactPosition.y <= 0f; public override void Impact(Thing hitThing) { From 8601c7660536f84613e66acc0732714d75e5b126 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 29 Nov 2024 00:14:10 +0600 Subject: [PATCH 098/127] Speed fix --- .../Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs index 832cb188b6..e0fe632199 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs @@ -86,7 +86,7 @@ public virtual float GetFlightTime(float shotAngle, float shotSpeed, float Gravi public virtual float GetSpeed(Vector3 velocity) { - return velocity.magnitude; + return velocity.magnitude * GenTicks.TicksPerRealSecond; } public virtual Vector3 GetVelocity(float shotSpeed, Vector3 origin, Vector3 destination) From a3027debfe507ec1b39aafb2567d833fc01a3b0d Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 29 Nov 2024 00:20:00 +0600 Subject: [PATCH 099/127] Removed useless class --- .../CombatExtended/Verbs/VerbCIWS.cs | 19 +++++++++- .../CombatExtended/Verbs/Verb_ShootCE_CIWS.cs | 38 ------------------- 2 files changed, 18 insertions(+), 39 deletions(-) delete mode 100644 Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs index 199c83551b..44e87e4d4d 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs @@ -13,7 +13,7 @@ namespace CombatExtended { - public abstract class VerbCIWS : Verb_ShootCE_CIWS, ITargetSearcher, IVerbDisableable + public abstract class VerbCIWS : Verb_ShootCE, ITargetSearcher, IVerbDisableable { protected bool debug = true; protected Texture2D icon; @@ -76,6 +76,23 @@ public virtual void ShowTrajectories() return (new Vector2(firstPos.x, firstPos.z), new Vector2(secondPos.x, secondPos.z)); } + public Building_CIWS_CE Turret => Caster as Building_CIWS_CE; + public override ThingDef Projectile + { + get + { + var result = base.Projectile; + var ciwsVersion = (result?.projectile as ProjectilePropertiesCE)?.CIWSVersion; + if (ciwsVersion == null && !typeof(ProjectileCE_CIWS).IsAssignableFrom(result.thingClass)) + { + Log.WarningOnce($"{result} is not a CIWS projectile and the projectile does not have the CIWS version specified in its properties. Must be on-ground projectile used for CIWS", result.GetHashCode()); + } + return ciwsVersion ?? result; + } + } + + protected int maximumPredectionTicks = 40; + public override bool TryCastShot() { var result = base.TryCastShot(); diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs deleted file mode 100644 index a051fbafad..0000000000 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE_CIWS.cs +++ /dev/null @@ -1,38 +0,0 @@ -using RimWorld; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; -using Verse; - -namespace CombatExtended -{ - public class Verb_ShootCE_CIWS : Verb_ShootCE - { - public Building_CIWS_CE Turret => Caster as Building_CIWS_CE; - public override ThingDef Projectile - { - get - { - var result = base.Projectile; - var ciwsVersion = (result?.projectile as ProjectilePropertiesCE)?.CIWSVersion; - if (ciwsVersion == null && !typeof(ProjectileCE_CIWS).IsAssignableFrom(result.thingClass)) - { - Log.WarningOnce($"{result} is not a CIWS projectile and the projectile does not have the CIWS version specified in its properties. Must be on-ground projectile used for CIWS", result.GetHashCode()); - } - return ciwsVersion ?? result; - } - } - - protected int maximumPredectionTicks = 40; - public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine, out Vector3 targetPos) - { - targetPos = default(Vector3); - resultingLine = default; - return false; - } - - } -} From 28b16ac8070c3ecbd3ef97e57537dee7164f5abe Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 29 Nov 2024 00:20:31 +0600 Subject: [PATCH 100/127] Disabled debug --- Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs index 44e87e4d4d..524679b20e 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs @@ -15,7 +15,7 @@ namespace CombatExtended { public abstract class VerbCIWS : Verb_ShootCE, ITargetSearcher, IVerbDisableable { - protected bool debug = true; + protected bool debug; protected Texture2D icon; public virtual bool HoldFire { get; set; } From 97e18f19d8ca4165c0828cd0b2f9d63e4c0a537f Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 29 Nov 2024 00:26:01 +0600 Subject: [PATCH 101/127] Some cleanup --- .../Projectiles/ProjectileCE_CIWS.cs | 20 +++++++++---------- .../CombatExtended/Things/Building_CIWS_CE.cs | 18 ++++++++--------- .../Things/Building_Turret_MultiVerbs.cs | 14 ++++++------- .../CombatExtended/Verbs/VerbCIWS.cs | 13 ++++++++---- .../Verbs/Verb_LaunchProjectileCE.cs | 4 ---- 5 files changed, 35 insertions(+), 34 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs index d54ae9ae47..c35fc71fa6 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs @@ -51,6 +51,15 @@ public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish) public virtual float CollideDistance => (def.projectile as ProjectilePropertiesCE)?.collideDistance ?? 1f; public virtual float ImpactChance => (def.projectile as ProjectilePropertiesCE)?.impactChance ?? 1f; + protected override bool ShouldCollideWithSomething => ExactPosition.y <= 0f; + + public override Quaternion DrawRotation + { + get + { + return Quaternion.LookRotation((NextPositions.FirstOrDefault() - ExactPosition).Yto0()); + } + } public override void Tick() { ticksToImpact++; //do not allow it hit zero @@ -83,16 +92,7 @@ protected override bool CanCollideWith(Thing thing, out float dist) return false; } - - public override Quaternion DrawRotation - { - get - { - return Quaternion.LookRotation((NextPositions.FirstOrDefault() - ExactPosition).Yto0()); - } - } - - protected override bool ShouldCollideWithSomething => ExactPosition.y <= 0f; + public override void Impact(Thing hitThing) { hitThing?.TryGetComp()?.OnImpact(this, DamageInfo); diff --git a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs index 0b9abc89dd..07d21fcefe 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs @@ -27,6 +27,14 @@ public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish) } #endregion + private List ignoredDefs = new List(); + public IEnumerable IgnoredDefsSettings + { + get + { + return ignoredDefs ??= new List(); + } + } public override void ExposeData() { base.ExposeData(); @@ -45,15 +53,7 @@ public override IEnumerable GetGizmos() defaultLabel = "Dialog_ManageCIWS".Translate(), }; } - - private List ignoredDefs = new List(); - public IEnumerable IgnoredDefsSettings - { - get - { - return ignoredDefs ??= new List(); - } - } + public override void Tick() { base.Tick(); diff --git a/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs b/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs index d8bc521758..56dabb1c95 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs @@ -11,13 +11,9 @@ namespace CombatExtended public class Building_Turret_MultiVerbs : Building_TurretGunCE { - public override void ExposeData() - { - base.ExposeData(); - Scribe_References.Look(ref activeVerb, nameof(activeVerb)); - } - Verb activeVerb; + IEnumerable cachedVerbsWithTargetSearcher; + public override Verb AttackVerb { get @@ -25,7 +21,6 @@ public override Verb AttackVerb return activeVerb ?? GunCompEq.AllVerbs.FirstOrDefault(x=>x.state == VerbState.Bursting) ?? base.AttackVerb; } } - IEnumerable cachedVerbsWithTargetSearcher; protected IEnumerable VerbsWithTargetSearcher => cachedVerbsWithTargetSearcher ??= GunCompEq.AllVerbs.OfType().ToList(); public override void DrawExtraSelectionOverlays() { @@ -86,5 +81,10 @@ public override IEnumerable GetGizmos() } } } + public override void ExposeData() + { + base.ExposeData(); + Scribe_References.Look(ref activeVerb, nameof(activeVerb)); + } } } diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs index 524679b20e..956f758202 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs @@ -17,11 +17,15 @@ public abstract class VerbCIWS : Verb_ShootCE, ITargetSearcher, IVerbDisableable { protected bool debug; protected Texture2D icon; + protected int maximumPredectionTicks = 40; + public virtual bool HoldFire { get; set; } public VerbProperties_CIWS Props => verbProps as VerbProperties_CIWS; public virtual string HoldFireLabel => Props.holdFireLabel; public virtual string HoldFireDesc => Props.holdFireDesc; + public Building_CIWS_CE Turret => Caster as Building_CIWS_CE; + public virtual Texture2D HoldFireIcon { get @@ -76,7 +80,6 @@ public virtual void ShowTrajectories() return (new Vector2(firstPos.x, firstPos.z), new Vector2(secondPos.x, secondPos.z)); } - public Building_CIWS_CE Turret => Caster as Building_CIWS_CE; public override ThingDef Projectile { get @@ -91,7 +94,6 @@ public override ThingDef Projectile } } - protected int maximumPredectionTicks = 40; public override bool TryCastShot() { @@ -114,6 +116,11 @@ public override bool Available() } public abstract class VerbCIWS : VerbCIWS where TargetType : Thing { + public abstract IEnumerable Targets { get; } + protected abstract IEnumerable TargetNextPositions(TargetType target); + + + public override bool TryFindNewTarget(out LocalTargetInfo target) { @@ -148,9 +155,7 @@ public override bool TryFindNewTarget(out LocalTargetInfo target) return false; } protected virtual bool IsFriendlyTo(TargetType thing) => !thing.HostileTo(Caster); - public abstract IEnumerable Targets { get; } //public override bool ValidateTarget(LocalTargetInfo target, bool showMessages = true) => target.Thing is TargetType && TryFindCEShootLineFromTo(Caster.Position, target, out _, out _) && base.ValidateTarget(target, showMessages); - protected abstract IEnumerable TargetNextPositions(TargetType target); public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targetInfo, out ShootLine resultingLine, out Vector3 targetPos) { diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index e02a6f4f8b..9185662260 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -349,10 +349,6 @@ public override void WarmupComplete() ); } - public virtual Vector3 GetTargetLoc(LocalTargetInfo target, int sinceTicks) - { - return target.Thing?.TrueCenter() ?? target.Cell.ToVector3Shifted(); //report.targetPawn != null ? report.targetPawn.DrawPos + report.targetPawn.Drawer.leaner.LeanOffset * 0.5f : report.target.Cell.ToVector3Shifted(); - } public virtual float GetTargetHeight(LocalTargetInfo target, Thing cover, bool roofed, Vector3 targetLoc) { float targetHeight = 0f; From 4f3bc137ea11fc139021ba1d90096edb2c47d7ff Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 29 Nov 2024 00:28:28 +0600 Subject: [PATCH 102/127] reverted change for other branch --- .../CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 47ad525fc2..b4c10532cb 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -729,7 +729,7 @@ protected virtual bool CheckForCollisionBetween() if (CheckIntercept(list[i], list[i].TryGetComp())) { landed = true; - InterceptProjectile(list[i], ExactPosition, def.projectile.flyOverhead); + this.Impact(null); return true; } } From 38c6d7ae3ceefd6a5567166709d7ad6e7dd7711d Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 29 Nov 2024 00:43:56 +0600 Subject: [PATCH 103/127] Backward compatibility for vehicles --- .../Projectiles/ProjectileCE.cs | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index b4c10532cb..6599cf711e 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -1509,7 +1509,27 @@ protected float GetHeightAtTicks(int ticks) /// Height from which the projectile is fired in vertical cells. /// Distance in cells that the projectile will fly at the given arc. protected float DistanceTraveled => TrajectoryWorker.DistanceTraveled(shotHeight, shotSpeed, shotAngle, GravityFactor); - + /// + /// Calculates the shot angle necessary to reach range with a projectile of speed velocity at a height difference of heightDifference, returning either the upper or lower arc in radians. Does not take into account air resistance. + /// + /// Projectile velocity in cells per second. + /// Cells between shooter and target. + /// Difference between initial shot height and target height in vertical cells. + /// Whether to take the lower (False) or upper (True) arc angle. + /// Arc angle in radians off the ground. + public static float GetShotAngle(float velocity, float range, float heightDifference, bool flyOverhead, float gravity) + { + Log.WarningOnce("ProjectileCE.GetShotAngle is obsolete and will be removed in future updates. Please, use TrajectoryWorker.GetShotAngle, that can be obtained from ProjectilePropertiesCE", 58606596); + float squareRootCheck = Mathf.Sqrt(Mathf.Pow(velocity, 4f) - gravity * (gravity * Mathf.Pow(range, 2f) + 2f * heightDifference * Mathf.Pow(velocity, 2f))); + if (float.IsNaN(squareRootCheck)) + { + //Target is too far to hit with given velocity/range/gravity params + //set firing angle for maximum distance + Log.Warning("[CE] Tried to fire projectile to unreachable target cell, truncating to maximum distance."); + return 45.0f * Mathf.Deg2Rad; + } + return Mathf.Atan((Mathf.Pow(velocity, 2f) + (flyOverhead ? 1f : -1f) * squareRootCheck) / (gravity * range)); + } #endregion From 0a7de3b0f92d218aca509a875ca6a5d78ae3b23f Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 29 Nov 2024 00:48:23 +0600 Subject: [PATCH 104/127] Whitespace --- Source/CombatExtended/CombatExtended/CE_Utility.cs | 2 +- .../CombatExtended/Comps/CompCIWSImpactHandler.cs | 4 ++-- Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs | 4 ++-- .../CombatExtended/CombatExtended/Comps/CompVerbDisabler.cs | 2 +- .../CombatExtended/CombatExtended/Dialog_ManageCIWSTargets.cs | 2 +- Source/CombatExtended/CombatExtended/IVerbDisableable.cs | 2 +- .../CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs | 2 +- .../CombatExtended/Projectiles/ProjectileCE_CIWS.cs | 2 +- .../Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs | 2 +- .../CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs | 4 ++-- .../CombatExtended/Things/Building_Turret_MultiVerbs.cs | 4 ++-- .../CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs | 2 +- .../CombatExtended/Verbs/Verb_LaunchProjectileCE.cs | 2 +- 13 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/CE_Utility.cs b/Source/CombatExtended/CombatExtended/CE_Utility.cs index 64ab983792..97785e7961 100644 --- a/Source/CombatExtended/CombatExtended/CE_Utility.cs +++ b/Source/CombatExtended/CombatExtended/CE_Utility.cs @@ -1706,7 +1706,7 @@ public static IEnumerable DrawPositions(this Skyfaller skyfaller) int max = skyfaller.ticksToImpact; for (int i = 1; i <= max; i++) { - yield return skyfaller.DrawPosSinceTicks(i); + yield return skyfaller.DrawPosSinceTicks(i); } } } diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs index c068b69174..83a0e46e18 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs @@ -13,7 +13,7 @@ namespace CombatExtended public class CompCIWSImpactHandler : ThingComp { public CompProperties_CIWSImpactHandler Props => props as CompProperties_CIWSImpactHandler; - + public virtual void OnImpact(ProjectileCE projectile, DamageInfo dinfo) { if (!Props.impacted.NullOrUndefined()) @@ -26,7 +26,7 @@ public virtual void OnImpact(ProjectileCE projectile, DamageInfo dinfo) } parent.Destroy(DestroyMode.Vanish); } - + } public class CompProperties_CIWSImpactHandler : CompProperties { diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs index c82623a9f7..bbb5f459f3 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSTarget.cs @@ -22,7 +22,7 @@ public static IEnumerable Targets(Map map) } public static IEnumerable Targets(Map map) where T : CompCIWSTarget { - return Targets(map).Where(x=>x.HasComp()); + return Targets(map).Where(x => x.HasComp()); } public CompProperties_CIWSTarget Props => props as CompProperties_CIWSTarget; @@ -67,7 +67,7 @@ public override void PostDeSpawn(Map map) } public class CompProperties_CIWSTarget : CompProperties { - public CompProperties_CIWSTarget(){} + public CompProperties_CIWSTarget() { } public override IEnumerable ConfigErrors(ThingDef parentDef) { foreach (var item in base.ConfigErrors(parentDef)) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompVerbDisabler.cs b/Source/CombatExtended/CombatExtended/Comps/CompVerbDisabler.cs index 67466ae447..53a0199a01 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompVerbDisabler.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompVerbDisabler.cs @@ -28,7 +28,7 @@ public override IEnumerable CompGetGizmosExtra() icon = verb.HoldFireIcon, isActive = () => verb.HoldFire, toggleAction = () => verb.HoldFire = !verb.HoldFire, - + }; yield return command; } diff --git a/Source/CombatExtended/CombatExtended/Dialog_ManageCIWSTargets.cs b/Source/CombatExtended/CombatExtended/Dialog_ManageCIWSTargets.cs index 98c2325a97..4585467810 100644 --- a/Source/CombatExtended/CombatExtended/Dialog_ManageCIWSTargets.cs +++ b/Source/CombatExtended/CombatExtended/Dialog_ManageCIWSTargets.cs @@ -76,7 +76,7 @@ public override void DoWindowContents(Rect inRect) Rect searchBarRect = new Rect(inRect.width / 2 + TextOffset, y, inRect.width / 2 - BufferArea * 3, ElementsHeight); Rect copyRect = new Rect(inRect.x + BufferArea, y, 46f, ElementsHeight); - Rect pasteRect = new Rect(copyRect.xMax + BufferArea, y, 46f, ElementsHeight); + Rect pasteRect = new Rect(copyRect.xMax + BufferArea, y, 46f, ElementsHeight); SearchString = Widgets.TextArea(searchBarRect, SearchString); diff --git a/Source/CombatExtended/CombatExtended/IVerbDisableable.cs b/Source/CombatExtended/CombatExtended/IVerbDisableable.cs index 5077665fc1..2a2b14c013 100644 --- a/Source/CombatExtended/CombatExtended/IVerbDisableable.cs +++ b/Source/CombatExtended/CombatExtended/IVerbDisableable.cs @@ -9,7 +9,7 @@ namespace CombatExtended { public interface IVerbDisableable { - bool HoldFire { get; set; } + bool HoldFire { get; set; } string HoldFireLabel { get; } string HoldFireDesc { get; } Texture2D HoldFireIcon { get; } diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 6599cf711e..3e58704153 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -570,7 +570,7 @@ public virtual void Launch(Thing launcher, Vector2 origin, float shotAngle, floa ballisticCoefficient = props.ballisticCoefficient.RandomInRange; mass = props.mass.RandomInRange; radius = props.diameter.RandomInRange / 2000; // half the diameter and mm -> m - + } if (shotHeight >= CollisionVertical.WallCollisionHeight && Position.Roofed(launcher.Map)) { diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs index c35fc71fa6..05a95ccfb1 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs @@ -92,7 +92,7 @@ protected override bool CanCollideWith(Thing thing, out float dist) return false; } - + public override void Impact(Thing hitThing) { hitThing?.TryGetComp()?.OnImpact(this, DamageInfo); diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs index e0fe632199..2f0bfaf505 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs @@ -142,7 +142,7 @@ public virtual float ShotAngle(ProjectilePropertiesCE projectilePropsCE, Vector3 public virtual float ShotRotation(ProjectilePropertiesCE projectilePropertiesCE, Vector3 source, Vector3 targetPos) { var w = targetPos - source; - return ( - 90 + Mathf.Rad2Deg * Mathf.Atan2(w.z, w.x)) % 360; + return (-90 + Mathf.Rad2Deg * Mathf.Atan2(w.z, w.x)) % 360; } } } diff --git a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs index 07d21fcefe..58aaa7d84f 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs @@ -49,11 +49,11 @@ public override IEnumerable GetGizmos() } yield return new Command_Action() { - action = () => Find.WindowStack.Add(new Dialog_ManageCIWSTargets(GunCompEq.AllVerbs.OfType().SelectMany(x=>x.Props.AllTargets).Distinct().ToList(), ignoredDefs)), + action = () => Find.WindowStack.Add(new Dialog_ManageCIWSTargets(GunCompEq.AllVerbs.OfType().SelectMany(x => x.Props.AllTargets).Distinct().ToList(), ignoredDefs)), defaultLabel = "Dialog_ManageCIWS".Translate(), }; } - + public override void Tick() { base.Tick(); diff --git a/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs b/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs index 56dabb1c95..322e768e6a 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs @@ -13,12 +13,12 @@ public class Building_Turret_MultiVerbs : Building_TurretGunCE Verb activeVerb; IEnumerable cachedVerbsWithTargetSearcher; - + public override Verb AttackVerb { get { - return activeVerb ?? GunCompEq.AllVerbs.FirstOrDefault(x=>x.state == VerbState.Bursting) ?? base.AttackVerb; + return activeVerb ?? GunCompEq.AllVerbs.FirstOrDefault(x => x.state == VerbState.Bursting) ?? base.AttackVerb; } } protected IEnumerable VerbsWithTargetSearcher => cachedVerbsWithTargetSearcher ??= GunCompEq.AllVerbs.OfType().ToList(); diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs index 5b2bbb1d11..39554e571a 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs @@ -16,7 +16,7 @@ public class VerbCIWSProjectile : VerbCIWS public override IEnumerable Targets => Caster.Map?.listerThings.ThingsInGroup(ThingRequestGroup.Projectile).OfType() ?? Array.Empty(); protected override bool IsFriendlyTo(ProjectileCE thing) => base.IsFriendlyTo(thing) && !thing.launcher.HostileTo(Caster); - + public override void ShowTrajectories() { base.ShowTrajectories(); diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index 9185662260..b19815cd95 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -1122,7 +1122,7 @@ public override bool TryCastShot() spreadDegrees = (EquipmentSource?.GetStatValue(CE_StatDefOf.ShotSpread) ?? 0) * pprop.spreadMult; aperatureSize = 0.03f; } - + ShiftVecReport report = ShiftVecReportFor(currentTarget, targetLoc.ToIntVec3()); bool pelletMechanicsOnly = false; for (int i = 0; i < projectilePropsCE.pelletCount; i++) From b377260a79b8dca3e4cdcdcfaadafd382a76b0d7 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 29 Nov 2024 22:11:00 +0600 Subject: [PATCH 105/127] Swap thingClass and trajectory workers if not CIWS projectile (can be reverted) --- .../Projectiles/ProjectileCE.cs | 3 +- .../CombatExtended/Verbs/VerbCIWS.cs | 38 ++++++++++++++++--- .../Verbs/Verb_LaunchProjectileCE.cs | 6 ++- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs index 3e58704153..f2b203597f 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs @@ -1460,7 +1460,8 @@ public virtual void Impact(Thing hitThing) #endregion #region Ballistics - public BaseTrajectoryWorker TrajectoryWorker => (def.projectile as ProjectilePropertiesCE).TrajectoryWorker; + public BaseTrajectoryWorker TrajectoryWorker => forcedTrajectoryWorker ?? (def.projectile as ProjectilePropertiesCE).TrajectoryWorker; + internal BaseTrajectoryWorker forcedTrajectoryWorker; public void DrawNextPositions() { diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs index 956f758202..14d4f6512a 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs @@ -57,10 +57,10 @@ public virtual void ShowTrajectories() var shotAngle = ShotAngle(targetPos); var shotRotation = ShotRotation(targetPos); - var destination = projectilePropsCE.TrajectoryWorker.Destination(originV2, shotRotation, ShotHeight, ShotSpeed, shotAngle, projectilePropsCE.Gravity); - var flightTime = projectilePropsCE.TrajectoryWorker.GetFlightTime(shotAngle, ShotSpeed, projectilePropsCE.Gravity, ShotHeight) * GenTicks.TicksPerRealSecond; - var initialVelocity = projectilePropsCE.TrajectoryWorker.GetVelocity(ShotSpeed, shotRotation, shotAngle); - var enumeration = projectilePropsCE.TrajectoryWorker.NextPositions(currentTarget, shotRotation, shotAngle, projectilePropsCE.Gravity, originV2, this.Caster.Position.ToVector3Shifted(), destination, (int)flightTime, flightTime, ShotHeight, false, initialVelocity, ShotSpeed, originV3, projectilePropsCE.mass.max, projectilePropsCE.ballisticCoefficient.max, projectilePropsCE.diameter.max / 2000, projectilePropsCE.Gravity, ShotSpeed, projectilePropsCE.speedGain, projectilePropsCE.speed, 0).GetEnumerator(); + var destination = TrajectoryWorker.Destination(originV2, shotRotation, ShotHeight, ShotSpeed, shotAngle, projectilePropsCE.Gravity); + var flightTime = TrajectoryWorker.GetFlightTime(shotAngle, ShotSpeed, projectilePropsCE.Gravity, ShotHeight) * GenTicks.TicksPerRealSecond; + var initialVelocity = TrajectoryWorker.GetVelocity(ShotSpeed, shotRotation, shotAngle); + var enumeration = TrajectoryWorker.NextPositions(currentTarget, shotRotation, shotAngle, projectilePropsCE.Gravity, originV2, this.Caster.Position.ToVector3Shifted(), destination, (int)flightTime, flightTime, ShotHeight, false, initialVelocity, ShotSpeed, originV3, projectilePropsCE.mass.max, projectilePropsCE.ballisticCoefficient.max, projectilePropsCE.diameter.max / 2000, projectilePropsCE.Gravity, ShotSpeed, projectilePropsCE.speedGain, projectilePropsCE.speed, 0).GetEnumerator(); for (int i = 1; i <= sinceTicks; i++) { firstPos = secondPos; @@ -74,8 +74,8 @@ public virtual void ShowTrajectories() } if (drawPos) { - firstPos = projectilePropsCE.TrajectoryWorker.ExactPosToDrawPos(firstPos, sinceTicks - 1, projectilePropsCE.TickToTruePos, Projectile.Altitude); - secondPos = projectilePropsCE.TrajectoryWorker.ExactPosToDrawPos(secondPos, sinceTicks, projectilePropsCE.TickToTruePos, Projectile.Altitude); + firstPos = TrajectoryWorker.ExactPosToDrawPos(firstPos, sinceTicks - 1, projectilePropsCE.TickToTruePos, Projectile.Altitude); + secondPos = TrajectoryWorker.ExactPosToDrawPos(secondPos, sinceTicks, projectilePropsCE.TickToTruePos, Projectile.Altitude); } return (new Vector2(firstPos.x, firstPos.z), new Vector2(secondPos.x, secondPos.z)); } @@ -113,6 +113,32 @@ public override bool Available() { return Active && base.Available(); } + protected override ProjectileCE SpawnProjectile() + { + if (!typeof(ProjectileCE_CIWS).IsAssignableFrom(Projectile.thingClass)) + { + var def = Projectile; + var thing = new ProjectileCE_CIWS(); + thing.forcedTrajectoryWorker = TrajectoryWorker; + thing.def = def; + thing.PostMake(); + thing.PostPostMake(); + return thing; + } + return base.SpawnProjectile(); + } + static BaseTrajectoryWorker lerpedTrajectoryWorker = new LerpedTrajectoryWorker_ExactPosDrawing(); + protected BaseTrajectoryWorker TrajectoryWorker + { + get + { + if (!typeof(ProjectileCE_CIWS).IsAssignableFrom(Projectile.thingClass) && projectilePropsCE.TrajectoryWorker.GetType() == typeof(LerpedTrajectoryWorker)) + { + return lerpedTrajectoryWorker; + } + return projectilePropsCE.TrajectoryWorker; + } + } } public abstract class VerbCIWS : VerbCIWS where TargetType : Thing { diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index b19815cd95..1989fbc905 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -1128,7 +1128,7 @@ public override bool TryCastShot() for (int i = 0; i < projectilePropsCE.pelletCount; i++) { - ProjectileCE projectile = (ProjectileCE)ThingMaker.MakeThing(Projectile, null); + ProjectileCE projectile = SpawnProjectile(); GenSpawn.Spawn(projectile, shootLine.Source, caster.Map); ShiftTarget(report, lastExactPos, pelletMechanicsOnly, instant); @@ -1195,6 +1195,10 @@ public override bool TryCastShot() lastShotTick = Find.TickManager.TicksGame; return true; } + protected virtual ProjectileCE SpawnProjectile() + { + return (ProjectileCE)ThingMaker.MakeThing(Projectile, null); + } /// /// Highlight the explosion radius for this projectile. From ba5e06a6f5878ab229430110c10a77996ff27718 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Fri, 29 Nov 2024 22:15:08 +0600 Subject: [PATCH 106/127] Whitespace --- .../CombatExtended/Verbs/Verb_LaunchProjectileCE.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index 1989fbc905..f3178fa802 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -1197,7 +1197,7 @@ public override bool TryCastShot() } protected virtual ProjectileCE SpawnProjectile() { - return (ProjectileCE)ThingMaker.MakeThing(Projectile, null); + return (ProjectileCE)ThingMaker.MakeThing(Projectile, null); } /// From 3989b82d96500e222d7db153dcabf0882cd98449 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sat, 30 Nov 2024 00:23:07 +0600 Subject: [PATCH 107/127] Health points --- Patches/Core/Skyfallers/SkyfallerBase.xml | 1 + .../Comps/CompCIWSImpactHandler.cs | 34 ++++++++++++++++++- .../Comps/CompCIWSImpactHandler_Skyfaller.cs | 21 ++++++++++-- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/Patches/Core/Skyfallers/SkyfallerBase.xml b/Patches/Core/Skyfallers/SkyfallerBase.xml index fbe625b425..677b05de52 100644 --- a/Patches/Core/Skyfallers/SkyfallerBase.xml +++ b/Patches/Core/Skyfallers/SkyfallerBase.xml @@ -18,6 +18,7 @@
  • CombatExtended.CompCIWSImpactHandler_Skyfaller + 22
  • diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs index 83a0e46e18..52d5e7a736 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler.cs @@ -12,8 +12,14 @@ namespace CombatExtended { public class CompCIWSImpactHandler : ThingComp { - public CompProperties_CIWSImpactHandler Props => props as CompProperties_CIWSImpactHandler; + private float hp; + public float HP + { + get => hp; + set => hp = value; + } + public CompProperties_CIWSImpactHandler Props => props as CompProperties_CIWSImpactHandler; public virtual void OnImpact(ProjectileCE projectile, DamageInfo dinfo) { if (!Props.impacted.NullOrUndefined()) @@ -24,8 +30,33 @@ public virtual void OnImpact(ProjectileCE projectile, DamageInfo dinfo) { Props.impactEffecter.Spawn(parent.DrawPos.ToIntVec3(), parent.Map); } + ApplyDamage(dinfo); + } + public virtual void ApplyDamage(DamageInfo dinfo) + { + HP -= dinfo.Amount; + if (HP <= 0.00001f && !parent.Destroyed) + { + OnDestroying(dinfo); + } + } + protected virtual void OnDestroying(DamageInfo dinfo) + { parent.Destroy(DestroyMode.Vanish); } + public override void PostExposeData() + { + base.PostExposeData(); + Scribe_Values.Look(ref hp, nameof(HP)); + } + public override void PostSpawnSetup(bool respawningAfterLoad) + { + base.PostSpawnSetup(respawningAfterLoad); + if (!respawningAfterLoad) + { + HP = Props.HP; + } + } } public class CompProperties_CIWSImpactHandler : CompProperties @@ -34,6 +65,7 @@ public CompProperties_CIWSImpactHandler() { compClass = typeof(CompCIWSImpactHandler); } + public float HP = 0.0001f; public SoundDef impacted; public EffecterDef impactEffecter; } diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs index ff4fff2018..41269ea422 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs @@ -12,6 +12,22 @@ namespace CombatExtended public class CompCIWSImpactHandler_Skyfaller : CompCIWSImpactHandler { public override void OnImpact(ProjectileCE projectile, DamageInfo dinfo) + { + + base.OnImpact(projectile, dinfo); + if (!parent.Destroyed) + { + if (parent is IThingHolder pod) + { + var pawns = pod.ContainedThings().OfType().ToList(); + if (pawns.Any()) + { + pawns.RandomElement().TakeDamage(dinfo); + } + } + } + } + protected override void OnDestroying(DamageInfo dinfo) { if (parent is IThingHolder pod) { @@ -25,7 +41,7 @@ public override void OnImpact(ProjectileCE projectile, DamageInfo dinfo) GenLeaving.DoLeavingsFor(thing, parent.Map, DestroyMode.KillFinalize, CellRect.CenteredOn(parent.Position, thing.def.size), listOfLeavingsOut: leavingList); continue; } - TryDropThing(thing, projectile.Map, projectile.Position); + TryDropThing(thing, parent.Map, parent.DrawPos.ToIntVec3()); if (thing is Pawn pawn) { pawn.TakeDamage(dinfo); @@ -41,8 +57,7 @@ public override void OnImpact(ProjectileCE projectile, DamageInfo dinfo) } } - base.OnImpact(projectile, dinfo); - + base.OnDestroying(dinfo); } private Thing TryDropThing(Thing thing, Map map, IntVec3 position) { From 94293e4c0781115da843099dbdf4242261b5430d Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sat, 30 Nov 2024 14:32:22 +0600 Subject: [PATCH 108/127] Shadow rotation fix --- .../CombatExtended/Projectiles/ProjectileCE_CIWS.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs index 05a95ccfb1..9b2260dab3 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE_CIWS.cs @@ -60,6 +60,7 @@ public override Quaternion DrawRotation return Quaternion.LookRotation((NextPositions.FirstOrDefault() - ExactPosition).Yto0()); } } + public override Quaternion ExactRotation => DrawRotation; public override void Tick() { ticksToImpact++; //do not allow it hit zero From 79a73931086ca74495ca6eb19d864107a54229c1 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sat, 30 Nov 2024 15:02:22 +0600 Subject: [PATCH 109/127] Removed tryPredict --- .../Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs | 1 + .../TrajectoryWorkers/SmartRocketTrajectoryWorker.cs | 1 + Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs | 3 +-- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs index 2f0bfaf505..ada9561f92 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/BaseTrajectoryWorker.cs @@ -144,5 +144,6 @@ public virtual float ShotRotation(ProjectilePropertiesCE projectilePropertiesCE, var w = targetPos - source; return (-90 + Mathf.Rad2Deg * Mathf.Atan2(w.z, w.x)) % 360; } + public virtual bool GuidedProjectile => false; } } diff --git a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs index 9f548e8785..228c5cb4f6 100644 --- a/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs +++ b/Source/CombatExtended/CombatExtended/Projectiles/TrajectoryWorkers/SmartRocketTrajectoryWorker.cs @@ -22,5 +22,6 @@ protected override void ReactiveAcceleration(LocalTargetInfo currentTarget, floa shotSpeed = Mathf.Min(shotSpeed + speedGain, maxSpeed); velocity = GetVelocity(shotSpeed, Vector3.zero, velocity + velocityChange); } + public override bool GuidedProjectile => true; } } diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs index 14d4f6512a..4932c9bd21 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs @@ -193,7 +193,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ } var maxDistSqr = Props.range * Props.range; var originV3 = Caster.Position.ToVector3Shifted(); - if (!Props.tryPredict) + if (TrajectoryWorker.GuidedProjectile) { if ((originV3 - target.DrawPos).MagnitudeHorizontalSquared() > maxDistSqr) { @@ -286,7 +286,6 @@ protected override IEnumerable TargetNextPositions(Thing target) public abstract class VerbProperties_CIWS : VerbPropertiesCE { - public bool tryPredict = true; public string holdFireIcon = "UI/Commands/HoldFire"; public string holdFireLabel = "HoldFire"; public string holdFireDesc; From d62426da967755e2bab56aeb1dae9819ace4e613 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sat, 30 Nov 2024 18:54:15 +0600 Subject: [PATCH 110/127] Checks for if Verb available (will be used with #3575 PR) --- .../CombatExtended/Things/Building_Turret_MultiVerbs.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs b/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs index 322e768e6a..019a0b7644 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_Turret_MultiVerbs.cs @@ -42,11 +42,12 @@ public override void DrawExtraSelectionOverlays() public override LocalTargetInfo TryFindNewTarget() { activeVerb = null; - foreach (var verb in VerbsWithTargetSearcher) + foreach (var targetSearcher in VerbsWithTargetSearcher) { - if (verb.TryFindNewTarget(out var target)) + var verb = (Verb)targetSearcher; + if (verb.Available() && targetSearcher.TryFindNewTarget(out var target)) { - activeVerb = (Verb)verb; + activeVerb = (Verb)targetSearcher; return target; } } From b7af0eadb38df91583b708eba5b6186043ab37ec Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sat, 30 Nov 2024 20:26:30 +0600 Subject: [PATCH 111/127] CIWS icons --- .../CombatExtended/Things/Building_CIWS_CE.cs | 3 ++- .../CombatExtended/Verbs/VerbCIWSProjectile.cs | 1 + .../CombatExtended/Verbs/VerbCIWSSkyfaller.cs | 1 + Textures/UI/Buttons/CE_CIWS_Projectile.png | Bin 0 -> 7164 bytes Textures/UI/Buttons/CE_CIWS_Skyfaller.png | Bin 0 -> 9600 bytes 5 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 Textures/UI/Buttons/CE_CIWS_Projectile.png create mode 100644 Textures/UI/Buttons/CE_CIWS_Skyfaller.png diff --git a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs index 58aaa7d84f..d6c9cfffc2 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs @@ -40,7 +40,7 @@ public override void ExposeData() base.ExposeData(); Scribe_Collections.Look(ref ignoredDefs, nameof(ignoredDefs)); } - + static Texture2D icon; public override IEnumerable GetGizmos() { foreach (var gizmo in base.GetGizmos()) @@ -50,6 +50,7 @@ public override IEnumerable GetGizmos() yield return new Command_Action() { action = () => Find.WindowStack.Add(new Dialog_ManageCIWSTargets(GunCompEq.AllVerbs.OfType().SelectMany(x => x.Props.AllTargets).Distinct().ToList(), ignoredDefs)), + icon = Building_CIWS_CE.icon ??= ContentFinder.Get("UI/Commands/LaunchReport"), defaultLabel = "Dialog_ManageCIWS".Translate(), }; } diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs index 39554e571a..3c55baa83a 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs @@ -38,6 +38,7 @@ public class VerbProperties_CIWSProjectile : VerbProperties_CIWS public VerbProperties_CIWSProjectile() { this.verbClass = typeof(VerbCIWSProjectile); + this.holdFireIcon = "UI/Buttons/CE_CIWS_Projectile"; } public override bool Interceptable(ThingDef targetDef) => targetDef.projectile.speed < maximumSpeed && targetDef.projectile.flyOverhead && base.Interceptable(targetDef); public float maximumSpeed = 80; diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSSkyfaller.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSSkyfaller.cs index c6767da0e6..52156b5600 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSSkyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSSkyfaller.cs @@ -27,6 +27,7 @@ public class VerbProperties_CIWSSkyfaller : VerbProperties_CIWS public VerbProperties_CIWSSkyfaller() { this.verbClass = typeof(VerbCIWSSkyfaller); + this.holdFireIcon = "UI/Buttons/CE_CIWS_Skyfaller"; } protected override IEnumerable InitAllTargets() => DefDatabase.AllDefsListForReading.Where(x => (typeof(Skyfaller).IsAssignableFrom(x.thingClass) && typeof(IActiveDropPod).IsAssignableFrom(x.thingClass))); } diff --git a/Textures/UI/Buttons/CE_CIWS_Projectile.png b/Textures/UI/Buttons/CE_CIWS_Projectile.png new file mode 100644 index 0000000000000000000000000000000000000000..1ea0559107c3bd45d7209fb09d7feda08b41f38a GIT binary patch literal 7164 zcmbtY2UJs8w>~#LA%TE|5)eZGjS30~NK+D|D;QKP2pXy&sECNDjE00JO+Xavmx#ik zAUdFoIufdgfU#qbh=`yg#exNRag=+Rwf?u>dhcbetlXTl&p!Kn``hK*J$x@$8ih## z0MOjsoR%nlg+IO|0sv5@jkmwz4>`(h)fNDh)P8)S+fR3W2S6v!-HEp>?nod^GBq_- z2!XLN33bl+qhl@c-qx{w!E7uR`_Eim2x&9HY{2#)LA-w9Z@=SFd-oU`Z?Jx8vFS1W0Y4=kin%gs_B=e zCKp%5jN&MDp+bPg*6-jvhCGMx1VXY(6ht75PihnHoP0I5#f%qEI?tf+?;*zytUaZz z-qP&VMAp*M`lU%b)eTCrJB1D;-8!MN(<4|Q_$e>}wg3Dm3Oe6{ArKS}`Dqzx00q+V z8g%sN(J`KuC+2b?l}i03lUz$+=`2~hc5j<>L@_!(d>~uv#*G^T52-U$SjMQvLwNzo zQJXi9jD32iv&cB0@JwgCx(~97ZFNx6L1~+kF+q_jcv|zctqndxetleNFo;g43*!3a zP<>sJlJ+>Zm?*hmx)S#;q`sd@&H827EBp~J7YNZ^cTzjUvcpFDtX3_PE|p4uNimcf z9=0I=eBlO%t18hB0n-qiCjiA<**Y#M+BpPYD#s`YaR#@%vS#}isLlV{_+*`SyW6Wf zgl~uQvEhMsGQh0zg&4EvSUI@>}Qhb9zAn#pl<&m5!)4dgY9!3SIRE*7s@ilGOJq_8E^|ww0=g zsjhWEvA3~ejawom=NU_}{MX{?n(~M@`|ya-lF)N$x|oK8H^vW`map_abn?Z=BLMcY6f?1JA4jeE8(eS1N{nAmqd99ocf=1*Xb`X!G=t3RlamS6pitG_SYD$# zP17Sqhl(J}zQBuq@$K{bRpNNsW>3Y*{lg9A zbQ4yqyy-@Y{<#--h{+$P@DAeE?bXIWVuI}lOpL8ei6F~qTxik79zsocltC00rpHymXSpZ z1tll@Ayn;QaUS6f`w`@3#Qd1H302hsRV2E6Tr(Si;y^;rNBrh)MM(YJ?7s<&hXvyp zF#qFYot3==94@mhDOc*vC|q$q=5U+D26fD(YWtG%^bLMex^1qx1xnaIuW}DRPK0Cv zCWpnvM!*+1gVFi5N+<<%#4c*Q`a`h3G2dBNLxZ5#)Y;XQn5m}UWKNig=$8~Vf>~3z z^`RB|7QtY0BgQPJcxfsGFH2PJ-+H#0h`=wYypCh;GAk)55zy5eo+%lau>=v8a*RyR z!tzNPS~}U`w{?|3rn_luOpG-2gBb|3R=q3E&&|a!BrFwC3w;ORdx%0@-=4UE>b3v^ zpl+82bGdp=P6YT2X7YU;1C~G2%>=FW-+1#@6+JT!m7ivBxtq9IQ|E3H6H01>R2#Ay0s-Q9i8GLb5)<(0NyDB=FO+6yWMpV{b#-Y)Mn-B` zMS`*_pmHUlxF{9Cd06FTGF!6W%mt|g^lTx3C3fV5T5tPXmn5bbcF5XfGAV&{1b3o<_ z(U6uGqCw(9fqR#1^6P`6AlaFlw^cT|pTp!Z5mHEeDXgtwU*)x8Dp8s1TU|YMTNG6E zah2TpdP4`z-cWTt?ODR0Q|Y?Go-%~%k`?--<32`~dnTt|Kb;_>gW*SL3t2+p5Ag+Cyb;vc;lF{H)kc@rJ)iBfjF?HT zTb!kBjzGwcC}MnB25Z*rHcNbdd5^K@?F*R@9&r|1M~n$57tOeGQ`whIoYxoFqf2W< zirCIQt)h!()%Hz!5-L~Zow5<=EQaUHoHL9?T6szEd8m@3_S%ML* zvpmDaH@StQ+2%_zRe%#3bsUQTDv3GD;w;zj`)dc|g099) zu7|#bXL}e3){K0G`&9NDa%xGFqr0r(8eVotz~>6EaAfYWW6FV|^R#;^PF!q-a{&f+ z)?&WZt@c5K<-UhE|F|5>nQ6cC6ZJI4$jC?*KxIuWIqiA+V;x*X@Ctz~$+#6T%FFI0 ztD@#??`+s(jfHk7V@cUDowyuutc$nwgOf=!;#WziA`#ltqe4>d-(Rk^&vzA+cS!E8 zXW_i~gPJZvXi2O>%9_r77;y90JdWD#(eDA)zkRh3r>2rp7iPYhC6iF2*0ZgypZHhO z69Nuh`R%j6bSk~HjKPpSNqC>U0E+V=9|U<_wGr8F?t>hJDiWU`8F?U=G(&}(sV}?4 z4VE@G;w7o`4C&g^seC-QFWb#?qI`%#KJ1b16U%2+5t>@{!t(N2Hr)v=wEpmg@T-9$ z{8}*my`WQ}1=chTOZUgN^B$FCt}ooLr8`qs3v|o)1w9yneL}%*b!} zir9kGr(;;`>#Mti3WmFlGL)E$rSo^RjdPC~2?@=Kyx#Ro>A>U)&P1As$-cJv{f1D1 z;8#1a2m;SlaG0X0+bi(}4YXE-4@|1gRKe*Md3W}qE}qWRiplv&c=!|v*}hv#KVO9H_v6xy7u6>flhn@ZP2>#s+~D^R*$;6 zx>o1Qmjk7)zFV^Z!dqsA=h9|nw&isL%@{aAgG?q5>eeFKb^;bHCih5Jj*_jivhop~ z3wtJ1uu6L3`$;TD_9ZAcQItjJ4l8csKQD|D7ZcD6)8{nckN2}Iub*JVFzqXiq+nNkldxR_#s%G~gp9_W!cdu-Ia%i+?sDB_S+5>Yn!z==Q3 z+?^0aeamekH{ke*VzyqMqT7wV)X?2__}0y79*Iv^I8aIeYU;N&?mcmJBX$nENrLpa zo`*A{`bS505{zG;qki4@H3hYfnc8-qA`6kpdqGSo-`AIU|Fo~-Wr88tPYQFj$efDv zK)_+9;=ox#WmT1SXJ@CI6?oI@s|7nd0wX^EauOe_fs+z{r~MgA8RssuF?|uICEF%Z%iFc6|VB8$SjG;&U8O4p; zl`O!@6dA8rENVXl8`gOv2WKua0_N4ggeD~piJAac)qVXQ;9<>RFsS9_<)-??u1O@K zzOc%l`}mAJN5xi~k#~nzd}7I*L2ZN<%t#|(D>TC8sU<+yO7yLOZI#cWMN~hwu1$0z z^oB34jjo^B6Gr2|NzCQ&obAIN&#TI6Za}Lj^Q{5~0U4Taja_dbGz~MIZegK*;u|S# zIO0LMS^UUXMl12CPj7d3a=dURC!e;AE%j{>M{g^w;N06{gQgwk427QgtfL~b-XhG= zyRqdY1~KSmlDVD?v<)52 zIGSx^qa&B0uyT;NYSk+3y#4#NEi5cdEfPF1*-xHc-p2Fed*Qa0m2CcQFbnklCS>cK zOeH#7b2`KQ8(yNVD6>UjQ})d!yyf86-D9I0qFy%92=q{4cf7m1JHf`rhOlebt}dLy ztYc8sBw+2WoXpmnje1vEVU8}>gNl)LT8%!wxQPOjT+?ELxouT@;3HXTZ?ON~ZKFaw zUg~{ChsC&d_v-ITdS76>$z0XN3xTa&?5D>Mno~l=U?9^Msp!ne;uMvs;5b!{P6t83 z{V(c?rY;0nGTDNUWmXh2z|o^hwrk%Lx^LTL2XXfa8qO9V@4uLypc?X?d064ok{Ykx zSA-(KFFHH+LGQtzwXnFLIieoTyq;hfDxpEl-Phc3A2^*nRb^XKrV@Bx23LPY6&jO; z1@A&Dam`zXtyf@fok%4fH741vr`>ouyMleJ!}eIzx8(5(&+Ng;O;gJQ2}T&cu<*$| z@{CSij#o?JY-Z0I&;kj%)-2%70{$Cg<-mUEM72@&+H8H{-qN(q&Hyu%!EWUi%&VR4F>x3%SV+C5g^ktshO3w&V@9lT6y{$E)!(Qmm}SxXrI zCS->)#_J`Z$jDlGO}Zury!EmCU~#lnL<7BkhUZ0W!ot zr(AkxZ~TbJbGoy^mY4|?E+q@N2fQ~7e@F-zaUJ$Q-XVn@*m`)>xgLLkOJ#Y^gdZpp zPG7w`zrHC`Cnt%wQODL!jOGanS@`#jk|@h=uF2>A{;1)qqaUiDrJq7e{h5CR`YpPp zeN^7a#{eR_Hj*s2pO^2g8rE7{%T>NBQ%84SM1~=aFO{=82Q0d?i&v$L`Ab~Hug!Kj83={$Z-L@mx?L9QVbQA{GnOnU+1q-Hf$pF|7FcKgYveXr z*xdAlBSl{@Fr&$WN;6kyq)lR~{WD;I4pja#Ktu=f6hwLBHkV&74GYS8gyOKswZVd$ zzNO1H9ut$cf3wA4I9i06jnz=t8q9;=?sxPH=IE#bzvo&it_{i|E8RmqJ;4mcGwH`QLh-r1bl;C3cV{oBaz}yazW|Q! B#c}`u literal 0 HcmV?d00001 diff --git a/Textures/UI/Buttons/CE_CIWS_Skyfaller.png b/Textures/UI/Buttons/CE_CIWS_Skyfaller.png new file mode 100644 index 0000000000000000000000000000000000000000..ae8106ffc257195333fcc85e395a22efa2dee0a5 GIT binary patch literal 9600 zcmbt)2{e>#80a_qVmA92+Zb6ASwgm$v9}r(N&Pj1{F1a#O3Y#np(KiY4Mi&dByCbL zR1%pav{Q;oLM6NV_5Ydao^$WH_ntfFd}rQyzxRFKXW!mQWv}ue;%RsQ0EkOHT~|Zj z++PnC4FIqzTkpT1AGk=*^}7K;PT|)BYkL(p1pstlsVi&kzJfpyYi4E!Edpj|g@i?O zL+AUm+qP|+{W&^1vz5c?@{;U9qaldDRt35S&VK#)5w>V%dh-6z^yJ>8iHZFzG&+fF z6D8dr$T#=jut9BR7PGz?I2%7R^+59G&8${~o4Ab2HLr!v&N5}Z-qG*?^&xihXQs}#k1p;Iy}t<-ht$qOB-)f-x+MR~mp#DjrKzj` zM}jy6z}B{L5hp%i2m}J103#3%L%<;}iGu-`%L(7(ZGElH>>+rf%a3dB)Y!w(bu}{jZ14IQoVSFT8wx zeQOE|3J63ZF#(Y&WxQLl%kt$9<47cuS>MCsrXp_r4lDxkALHN)M3*j&e|`6^zE%u3 z|9U@DyL-Uc$f$|EX%p#TMqZNnoJioM0$q>8X0bCkHIt}L!|UVrzSAp_#3q%{^DF7>JLHo3XdHw${nIYq)S? zwy3AI$cX@%Oz_y`Pt*ExpYzmHjt395Dki|@pgS*3q%Xf6H*JJ8I>yZ9#gZ;l*S7Oc zED>E@6A++db5i%1Ca4cHzoIH+21*66vlg;GWmVHnQ+=afUZ^@AoIozrV&(G8%5pGn zh%(L5!B_T4e?K`pZL{-j!v@9@eAocj!Un5etNCD#V&~RIvX)a^b9LxrhA7iw(IU0H zyu4aJclV^8r{~uZ6ciK)3w$pC4|enM2jSiE8n691Du!$6LwNU?t7yx|dDf9D5_ zIRzI#t9C`eJkL?KdNMDIhAVe-x9EOazZ2b*0YH zz`J7$*2M{EMf8VE5;q_#Sd?pl<)Tr{FD~ED+QWdbdpu{%>%L&AESysZ4o;3<8u|9^ z&YCrA6yf8i3N_nWFzX3;6kAs*2kq+WN>zbu;p3B1uUJ?Anav4_iKo}CR*4!*lhWq3 zJsmQcy%c5TSIQb1%|;6slCDy7P&;1N;37^eU$)F*;N=ZPOC@pUp!&vKuj9E}y932- zqXBcOE7srN4F#qPPEc$dnfS3S>F3us0s*bv`1sMIh~e2-fY`tUZhHr?V_*@ip2`B= z+`(cW1&c>TPP6fmk!Bm2etvlY502>3Ll&5~?2<$VUrw-$^O5pY+^HY5@n*D19&8yx z5=X~UDhpsryaWEejxH#sIRz-@%`8ew%xk zb3IPBO;4V`zj2?5si~I6!j>vUSg3+N18Y-1BNfE|#=xKD%|W5bh747KeuP9l#4=xUdcIU;8Q1(K z|2cE!Zuf@|=u^Ag2Oq{yjmbOY1D{%$u(BWAnz4W(K*j|w|=_fbUwUWzp1Dr`mKk^-K=l)iyF zOR^j#5>lhFU(BVLZy`xX4ZIjP5e2U#$BX477yJQ4`HbpeO?&jh2RmL>ql#{#W6;*o zxDjOKR#u=HSrDkA^o^b=2$irIo`eJzBAiYLJYQBO5qp^dwCgSvLhpNSbyAF~PAta* zbgXM%$|i}+jgFg2rn}Zut-!vtYfip!yetN$F}QHi8lTiVhg*;}U@(id_tD>cE)T}g z1=3Sc`b*)LExz6FUT`sV|AHI;c>mO2(}w&vU9sOvrlmd?1t3Dl)PIFiD%0hx8Ce$t zH&*6`vYVY^Mvyfp2uc(vJHVJ)0}r-8t3Yegh2xKJilRp=u64YMqOVzN3xcOV- z*Ip3Zg9mVC_$WCAu~__i_s*R-ejw$R3Ef)h*lOHf2u)YL8@dlo{bm>x_!;E%S z^-suQis0!ql$yJOfx1lbwzAQ^soX2uIxDVSxiZbr*GF$wLNuv>vBYJc=rso?qbpV0 z17Y1H;3OyT||Wae6KS(4gZ<|*v7F}q&btRDlf$$LoeyGL!h%Dz61_NCG ztZoy>>-tY3VO3%Ry6mg3)YgTGr@M_|VIY@g)BrERX-8hRU9v>8`Rw02vgXJX`s!fI zZ`XReFH`U^Z3d^~FnN7{{{i0@;C{f=>Dii}@>tNEwHSV6NsGrHiHpCLCstBzrYk3v znDB2P>xo720;zWr?g!|qA)yb?W3**+5Lo*OPc3cQ`BEvhwDi2VH4#$g{o(fh|A!3K zE$7d(s0V%bM#|g_qf`&8#U|iz;}4sgn+Ye>;9t%?yLDi(C-rKULi+6H#P87iFu-N*! zAbM)|?%jgB%r!j%Eh(QF`ata|Ov{w-x^;q1yiO}t0HmN(1*_qq!-&uqPtsIPIrb!$ zW!<|XG*Y%H>>al8n~#srP~z$?>%(;&$T}5IZhN6q{HcI?^jK{xsD|Rp7$jB&z`RV% zBS%Ljt(%JAxLY{2-2a1I7Xr`@gHGB1}F`Zs3mlhK^xKU0M3MYOU+WezPzq{QJ2`$?*ik1LQ?kKfX@gP_3C_$ z1lBVk_XvlIPbp%~)8xWQN+VsJdeX*;I3G3o^$mH`bM!Z4W&Pu$*1N2EDC!Dw_)|kq zV(3SWl+2p>g-J0Qxfx7g5|5XicMR^xeLg~O6{t8czLtBKk|kS|&yqUyyWhTrt0sU} zuInl`!giDaS5!`af&0VQ7X%M8m~jpV&1E2zf$n=vP(Q#)5J*u|sdo^U5_dg4V(ONMeg$h&K?YZ6eQfB?L3|IVL-f8`wOrAJPU4aaZ3 z9h-e8cH9Dib%9x-SBg%VE|-ax(S8**PO&UL(A{xy!v(0@G=}gWBQ({EG<8I6S~)eW zarK;F&UrT$4DkN~D~B<|ik#v}mE?A90JX5+a^gnhx%) zWk)=qp3(1C1|#^)&YnzdC!3#xuO^i`4Eaxg(h184!9|Oiz@7o3@rHrdx72f8mu4~s zfS^;bP)!BHj-~6Pl4R`)C=wHL6uuWZ#2gVte|b)hj*jl`S?ITboWSZk$UPhg*Nb7F z-uw0StyzOr1zeLn^u^X<%R2(=UA(P_b{5WOD#$!r)Cx+?jbD{J?ibhZH8nLQzPyJy z1F(A_$8}E>J3eyfSBU-c4?=G*yLrv?&j`JkA^&-+J85r`GK#idT4F=7-u^t{ZA|Z{ zp=X!3f=a-MgWE|rB{cYsilC5?nc#?sIF}VG(r4d4JRS>`Vm(ts zJ@sE9|MKlf0H))%b*McdbOYg1cT15Ir_}{EcmpTZG@<(vLd78wz#cKU(vDHS0M?LJ z*_KpTqj=B0Zd#-}rJ#hPELi@@`B~|^6vL1;ryw5xUc#f7E zbtv<8In>AcVRxjDWn%Zq^oq0+76#+#2aYe!U62*J=%TbCA#}q7n}>ht$^%8a*UD;K zyj@-&>kGa_^K{kvZ4GmM3t_Ys*69JSefwY|N;9;R8ftdzgAA(>AnRD~W4v8t^OJ|) zAm;wIGoh~vU=Y)VyVkH@YdOnfvotmf!&K<+vk)48txK<043(9Q!YHd07{vL|V)R-? zVzY&sOl!7n1}?f`{IwIP-_@})K+6G1vD=?XR15%7AW0!A5h^aDWSoT(sYUJ{>tq|3 z>ezJQ?PMjVa6g`!j?!EuTM-7(?@oYk3}Lba93qIRRRXT>JoZUSJT08s8DhNgvR4jF ziY+u3n+;Q0p)Q5?|CDvz)m4+mNZSA158+P*+pZALjoWZq%xkUT)CwMWI-CS}aTV*|91;<6c-I0)mZBH^Yikk(Bqe#slkU) z)qNGXqken_t*U@pwOA3!IoZk@@yu=oOx7da)iZ)*g}l%m2Lgrnfa9HD)L-DXJR4iv zx*OE-mujmkLIv;l^`_M@f#^ezU*9@V=V1@>JcDoi%sO%nvaa9#C9c5+Mhr8K_Q!wKtmO-|= zfRRhP`!UMqbj?i@ms_w^5){a4jaqlIIK$&6a?_G)!m zCB(RTB&o9qJij-)74PC?OX|Gj-zfiptLHpi=$hE#800vT>f4B^sRKqHZ=y$m*`8f= zMN4^(eG#SojGpxf3&`kN!B&?QFL8?H>JHe{~f_a8s%^k7O5SozzNn$s&hg1FlhC$a#kvO^-O zMPT;yS%yZUEuArG90{E`kx?&N)SIQA(2s*}Xwbd<`1679N4T)(L|0#oh3X!J#faLm z#taWCTJuvPGUeGvhb|yC4n?HI$E(g|fQ%ox!9$*J-rh}9b8v8|<%3u>afVA1G`^c? zyrF6PQ#W(G81a3#ZT5zl{=1GVi2bn(LscoUcda}Ldj<{4}nqg>d>gf1O4 zQ%^ZG+p_6`VW=0Q&F3H(mUbN}bzP8_8goD7AlaNE=(-{~H5G?3bO!GS@jmM@K|0OV~gB7DW{dp!ASk=M>CtvLf8!f|ztb z=^5zh@pmbAlp{DShups6?oQ450kR|ex^1!q@L#tauxk6d$B*S-qW6uD=v_aFva=+` zASpN2ax+M8?b2zRA0?l|1&dVA6x(@iyFqfm;x z5ONYBYzE3_GgwZ*vA+@4g~2YkIrKN8Br&Vk{*fAPwJ@YaYuc5~>#B}g(7$?m9hBV! z%>MYS>O>~DmU6kkDsOLZ-`;$OE{O@E&C<+{**e`wWTN|dHFUzKRPLdeER9BEb|7$3 z2Y6;+WQ6xJYdy6Dq4^41NsUfWH{4m%)7{-YG4ftcbuBh$67x`*47!13fO{I?@Oq-pGShlBYKNdWK@r836oMOiS`)i8NT5wP+TppH>(wxe-!B$6r zuhE7Y-br2AY5PvdLYOefZVZtdvu`Y=2lC>!g#`t#n;ILjg6hK}mU3yxPuEv|0o8trwLI+siL2(^i!ewlBcSjdYvVJ%i@>#K6xM`86 zM}#(Xhdnt9RTXNGFCSD}k>(~+83q>xGv&R~7+R(>mwZ=0ri*u@yVwV+EGlZC%Q7@{ z#kZrPq9Pvh?&BOe`>Z}nR@$B}4$-gP| z?RnWR&HXBNi2WM`hep>1c%M)m-Y1Ko@8{!E*@TFexT&%1Z7nCP2)Vhr@g*fCDV3^w zNKS_0GbJU%rkQa7fFk_*FF@^6Oxbx%`6?}_DC&cpyRoEN!#CZGEIhZFO~NP-gFdSx zfuC+yCAZ@nT(rQeznAO`Y-)Z|oPx=iF_|7x85f1O$=Ylw^_RU>GWm!0ZrSqA zDLg#98Qie!Qq(XN+>J<2PoJHg8vpinZ1`O>7_iw8d}?W2_8M*VytX){e`^=7oFVbl zwE*5nvg0+|ca-YYE*kM@bNB@t0d-AhXK9U3p7a%WW(NWO6_fQhktDUO-EH>gfITl& z`d@NN%;TxRF)sCfj{-`X4bY75_Zcwz)ReOB)o9aulG&FKo`K&1`ZaFS7V{1{?xAQ2 zlQ_Thz8}VV!Q2Y96=|wWl7{}!16}Y=_PnC&CZ4!uTH*3SvH)E+kDwnY3 zGb`uA$@Btm*?9z9_YA!{M|aorYD6|dv<>r(@1@{%cJSYx1mIrc7_1 zVI?b@bSTyzwlTw&Ehdx6rDN8FBQjxlpnbE)ow~dZHwOs3$v*aSElqmng4zf+O?K-?BV;gFcf4MM zWd3E%UU16S&7sT>^L|f>ZY74s{S+q&HykyW=@%`$v)>!vUzv{Aq)_t_R~pfMk91{e zF$u>Vd|1W=+Jg~MugaEK{E?8;%5fZKu6IvZvkol%fDy(@hHluuyCSVVFp0KoIj#0W zSGddP>ogfy{3~X)>hKtCch064wq-J=T$lsNs}2Xfm+dFFNi<}MbvTsrO{2~IO^d}( z@&pKW1NnX1r+4gzA>BVD^`>gAl_kHlTpY(Rv-z>I3=eA@=X(18G}DITHr{(_ zSo?=^@4|7a%st#>rz`wBp(~qc|94`GY+?lt(6e~4d5Ony?d{FpvTFd^ikr%&%%5aN zXAcH^ctQ<#F!)8u literal 0 HcmV?d00001 From e2f286403198f61faf550651f388d2ff6446d546 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sat, 30 Nov 2024 20:49:23 +0600 Subject: [PATCH 112/127] CIWS text --- Languages/English/Keyed/Keys.xml | 6 ++++++ Languages/Russian/Keyed/Keys.xml | 6 ++++++ .../CombatExtended/Things/Building_CIWS_CE.cs | 1 + 3 files changed, 13 insertions(+) diff --git a/Languages/English/Keyed/Keys.xml b/Languages/English/Keyed/Keys.xml index c622630e75..ebac2fe8fd 100644 --- a/Languages/English/Keyed/Keys.xml +++ b/Languages/English/Keyed/Keys.xml @@ -182,5 +182,11 @@ Paste Available targets Ignored targets + Hold fire - projectiles + Ignore incoming projectiles + Hold fire - skyfallers + Ignore landing skyfallers and drop pods + Configure CIWS + Change available and ignored targets for selected CIWS \ No newline at end of file diff --git a/Languages/Russian/Keyed/Keys.xml b/Languages/Russian/Keyed/Keys.xml index 1dcabe3754..452e27bb7f 100644 --- a/Languages/Russian/Keyed/Keys.xml +++ b/Languages/Russian/Keyed/Keys.xml @@ -140,5 +140,11 @@ Вставить Доступные цели Игнорировать + Остановить огонь - снаряды + Игнорировать летящие снаряды + Остановить огонь - транспорт + Игнорировать транспорт и другие летящие объекты + Настройка ПВО + Настроить доступные и игнорируемые цели \ No newline at end of file diff --git a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs index d6c9cfffc2..5697ee00f4 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs @@ -52,6 +52,7 @@ public override IEnumerable GetGizmos() action = () => Find.WindowStack.Add(new Dialog_ManageCIWSTargets(GunCompEq.AllVerbs.OfType().SelectMany(x => x.Props.AllTargets).Distinct().ToList(), ignoredDefs)), icon = Building_CIWS_CE.icon ??= ContentFinder.Get("UI/Commands/LaunchReport"), defaultLabel = "Dialog_ManageCIWS".Translate(), + defaultDesc = "Dialog_ManageCIWSDesc".Translate() }; } From 8a2018598eed57ed1067a2a49c7919060d3fce57 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sat, 30 Nov 2024 21:04:49 +0600 Subject: [PATCH 113/127] Fixed warning --- .../CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs index 5697ee00f4..c71566b4db 100644 --- a/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs +++ b/Source/CombatExtended/CombatExtended/Things/Building_CIWS_CE.cs @@ -11,6 +11,7 @@ namespace CombatExtended { + [StaticConstructorOnStartup] public class Building_CIWS_CE : Building_Turret_MultiVerbs { #region Caching @@ -40,7 +41,7 @@ public override void ExposeData() base.ExposeData(); Scribe_Collections.Look(ref ignoredDefs, nameof(ignoredDefs)); } - static Texture2D icon; + static Texture2D icon = ContentFinder.Get("UI/Commands/LaunchReport"); public override IEnumerable GetGizmos() { foreach (var gizmo in base.GetGizmos()) @@ -50,7 +51,7 @@ public override IEnumerable GetGizmos() yield return new Command_Action() { action = () => Find.WindowStack.Add(new Dialog_ManageCIWSTargets(GunCompEq.AllVerbs.OfType().SelectMany(x => x.Props.AllTargets).Distinct().ToList(), ignoredDefs)), - icon = Building_CIWS_CE.icon ??= ContentFinder.Get("UI/Commands/LaunchReport"), + icon = icon, defaultLabel = "Dialog_ManageCIWS".Translate(), defaultDesc = "Dialog_ManageCIWSDesc".Translate() }; From 1ddbee51b0c34e94451a86f3ee9352dc6ac47c63 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sat, 30 Nov 2024 21:13:11 +0600 Subject: [PATCH 114/127] Default values for hold fire --- .../CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs | 2 ++ Source/CombatExtended/CombatExtended/Verbs/VerbCIWSSkyfaller.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs index 3c55baa83a..cbf1712b98 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSProjectile.cs @@ -39,6 +39,8 @@ public VerbProperties_CIWSProjectile() { this.verbClass = typeof(VerbCIWSProjectile); this.holdFireIcon = "UI/Buttons/CE_CIWS_Projectile"; + this.holdFireLabel = "HoldCloseInProjectilesFire"; + this.holdFireDesc = "HoldCloseInProjectilesFireDesc"; } public override bool Interceptable(ThingDef targetDef) => targetDef.projectile.speed < maximumSpeed && targetDef.projectile.flyOverhead && base.Interceptable(targetDef); public float maximumSpeed = 80; diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSSkyfaller.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSSkyfaller.cs index 52156b5600..b0a9a00923 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSSkyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWSSkyfaller.cs @@ -28,6 +28,8 @@ public VerbProperties_CIWSSkyfaller() { this.verbClass = typeof(VerbCIWSSkyfaller); this.holdFireIcon = "UI/Buttons/CE_CIWS_Skyfaller"; + this.holdFireLabel = "HoldCloseInSkyfallersFire"; + this.holdFireDesc = "HoldCloseInSkyfallersFireDesc"; } protected override IEnumerable InitAllTargets() => DefDatabase.AllDefsListForReading.Where(x => (typeof(Skyfaller).IsAssignableFrom(x.thingClass) && typeof(IActiveDropPod).IsAssignableFrom(x.thingClass))); } From fd9c0366220d58ab2fbcf6e7fc031a72bb869511 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sat, 30 Nov 2024 21:21:27 +0600 Subject: [PATCH 115/127] KPV now able to target skyfallers --- Defs/ThingDefs_Buildings/Buildings_Turrets.xml | 1 + Defs/ThingDefs_Misc/Weapons_Turrets.xml | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/Defs/ThingDefs_Buildings/Buildings_Turrets.xml b/Defs/ThingDefs_Buildings/Buildings_Turrets.xml index aa83f7c35d..d8017c28dd 100644 --- a/Defs/ThingDefs_Buildings/Buildings_Turrets.xml +++ b/Defs/ThingDefs_Buildings/Buildings_Turrets.xml @@ -258,6 +258,7 @@ Turret_KPV + CombatExtended.Building_CIWS_CE 7 Things/Building/Turrets/KPV_base diff --git a/Defs/ThingDefs_Misc/Weapons_Turrets.xml b/Defs/ThingDefs_Misc/Weapons_Turrets.xml index 93046283f5..7472215b82 100644 --- a/Defs/ThingDefs_Misc/Weapons_Turrets.xml +++ b/Defs/ThingDefs_Misc/Weapons_Turrets.xml @@ -286,6 +286,20 @@ 16 Mounted +
  • + CombatExtended.VerbCIWSSkyfaller + 1.43 + true + Bullet_145x114mm_FMJ + 0.8 + 125 + 6 + 15 + HeavyMG + GunTail_Heavy + 16 + Mounted +
  • @@ -297,6 +311,9 @@ 5 SuppressFire
  • +
  • + CombatExtended.CompVerbDisabler +
  • From dec17b4d42a8280bee39fd0312c2bed03fd2f4c8 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Sat, 30 Nov 2024 21:26:31 +0600 Subject: [PATCH 116/127] Fixed whitespaces --- .../Verbs/Verb_LaunchProjectileCE.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index 59a0a9ddce..2e060cb1b6 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -401,23 +401,23 @@ public virtual float GetTargetHeight(LocalTargetInfo target, Thing cover, bool r Apparel LegArmor = LegArmors.MaxByWithFallback(funcArmor); #endregion - #region checks for whether the pawn can penetrate armor, which armor is stronger, etc + #region checks for whether the pawn can penetrate armor, which armor is stronger, etc var TargetedBodyPartArmor = TorsoArmor; bool flagTorsoArmor = ((TorsoArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f) >= (Helmet?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0f)); - bool flag2 = (projectilePropsCE.armorPenetrationSharp >= (TorsoArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f)); - //Headshots do too little damage too often, so if the pawn can penetrate torso armor, they should aim at it - if ((flagTorsoArmor && !flag2)) - { - TargetedBodyPartArmor = Helmet; - } - //Leg armor is artificially increased in calculation so pawns will prefer headshots over leg shots even with medium strength helmets - bool flag3 = (TargetedBodyPartArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0f) >= ((LegArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0f) + 4f); - - //bool for whether the pawn can penetrate helmet - bool flag4 = (projectilePropsCE.armorPenetrationSharp >= (Helmet?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f)); + bool flag2 = (projectilePropsCE.armorPenetrationSharp >= (TorsoArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f)); + //Headshots do too little damage too often, so if the pawn can penetrate torso armor, they should aim at it + if ((flagTorsoArmor && !flag2)) + { + TargetedBodyPartArmor = Helmet; + } + //Leg armor is artificially increased in calculation so pawns will prefer headshots over leg shots even with medium strength helmets + bool flag3 = (TargetedBodyPartArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0f) >= ((LegArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0f) + 4f); + + //bool for whether the pawn can penetrate helmet + bool flag4 = (projectilePropsCE.armorPenetrationSharp >= (Helmet?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f)); //if the pawn can penetrate the helmet or torso armor there's no need to aim for legs if (flag3 && (!flag4) && (!flag2)) From 6d99b3d8315a26f622c4df4f5bf21349a2e94847 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Tue, 3 Dec 2024 00:41:51 +0600 Subject: [PATCH 117/127] TryDropThing cleanup --- .../Comps/CompCIWSImpactHandler_Skyfaller.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs index 41269ea422..18a6d66f1b 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs @@ -59,29 +59,28 @@ protected override void OnDestroying(DamageInfo dinfo) } base.OnDestroying(dinfo); } - private Thing TryDropThing(Thing thing, Map map, IntVec3 position) + private Thing TryDropThing(Thing thingToDrop, Map map, IntVec3 position) { var contents = (parent as IActiveDropPod)?.Contents; Rot4 rot = (contents?.setRotation != null) ? contents.setRotation.Value : Rot4.North; if (contents?.moveItemsAsideBeforeSpawning ?? false) { - GenSpawn.CheckMoveItemsAside(parent.Position, rot, thing.def, map); + GenSpawn.CheckMoveItemsAside(parent.Position, rot, thingToDrop.def, map); } - Thing thing2; + Thing dropedThing; if (contents?.spawnWipeMode == null) { - GenPlace.TryPlaceThing(thing, position, map, ThingPlaceMode.Near, out thing2, null, null, rot); + GenPlace.TryPlaceThing(thingToDrop, position, map, ThingPlaceMode.Near, out dropedThing, null, null, rot); } else if (contents?.setRotation != null) { - thing2 = GenSpawn.Spawn(thing, position, map, contents.setRotation.Value, contents.spawnWipeMode.Value, false, false); + dropedThing = GenSpawn.Spawn(thingToDrop, position, map, contents.setRotation.Value, contents.spawnWipeMode.Value, false, false); } else { - thing2 = GenSpawn.Spawn(thing, position, map, contents.spawnWipeMode.Value); + dropedThing = GenSpawn.Spawn(thingToDrop, position, map, contents.spawnWipeMode.Value); } - Pawn pawn = thing2 as Pawn; - if (pawn != null) + if (dropedThing is Pawn pawn) { if (pawn.RaceProps.Humanlike) { @@ -91,7 +90,7 @@ private Thing TryDropThing(Thing thing, Map map, IntVec3 position) }); } } - return thing2; + return dropedThing; } } } From 945b9f15cb09c348182e756849c9b0566aded9f1 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Tue, 3 Dec 2024 00:42:33 +0600 Subject: [PATCH 118/127] Another cleanup --- .../Comps/CompCIWSImpactHandler_Skyfaller.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs index 18a6d66f1b..d7fd56f364 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs @@ -80,15 +80,12 @@ private Thing TryDropThing(Thing thingToDrop, Map map, IntVec3 position) { dropedThing = GenSpawn.Spawn(thingToDrop, position, map, contents.spawnWipeMode.Value); } - if (dropedThing is Pawn pawn) + if (dropedThing is Pawn pawn && pawn.RaceProps.Humanlike) { - if (pawn.RaceProps.Humanlike) + TaleRecorder.RecordTale(TaleDefOf.LandedInPod, new object[] { - TaleRecorder.RecordTale(TaleDefOf.LandedInPod, new object[] - { - pawn - }); - } + pawn + }); } return dropedThing; } From 373edb09930b99e45083d79a25b0d8d5cb8cb2a2 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Tue, 3 Dec 2024 00:50:16 +0600 Subject: [PATCH 119/127] typo --- .../Comps/CompCIWSImpactHandler_Skyfaller.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs index d7fd56f364..9669b87242 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompCIWSImpactHandler_Skyfaller.cs @@ -67,27 +67,27 @@ private Thing TryDropThing(Thing thingToDrop, Map map, IntVec3 position) { GenSpawn.CheckMoveItemsAside(parent.Position, rot, thingToDrop.def, map); } - Thing dropedThing; + Thing droppedThing; if (contents?.spawnWipeMode == null) { - GenPlace.TryPlaceThing(thingToDrop, position, map, ThingPlaceMode.Near, out dropedThing, null, null, rot); + GenPlace.TryPlaceThing(thingToDrop, position, map, ThingPlaceMode.Near, out droppedThing, null, null, rot); } else if (contents?.setRotation != null) { - dropedThing = GenSpawn.Spawn(thingToDrop, position, map, contents.setRotation.Value, contents.spawnWipeMode.Value, false, false); + droppedThing = GenSpawn.Spawn(thingToDrop, position, map, contents.setRotation.Value, contents.spawnWipeMode.Value, false, false); } else { - dropedThing = GenSpawn.Spawn(thingToDrop, position, map, contents.spawnWipeMode.Value); + droppedThing = GenSpawn.Spawn(thingToDrop, position, map, contents.spawnWipeMode.Value); } - if (dropedThing is Pawn pawn && pawn.RaceProps.Humanlike) + if (droppedThing is Pawn pawn && pawn.RaceProps.Humanlike) { TaleRecorder.RecordTale(TaleDefOf.LandedInPod, new object[] { pawn }); } - return dropedThing; + return droppedThing; } } } From ab5151acbb1ea5175d0717333ea79dcd829ed2a4 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 4 Dec 2024 00:39:28 +0600 Subject: [PATCH 120/127] convert -> cast --- Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs index 4932c9bd21..3258eb460a 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs @@ -21,7 +21,7 @@ public abstract class VerbCIWS : Verb_ShootCE, ITargetSearcher, IVerbDisableable public virtual bool HoldFire { get; set; } - public VerbProperties_CIWS Props => verbProps as VerbProperties_CIWS; + public VerbProperties_CIWS Props => (VerbProperties_CIWS)verbProps; public virtual string HoldFireLabel => Props.holdFireLabel; public virtual string HoldFireDesc => Props.holdFireDesc; public Building_CIWS_CE Turret => Caster as Building_CIWS_CE; From db11cc091fa64ecacc0c038da6e881c9ba57d1fa Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 4 Dec 2024 00:40:43 +0600 Subject: [PATCH 121/127] Variable names --- Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs index 3258eb460a..d93303017e 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs @@ -163,14 +163,14 @@ public override bool TryFindNewTarget(out LocalTargetInfo target) { return false; } - float num = verb.verbProps.EffectiveMinRange(t, this.Caster); + float minRange = verb.verbProps.EffectiveMinRange(t, this.Caster); if (!verb.TryFindCEShootLineFromTo(Caster.Position, t, out var shootLine, out var targetPos)) { return false; } var intersectionPoint = shootLine.Dest; - float num2 = intersectionPoint.DistanceToSquared(Caster.Position); - return num2 > num * num && num2 < range * range; + float distToSqr = intersectionPoint.DistanceToSquared(Caster.Position); + return distToSqr > minRange * minRange && distToSqr < range * range; }); if (_target != null) { From ea5b0068b4cfc343caa812f1c88b5f56772f2d7a Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 4 Dec 2024 00:50:22 +0600 Subject: [PATCH 122/127] Created MidBurst property --- Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs | 2 +- .../CombatExtended/Verbs/Verb_LaunchProjectileCE.cs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs index d93303017e..fbbef8bc5d 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/VerbCIWS.cs @@ -206,7 +206,7 @@ public override bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ resultingLine = new ShootLine(Shooter.Position, new IntVec3((int)targetPos.x, (int)y, (int)targetPos.z)); return true; } - var midBurst = numShotsFired > 0; + var midBurst = MidBurst; var ticksToSkip = (Caster as Building_TurretGunCE)?.CurrentTarget.IsValid ?? CurrentTarget.IsValid ? this.BurstWarmupTicksLeft : VerbPropsCE.warmupTime.SecondsToTicks(); var instant = projectilePropsCE.isInstant; if (instant) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index 2e060cb1b6..208d0ab05d 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -468,7 +468,9 @@ public virtual float GetTargetHeight(LocalTargetInfo target, Thing cover, bool r } return targetHeight; } - protected virtual bool LockRotationAndAngle => numShotsFired > 0; + public bool MidBurst => numShotsFired > 0; + protected virtual bool LockRotationAndAngle => MidBurst; + public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalOnly = false, bool isInstant = false, bool midBurst = false) { ShiftTarget(report, report.target.Thing?.TrueCenter() ?? report.target.Cell.ToVector3Shifted(), calculateMechanicalOnly, isInstant); From 22060a6f06dcf74de01a7e26081bd6f5ddb2abdb Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 4 Dec 2024 00:51:16 +0600 Subject: [PATCH 123/127] Removed unused param --- .../CombatExtended/Verbs/Verb_LaunchProjectileCE.cs | 2 +- Source/SOS2Compat/SOS2Compat/Verb_ShootShipCE.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index 208d0ab05d..e84e1d76aa 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -471,7 +471,7 @@ public virtual float GetTargetHeight(LocalTargetInfo target, Thing cover, bool r public bool MidBurst => numShotsFired > 0; protected virtual bool LockRotationAndAngle => MidBurst; - public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalOnly = false, bool isInstant = false, bool midBurst = false) + public void ShiftTarget(ShiftVecReport report, bool calculateMechanicalOnly = false, bool isInstant = false) { ShiftTarget(report, report.target.Thing?.TrueCenter() ?? report.target.Cell.ToVector3Shifted(), calculateMechanicalOnly, isInstant); } diff --git a/Source/SOS2Compat/SOS2Compat/Verb_ShootShipCE.cs b/Source/SOS2Compat/SOS2Compat/Verb_ShootShipCE.cs index 8e9aa3f1bc..5d0ab0d9aa 100644 --- a/Source/SOS2Compat/SOS2Compat/Verb_ShootShipCE.cs +++ b/Source/SOS2Compat/SOS2Compat/Verb_ShootShipCE.cs @@ -163,7 +163,7 @@ public override bool TryCastShot() projectileCE = (ShipProjectileCE)ThingMaker.MakeThing(Projectile, null); } GenSpawn.Spawn(projectileCE, shootLine.Source, caster.Map); - ShiftTarget(report, pelletMechanicsOnly, instant, midBurst); + ShiftTarget(report, pelletMechanicsOnly, instant); //New aiming algorithm projectileCE.canTargetSelf = false; From 87e172ff7cb5b2bbc3d05c2817a3d8913accce80 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 4 Dec 2024 00:54:52 +0600 Subject: [PATCH 124/127] Moved new properties to other properties --- .../CombatExtended/Verbs/Verb_LaunchProjectileCE.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index e84e1d76aa..ec837daba3 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -218,6 +218,9 @@ protected LightingTracker LightingTracker } } + public bool MidBurst => numShotsFired > 0; + protected virtual bool LockRotationAndAngle => MidBurst; + #endregion #region Methods @@ -468,8 +471,6 @@ public virtual float GetTargetHeight(LocalTargetInfo target, Thing cover, bool r } return targetHeight; } - public bool MidBurst => numShotsFired > 0; - protected virtual bool LockRotationAndAngle => MidBurst; public void ShiftTarget(ShiftVecReport report, bool calculateMechanicalOnly = false, bool isInstant = false) { From 87d2cf3fcffafca867a70f781e7e464dea06e688 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 4 Dec 2024 01:06:15 +0600 Subject: [PATCH 125/127] Moved comments --- .../Verbs/Verb_LaunchProjectileCE.cs | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index ec837daba3..8add7d3355 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -984,14 +984,23 @@ public override bool TryStartCastOn(LocalTargetInfo castTarg, LocalTargetInfo de protected virtual bool KeepBurstOnNoShootLine(bool suppressing, out ShootLine shootLine) { + // 1: Interruptible -> stop shooting + // 2: Not interruptible -> continue shooting at last position (do *not* shoot at target position as it will play badly with skip or other teleport effects) + // 3: Suppressing fire -> set our shoot line and continue + // 4: else -> stop + // Target missing + // Mid burst + // 5: Interruptible -> stop shooting + // 6: Not interruptible -> shoot along previous line + // 7: else -> stop shootLine = (ShootLine)lastShootLine; - if (LockRotationAndAngle) // Case 2,3,6,7 + if (LockRotationAndAngle) // Case 1,2,5,6 { - if (VerbPropsCE.interruptibleBurst && !suppressing) // Case 2, 6 + if (VerbPropsCE.interruptibleBurst && !suppressing) // Case 1, 5 { return false; } - // Case 3, 7 + // Case 2, 6 if (lastShootLine == null) { return false; @@ -1000,9 +1009,9 @@ protected virtual bool KeepBurstOnNoShootLine(bool suppressing, out ShootLine sh currentTarget = new LocalTargetInfo(lastTargetPos); lastExactPos = lastTargetPos.ToVector3Shifted(); } - else // case 4,5,8 + else // case 3,4,7 { - if (suppressing) // case 4,5 + if (suppressing) // case 3,4 { if (currentTarget.IsValid && !currentTarget.ThingDestroyed) { @@ -1040,21 +1049,13 @@ public override bool TryCastShot() // Cannot hit target // Target exists // Mid burst - // 2: Interruptible -> stop shooting - // 3: Not interruptible -> continue shooting at last position (do *not* shoot at target position as it will play badly with skip or other teleport effects) - // 4: Suppressing fire -> set our shoot line and continue - // 5: else -> stop - // Target missing - // Mid burst - // 6: Interruptible -> stop shooting - // 7: Not interruptible -> shoot along previous line - // 8: else -> stop + // 2: Check if we should continue shooting if (TryFindCEShootLineFromTo(caster.Position, currentTarget, out var shootLine, out var targetLoc)) // Case 1 { lastShootLine = shootLine; lastExactPos = targetLoc; } - else // We cannot hit the current target + else // Case 2. We cannot hit the current target, check if we should continue shooting { if (!KeepBurstOnNoShootLine(suppressing, out shootLine)) { From c6173091e83d90522373fc06f702219435045be5 Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 4 Dec 2024 01:07:47 +0600 Subject: [PATCH 126/127] Cleanup --- .../CombatExtended/Verbs/Verb_LaunchProjectileCE.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs index 8add7d3355..c8f9e679ab 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs @@ -1055,12 +1055,9 @@ public override bool TryCastShot() lastShootLine = shootLine; lastExactPos = targetLoc; } - else // Case 2. We cannot hit the current target, check if we should continue shooting + else if (!KeepBurstOnNoShootLine(suppressing, out shootLine))// Case 2. We cannot hit the current target, check if we should continue shooting { - if (!KeepBurstOnNoShootLine(suppressing, out shootLine)) - { - return false; - } + return false; } if (projectilePropsCE.pelletCount < 1) { From 9cc2ed926eff7af31b8c40382950de40d098a33f Mon Sep 17 00:00:00 2001 From: MaxDorob Date: Wed, 4 Dec 2024 01:17:48 +0600 Subject: [PATCH 127/127] Removed linq --- .../CombatExtended/Comps/CompVerbDisabler.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Source/CombatExtended/CombatExtended/Comps/CompVerbDisabler.cs b/Source/CombatExtended/CombatExtended/Comps/CompVerbDisabler.cs index 53a0199a01..eac14a7382 100644 --- a/Source/CombatExtended/CombatExtended/Comps/CompVerbDisabler.cs +++ b/Source/CombatExtended/CombatExtended/Comps/CompVerbDisabler.cs @@ -16,18 +16,22 @@ public override IEnumerable CompGetGizmosExtra() { yield return gizmo; } - var verbs = parent.GetComp()?.AllVerbs.OfType(); + var verbs = parent.GetComp()?.AllVerbs; if (verbs != null) { foreach (var verb in verbs) { + if (!(verb is IVerbDisableable disableableVerb)) + { + continue; + } var command = new Command_Toggle() { - defaultDesc = verb.HoldFireDesc.Translate(), - defaultLabel = verb.HoldFireLabel.Translate(), - icon = verb.HoldFireIcon, - isActive = () => verb.HoldFire, - toggleAction = () => verb.HoldFire = !verb.HoldFire, + defaultDesc = disableableVerb.HoldFireDesc.Translate(), + defaultLabel = disableableVerb.HoldFireLabel.Translate(), + icon = disableableVerb.HoldFireIcon, + isActive = () => disableableVerb.HoldFire, + toggleAction = () => disableableVerb.HoldFire = !disableableVerb.HoldFire, }; yield return command;