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); }
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); }
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); }