public override void DoImpact(WPos pos, Actor firedBy, IEnumerable <int> damageModifiers) { var world = firedBy.World; var resLayer = world.WorldActor.Trait <RadioactivityLayer>(); if (world.LocalPlayer != null) { var devMode = world.LocalPlayer.PlayerActor.TraitOrDefault <DeveloperMode>(); if (devMode != null && devMode.ShowCombatGeometry) { WDist[] rng = Exts.MakeArray(Range.Length, i => WDist.FromCells(Range[i])); world.WorldActor.Trait <WarheadDebugOverlay>().AddImpact(pos, rng, DebugOverlayColor); } } // Accumulate radiation var targetTile = world.Map.CellContaining(pos); //for (var i = Range.Length-1; i >=0; i--) for (var i = 0; i < Range.Length; i++) { // Find affected cells, from outer Range down to inner range. var affectedCells = world.Map.FindTilesInAnnulus(targetTile, 0, Range[i]); var ra_layer = world.WorldActor.Trait <RadioactivityLayer>(); foreach (var cell in affectedCells) { var foff = FalloffDifference[i]; IncreaseRALevel(cell, foff, ra_layer); } } }
public void Tick(Actor self) { if (CurrentDelay++ < info.Delay || !info.AutoTarget || !self.IsIdle) { return; } var pr = self.Owner.PlayerActor.Trait <PlayerResources>(); var targets = self.World.FindActorsInCircle(self.CenterPosition, WDist.FromCells(info.Range)).ToArray(); var allowed = targets.Where(a => a.IsInWorld && !a.IsDead && a.TraitOrDefault <Building>() == null && a.TraitOrDefault <Health>() != null && (a.Location - self.Location).Length < info.Range && a.TraitOrDefault <Health>().HP < a.TraitOrDefault <Health>().MaxHP && a.Owner.IsAlliedWith(self.Owner) && pr.Cash + pr.Resources >= info.Ammount && a.TraitOrDefault <DungeonsAndDragonsStats>() != null && a.Info.TraitInfo <DungeonsAndDragonsStatsInfo>().Attributes.Contains("alive") ); if (allowed.Any()) { self.World.IssueOrder(new Order("HealTarget", self, Target.FromActor(allowed.ClosestTo(self)), false)); } }
void TryToRushAttack() { var allEnemyBaseBuilder = FindEnemyConstructionYards(); var ownUnits = activeUnits .Where(unit => unit.IsIdle && unit.Info.HasTraitInfo <AttackBaseInfo>() && !unit.Info.HasTraitInfo <AircraftInfo>() && !unit.Info.HasTraitInfo <HarvesterInfo>()).ToList(); if (!allEnemyBaseBuilder.Any() || (ownUnits.Count < Info.SquadSize)) { return; } foreach (var b in allEnemyBaseBuilder) { var enemies = World.FindActorsInCircle(b.CenterPosition, WDist.FromCells(Info.RushAttackScanRadius)) .Where(unit => Player.Stances[unit.Owner] == Stance.Enemy && unit.Info.HasTraitInfo <AttackBaseInfo>()).ToList(); if (AttackOrFleeFuzzy.Rush.CanAttack(ownUnits, enemies)) { var target = enemies.Any() ? enemies.Random(Random) : b; var rush = GetSquadOfType(SquadType.Rush); if (rush == null) { rush = RegisterNewSquad(SquadType.Rush, target); } foreach (var a3 in ownUnits) { rush.Units.Add(a3); } return; } } }
void IResolveOrder.ResolveOrder(Actor self, Order order) { if (IsTraitDisabled) { return; } if (order.OrderString == "Move") { var cell = self.World.Map.Clamp(this.self.World.Map.CellContaining(order.Target.CenterPosition)); if (!Info.LocomotorInfo.MoveIntoShroud && !self.Owner.Shroud.IsExplored(cell)) { return; } if (!order.Queued) { self.CancelActivity(); } self.SetTargetLine(Target.FromCell(self.World, cell), Color.Green); self.QueueActivity(order.Queued, new Move(self, cell, WDist.FromCells(8), null, true)); } if (order.OrderString == "Stop") { self.CancelActivity(); } if (order.OrderString == "Scatter") { Nudge(self, self, true); } }
bool IdleArmyGather(HashSet <Actor> army, Actor self, CPos location, int locationRad) { var check = true; if (!army.Any()) { return(true); } if (location == CPos.Zero) { return(false); } foreach (var vari in army) { if (vari != null && !vari.IsDead && vari.IsInWorld && vari.IsIdle && (vari.CenterPosition - self.World.Map.CenterOfCell(location)).LengthSquared > WDist.FromCells(locationRad).LengthSquared&& vari.Info.HasTraitInfo <IMoveInfo>()) { var moveto = vari.TraitOrDefault <IMove>(); var randloc = new CVec(self.World.SharedRandom.Next(locationRad / 2, locationRad / 2), self.World.SharedRandom.Next(locationRad / 2, locationRad / 2)); vari.CancelActivity(); vari.QueueActivity(new AttackMoveActivity(vari, moveto.MoveTo(location + randloc, 4))); check = false; } else if (vari != null && (vari.CenterPosition - self.World.Map.CenterOfCell(location)).LengthSquared > WDist.FromCells(locationRad).LengthSquared) { check = false; } } return(check); }
public Target ScanForTarget(Actor self, bool allowMove, bool allowTurn) { if (nextScanTime <= 0 && ActiveAttackBases.Any()) { nextScanTime = self.World.SharedRandom.Next(Info.MinimumScanTimeInterval, Info.MaximumScanTimeInterval); foreach (var dat in disableAutoTarget) { if (dat.DisableAutoTarget(self)) { return(Target.Invalid); } } foreach (var ab in ActiveAttackBases) { // If we can't attack right now, there's no need to try and find a target. var attackStances = ab.UnforcedAttackTargetStances(); if (attackStances != OpenRA.Traits.Stance.None) { var range = Info.ScanRadius > 0 ? WDist.FromCells(Info.ScanRadius) : ab.GetMaximumRange(); return(ChooseTarget(self, ab, attackStances, range, allowMove, allowTurn)); } } } return(Target.Invalid); }
public Actor FindNewDeerstand() { var deerStands = world.ActorsHavingTrait <ISeedableResource>().Where(a => hackyAIInfo.UndeadCommonNames.PrayableDeerStands.Contains(a.Info.Name)).ToList(); if (!deerStands.Any()) { return(null); } var closestDeerStands = deerStands.OrderBy(a => (a.CenterPosition - Player.World.Map.CenterOfCell(hackyAI.InitialBaseCenter)).LengthSquared); foreach (var stand in closestDeerStands) { var prayer = world.FindActorsInCircle(stand.CenterPosition, WDist.FromCells(4)).Where(a => { return(a.Owner == Player && hackyAIInfo.UndeadCommonNames.PrayableDeerStands.Contains(a.Info.Name)); }).Count(); if (prayer >= 3) { continue; } return(stand); } return(null); }
public override void DoImpact(WPos pos, Actor firedBy, IEnumerable <int> damageModifiers) { var world = firedBy.World; if (world.LocalPlayer != null) { var devMode = world.LocalPlayer.PlayerActor.TraitOrDefault <DebugVisualizations>(); if (devMode != null && devMode.CombatGeometry) { var range = Exts.MakeArray(Range.Length, i => WDist.FromCells(Range[i].Length)); world.WorldActor.Trait <WarheadDebugOverlay>().AddImpact(pos, range, DebugOverlayColor); } } var targetTile = world.Map.CellContaining(pos); for (var i = 0; i < Range.Length; i++) { var affectedCells = world.Map.FindTilesInCircle(targetTile, (int)Math.Ceiling((decimal)Range[i].Length / 1024)); var raLayer = world.WorldActor.TraitsImplementing <TintedCellsLayer>() .First(l => l.Info.Name == LayerName); foreach (var cell in affectedCells) { int mul = GetIntensityFalloff((pos - world.Map.CenterOfCell(cell)).Length); IncreaseTintedCellLevel(cell, mul, Falloff[i], raLayer); } } }
WDist GetScanRange(Actor self, AttackBase[] atbs) { WDist range = WDist.Zero; // Get max value of autotarget scan range. var autoTargets = self.TraitsImplementing <AutoTarget>().Where(a => !a.IsTraitDisabled).ToArray(); foreach (var at in autoTargets) { var r = at.Info.ScanRadius; if (r > range.Length) { range = WDist.FromCells(r); } } // Get maxrange weapon. foreach (var atb in atbs) { var r = atb.GetMaximumRange(); if (r.Length > range.Length) { range = r; } } return(range); }
protected virtual bool ShouldFlee(Squad squad, Func <IEnumerable <Actor>, bool> flee) { if (!squad.IsValid) { return(false); } var u = squad.Units.Random(squad.Random); var units = squad.World.FindActorsInCircle(u.CenterPosition, WDist.FromCells(DangerRadius)).ToList(); var ownBaseBuildingAround = units.Where(unit => unit.Owner == squad.Bot.Player && unit.Info.HasTraitInfo <BuildingInfo>()); if (ownBaseBuildingAround.Any()) { return(false); } var enemyAroundUnit = units.Where(unit => squad.Bot.Player.Stances[unit.Owner] == Stance.Enemy && unit.Info.HasTraitInfo <AttackBaseInfo>()); if (!enemyAroundUnit.Any()) { return(false); } return(flee(enemyAroundUnit)); }
public IEnumerable <IRenderable> RenderAfterWorld(WorldRenderer wr) { if (!self.Owner.IsAlliedWith(self.World.RenderPlayer)) { yield break; } var jamsMissiles = self.Info.Traits.GetOrDefault <JamsMissilesInfo>(); if (jamsMissiles != null) { yield return(new RangeCircleRenderable( self.CenterPosition, WDist.FromCells(jamsMissiles.Range), 0, Color.FromArgb(128, Color.Red), Color.FromArgb(96, Color.Black))); } var jamsRadar = self.Info.Traits.GetOrDefault <JamsRadarInfo>(); if (jamsRadar != null) { yield return(new RangeCircleRenderable( self.CenterPosition, WDist.FromCells(jamsRadar.Range), 0, Color.FromArgb(128, Color.Blue), Color.FromArgb(96, Color.Black))); } }
public void AfterTransform(Actor toActor) { if (order != null && toActor != null && !toActor.IsDead && toActor.IsInWorld) { toActor.QueueActivity(new Move(toActor, order.TargetLocation, WDist.FromCells(2), null, true)); } }
public void ResolveOrder(Actor self, Order order) { if (order.OrderString == "Move") { var loc = self.World.Map.Clamp(order.TargetLocation); if (!Info.MoveIntoShroud && !self.Owner.Shroud.IsExplored(loc)) { return; } if (!order.Queued) { self.CancelActivity(); } TicksBeforePathing = AverageTicksBeforePathing + self.World.SharedRandom.Next(-SpreadTicksBeforePathing, SpreadTicksBeforePathing); self.SetTargetLine(Target.FromCell(self.World, loc), Color.Green); self.QueueActivity(order.Queued, new Move(self, loc, WDist.FromCells(8), null, true)); } if (order.OrderString == "Stop") { self.CancelActivity(); } if (order.OrderString == "Scatter") { Nudge(self, self, true); } }
void IResolveOrder.ResolveOrder(Actor self, Order order) { if (IsTraitDisabled) { return; } if (order.OrderString == "Move") { var cell = self.World.Map.Clamp(this.self.World.Map.CellContaining(order.Target.CenterPosition)); if (!Info.LocomotorInfo.MoveIntoShroud && !self.Owner.Shroud.IsExplored(cell)) { return; } self.QueueActivity(order.Queued, WrapMove(new Move(self, cell, WDist.FromCells(8), null, true, Color.Green))); self.ShowTargetLines(); } // TODO: This should only cancel activities queued by this trait else if (order.OrderString == "Stop") { self.CancelActivity(); } else if (order.OrderString == "Scatter") { Nudge(self); } }
void IResolveOrder.ResolveOrder(Actor self, Order order) { if (order.OrderString == "Move") { var loc = self.World.Map.Clamp(order.TargetLocation); if (!Info.LocomotorInfo.MoveIntoShroud && !self.Owner.Shroud.IsExplored(loc)) { return; } if (!order.Queued) { self.CancelActivity(); } self.SetTargetLine(Target.FromCell(self.World, loc), Color.Green); self.QueueActivity(order.Queued, new Move(self, loc, WDist.FromCells(8), null, true)); } if (order.OrderString == "Stop") { self.CancelActivity(); } if (order.OrderString == "Scatter") { Nudge(self, self, true); } }
public Actor PossibleActor(Actor self, HashSet <Actor> AlreadyUsed, HashSet <string> ValidList) { // Find all Actors within the range, and filter thier Type and if they r taken var possibles = self.World.FindActorsInCircle(self.CenterPosition, WDist.FromCells(info.FindRadius)) .Where(a => { if (a == self) { return(false); } if (a.Owner != self.Owner) { return(false); } if (FactoriesGet(self, a)) { return(false); } if (FreeSpawnable(self, a)) { return(false); } if (AlreadyUsed.Contains(a)) { return(false); } if (ValidList.Count > 0) { if (ValidList.Contains(a.Info.Name)) { return(true); } } else { if (info.TrainingActors.Contains(a.Info.Name)) { return(true); } } return(false); }); // TODO: change to smalles path var closest = possibles.ClosestTo(self); if (closest != null) { return(closest); } return(null); }
public void GuardTarget(Actor self, Target target) { self.SetTargetLine(target, Color.Yellow); var range = WDist.FromCells(target.Actor.Info.Traits.Get <GuardableInfo>().Range); self.QueueActivity(false, new AttackMoveActivity(self, self.Trait <IMove>().MoveFollow(self, target, WDist.Zero, range))); }
void IResolveOrder.ResolveOrder(Actor self, Order order) { var os = order.OrderString; if (os != "BuildUnitPlaceBuilding") { return; } self.World.AddFrameEndTask(w => { var targetActor = w.GetActorById(order.ExtraData); if (targetActor == null || targetActor.IsDead) { return; } var actorInfo = self.World.Map.Rules.Actors[order.TargetString]; var queue = targetActor.TraitsImplementing <BuilderUnit>() .FirstOrDefault(q => q.CanBuild(actorInfo)); if (queue == null) { return; } var producer = queue.MostLikelyProducer(); var faction = producer.Trait != null ? producer.Trait.Faction : self.Owner.Faction.InternalName; var buildingInfo = actorInfo.TraitInfo <BuildingInfo>(); var buildableInfo = actorInfo.TraitInfoOrDefault <BuildableInfo>(); if (buildableInfo != null && buildableInfo.ForceFaction != null) { faction = buildableInfo.ForceFaction; } if (!self.World.CanPlaceBuilding(order.ExtraLocation, actorInfo, buildingInfo, targetActor)) { return; } if (!order.Queued) { targetActor.CancelActivity(); } var cell = self.World.Map.Clamp(self.World.Map.CellContaining(order.Target.CenterPosition)); // Make the actor move to the location var moveActivity = new Move(targetActor, cell, WDist.FromCells(1), null, true, Primitives.Color.Green); var buildActivity = new BuildOnSite(w, targetActor, order, faction, buildingInfo); targetActor.QueueActivity(moveActivity); targetActor.ShowTargetLines(); targetActor.QueueActivity(buildActivity); }); }
public void Tick(SquadCA owner) { if (!owner.IsValid) { return; } // rescan target to prevent being ambushed and die without fight // return to AttackMove state for formation var teamLeader = owner.Units.ClosestTo(owner.TargetActor.CenterPosition); if (teamLeader == null) { return; } var teamTail = owner.Units.MaxByOrDefault(a => (a.CenterPosition - owner.TargetActor.CenterPosition).LengthSquared); var attackScanRadius = WDist.FromCells(owner.SquadManager.Info.AttackScanRadius); var cannotRetaliate = false; var targetActor = ThreatScan(owner, teamLeader, attackScanRadius) ?? ThreatScan(owner, teamTail, attackScanRadius); if (targetActor == null) { owner.TargetActor = null; owner.FuzzyStateMachine.ChangeState(owner, new GroundUnitsAttackMoveState(), true); return; } else { cannotRetaliate = true; owner.TargetActor = targetActor; foreach (var a in owner.Units) { if (!BusyAttack(a)) { if (CanAttackTarget(a, targetActor)) { owner.Bot.QueueOrder(new Order("Attack", a, Target.FromActor(owner.TargetActor), false)); cannotRetaliate = false; } else { owner.Bot.QueueOrder(new Order("AttackMove", a, Target.FromCell(owner.World, teamLeader.Location), false)); } } else { cannotRetaliate = false; } } } if (ShouldFlee(owner) || cannotRetaliate) { owner.FuzzyStateMachine.ChangeState(owner, new GroundUnitsFleeState(), true); return; } }
public void Tick(SquadCA owner) { var cannotRetaliate = false; // Basic check if (!owner.IsValid) { return; } TeamLeader = owner.Units.FirstOrDefault(); if (TeamLeader == null) { return; } // Rescan target to prevent being ambushed and die without fight // If there is no threat around, return to AttackMove state for formation var attackScanRadius = WDist.FromCells(owner.SquadManager.Info.AttackScanRadius); var targetActor = ThreatScan(owner, TeamLeader, attackScanRadius); if (targetActor == null) { owner.TargetActor = GetRandomValuableTarget(owner); owner.FuzzyStateMachine.ChangeState(owner, new GroundUnitsAttackMoveState(), true); return; } else { cannotRetaliate = true; owner.TargetActor = targetActor; foreach (var a in owner.Units) { if (!BusyAttack(a)) { if (CanAttackTarget(a, targetActor)) { owner.Bot.QueueOrder(new Order("Attack", a, Target.FromActor(owner.TargetActor), false)); cannotRetaliate = false; } else { owner.Bot.QueueOrder(new Order("AttackMove", a, Target.FromCell(owner.World, TeamLeader.Location), false)); } } else { cannotRetaliate = false; } } } if (ShouldFlee(owner) || cannotRetaliate) { owner.FuzzyStateMachine.ChangeState(owner, new GroundUnitsFleeState(), true); } }
void Move(Actor self, Actor targetActor) { if ((self.CenterPosition - targetActor.CenterPosition).LengthSquared > WDist.FromCells(4).LengthSquared) { var cells = self.World.Map.FindTilesInCircle(targetActor.Location, 4, false); var move = self.TraitOrDefault <IMove>(); self.QueueActivity(new AttackMoveActivity(self, move.MoveTo(self.ClosestCell(cells), 5))); } }
public Activity MoveToTarget(Actor self, Target target) { if (IsPlane) { return(new Fly(self, target, WDist.FromCells(3), WDist.FromCells(5))); } return(Util.SequenceActivities(new HeliFly(self, target), new Turn(self, Info.InitialFacing))); }
void INotifyDeployComplete.FinishedUndeploy(Actor self) { allowKicks = false; // Interrupt harvesters and order them to follow me. foreach (var se in SlaveEntries) { se.SpawnerSlave.Stop(se.Actor); se.Actor.QueueActivity(new Follow(se.Actor, Target.FromActor(self), WDist.FromCells(1), WDist.FromCells(3), null)); } }
public void UnloadPassengers(CPos?cell = null, int unloadRange = 5) { if (cell.HasValue) { var destination = Target.FromCell(Self.World, cell.Value); Self.QueueActivity(new UnloadCargo(Self, destination, WDist.FromCells(unloadRange))); } else { Self.QueueActivity(new UnloadCargo(Self, WDist.FromCells(unloadRange))); } }
public static Target ResolveFrozenActorOrder(this Actor self, Order order, Color targetLine) { // Not targeting a frozen actor if (order.ExtraData == 0) { return(Target.FromOrder(self.World, order)); } // Targeted an actor under the fog var frozenLayer = self.Owner.PlayerActor.TraitOrDefault <FrozenActorLayer>(); if (frozenLayer == null) { return(Target.Invalid); } var frozen = frozenLayer.FromID(order.ExtraData); if (frozen == null) { return(Target.Invalid); } // Flashes the frozen proxy self.SetTargetLine(frozen, targetLine, true); // Target is still alive - resolve the real order if (frozen.Actor != null && frozen.Actor.IsInWorld) { return(Target.FromActor(frozen.Actor)); } if (!order.Queued) { self.CancelActivity(); } var move = self.TraitOrDefault <IMove>(); if (move != null) { // Move within sight range of the frozen actor var range = self.TraitsImplementing <RevealsShroud>() .Where(s => !s.IsTraitDisabled) .Select(s => s.Range) .Append(WDist.FromCells(2)) .Max(); self.QueueActivity(move.MoveWithinRange(Target.FromPos(frozen.CenterPosition), range)); } return(Target.Invalid); }
public override void Activate(Actor self, Order order, SupportPowerManager manager) { base.Activate(self, order, manager); if (info.Actor != null) { self.World.AddFrameEndTask(w => { dics = new List <TypeDictionary>(); var location = order.Target.CenterPosition; PlayLaunchSounds(); //Game.Sound.Play(SoundType.World, info.DeploySound, location); var victimActors = w.FindActorsInCircle(location, WDist.FromCells(10)); if (victimActors != null) { foreach (Actor victimActor in victimActors) { if (!victimActor.IsDead && victimActor.TraitsImplementing <WithInfantryBody>().Count() > 0 && !excludeActors.Contains(victimActor.Info.Name)) { WPos victimPos = victimActor.CenterPosition; if (!string.IsNullOrEmpty(info.EffectSequence) && !string.IsNullOrEmpty(info.EffectPalette)) { string palette = null; if (info.EffectPalette == "player") { palette = "player" + self.Owner.InternalName; } else { palette = info.EffectPalette; } w.Add(new SpriteEffect(victimPos, w, victimActor.Info.Name, info.EffectSequence, palette)); } CPos pos = victimActor.World.Map.CellContaining(victimActor.CenterPosition); dics.Add(new TypeDictionary { new CenterPositionInit(victimPos), new LocationInit(pos), new OwnerInit(self.Owner), new FacingInit(128) }); victimActor.Kill(self); } } delay = 105; } }); } }
public Activity MoveToTarget(Actor self, Target target, WPos?initialTargetPosition = null, Color?targetLineColor = null) { if (!Info.CanHover) { return(new Fly(self, target, WDist.FromCells(3), WDist.FromCells(5), initialTargetPosition, targetLineColor)); } return(ActivityUtils.SequenceActivities(self, new HeliFly(self, target, initialTargetPosition, targetLineColor), new Turn(self, Info.InitialFacing))); }
public Actor ScanForTarget(Actor self, Actor currentTarget) { if (nextScanTime <= 0) { var range = info.ScanRadius > 0 ? WDist.FromCells(info.ScanRadius) : attack.GetMaximumRange(); if (self.IsIdle || currentTarget == null || !Target.FromActor(currentTarget).IsInRange(self.CenterPosition, range)) { return(ChooseTarget(self, range)); } } return(currentTarget); }
public void Attacking(Actor self, Target target, Armament a, Barrel barrel) { if (a.Info.Name != info.ArmamentName) { return; } switch (info.ArmamentType) { case WeaponType.Range: var actors = self.World.FindActorsInCircle(self.CenterPosition, WDist.FromCells(info.ArmamentRange)); foreach (var actor in actors) { var external = actor.TraitsImplementing <ExternalCondition>() .FirstOrDefault(t => t.Info.Condition == info.Condition && t.CanGrantCondition(actor, self)); if (external != null) { external.GrantCondition(actor, self, info.EffectDuration); } } break; case WeaponType.Single: var thisVictimExternal = target.Actor.TraitsImplementing <ExternalCondition>() .FirstOrDefault(t => t.Info.Condition == info.Condition && t.CanGrantCondition(target.Actor, self)); if (thisVictimExternal != null) { thisVictimExternal.GrantCondition(target.Actor, self, info.EffectDuration); } switch (info.DamageRangeType) { case DamageRangeType.Target: var victimActors = self.World.FindActorsInCircle(target.Actor.CenterPosition, WDist.FromCells(info.DamageRange)); foreach (var actor in victimActors) { var victimExternal = actor.TraitsImplementing <ExternalCondition>() .FirstOrDefault(t => t.Info.Condition == info.Condition && t.CanGrantCondition(actor, self)); if (victimExternal != null) { victimExternal.GrantCondition(actor, self, info.EffectDuration); } } break; } break; } }
public Actor ScanForTarget(Actor self, Actor currentTarget, bool allowMove) { if (nextScanTime <= 0) { var range = info.ScanRadius > 0 ? WDist.FromCells(info.ScanRadius) : attack.GetMaximumRange(); if (self.IsIdle || currentTarget == null || !Target.FromActor(currentTarget).IsInRange(self.CenterPosition, range)) { nextScanTime = self.World.SharedRandom.Next(info.MinimumScanTimeInterval, info.MaximumScanTimeInterval); return(ChooseTarget(self, range, allowMove)); } } return(currentTarget); }