예제 #1
0
        private bool TryCollideWithRoof(IntVec3 cell)
        {
            if (!cell.Roofed(Map))
            {
                return(false);
            }

            var bounds = CE_Utility.GetBoundsFor(cell, cell.GetRoof(Map));

            float dist;

            if (!bounds.IntersectRay(ShotLine, out dist))
            {
                return(false);
            }
            if (dist * dist > ExactMinusLastPos.sqrMagnitude)
            {
                return(false);
            }

            var point = ShotLine.GetPoint(dist);

            ExactPosition = point;
            landed        = true;

            if (DebugViewSettings.drawInterceptChecks)
            {
                MoteMaker.ThrowText(cell.ToVector3Shifted(), Map, "x", Color.red);
            }

            Impact(null);
            return(true);
        }
예제 #2
0
        /// <summary>
        /// Tries to impact the thing based on whether it intersects the given flight path. Trees have RNG chance to not collide even on intersection.
        /// </summary>
        /// <param name="thing">What to impact</param>
        /// <returns>True if impact occured, false otherwise</returns>
        private bool TryCollideWith(Thing thing)
        {
            if (thing == launcher && !canTargetSelf)
            {
                return(false);
            }

            var   bounds = CE_Utility.GetBoundsFor(thing);
            float dist;

            if (!bounds.IntersectRay(ShotLine, out dist))
            {
                return(false);
            }
            if (dist * dist > ExactMinusLastPos.sqrMagnitude)
            {
                return(false);
            }

            // Trees and bushes have RNG chance to collide
            var plant = thing as Plant;

            if (plant != null)
            {
                //TODO: Remove fillPercent dependency because all fillPercents on trees are 0.25
                //Prevents trees near the shooter (e.g the shooter's cover) to be hit
                float chance = thing.def.fillPercent * ((thing.Position - OriginIV3).LengthHorizontal / 40);
                if (Controller.settings.DebugShowTreeCollisionChance)
                {
                    MoteMaker.ThrowText(thing.Position.ToVector3Shifted(), thing.Map, chance.ToString());
                }
                if (!Rand.Chance(chance))
                {
                    return(false);
                }
            }

            var point = ShotLine.GetPoint(dist);

            if (!point.InBounds(this.Map))
            {
                Log.Error("TryCollideWith out of bounds point from ShotLine: obj " + thing.ThingID + ", proj " + this.ThingID + ", dist " + dist + ", point " + point);
            }

            ExactPosition = point;
            landed        = true;

            if (DebugViewSettings.drawInterceptChecks)
            {
                MoteMaker.ThrowText(thing.Position.ToVector3Shifted(), thing.Map, "x", Color.red);
            }

            Impact(thing);
            return(true);
        }
예제 #3
0
        /// <summary>
        /// Tries to impact the thing based on whether it intersects the given flight path. Trees have RNG chance to not collide even on intersection.
        /// </summary>
        /// <param name="thing">What to impact</param>
        /// <returns>True if impact occured, false otherwise</returns>
        private bool TryCollideWith(Thing thing)
        {
            if (thing == launcher && !canTargetSelf)
            {
                return(false);
            }

            var bounds = CE_Utility.GetBoundsFor(thing);

            if (!bounds.IntersectRay(ShotLine, out var dist))
            {
                return(false);
            }
            if (dist * dist > ExactMinusLastPos.sqrMagnitude)
            {
                return(false);
            }

            // Trees and bushes have RNG chance to collide
            if (thing is Plant)
            {
                //Prevents trees near the shooter (e.g the shooter's cover) to be hit
                var accuracyFactor = def.projectile.alwaysFreeIntercept ? 1 : (thing.Position - OriginIV3).LengthHorizontal / 40 * AccuracyFactor;
                var chance         = thing.def.fillPercent * accuracyFactor;
                if (Controller.settings.DebugShowTreeCollisionChance)
                {
                    MoteMaker.ThrowText(thing.Position.ToVector3Shifted(), thing.Map, chance.ToString());
                }
                if (!Rand.Chance(chance))
                {
                    return(false);
                }
            }

            var point = ShotLine.GetPoint(dist);

            if (!point.InBounds(Map))
            {
                Log.Error("TryCollideWith out of bounds point from ShotLine: obj " + thing.ThingID + ", proj " + ThingID + ", dist " + dist + ", point " + point);
            }

            ExactPosition = point;
            landed        = true;

            if (Controller.settings.DebugDrawInterceptChecks)
            {
                MoteMaker.ThrowText(thing.Position.ToVector3Shifted(), thing.Map, "x", Color.red);
            }

            Impact(thing);
            return(true);
        }
