public Turreted(ActorInitializer init, TurretedInfo info) { this.info = info; turretFacing = info.InitialFacing; turretFacing = init.Contains<FacingInit>() ? init.Get<FacingInit,int>() : info.InitialFacing; facing = init.self.TraitOrDefault<IFacing>(); }
public HarvestResource(Actor self) { harv = self.Trait<Harvester>(); harvInfo = self.Info.Traits.Get<HarvesterInfo>(); facing = self.Trait<IFacing>(); territory = self.World.WorldActor.TraitOrDefault<ResourceClaimLayer>(); resLayer = self.World.WorldActor.Trait<ResourceLayer>(); }
public Contrail(Actor self, ContrailInfo info) { contrailTurret = new Turret(info.ContrailOffset); history = new ContrailHistory(info.TrailLength, info.UsePlayerColor ? ContrailHistory.ChooseColor(self) : info.Color); facing = self.Trait<IFacing>(); move = self.Trait<IMove>(); }
public HarvestResource(Actor self, int2 cell) { harv = self.Trait<Harvester>(); facing = self.Trait<IFacing>(); renderUnit = self.Trait<RenderUnit>(); resourceLayer = self.World.WorldActor.Trait<ResourceLayer>(); harvestCell = cell; }
public RenderGunboat(Actor self) : base(self, () => self.HasTrait<Turreted>() ? self.Trait<Turreted>().turretFacing : 0) { facing = self.Trait<IFacing>(); anim.Play("left"); anims.Add( "smoke", new AnimationWithOffset( new Animation( "smoke_m" ), null, () => !isSmoking ) ); }
void INotifyCreated.Created(Actor self) { facing = self.TraitOrDefault <IFacing>(); Armaments = self.TraitsImplementing <Armament>().Where(t => t.Info.Name.Contains(FireArmamentPowerInfo.ArmamentName)).ToArray(); var armamentturrets = Armaments.Select(x => x.Info.Turret).ToHashSet(); turreted = self.TraitsImplementing <Turreted>().Where(x => armamentturrets.Contains(x.Name)).Count() > 0; }
public HarvestResource(Actor self) { harv = self.Trait <Harvester>(); harvInfo = self.Info.TraitInfo <HarvesterInfo>(); facing = self.Trait <IFacing>(); body = self.Trait <BodyOrientation>(); territory = self.World.WorldActor.TraitOrDefault <ResourceClaimLayer>(); resLayer = self.World.WorldActor.Trait <ResourceLayer>(); }
protected override void Created(Actor self) { facing = self.TraitOrDefault <IFacing>(); positionable = self.TraitOrDefault <IPositionable>(); notifyAiming = self.TraitsImplementing <INotifyAiming>().ToArray(); getArmaments = InitializeGetArmaments(self); base.Created(self); }
protected override void Created(Actor self) { facing = self.TraitOrDefault <IFacing>(); building = self.TraitOrDefault <Building>(); positionable = self.TraitOrDefault <IPositionable>(); getArmaments = InitializeGetArmaments(self); base.Created(self); }
public SwallowActor(Actor self, Target target, Armament a, IFacing facing) { this.target = target; this.facing = facing; armament = a; weapon = a.Weapon; sandworm = self.Trait <Sandworm>(); positionable = self.Trait <Mobile>(); swallow = self.Trait <AttackSwallow>(); }
internal Actor(World world, string name, TypeDictionary initDict) { var init = new ActorInitializer(this, initDict); World = world; ActorID = world.NextAID(); if (initDict.Contains <OwnerInit>()) { Owner = init.Get <OwnerInit, Player>(); } if (name != null) { name = name.ToLowerInvariant(); if (!world.Map.Rules.Actors.ContainsKey(name)) { throw new NotImplementedException("No rules definition for unit " + name); } Info = world.Map.Rules.Actors[name]; foreach (var trait in Info.TraitsInConstructOrder()) { AddTrait(trait.Create(init)); // Some traits rely on properties provided by IOccupySpace in their initialization, // so we must ready it now, we cannot wait until all traits have finished construction. if (trait is IOccupySpaceInfo) { OccupiesSpace = Trait <IOccupySpace>(); } } } // PERF: Cache all these traits as soon as the actor is created. This is a fairly cheap one-off cost per // actor that allows us to provide some fast implementations of commonly used methods that are relied on by // performance-sensitive parts of the core game engine, such as pathfinding, visibility and rendering. Bounds = DetermineBounds(); VisualBounds = DetermineVisualBounds(); EffectiveOwner = TraitOrDefault <IEffectiveOwner>(); facing = TraitOrDefault <IFacing>(); health = TraitOrDefault <IHealth>(); renderModifiers = TraitsImplementing <IRenderModifier>().ToArray(); renders = TraitsImplementing <IRender>().ToArray(); disables = TraitsImplementing <IDisable>().ToArray(); visibilityModifiers = TraitsImplementing <IVisibilityModifier>().ToArray(); defaultVisibility = Trait <IDefaultVisibility>(); Targetables = TraitsImplementing <ITargetable>().ToArray(); SyncHashes = TraitsImplementing <ISync>() .Select(sync => Pair.New(sync, Sync.GetHashFunction(sync))) .ToArray() .Select(pair => new SyncHash(pair.First, pair.Second(pair.First))); }
public Attack(Actor self, Target target, WRange minRange, WRange maxRange, bool allowMovement) { Target = target; this.minRange = minRange; this.maxRange = maxRange; attack = self.Trait <AttackBase>(); facing = self.Trait <IFacing>(); move = allowMovement ? self.TraitOrDefault <IMove>() : null; }
public PickupUnit(Actor self, Actor cargo) { this.cargo = cargo; carryable = cargo.Trait <Carryable>(); cargoFacing = cargo.Trait <IFacing>(); movement = self.Trait <IMove>(); carryall = self.Trait <Carryall>(); aircraft = self.Trait <Aircraft>(); selfFacing = self.Trait <IFacing>(); state = State.Intercept; }
public RenderGunboat(Actor self) : base(self, () => self.HasTrait<Turreted>() ? self.Trait<Turreted>().turretFacing : 0) { facing = self.Trait<IFacing>(); anim.Play("left"); var wake = new Animation(anim.Name); wake.Play("left-wake"); Func<float2> offset = () => new float2(((anims["wake"].Animation.CurrentSequence.Name == "left-wake") ? 1 : -1),2); anims.Add( "wake", new AnimationWithOffset( wake, offset, () => false ) { ZOffset = -2 } ); }
public EatResource(Actor self, CPos targetcell) { harv = self.Trait <Sandworm>(); harvInfo = self.Info.TraitInfo <SandwormInfo>(); facing = self.Trait <IFacing>(); body = self.Trait <BodyOrientation>(); move = self.Trait <IMove>(); claimLayer = self.World.WorldActor.Trait <ResourceClaimLayer>(); resLayer = self.World.WorldActor.Trait <ResourceLayer>(); this.targetCell = targetcell; }
protected override void Created(Actor self) { body = self.Trait <BodyOrientation>(); facing = self.TraitOrDefault <IFacing>(); cachedFacing = facing != null ? facing.Facing : 0; cachedCell = self.World.Map.CellContaining(self.CenterPosition); previouslySpawned = false; base.Created(self); }
public Attack(Actor self, Target target, WRange minRange, WRange maxRange, bool allowMovement) { Target = target; this.minRange = minRange; this.maxRange = maxRange; attack = self.Trait<AttackBase>(); facing = self.Trait<IFacing>(); move = allowMovement ? self.TraitOrDefault<IMove>() : null; }
public PickupUnit(Actor self, Actor cargo) { this.cargo = cargo; carryable = cargo.Trait<Carryable>(); cargoFacing = cargo.Trait<IFacing>(); movement = self.Trait<IMove>(); carryall = self.Trait<Carryall>(); helicopter = self.Trait<Helicopter>(); selfFacing = self.Trait<IFacing>(); state = State.Intercept; }
protected override void Created(Actor self) { facing = self.TraitOrDefault <IFacing>(); Armaments = self.TraitsImplementing <Armament>().Where(t => t.Info.Name.Contains(FireArmamentPowerInfo.ArmamentName)).ToArray(); var armamentturrets = Armaments.Select(x => x.Info.Turret).ToHashSet(); turreted = self.TraitsImplementing <Turreted>().Where(x => armamentturrets.Contains(x.Name)).Any(); base.Created(self); }
public Attack(Actor self, Target target, bool allowMovement, bool forceAttack) { Target = target; this.forceAttack = forceAttack; attack = self.Trait<AttackBase>(); facing = self.Trait<IFacing>(); positionable = self.Trait<IPositionable>(); move = allowMovement ? self.TraitOrDefault<IMove>() : null; }
public Turn(Actor self, int desiredFacing, bool setIsMoving = false, bool isInterruptible = true) { disablable = self.TraitOrDefault <IMove>() as IDisabledTrait; facing = self.Trait <IFacing>(); this.desiredFacing = desiredFacing; this.setIsMoving = setIsMoving; IsInterruptible = isInterruptible; // This might look confusing, but the current implementation of Mobile is both IMove and IDisabledTrait, // and this way we can save a separate Mobile trait look-up. mobile = disablable as Mobile; }
public Carryall(Actor self, CarryallInfo info) { Info = info; Carryable = null; State = CarryallState.Idle; aircraftInfo = self.Info.TraitInfoOrDefault <AircraftInfo>(); body = self.Trait <BodyOrientation>(); move = self.Trait <IMove>(); facing = self.Trait <IFacing>(); }
public Attack(Actor self, Target target, bool allowMovement, bool forceAttack) { Target = target; this.forceAttack = forceAttack; attack = self.Trait <AttackBase>(); facing = self.Trait <IFacing>(); positionable = self.Trait <IPositionable>(); move = allowMovement ? self.TraitOrDefault <IMove>() : null; }
public HarvestResource(Actor self, CPos targetCell) { harv = self.Trait <Harvester>(); harvInfo = self.Info.TraitInfo <HarvesterInfo>(); facing = self.Trait <IFacing>(); body = self.Trait <BodyOrientation>(); move = self.Trait <IMove>(); claimLayer = self.World.WorldActor.Trait <ResourceClaimLayer>(); resourceLayer = self.World.WorldActor.Trait <IResourceLayer>(); this.targetCell = targetCell; notifyHarvesterActions = self.TraitsImplementing <INotifyHarvesterAction>().ToArray(); }
public PickupUnit(Actor self, Actor cargo, int delay) { this.cargo = cargo; this.delay = delay; carryable = cargo.Trait <Carryable>(); carryableFacing = cargo.Trait <IFacing>(); carryableBody = cargo.Trait <BodyOrientation>(); carryall = self.Trait <Carryall>(); ChildHasPriority = false; }
public DeliverUnit(Actor self) { carryall = self.Trait<Carryall>(); this.self = self; cargo = carryall.Carrying; movement = self.Trait<IMove>(); carryable = cargo.Trait<Carryable>(); aircraft = self.Trait<Aircraft>(); positionable = cargo.Trait<IPositionable>(); cargoFacing = cargo.Trait<IFacing>(); selfFacing = self.Trait<IFacing>(); state = State.Transport; }
float2 TurretPosition(Actor self, WorldRenderer wr, Turreted t, IFacing facing) { var recoil = self.TraitsImplementing <Armament>() .Where(w => w.Info.Turret == t.Name) .Aggregate(WRange.Zero, (a, b) => a + b.Recoil); var localOffset = new WVec(-recoil, WRange.Zero, WRange.Zero); var bodyOrientation = QuantizeOrientation(self, self.Orientation); var turretOrientation = QuantizeOrientation(self, t.LocalOrientation(self)); var worldPos = t.Position(self) + LocalToWorld(localOffset.Rotate(turretOrientation).Rotate(bodyOrientation)); return(wr.ScreenPxOffset(worldPos)); }
static PVecInt GetUnitspaceBarrelOffset(Actor self, IFacing facing, Turret turret, Barrel barrel) { var turreted = self.TraitOrDefault <Turreted>(); if (turreted == null && facing == null) { return(PVecInt.Zero); } var turretFacing = turreted != null ? turreted.turretFacing : facing.Facing; return((PVecInt)(PVecFloat)Util.RotateVectorByFacing(barrel.TurretSpaceOffset.ToFloat2(), turretFacing, .7f)); }
public WithCargo(Actor self, WithCargoInfo info) { cargo = self.Trait <Cargo>(); facing = self.TraitOrDefault <IFacing>(); cargoInfo = info; body = self.Trait <IBodyOrientation>(); if (info.LocalOffset.Length == 0) { throw new InvalidOperationException("LocalOffset must have at least one entry"); } }
public DeliverUnit(Actor self) { carryall = self.Trait <Carryall>(); this.self = self; cargo = carryall.Carrying; movement = self.Trait <IMove>(); carryable = cargo.Trait <Carryable>(); aircraft = self.Trait <Aircraft>(); positionable = cargo.Trait <IPositionable>(); cargoFacing = cargo.Trait <IFacing>(); selfFacing = self.Trait <IFacing>(); state = State.Transport; }
public Attack(Actor self, Target target, bool allowMovement, bool forceAttack, int facingTolerance) { Target = target; this.forceAttack = forceAttack; this.facingTolerance = facingTolerance; attackTraits = self.TraitsImplementing <AttackBase>().ToArray(); facing = self.Trait <IFacing>(); positionable = self.Trait <IPositionable>(); move = allowMovement ? self.TraitOrDefault <IMove>() : null; }
public PickupUnit(Actor self, Actor cargo, int delay) { this.cargo = cargo; this.delay = delay; carryable = cargo.Trait <Carryable>(); carryableFacing = cargo.Trait <IFacing>(); carryableBody = cargo.Trait <BodyOrientation>(); movement = self.Trait <IMove>(); carryall = self.Trait <Carryall>(); carryallFacing = self.Trait <IFacing>(); state = PickupState.Intercept; }
public PickupUnit(Actor self, Actor cargo, int delay) { this.cargo = cargo; this.delay = delay; carryable = cargo.Trait<Carryable>(); carryableFacing = cargo.Trait<IFacing>(); carryableBody = cargo.Trait<BodyOrientation>(); movement = self.Trait<IMove>(); carryall = self.Trait<Carryall>(); carryallFacing = self.Trait<IFacing>(); state = State.Intercept; }
public DeliverUnit(Actor self, CPos destination) { this.self = self; this.destination = destination; carryallFacing = self.Trait <IFacing>(); carryall = self.Trait <Carryall>(); body = self.Trait <BodyOrientation>(); carryable = carryall.Carryable.Trait <Carryable>(); positionable = carryall.Carryable.Trait <IPositionable>(); carryableFacing = carryall.Carryable.Trait <IFacing>(); state = DeliveryState.Transport; }
public DeliverUnit(Actor self, CPos destination) { this.self = self; this.destination = destination; carryallFacing = self.Trait<IFacing>(); carryall = self.Trait<Carryall>(); body = self.Trait<BodyOrientation>(); carryable = carryall.Carryable.Trait<Carryable>(); positionable = carryall.Carryable.Trait<IPositionable>(); carryableFacing = carryall.Carryable.Trait<IFacing>(); state = State.Transport; }
// gets the screen-space position of a barrel. public static float2 GetBarrelPosition(Actor self, IFacing facing, Turret turret, Barrel barrel) { var turreted = self.TraitOrDefault <Turreted>(); if (turreted == null && facing == null) { return(float2.Zero); } var turretFacing = turreted != null ? turreted.turretFacing : facing.Facing; return(GetTurretPosition(self, facing, turret) + barrel.ScreenSpaceOffset + Util.RotateVectorByFacing(barrel.TurretSpaceOffset, turretFacing, .7f)); }
internal Actor(World world, string name, TypeDictionary initDict) { var init = new ActorInitializer(this, initDict); World = world; ActorID = world.NextAID(); if (initDict.Contains <OwnerInit>()) { Owner = init.Get <OwnerInit, Player>(); } if (name != null) { name = name.ToLowerInvariant(); if (!world.Map.Rules.Actors.ContainsKey(name)) { throw new NotImplementedException("No rules definition for unit {0}".F(name)); } Info = world.Map.Rules.Actors[name]; foreach (var trait in Info.TraitsInConstructOrder()) { AddTrait(trait.Create(init)); if (trait is IOccupySpaceInfo) { OccupiesSpace = Trait <IOccupySpace>(); } } } EffectiveOwner = TraitOrDefault <IEffectiveOwner>(); facing = TraitOrDefault <IFacing>(); health = TraitOrDefault <IHealth>(); disables = TraitsImplementing <IDisable>().ToArray(); renders = TraitsImplementing <IRender>().ToArray(); renderModifiers = TraitsImplementing <IRenderModifier>().ToArray(); visibilityModifiers = TraitsImplementing <IVisibilityModifier>().ToArray(); defaultVisibility = Trait <IDefaultVisibility>(); Targetables = TraitsImplementing <ITargetable>().ToArray(); mouseBounds = TraitsImplementing <IMouseBounds>().ToArray(); //Bounds = DetermineBounds(); //SyncHashes = TraitsImplementing<ISync>() // .Select(sync => Pair.New(sync, Sync.GetHashFunction(sync))) // .ToArray() // .Select(pair => new SyncHash(pair.First, pair.Second(pair.First))); SyncHashes = TraitsImplementing <ISync>().Select(sync => new SyncHash(sync)).ToArray(); }
public WithGunboatBody(ActorInitializer init, WithGunboatBodyInfo info) : base(init, info, MakeTurretFacingFunc(init.Self)) { this.info = info; rs = init.Self.Trait <RenderSprites>(); facing = init.Self.Trait <IFacing>(); var name = rs.GetImage(init.Self); turret = init.Self.TraitsImplementing <Turreted>() .First(t => t.Name == info.Turret); wake = new Animation(init.World, name); wake.PlayRepeating(info.WakeLeftSequence); rs.Add(new AnimationWithOffset(wake, null, null, -87)); }
public static float2 GetTurretPosition(Actor self, IFacing facing, Turret turret) { if (facing == null) { return(turret.ScreenSpacePosition); /* things that don't have a rotating base don't need the turrets repositioned */ } var ru = self.TraitOrDefault <RenderUnit>(); var numDirs = (ru != null) ? ru.anim.CurrentSequence.Facings : 8; var bodyFacing = facing.Facing; var quantizedFacing = Util.QuantizeFacing(bodyFacing, numDirs) * (256 / numDirs); return((Util.RotateVectorByFacing(turret.UnitSpacePosition, quantizedFacing, .7f) + GetRecoil(self, turret.Recoil)) + turret.ScreenSpacePosition); }
protected override void Created(Actor self) { base.Created(self); facing = self.TraitOrDefault <IFacing>(); exits = self.Info.TraitInfos <ExitInfo>().ToArray(); // Spawn initial load. int burst = Info.InitialActorCount == -1 ? Info.Actors.Length : Info.InitialActorCount; for (int i = 0; i < burst; i++) { Replenish(self, SlaveEntries); } }
public RenderGunboat(Actor self) : base(self, () => self.HasTrait <Turreted>() ? self.Trait <Turreted>().turretFacing : 0) { facing = self.Trait <IFacing>(); anim.Play("left"); var wake = new Animation(anim.Name); wake.Play("left-wake"); Func <float2> offset = () => new float2(((anims["wake"].Animation.CurrentSequence.Name == "left-wake") ? 1 : -1), 2); anims.Add("wake", new AnimationWithOffset(wake, offset, () => false) { ZOffset = -2 }); }
internal Actor(World world, string name, TypeDictionary initDict) { var init = new ActorInitializer(this, initDict); World = world; ActorID = world.NextAID(); if (initDict.Contains <OwnerInit>()) { Owner = init.Get <OwnerInit, Player>(); } if (name != null) { name = name.ToLowerInvariant(); if (!world.Map.Rules.Actors.ContainsKey(name)) { throw new NotImplementedException("No rules definition for unit " + name); } Info = world.Map.Rules.Actors[name]; foreach (var trait in Info.TraitsInConstructOrder()) { AddTrait(trait.Create(init)); // Some traits rely on properties provided by IOccupySpace in their initialization, // so we must ready it now, we cannot wait until all traits have finished construction. if (trait is IOccupySpaceInfo) { OccupiesSpace = Trait <IOccupySpace>(); } } } Bounds = DetermineBounds(); VisualBounds = DetermineVisualBounds(); EffectiveOwner = TraitOrDefault <IEffectiveOwner>(); facing = TraitOrDefault <IFacing>(); health = TraitOrDefault <IHealth>(); renderModifiers = TraitsImplementing <IRenderModifier>().ToArray(); renders = TraitsImplementing <IRender>().ToArray(); disables = TraitsImplementing <IDisable>().ToArray(); visibilityModifiers = TraitsImplementing <IVisibilityModifier>().ToArray(); defaultVisibility = Trait <IDefaultVisibility>(); }
// gets the screen-space position of a barrel. public static PVecInt GetBarrelPosition(Actor self, IFacing facing, Turret turret, Barrel barrel) { var turreted = self.TraitOrDefault<Turreted>(); if (turreted == null && facing == null) return PVecInt.Zero; var turretFacing = turreted != null ? turreted.turretFacing : facing.Facing; return GetTurretPosition(self, facing, turret) + barrel.ScreenSpaceOffset + (PVecInt)(PVecFloat)Util.RotateVectorByFacing(barrel.TurretSpaceOffset.ToFloat2(), turretFacing, .7f); }
public GeneralProperties(ScriptContext context, Actor self) : base(context, self) { facing = self.TraitOrDefault<IFacing>(); autotarget = self.TraitOrDefault<AutoTarget>(); scriptTags = self.TraitOrDefault<ScriptTags>(); }
bool CheckFire(Actor self, IMove move, IFacing facing, Weapon w) { if (w.FireDelay > 0) return false; var limitedAmmo = self.TraitOrDefault<LimitedAmmo>(); if (limitedAmmo != null && !limitedAmmo.HasAmmo()) return false; if (w.Info.Range * w.Info.Range * Game.CellSize * Game.CellSize < (target.CenterLocation - self.CenterLocation).LengthSquared) return false; if (!w.IsValidAgainst(target)) return false; var barrel = w.Barrels[w.Burst % w.Barrels.Length]; var destMove = target.IsActor ? target.Actor.TraitOrDefault<IMove>() : null; var args = new ProjectileArgs { weapon = w.Info, firedBy = self, target = this.target, src = (self.CenterLocation + Combat.GetTurretPosition(self, facing, w.Turret) + Combat.GetBarrelPosition(self, facing, w.Turret, barrel)).ToInt2(), srcAltitude = move != null ? move.Altitude : 0, dest = target.CenterLocation.ToInt2(), destAltitude = destMove != null ? destMove.Altitude : 0, facing = barrel.Facing + (self.HasTrait<Turreted>() ? self.Trait<Turreted>().turretFacing : facing != null ? facing.Facing : Util.GetFacing(target.CenterLocation - self.CenterLocation, 0)), firepowerModifier = self.TraitsImplementing<IFirepowerModifier>() .Select(a => a.GetFirepowerModifier()) .Product() }; ScheduleDelayedAction( FireDelay( self, self.Info.Traits.Get<AttackBaseInfo>() ), () => { if (args.weapon.Projectile != null) { var projectile = args.weapon.Projectile.Create(args); if (projectile != null) self.World.Add(projectile); if (!string.IsNullOrEmpty(args.weapon.Report)) Sound.Play(args.weapon.Report + ".aud", self.CenterLocation); } }); foreach (var na in self.TraitsImplementing<INotifyAttack>()) na.Attacking(self); return true; }
public Turreted(ActorInitializer init, TurretedInfo info) { this.info = info; turretFacing = GetInitialTurretFacing(init, info.InitialFacing); facing = init.self.TraitOrDefault<IFacing>(); }
// gets the screen-space position of a barrel. public static PVecInt GetBarrelPosition(Actor self, IFacing facing, Turret turret, Barrel barrel) { return GetTurretPosition(self, facing, turret) + barrel.ScreenSpaceOffset + GetUnitspaceBarrelOffset(self, facing, turret, barrel); }
static PVecInt GetUnitspaceBarrelOffset(Actor self, IFacing facing, Turret turret, Barrel barrel) { var turreted = self.TraitOrDefault<Turreted>(); if (turreted == null && facing == null) return PVecInt.Zero; var turretFacing = turreted != null ? turreted.turretFacing : facing.Facing; return (PVecInt)(PVecFloat)Util.RotateVectorByFacing(barrel.TurretSpaceOffset.ToFloat2(), turretFacing, .7f); }
public GeneralProperties(Actor self) : base(self) { facing = self.TraitOrDefault<IFacing>(); autotarget = self.TraitOrDefault<AutoTarget>(); }
void INotifyCreated.Created(Actor self) { facing = self.TraitOrDefault<IFacing>(); Armaments = self.TraitsImplementing<Armament>().Where(t => t.Info.Name.Contains(FireArmamentPowerInfo.ArmamentName)).ToArray(); }
public void CheckFire(Actor self, AttackBase attack, IMove move, IFacing facing, Target target) { if (FireDelay > 0) return; var limitedAmmo = self.TraitOrDefault<LimitedAmmo>(); if (limitedAmmo != null && !limitedAmmo.HasAmmo()) return; if (!Combat.IsInRange(self.CenterLocation, Info.Range, target)) return; if (Combat.IsInRange(self.CenterLocation, Info.MinRange, target)) return; if (!IsValidAgainst(self.World, target)) return; var barrel = Barrels[Burst % Barrels.Length]; var destMove = target.IsActor ? target.Actor.TraitOrDefault<IMove>() : null; var turreted = self.TraitOrDefault<Turreted>(); var args = new ProjectileArgs { weapon = Info, firedBy = self, target = target, src = (self.CenterLocation + Combat.GetBarrelPosition(self, facing, Turret, barrel)).ToInt2(), srcAltitude = move != null ? move.Altitude : 0, dest = target.CenterLocation, destAltitude = destMove != null ? destMove.Altitude : 0, facing = barrel.Facing + (turreted != null ? turreted.turretFacing : facing != null ? facing.Facing : Util.GetFacing(target.CenterLocation - self.CenterLocation, 0)), firepowerModifier = self.TraitsImplementing<IFirepowerModifier>() .Select(a => a.GetFirepowerModifier()) .Product() }; attack.ScheduleDelayedAction( attack.FireDelay( self, target, self.Info.Traits.Get<AttackBaseInfo>() ), () => { if (args.weapon.Projectile != null) { var projectile = args.weapon.Projectile.Create(args); if (projectile != null) self.World.Add(projectile); if (!string.IsNullOrEmpty(args.weapon.Report)) Sound.Play(args.weapon.Report + ".aud", self.CenterLocation); } }); foreach (var na in self.TraitsImplementing<INotifyAttack>()) na.Attacking(self, target); FiredShot(); }
public static float2 GetTurretPosition(Actor self, IFacing facing, Turret turret) { if(facing == null) return turret.ScreenSpacePosition; /* things that don't have a rotating base don't need the turrets repositioned */ var ru = self.TraitOrDefault<RenderUnit>(); var numDirs = (ru != null) ? ru.anim.CurrentSequence.Facings : 8; var bodyFacing = facing.Facing; var quantizedFacing = Util.QuantizeFacing(bodyFacing, numDirs) * (256 / numDirs); return (Util.RotateVectorByFacing(turret.UnitSpacePosition, quantizedFacing, .7f) + GetRecoil(self, turret.Recoil)) + turret.ScreenSpacePosition; }
// gets the screen-space position of a barrel. public static float2 GetBarrelPosition(Actor self, IFacing facing, Turret turret, Barrel barrel) { var turreted = self.TraitOrDefault<Turreted>(); if (turreted == null && facing == null) return float2.Zero; var turretFacing = turreted != null ? turreted.turretFacing : facing.Facing; return Util.RotateVectorByFacing(barrel.Position, turretFacing, .7f); }