diff --git a/Patches/Vanilla Factions Expanded - Settlers/ThingDefs_Buildings/TurretGatlingGun.xml b/Patches/Vanilla Factions Expanded - Settlers/ThingDefs_Buildings/TurretGatlingGun.xml
index 604ae94975..e6127f76d6 100644
--- a/Patches/Vanilla Factions Expanded - Settlers/ThingDefs_Buildings/TurretGatlingGun.xml
+++ b/Patches/Vanilla Factions Expanded - Settlers/ThingDefs_Buildings/TurretGatlingGun.xml
@@ -77,8 +77,8 @@
-
- Defs/ThingDef[defName="Turret_GatlingGun"]/costList
+
+ Defs/ThingDef[defName="Turret_GatlingGun"]
325
diff --git a/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs b/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs
index 322125000f..16bf2ac8aa 100644
--- a/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs
+++ b/Source/CombatExtended/CombatExtended/Comps/CompSuppressable.cs
@@ -246,7 +246,7 @@ public void AddSuppression(float amount, IntVec3 origin)
}
public bool IgnoreSuppresion(IntVec3 origin)
{
- return BlockerRegistry.PawnUnsuppresableFromCallback(parent as Pawn, origin) || SuppressionUtility.InterceptorZonesFor((Pawn)parent).Where(x => x.Contains(parent.Position)).Any(x => !x.Contains(origin));
+ return BlockerRegistry.PawnUnsuppressableFromCallback(parent as Pawn, origin) || SuppressionUtility.InterceptorZonesFor((Pawn)parent).Where(x => x.Contains(parent.Position)).Any(x => !x.Contains(origin));
}
public override void CompTick()
diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs
index dfea34a41d..8087b71485 100644
--- a/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs
+++ b/Source/CombatExtended/CombatExtended/Projectiles/ProjectileCE.cs
@@ -28,17 +28,6 @@ public abstract class ProjectileCE : ThingWithComps
///
protected const int collisionCheckSize = 5;
- #region Kinetic Projectiles
- protected bool lerpPosition = true;
- protected bool kinit = false;
- protected float ballisticCoefficient;
- protected float mass;
- protected float radius;
- protected float gravity;
- protected Vector3 velocity;
- protected float initialSpeed;
- #endregion
-
#region Origin destination
public bool OffMapOrigin = false;
@@ -112,11 +101,7 @@ public virtual float DamageAmount
this.damageAmount = def.projectile.GetDamageAmount(weaponDamageMultiplier);
}
- if (lerpPosition)
- {
- return (float)this.damageAmount;
- }
- return ((float)this.damageAmount) * (shotSpeed * shotSpeed) / (initialSpeed * initialSpeed);
+ return (float)this.damageAmount;
}
}
@@ -139,7 +124,7 @@ public virtual float DamageAmount
#region Vanilla
public bool landed;
public int ticksToImpact;
- protected Sustainer ambientSustainer;
+ private Sustainer ambientSustainer;
#endregion
@@ -148,25 +133,33 @@ public virtual float DamageAmount
public float AccuracyFactor;
#region Height
+ protected int lastHeightTick = -1;
+ protected float heightInt = 0f;
+ ///
+ /// If lastHeightTick is not FlightTicks, Height calculates the quadratic formula (g/2)t^2 + (-v_0y)t + (y-y0) for {g -> gravity, v_0y -> shotSpeed * Mathf.Sin(shotAngle), y0 -> shotHeight, t -> seconds} to find y rounded to the nearest 3 decimals.
+ ///
+ /// If lastHeightTick equals FlightTicks, it returns a locally stored value heightInt which is the product of previous calculation.
+ ///
public virtual float Height
{
get
{
- return ExactPosition.y;
+ if (lastHeightTick != FlightTicks)
+ {
+ heightInt = ticksToImpact > 0 ? GetHeightAtTicks(FlightTicks) : 0f;
+ lastHeightTick = FlightTicks;
+ }
+ return heightInt;
}
}
#endregion
#region Ticks/Seconds
- protected float startingTicksToImpactInt = -1f;
+ float startingTicksToImpactInt = -1f;
public float StartingTicksToImpact
{
get
{
- if (!lerpPosition)
- {
- return float.MaxValue;
- }
if (startingTicksToImpactInt < 0f)
{
// Optimization in case shotHeight is zero (for example for fragments)
@@ -203,10 +196,6 @@ public int IntTicksToImpact
{
get
{
- if (!lerpPosition)
- {
- return 1;
- }
if (intTicksToImpact < 0)
{
intTicksToImpact = Mathf.CeilToInt(StartingTicksToImpact);
@@ -215,7 +204,6 @@ public int IntTicksToImpact
}
}
- private int flightTicks;
///
/// The amount of integer ticks this projectile has remained in the air for, ignoring impact.
///
@@ -223,7 +211,7 @@ public int FlightTicks
{
get
{
- return flightTicks;
+ return IntTicksToImpact - ticksToImpact;
}
}
///
@@ -248,7 +236,7 @@ protected virtual Vector2 Vec2Position(float ticks = -1f)
return Vector2.Lerp(origin, Destination, ticks / StartingTicksToImpact);
}
- private Vector3? exactPosition = null;
+ private Vector3 impactPosition = new Vector3();
///
/// Exact x,y,z (x,height,y) position in terms of Vec2Position.x, .y (lerped origin to Destination) and Height.
///
@@ -256,16 +244,17 @@ public virtual Vector3 ExactPosition
{
set
{
- exactPosition = new Vector3(value.x, value.y, value.z);
- Position = ((Vector3)exactPosition).ToIntVec3();
+ impactPosition = new Vector3(value.x, value.y, value.z);
+ Position = impactPosition.ToIntVec3();
}
get
{
- if (exactPosition == null)
+ if (landed)
{
- exactPosition = new Vector3(origin.x, shotHeight, origin.y);
+ return impactPosition;
}
- return ((Vector3)exactPosition);
+ var v = Vec2Position();
+ return new Vector3(v.x, Height, v.y);
}
}
@@ -273,7 +262,7 @@ public virtual Vector2 DrawPosV2
{
get
{
- return new Vector2(ExactPosition.x, ExactPosition.z);
+ return Vec2Position() + new Vector2(0, Height - shotHeight * ((StartingTicksToImpact - fTicks) / StartingTicksToImpact));
}
}
@@ -281,7 +270,8 @@ public override Vector3 DrawPos
{
get
{
- return ExactPosition;
+ var v = DrawPosV2;
+ return new Vector3(v.x, def.Altitude, v.y);
}
}
@@ -380,7 +370,7 @@ public virtual Quaternion ExactRotation
///
public float shotHeight = 0f;
///
- /// The assigned shot speed [cells/s] (not speed in y axis or x-z plane), in general equal to the projectile.def.speed value.
+ /// The assigned shot speed [cells/s] (not speed in z axis or x-y plane), in general equal to the projectile.def.speed value.
///
public float shotSpeed = -1f;
@@ -472,42 +462,13 @@ public override void ExposeData()
Scribe_Values.Look(ref canTargetSelf, "canTargetSelf");
Scribe_Values.Look(ref logMisses, "logMisses", true);
Scribe_Values.Look(ref castShadow, "castShadow", true);
- Scribe_Values.Look(ref lerpPosition, "lerpPosition", true);
//To fix landed grenades sl problem
- Scribe_Values.Look(ref exactPosition, "exactPosition");
+ Scribe_Values.Look(ref impactPosition, "impactPosition");
// To insure saves don't get affected..
}
#endregion
- #region Throw
- public virtual void Throw(Thing launcher, Vector3 origin, Vector3 heading, Thing equipment = null)
- {
- this.ExactPosition = origin;
- this.shotHeight = origin.y;
- this.origin = new Vector2(origin.x, origin.z);
- this.shotSpeed = Math.Max(heading.magnitude, def.projectile.speed);
- var projectileProperties = def.projectile as ProjectilePropertiesCE;
- this.castShadow = projectileProperties.castShadow;
- this.velocity = heading;
- this.launcher = launcher;
- this.equipment = equipment;
- //For explosives/bullets, equipmentDef is important
- equipmentDef = (equipment != null) ? equipment.def : null;
-
- if (!def.projectile.soundAmbient.NullOrUndefined())
- {
- var info = SoundInfo.InMap(this, MaintenanceType.PerTick);
- ambientSustainer = def.projectile.soundAmbient.TrySpawnSustainer(info);
- }
- ballisticCoefficient = projectileProperties.ballisticCoefficient.RandomInRange;
- mass = projectileProperties.mass.RandomInRange;
- radius = projectileProperties.diameter.RandomInRange / 2000; // half the diameter and mm -> m
- gravity = projectileProperties.Gravity;
- initialSpeed = shotSpeed;
- }
- #endregion
-
#region Raycast
public virtual void RayCast(Thing launcher, VerbProperties verbProps, Vector2 origin, float shotAngle, float shotRotation, float shotHeight = 0f, float shotSpeed = -1f, float spreadDegrees = 0f, float aperatureSize = 0.03f, Thing equipment = null)
{
@@ -666,7 +627,6 @@ public virtual void Launch(Thing launcher, Vector2 origin, float shotAngle, floa
if (def.projectile is ProjectilePropertiesCE props)
{
this.castShadow = props.castShadow;
- this.lerpPosition = props.lerpPosition;
}
Launch(launcher, origin, equipment);
this.ticksToImpact = IntTicksToImpact;
@@ -926,7 +886,7 @@ protected bool CheckCellForCollision(IntVec3 cell)
roofChecked = true;
}
- foreach (var thing in mainThingList.Distinct().Where(x => !(x is ProjectileCE)).OrderBy(x => (x.DrawPos - LastPos).sqrMagnitude))
+ foreach (var thing in mainThingList.Distinct().OrderBy(x => (x.DrawPos - LastPos).sqrMagnitude))
{
if ((thing == launcher || thing == mount) && !canTargetSelf)
{
@@ -1166,47 +1126,6 @@ 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;
- }
- Vector3 newPosition = curPosition + velocity;
- Accelerate();
- return newPosition;
- }
-
- // This can also be made virtual, and would be the ideal entry point for guided ammunition and rockets.
- protected void Accelerate()
- {
- 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;
- }
-
#region Tick/Draw
public override void Tick()
{
@@ -1217,18 +1136,7 @@ public override void Tick()
}
LastPos = ExactPosition;
ticksToImpact--;
- flightTicks++;
- Vector3 nextPosition;
- if (lerpPosition)
- {
- var v = Vec2Position();
- nextPosition = new Vector3(v.x, Height, v.y);
- }
- else
- {
- nextPosition = MoveForward();
- }
- if (!nextPosition.InBounds(Map))
+ if (!ExactPosition.InBounds(Map))
{
if (globalTargetInfo.IsValid)
{
@@ -1257,12 +1165,11 @@ public override void Tick()
Destroy();
return;
}
- ExactPosition = nextPosition;
if (CheckForCollisionBetween())
{
return;
}
- Position = nextPosition.ToIntVec3();
+ Position = ExactPosition.ToIntVec3();
if (globalTargetInfo.IsValid)
{
return;
@@ -1272,7 +1179,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 (ticksToImpact <= 0 || nextPosition.y <= 0f)
+ if (ticksToImpact <= 0)
{
ImpactSomething();
return;
@@ -1298,7 +1205,7 @@ public override void Tick()
}
float distToOrigin = originInt.DistanceTo(positionInt);
float dangerFactor = (def.projectile as ProjectilePropertiesCE).dangerFactor;
- if (dangerFactor > 0f && nextPosition.y < CollisionVertical.WallCollisionHeight && distToOrigin > 3)
+ if (dangerFactor > 0f && ExactPosition.y < CollisionVertical.WallCollisionHeight && distToOrigin > 3)
{
DangerTracker?.Notify_BulletAt(Position, def.projectile.damageAmountBase * dangerFactor);
}
@@ -1575,7 +1482,7 @@ public virtual void Impact(Thing hitThing)
///
/// Integer ticks, since the only time value which is not an integer (accessed by StartingTicksToImpact) has height zero by definition.
/// Projectile height at time ticks in ticks.
- private float GetHeightAtTicks(int ticks)
+ protected virtual float GetHeightAtTicks(int ticks)
{
var seconds = ((float)ticks) / GenTicks.TicksPerRealSecond;
return (float)Math.Round(shotHeight + shotSpeed * Mathf.Sin(shotAngle) * seconds - (GravityFactor * seconds * seconds) / 2f, 3);
diff --git a/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs b/Source/CombatExtended/CombatExtended/Projectiles/ProjectilePropertiesCE.cs
index 3a55f3ae30..3c42e78272 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;
@@ -31,11 +31,6 @@ public class ProjectilePropertiesCE : ProjectileProperties
public float airborneSuppressionFactor = 1;
public float dangerFactor = 1;
- public FloatRange ballisticCoefficient = new FloatRange(1f, 1f);
- public FloatRange mass = new FloatRange(1f, 1f);
- public FloatRange diameter = new FloatRange(1f, 1f);
-
- public bool lerpPosition = true;
public ThingDef detonateMoteDef;
public FleckDef detonateFleckDef;
public float detonateEffectsScaleOverride = -1;
diff --git a/Source/CombatExtended/Compatibility/BlockerRegistry.cs b/Source/CombatExtended/Compatibility/BlockerRegistry.cs
index f0f3fdf7cd..5489f34c28 100644
--- a/Source/CombatExtended/Compatibility/BlockerRegistry.cs
+++ b/Source/CombatExtended/Compatibility/BlockerRegistry.cs
@@ -21,7 +21,7 @@ public static class BlockerRegistry
private static List> checkCellForCollisionCallbacks;
private static List> impactSomethingCallbacks;
private static List> beforeCollideWithCallbacks;
- private static List> pawnUnsuppresableFromCallback;
+ private static List> pawnUnsuppressableFromCallback;
private static List>>> shieldZonesCallback;
private static void EnableCB()
@@ -47,7 +47,7 @@ private static void EnableSZ()
private static void EnablePUF()
{
enabledPUF = true;
- pawnUnsuppresableFromCallback = new List>();
+ pawnUnsuppressableFromCallback = new List>();
}
private static void EnableBCW()
{
@@ -118,7 +118,7 @@ public static void RegisterUnsuppresableFromCallback(Func f
{
EnablePUF();
}
- pawnUnsuppresableFromCallback.Add(f);
+ pawnUnsuppressableFromCallback.Add(f);
}
public static bool CheckCellForCollisionCallback(ProjectileCE projectile, IntVec3 cell, Thing launcher)
@@ -159,13 +159,13 @@ public static IEnumerable> ShieldZonesCallback(Thing thing)
}
return shieldZonesCallback.SelectMany(cb => cb(thing));
}
- public static bool PawnUnsuppresableFromCallback(Pawn pawn, IntVec3 origin)
+ public static bool PawnUnsuppressableFromCallback(Pawn pawn, IntVec3 origin)
{
if (!enabledPUF)
{
return false;
}
- foreach (var cb in pawnUnsuppresableFromCallback)
+ foreach (var cb in pawnUnsuppressableFromCallback)
{
if (cb(pawn, origin))
{