예제 #4
0
        /// <summary>
        /// Tries to impact the thing based on whether it intersects the given flight path. Trees have RNG chance to not collide even on intersection.
        /// </summary>
        /// <param name="thing">What to impact</param>
        /// <returns>True if impact occured, false otherwise</returns>
        private bool TryCollideWith(Thing thing)
        {
            if (thing == launcher && !canTargetSelf)
            {
                return(false);
            }

            var   bounds = CE_Utility.GetBoundsFor(thing);
            float dist;

            if (!bounds.IntersectRay(ShotLine, out dist))
            {
                return(false);
            }
            if (dist * dist > ExactMinusLastPos.sqrMagnitude)
            {
                return(false);
            }

            // Trees and bushes have RNG chance to collide
            var plant = thing as Plant;

            if (plant != null)
            {
                //TODO: Remove fillPercent dependency because all fillPercents on trees are 0.25
                //Prevents trees near the shooter (e.g the shooter's cover) to be hit

                //Dependence to catch the tree from armorPenetration. Large calibers have less chance.
                var   propsCE               = def.projectile as ProjectilePropertiesCE;
                float penetrationAmount     = propsCE == null ? 0.1f : propsCE.armorPenetration;                            //Every projectile, which not use flyoverhead, require armorPenetration stat for calculating collision.
                float penetrationmultiplier = Mathf.Clamp(((thing.def.fillPercent * 3.2f) - penetrationAmount), 0.05f, 1f); // 2.5-3.5 good values for 0.20-0.30 fillpercent.
                float rangemultiplier       = ((thing.Position - OriginIV3).LengthHorizontal / 15);                         // 10-20 is fine for prevent to shoot near tree.
                float chance = penetrationmultiplier * (rangemultiplier < 1f ? rangemultiplier : 1f);                       // when projectile reach 15 cells distance, we set limit for multiplier bcs chances to hit greatly increased.
                if (Controller.settings.DebugShowTreeCollisionChance)
                {
                    MoteMaker.ThrowText(thing.Position.ToVector3Shifted(), thing.Map, chance.ToString());
                }
                if (!Rand.Chance(chance))
                {
                    return(false);
                }
            }

            var point = ShotLine.GetPoint(dist);

            if (!point.InBounds(this.Map))
            {
                Log.Error("TryCollideWith out of bounds point from ShotLine: obj " + thing.ThingID + ", proj " + this.ThingID + ", dist " + dist + ", point " + point);
            }

            ExactPosition = point;

            if (intendedTarget != null)
            {
                var fulldistance         = (intendedTarget.Position - OriginIV3).LengthHorizontalSquared;
                var traveleddistance     = (thing.Position - OriginIV3).LengthHorizontalSquared;
                var requireddisttotarget = fulldistance - traveleddistance;
                if (thing is Building && thing.def.fillPercent > 0.5f)
                {
                    //    Log.Message("fulldist: " + fulldistance.ToString() + " traveled: " + traveleddistance.ToString() + " required: " + requireddisttotarget.ToString());
                    if (traveleddistance < requireddisttotarget)
                    {
                        return(false);
                    }
                }
            }

            landed = true;

            //    if (Controller.settings.DebugDrawInterceptChecks) MoteMaker.ThrowText(thing.Position.ToVector3Shifted(), thing.Map, "x", Color.red);

            Impact(thing);
            return(true);
        }