Exemplo n.º 1
0
        //Modified collision with downed pawns
        private void ImpactSomething()
        {
            if (BlockerRegistry.ImpactSomethingCallback(this, launcher))
            {
                this.Destroy();
                return;
            }
            var pos = ExactPosition.ToIntVec3();

            //Not modified, just mortar code
            if (def.projectile.flyOverhead)
            {
                var roofDef = Map.roofGrid.RoofAt(pos);
                if (roofDef != null)
                {
                    if (roofDef.isThickRoof)
                    {
                        def.projectile.soundHitThickRoof.PlayOneShot(new TargetInfo(pos, Map));
                        Destroy();
                        return;
                    }
                    if (pos.GetEdifice(Map) == null || pos.GetEdifice(Map).def.Fillage != FillCategory.Full)
                    {
                        RoofCollapserImmediate.DropRoofInCells(pos, Map);
                    }
                }
            }

            // FIXME : Early opt-out
            Thing thing = pos.GetFirstPawn(Map);

            if (thing != null && TryCollideWith(thing))
            {
                return;
            }

            var list = Map.thingGrid.ThingsListAt(pos).Where(t => t is Pawn || t.def.Fillage != FillCategory.None).ToList();

            if (list.Count > 0)
            {
                foreach (var thing2 in list)
                {
                    if (TryCollideWith(thing2))
                    {
                        return;
                    }
                }
            }

            ExactPosition = ExactPosition;
            landed        = true;
            Impact(null);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Checks whether a collision occurs along flight path within this cell.
        /// </summary>
        /// <param name="cell">Where to check for collisions in</param>
        /// <returns>True if collision occured, false otherwise</returns>
        private bool CheckCellForCollision(IntVec3 cell)
        {
            if (BlockerRegistry.CheckCellForCollisionCallback(this, cell, launcher))
            {
                this.ticksToImpact = 0;
                this.landed        = true;

                this.Impact(null);
                return(true);
            }
            var roofChecked    = false;
            var justWallsRoofs = false;

            //Check for minimum PAWN collision distance
            float distFromOrigin = cell.DistanceToSquared(OriginIV3);
            bool  skipCollision  = !def.projectile.alwaysFreeIntercept &&
                                   (minCollisionSqr <= 1f
                    ? distFromOrigin < 1f
                    : distFromOrigin <= Mathf.Min(144f, minCollisionSqr / 4));

            var mainThingList = new List <Thing>(Map.thingGrid.ThingsListAtFast(cell))
                                .Where(t => justWallsRoofs ? t.def.Fillage == FillCategory.Full : (t is Pawn || t.def.Fillage != FillCategory.None)).ToList();

            //Find pawns in adjacent cells and append them to main list
            if (!justWallsRoofs)
            {
                var adjList = new List <IntVec3>();
                adjList.AddRange(GenAdj.CellsAdjacentCardinal(cell, Rot4.FromAngleFlat(shotRotation), new IntVec2(collisionCheckSize, 0)).ToList());

                //Iterate through adjacent cells and find all the pawns
                foreach (var curCell in adjList)
                {
                    if (curCell != cell && curCell.InBounds(Map))
                    {
                        mainThingList.AddRange(Map.thingGrid.ThingsListAtFast(curCell)
                                               .Where(x => x is Pawn));

                        if (Controller.settings.DebugDrawInterceptChecks)
                        {
                            Map.debugDrawer.FlashCell(curCell, 0.7f);
                        }
                    }
                }
            }

            //If the last position is above the wallCollisionHeight, we should check for roof intersections first
            if (LastPos.y > CollisionVertical.WallCollisionHeight)
            {
                if (TryCollideWithRoof(cell))
                {
                    return(true);
                }
                roofChecked = true;
            }

            foreach (var thing in mainThingList.Distinct().OrderBy(x => (x.DrawPos - LastPos).sqrMagnitude))
            {
                if ((thing == launcher || thing == mount) && !canTargetSelf)
                {
                    continue;
                }

                // Check for collision
                if ((!skipCollision || thing == intendedTarget) && TryCollideWith(thing))
                {
                    return(true);
                }

                // Apply suppression. The height here is NOT that of the bullet in CELL,
                // it is the height at the END OF THE PATH. This is because SuppressionRadius
                // is not considered an EXACT limit.
                if (!justWallsRoofs && ExactPosition.y < SuppressionRadius)
                {
                    var pawn = thing as Pawn;
                    if (pawn != null)
                    {
                        ApplySuppression(pawn);
                    }
                }
            }

            //Finally check for intersecting with a roof (again).
            if (!roofChecked && TryCollideWithRoof(cell))
            {
                return(true);
            }
            return(false);
        }