public WVec MuzzleOffset(Actor self, Barrel b) { var bodyOrientation = coords.Value.QuantizeOrientation(self, self.Orientation); var localOffset = b.Offset + new WVec(-Recoil, WDist.Zero, WDist.Zero); if (turret.Value != null) { var turretOrientation = coords.Value.QuantizeOrientation(self, turret.Value.LocalOrientation(self)); localOffset = localOffset.Rotate(turretOrientation); localOffset += turret.Value.Offset; } return(coords.Value.LocalToWorld(localOffset.Rotate(bodyOrientation))); }
void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel) { if (IsTraitDisabled || IsTraitPaused) { return; } if (!Info.ArmamentNames.Contains(a.Info.Name)) { return; } if (Info.RevokeOnNewTarget) { if (TargetChanged(lastTarget, target)) { RevokeInstance(self, Info.RevokeAll); } lastTarget = target; } cooldown = Info.RevokeDelay; if (!Info.IsCyclic && tokens.Count >= Info.MaximumInstances) { return; } shotsFired++; var requiredShots = tokens.Count < Info.RequiredShotsPerInstance.Length ? Info.RequiredShotsPerInstance[tokens.Count] : Info.RequiredShotsPerInstance[Info.RequiredShotsPerInstance.Length - 1]; if (shotsFired >= requiredShots) { if (Info.IsCyclic && tokens.Count == Info.MaximumInstances) { RevokeInstance(self, true); } else { GrantInstance(self, Info.Condition); } shotsFired = 0; } }
protected virtual WVec CalculateMuzzleOffset(Actor self, Barrel b) { var bodyOrientation = coords.QuantizeOrientation(self, self.Orientation); var localOffset = b.Offset + new WVec(-Recoil, WDist.Zero, WDist.Zero); if (turret != null) { // WorldOrientation is quantized to satisfy the *Fudges. // Need to then convert back to a pseudo-local coordinate space, apply offsets, // then rotate back at the end var turretOrientation = turret.WorldOrientation(self) - bodyOrientation; localOffset = localOffset.Rotate(turretOrientation); localOffset += turret.Offset; } return(coords.LocalToWorld(localOffset.Rotate(bodyOrientation))); }
public void Attacking(Actor self, Target target, Armament a, Barrel barrel) { var sequence = a.Info.MuzzleSequence; if (sequence == null) { return; } if (a.Info.MuzzleSplitFacings > 0) { sequence += OpenRA.Traits.Util.QuantizeFacing(getFacing(), a.Info.MuzzleSplitFacings).ToString(); } visible[barrel] = true; anims[barrel].Animation.PlayThen(sequence, () => visible[barrel] = false); }
IEnumerable <IRenderable> RenderArmaments(Actor self, AttackBase attack) { // Fire ports on garrisonable structures var garrison = attack as AttackGarrisoned; if (garrison != null) { var bodyOrientation = coords.Value.QuantizeOrientation(self, self.Orientation); foreach (var p in garrison.Info.Ports) { var pos = self.CenterPosition + coords.Value.LocalToWorld(p.Offset.Rotate(bodyOrientation)); var da = coords.Value.LocalToWorld(new WVec(224, 0, 0).Rotate(WRot.FromYaw(p.Yaw + p.Cone)).Rotate(bodyOrientation)); var db = coords.Value.LocalToWorld(new WVec(224, 0, 0).Rotate(WRot.FromYaw(p.Yaw - p.Cone)).Rotate(bodyOrientation)); yield return(new LineAnnotationRenderable(pos, pos + da * 224 / da.Length, 1, Color.White)); yield return(new LineAnnotationRenderable(pos, pos + db * 224 / da.Length, 1, Color.White)); } yield break; } foreach (var a in attack.Armaments) { if (a.IsTraitDisabled) { continue; } foreach (var b in a.Barrels) { var barrelEnd = new Barrel { Offset = b.Offset + new WVec(224, 0, 0), Yaw = b.Yaw }; var muzzle = self.CenterPosition + a.MuzzleOffset(self, b); var endMuzzle = self.CenterPosition + a.MuzzleOffset(self, barrelEnd); yield return(new LineAnnotationRenderable(muzzle, endMuzzle, 1, Color.White)); } } }
protected virtual WVec CalculateMuzzleOffset(Actor self, Barrel b) { // Weapon offset in turret coordinates var localOffset = b.Offset + new WVec(-Recoil, WDist.Zero, WDist.Zero); // Turret coordinates to body coordinates var bodyOrientation = coords.QuantizeOrientation(self, self.Orientation); if (turret != null) { localOffset = localOffset.Rotate(turret.WorldOrientation) + turret.Offset.Rotate(bodyOrientation); } else { localOffset = localOffset.Rotate(bodyOrientation); } // Body coordinates to world coordinates return(coords.LocalToWorld(localOffset)); }
void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel) { if (IsTraitDisabled) { return; } if (!info.ArmamentNames.Contains(a.Info.Name)) { return; } var targetPlayer = GetTargetPlayer(target); if (targetPlayer != null && targetPlayer.WinState == WinState.Undefined) { self.World.AddFrameEndTask(w => w.Add(new RevealShroudEffect(self.CenterPosition, info.Radius, info.RevealGeneratedShroud ? Shroud.SourceType.Visibility : Shroud.SourceType.PassiveVisibility, targetPlayer, info.RevealForStancesRelativeToTarget, duration: info.Duration))); } }
public void Attacking(Actor self, Target target, Armament a, Barrel barrel) { --charges; timeToRecharge = info.ReloadTime; }
public void Attacking(Actor self, Target target, Armament a, Barrel barrel) { if (self.World.SharedRandom.Next(100 / info.AttackPanicChance) == 0) Panic(); }
public WRot MuzzleOrientation(Actor self, Barrel b) { return(CalculateMuzzleOrientation(self, b)); }
public WVec MuzzleOffset(Actor self, Barrel b) { return(CalculateMuzzleOffset(self, b)); }
protected virtual void FireBarrel(Actor self, IFacing facing, Target target, Barrel barrel) { foreach (var na in notifyAttacks) { na.PreparingAttack(self, target, this, barrel); } Func <WPos> muzzlePosition = () => self.CenterPosition + MuzzleOffset(self, barrel); var legacyFacing = MuzzleOrientation(self, barrel).Yaw.Angle / 4; Func <int> legacyMuzzleFacing = () => MuzzleOrientation(self, barrel).Yaw.Angle / 4; var passiveTarget = Weapon.TargetActorCenter ? target.CenterPosition : target.Positions.PositionClosestTo(muzzlePosition()); var initialOffset = Weapon.FirstBurstTargetOffset; if (initialOffset != WVec.Zero) { // We want this to match Armament.LocalOffset, so we need to convert it to forward, right, up initialOffset = new WVec(initialOffset.Y, -initialOffset.X, initialOffset.Z); passiveTarget += initialOffset.Rotate(WRot.FromFacing(legacyFacing)); } var followingOffset = Weapon.FollowingBurstTargetOffset; if (followingOffset != WVec.Zero) { // We want this to match Armament.LocalOffset, so we need to convert it to forward, right, up followingOffset = new WVec(followingOffset.Y, -followingOffset.X, followingOffset.Z); passiveTarget += ((Weapon.Burst - Burst) * followingOffset).Rotate(WRot.FromFacing(legacyFacing)); } var args = new ProjectileArgs { Weapon = Weapon, Facing = legacyFacing, CurrentMuzzleFacing = legacyMuzzleFacing, DamageModifiers = damageModifiers.ToArray(), InaccuracyModifiers = inaccuracyModifiers.ToArray(), RangeModifiers = rangeModifiers.ToArray(), Source = muzzlePosition(), CurrentSource = muzzlePosition, SourceActor = self, PassiveTarget = passiveTarget, GuidedTarget = target }; ScheduleDelayedAction(Info.FireDelay, () => { if (args.Weapon.Projectile != null) { var projectile = args.Weapon.Projectile.Create(args); if (projectile != null) { self.World.Add(projectile); } if (args.Weapon.Report != null && args.Weapon.Report.Any()) { Game.Sound.Play(SoundType.World, args.Weapon.Report, self.World, self.CenterPosition); } if (Burst == args.Weapon.Burst && args.Weapon.StartBurstReport != null && args.Weapon.StartBurstReport.Any()) { Game.Sound.Play(SoundType.World, args.Weapon.StartBurstReport, self.World, self.CenterPosition); } foreach (var na in notifyAttacks) { na.Attacking(self, target, this, barrel); } Recoil = Info.Recoil; } }); }
void INotifyAttack.PreparingAttack(Actor self, OpenRA.Traits.Target target, Armament a, Barrel barrel) { }
void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel) { ChargeLevel = 0; }
void INotifyAttack.Attacking(Actor self, Target target, Armament a, Barrel barrel) { --charges; timeToRecharge = info.ReloadDelay; }
protected virtual WRot CalculateMuzzleOrientation(Actor self, Barrel b) { return(WRot.FromYaw(b.Yaw).Rotate(turret != null ? turret.WorldOrientation : self.Orientation)); }
void INotifyAttack.PreparingAttack(Actor self, Target target, Armament a, Barrel barrel) { }
public void Attacking(Actor self, Target target, Armament a, Barrel barrel) { Attacking(self, target); }