Ejemplo n.º 1
0
        bool IsBlockedBy(Actor self, Actor otherActor, Actor ignoreActor, BlockedByActor check, CellFlag cellFlag)
        {
            if (otherActor == ignoreActor)
            {
                return(false);
            }

            // If the check allows: We are not blocked by units that we can force to move out of the way.
            if (check <= BlockedByActor.Immovable && cellFlag.HasCellFlag(CellFlag.HasMovableActor) &&
                self.Owner.Stances[otherActor.Owner] == Stance.Ally)
            {
                var mobile = otherActor.TraitOrDefault <Mobile>();
                if (mobile != null && !mobile.IsTraitDisabled && !mobile.IsTraitPaused && !mobile.IsImmovable)
                {
                    return(false);
                }
            }

            // If the check allows: we are not blocked by moving units.
            if (check <= BlockedByActor.Stationary && cellFlag.HasCellFlag(CellFlag.HasMovingActor) &&
                IsMoving(self, otherActor))
            {
                return(false);
            }

            if (cellFlag.HasCellFlag(CellFlag.HasTemporaryBlocker))
            {
                // If there is a temporary blocker in our path, but we can remove it, we are not blocked.
                var temporaryBlocker = otherActor.TraitOrDefault <ITemporaryBlocker>();
                if (temporaryBlocker != null && temporaryBlocker.CanRemoveBlockage(otherActor, self))
                {
                    return(false);
                }
            }

            // If we cannot crush the other actor in our way, we are blocked.
            if (!cellFlag.HasCellFlag(CellFlag.HasCrushableActor) || Info.Crushes.IsEmpty)
            {
                return(true);
            }

            // If the other actor in our way cannot be crushed, we are blocked.
            // PERF: Avoid LINQ.
            var crushables = otherActor.TraitsImplementing <ICrushable>();

            foreach (var crushable in crushables)
            {
                if (crushable.CrushableBy(otherActor, self, Info.Crushes))
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 2
0
        bool IsBlockedBy(Actor self, Actor otherActor, Actor ignoreActor, CellConditions check, CellFlag cellFlag)
        {
            if (otherActor == ignoreActor)
            {
                return(false);
            }

            // If the check allows: we are not blocked by allied units moving in our direction.
            if (!check.HasCellCondition(CellConditions.BlockedByMovers) && cellFlag.HasCellFlag(CellFlag.HasMovingActor) &&
                self.Owner.Stances[otherActor.Owner] == Stance.Ally &&
                IsMovingInMyDirection(self, otherActor))
            {
                return(false);
            }

            if (cellFlag.HasCellFlag(CellFlag.HasTemporaryBlocker))
            {
                // If there is a temporary blocker in our path, but we can remove it, we are not blocked.
                var temporaryBlocker = otherActor.TraitOrDefault <ITemporaryBlocker>();
                if (temporaryBlocker != null && temporaryBlocker.CanRemoveBlockage(otherActor, self))
                {
                    return(false);
                }
            }

            if (!cellFlag.HasCellFlag(CellFlag.HasCrushableActor))
            {
                return(true);
            }

            // If we cannot crush the other actor in our way, we are blocked.
            if (Info.Crushes.IsEmpty)
            {
                return(true);
            }

            // If the other actor in our way cannot be crushed, we are blocked.
            // PERF: Avoid LINQ.
            var crushables = otherActor.TraitsImplementing <ICrushable>();

            foreach (var crushable in crushables)
            {
                if (crushable.CrushableBy(otherActor, self, Info.Crushes))
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 3
0
        bool IsBlockedBy(Actor actor, Actor otherActor, Actor ignoreActor, CPos cell, BlockedByActor check, CellFlag cellFlag)
        {
            if (otherActor == ignoreActor)
            {
                return(false);
            }

            // If the check allows: We are not blocked by units that we can force to move out of the way.
            if (check <= BlockedByActor.Immovable && cellFlag.HasCellFlag(CellFlag.HasMovableActor) &&
                actor.Owner.RelationshipWith(otherActor.Owner) == PlayerRelationship.Ally)
            {
                var mobile = otherActor.OccupiesSpace as Mobile;
                if (mobile != null && !mobile.IsTraitDisabled && !mobile.IsTraitPaused && !mobile.IsImmovable)
                {
                    return(false);
                }
            }

            // If the check allows: we are not blocked by moving units.
            if (check <= BlockedByActor.Stationary && cellFlag.HasCellFlag(CellFlag.HasMovingActor) &&
                IsMoving(actor, otherActor))
            {
                return(false);
            }

            if (cellFlag.HasCellFlag(CellFlag.HasTemporaryBlocker))
            {
                // If there is a temporary blocker in our path, but we can remove it, we are not blocked.
                var temporaryBlocker = otherActor.TraitOrDefault <ITemporaryBlocker>();
                if (temporaryBlocker != null && temporaryBlocker.CanRemoveBlockage(otherActor, actor))
                {
                    return(false);
                }
            }

            if (cellFlag.HasCellFlag(CellFlag.HasTransitOnlyActor))
            {
                // Transit only tiles should not block movement
                var building = otherActor.OccupiesSpace as Building;
                if (building != null && building.TransitOnlyCells().Contains(cell))
                {
                    return(false);
                }
            }

            // If we cannot crush the other actor in our way, we are blocked.
            if (!cellFlag.HasCellFlag(CellFlag.HasCrushableActor) || Info.Crushes.IsEmpty)
            {
                return(true);
            }

            // If the other actor in our way cannot be crushed, we are blocked.
            // PERF: Avoid LINQ.
            var crushables = otherActor.TraitsImplementing <ICrushable>();

            foreach (var crushable in crushables)
            {
                if (crushable.CrushableBy(otherActor, actor, Info.Crushes))
                {
                    return(false);
                }
            }

            return(true);
        }