// Enumerates all armaments, that this actor possesses, that can be used against Target t public IEnumerable <Armament> ChooseArmamentsForTarget(Target t, bool forceAttack) { // If force-fire is not used, and the target requires force-firing or the target is // terrain or invalid, no armaments can be used if (!forceAttack && (t.Type == TargetType.Terrain || t.Type == TargetType.Invalid || t.RequiresForceFire)) { return(Enumerable.Empty <Armament>()); } // Get target's owner; in case of terrain or invalid target there will be no problems // with owner == null since forceFire will have to be true in this part of the method // (short-circuiting in the logical expression below) Player owner = null; if (t.Type == TargetType.FrozenActor) { owner = t.FrozenActor.Owner; } else if (t.Type == TargetType.Actor) { owner = t.Actor.Owner; } return(Armaments.Where(a => !a.IsTraitDisabled && (owner == null || (forceAttack ? a.Info.ForceTargetStances : a.Info.TargetStances) .HasStance(self.Owner.Stances[owner])) && a.Weapon.IsValidAgainst(t, self.World, self))); }
public void Tick(Actor self) { var cp = self.CenterPosition; var bombTarget = Target.FromPos(cp - new WVec(0, 0, cp.Z)); var wasInAttackRange = inAttackRange; var wasFacingTarget = facingTarget; inAttackRange = false; var f = facing.Value.Facing; var delta = target.CenterPosition - self.CenterPosition; var facingToTarget = delta.HorizontalLengthSquared != 0 ? delta.Yaw.Facing : f; facingTarget = Math.Abs(facingToTarget - f) % 256 <= info.FacingTolerance; // Bombs drop anywhere in range foreach (var a in Armaments.Where(a => a.Info.Name == info.Bombs)) { if (!target.IsInRange(self.CenterPosition, a.MaxRange())) { continue; } inAttackRange = true; a.CheckFire(self, facing.Value, bombTarget); } // Guns only fire when approaching the target if (facingTarget) { foreach (var a in Armaments.Where(a => a.Info.Name == info.Guns)) { if (!target.IsInRange(self.CenterPosition, a.MaxRange())) { continue; } var t = Target.FromPos(cp - new WVec(0, a.MaxRange().Length / 2, cp.Z).Rotate(WRot.FromFacing(f))); inAttackRange = true; a.CheckFire(self, facing.Value, t); } } // Actors without armaments may want to trigger an action when it passes the target if (!Armaments.Any()) { inAttackRange = !wasInAttackRange && !facingTarget && wasFacingTarget; } if (inAttackRange && !wasInAttackRange) { OnEnteredAttackRange(self); } if (!inAttackRange && wasInAttackRange) { OnExitedAttackRange(self); } }
public WRange GetMinimumRange() { if (IsTraitDisabled) { return(WRange.Zero); } return(Armaments.Where(a => !a.IsTraitDisabled) .Select(a => a.Weapon.MinRange).Min()); }
public WRange GetMaximumRange() { if (IsTraitDisabled) { return(WRange.Zero); } return(Armaments.Where(a => !a.IsTraitDisabled) .Select(a => a.Weapon.Range) .Append(WRange.Zero).Max()); }
public WDist GetMaximumRange() { if (IsTraitDisabled) { return(WDist.Zero); } return(Armaments.Where(a => !a.IsTraitDisabled) .Select(a => a.MaxRange()) .Append(WDist.Zero).Max()); }
public WDist GetMinimumRange() { if (IsTraitDisabled) { return(WDist.Zero); } var min = Armaments.Where(a => !a.IsTraitDisabled) .Select(a => a.Weapon.MinRange) .Append(WDist.MaxValue).Min(); return(min != WDist.MaxValue ? min : WDist.Zero); }
public void Tick(Actor self) { var cp = self.CenterPosition; var bombTarget = Target.FromPos(cp - new WVec(0, 0, cp.Z)); var wasInAttackRange = inAttackRange; inAttackRange = false; // Bombs drop anywhere in range foreach (var a in Armaments.Where(a => a.Info.Name == info.Bombs)) { if (!target.IsInRange(self.CenterPosition, a.Weapon.Range)) { continue; } inAttackRange = true; a.CheckFire(self, facing.Value, bombTarget); } // Guns only fire when approaching the target var f = facing.Value.Facing; var facingToTarget = Util.GetFacing(target.CenterPosition - self.CenterPosition, f); if (Math.Abs(facingToTarget - f) % 256 <= info.FacingTolerance) { foreach (var a in Armaments.Where(a => a.Info.Name == info.Guns)) { if (!target.IsInRange(self.CenterPosition, a.Weapon.Range)) { continue; } var t = Target.FromPos(cp - new WVec(0, a.Weapon.Range.Range / 2, cp.Z).Rotate(WRot.FromFacing(f))); inAttackRange = true; a.CheckFire(self, facing.Value, t); } } if (inAttackRange && !wasInAttackRange) { OnEnteredAttackRange(self); } if (!inAttackRange && wasInAttackRange) { OnExitedAttackRange(self); } }
public override void Tick(Actor self) { base.Tick(self); var facing = self.TraitOrDefault <IFacing>(); var cp = self.CenterPosition; var bombTarget = Target.FromPos(cp - new WVec(0, 0, cp.Z)); // Bombs drop anywhere in range foreach (var a in Armaments.Where(a => a.Info.Name == info.Bombs)) { var range = new WRange((int)(1024 * a.Weapon.Range)); if (!target.IsInRange(self.CenterPosition, range)) { continue; } a.CheckFire(self, this, facing, bombTarget); } // Guns only fire when approaching the target var facingToTarget = Util.GetFacing(target.CenterPosition - self.CenterPosition, facing.Facing); if (Math.Abs(facingToTarget - facing.Facing) % 256 > info.FacingTolerance) { return; } foreach (var a in Armaments.Where(a => a.Info.Name == info.Guns)) { var range = new WRange((int)(1024 * a.Weapon.Range)); if (!target.IsInRange(self.CenterPosition, range)) { continue; } var t = Target.FromPos(cp - new WVec(0, range.Range / 2, cp.Z).Rotate(WRot.FromFacing(facing.Facing))); a.CheckFire(self, this, facing, t); } }
// Enumerates all armaments, that this actor possesses, that can be used against Target t public IEnumerable <Armament> ChooseArmamentsForTarget(Target t, bool forceAttack) { // If force-fire is not used, and the target requires force-firing or the target is // terrain or invalid, no armaments can be used if (!forceAttack && (t.Type == TargetType.Terrain || t.Type == TargetType.Invalid || t.RequiresForceFire)) { return(Enumerable.Empty <Armament>()); } // Get target's owner; in case of terrain or invalid target there will be no problems // with owner == null since forceFire will have to be true in this part of the method // (short-circuiting in the logical expression below) Player owner = null; if (t.Type == TargetType.FrozenActor) { owner = t.FrozenActor.Owner; } else if (t.Type == TargetType.Actor) { owner = t.Actor.EffectiveOwner != null && t.Actor.EffectiveOwner.Owner != null ? t.Actor.EffectiveOwner.Owner : t.Actor.Owner; // Special cases for spies so we don't kill friendly disguised spies // and enable dogs to kill enemy disguised spies. if (self.Owner.Stances[t.Actor.Owner] == Stance.Ally || self.Info.HasTraitInfo <IgnoresDisguiseInfo>()) { owner = t.Actor.Owner; } } return(Armaments.Where(a => !a.IsTraitDisabled && (owner == null || (forceAttack ? a.Info.ForceTargetStances : a.Info.TargetStances) .HasStance(self.Owner.Stances[owner])) && a.Weapon.IsValidAgainst(t, self.World, self))); }
/// <summary> /// 为目标挑选武器 /// </summary> /// <param name="t"></param> /// <param name="forceAttack"></param> /// <returns></returns> public IEnumerable <Armament> ChooseArmamentsForTarget(Target t, bool forceAttack) { if ((!forceAttack) && (t.Type == TargetT.Terrain || t.Type == TargetT.Invalid)) { return(Enumerable.Empty <Armament>()); } Player owner = null; if (t.Type == TargetT.FrozenActor) { owner = t.FrozenActor.Owner; } else if (t.Type == TargetT.Actor) { owner = t.Actor.EffectiveOwner != null && t.Actor.EffectiveOwner.Owner != null ? t.Actor.EffectiveOwner.Owner : t.Actor.Owner; } return(Armaments.Where(a => !a.IsTraitDisabled && (owner == null || (forceAttack ? a.Info.ForceTargetsStance:a.Info.TargetStances).HasStance(self.Owner.Stances[owner])) && a.Weapon.IsValidAgainst(t, self.World, self))); }