예제 #1
0
        protected override void OnFirstRun(Actor self)
        {
            if (host.Type == TargetType.Invalid)
            {
                return;
            }

            if (activeResupplyTypes > 0)
            {
                foreach (var notifyResupply in notifyResupplies)
                {
                    notifyResupply.BeforeResupply(host.Actor, self, activeResupplyTypes);
                }
            }

            // Reset the ReloadDelay to avoid any issues with early cancellation
            // from previous reload attempts (explicit order, host building died, etc).
            // HACK: this really shouldn't be managed from here
            if (activeResupplyTypes.HasFlag(ResupplyType.Rearm))
            {
                foreach (var pool in rearmable.RearmableAmmoPools)
                {
                    pool.RemainingTicks = pool.Info.ReloadDelay;
                }
            }
        }
예제 #2
0
        void INotifyResupply.ResupplyTick(Actor self, Actor target, ResupplyType types)
        {
            var wasRepairing = repairing;

            repairing = types.HasFlag(ResupplyType.Repair);

            if (repairing && Info.StartSequence == null && idling)
            {
                idling = false;
                overlay.PlayThen(Info.Sequence, () =>
                {
                    overlay.PlayRepeating(RenderSprites.NormalizeSequence(overlay, self.GetDamageState(), Info.IdleSequence));
                    idling = true;
                });
            }

            if (!repairing && wasRepairing && Info.EndSequence != null)
            {
                idling = false;
                overlay.PlayThen(Info.EndSequence, () =>
                {
                    overlay.PlayRepeating(RenderSprites.NormalizeSequence(overlay, self.GetDamageState(), Info.IdleSequence));
                    idling = true;
                });
            }
        }
예제 #3
0
 public void ResupplyTick(Actor host, Actor target, ResupplyType types)
 {
     if (types.HasFlag(ResupplyType.Repair))
     {
         if (conditionToken == ConditionManager.InvalidConditionToken)
         {
             conditionToken = conditionManager.GrantCondition(host, info.RepairingCondition);
         }
     }
     else if (types.HasFlag(ResupplyType.None))
     {
         if (conditionToken != ConditionManager.InvalidConditionToken)
         {
             conditionToken = conditionManager.RevokeCondition(host, conditionToken);
         }
     }
 }
예제 #4
0
        void INotifyResupply.BeforeResupply(Actor self, Actor target, ResupplyType types)
        {
            if (!types.HasFlag(ResupplyType.Rearm))
            {
                return;
            }

            // Reset the ReloadDelay to avoid any issues with early cancellation
            // from previous reload attempts (explicit order, host building died, etc).
            foreach (var pool in RearmableAmmoPools)
            {
                pool.RemainingTicks = pool.Info.ReloadDelay;
            }
        }
예제 #5
0
        void INotifyResupply.BeforeResupply(Actor self, Actor target, ResupplyType types)
        {
            repairing = types.HasFlag(ResupplyType.Repair);
            if (!repairing)
            {
                return;
            }

            if (Info.StartSequence != null)
            {
                visible = true;
                overlay.PlayThen(RenderSprites.NormalizeSequence(overlay, self.GetDamageState(), Info.StartSequence),
                                 () => overlay.PlayRepeating(RenderSprites.NormalizeSequence(overlay, self.GetDamageState(), Info.Sequence)));
            }
        }
예제 #6
0
        void INotifyResupply.ResupplyTick(Actor self, Actor target, ResupplyType types)
        {
            var wasRepairing = repairing;

            repairing = types.HasFlag(ResupplyType.Repair);

            if (repairing && Info.StartSequence == null && !visible)
            {
                visible = true;
                overlay.PlayThen(overlay.CurrentSequence.Name, () => visible = false);
            }

            if (!repairing && wasRepairing && Info.EndSequence != null)
            {
                visible = true;
                overlay.PlayThen(Info.EndSequence, () => visible = false);
            }
        }
예제 #7
0
        public override bool Tick(Actor self)
        {
            // Wait for the cooldown to expire before releasing the unit if this was cancelled
            if (IsCanceling && remainingTicks > 0)
            {
                remainingTicks--;
                return(false);
            }

            var isHostInvalid = host.Type != TargetType.Actor || !host.Actor.IsInWorld;
            var isCloseEnough = false;

            if (!isHostInvalid)
            {
                // Negative means there's no distance limit.
                // If RepairableNear, use TargetablePositions instead of CenterPosition
                // to ensure the actor moves close enough to the host.
                // Otherwise check against host CenterPosition.
                if (closeEnough < WDist.Zero)
                {
                    isCloseEnough = true;
                }
                else if (repairableNear != null)
                {
                    isCloseEnough = host.IsInRange(self.CenterPosition, closeEnough);
                }
                else
                {
                    isCloseEnough = (host.CenterPosition - self.CenterPosition).HorizontalLengthSquared <= closeEnough.LengthSquared;
                }
            }

            // This ensures transports are also cancelled when the host becomes invalid
            if (!IsCanceling && isHostInvalid)
            {
                Cancel(self, true);
            }

            if (IsCanceling || isHostInvalid)
            {
                // Only tick host INotifyResupply traits one last time if host is still alive
                if (!isHostInvalid)
                {
                    foreach (var notifyResupply in notifyResupplies)
                    {
                        notifyResupply.ResupplyTick(host.Actor, self, ResupplyType.None);
                    }
                }

                // HACK: If the activity is cancelled while we're on the host resupplying (or about to start resupplying),
                // move actor outside the resupplier footprint to prevent it from blocking other actors.
                // Additionally, if the host is no longer valid, make aircaft take off.
                if (isCloseEnough || isHostInvalid)
                {
                    OnResupplyEnding(self, isHostInvalid);
                }

                return(true);
            }
            else if (activeResupplyTypes != 0 && aircraft == null && !isCloseEnough)
            {
                var targetCell = self.World.Map.CellContaining(host.Actor.CenterPosition);

                QueueChild(move.MoveWithinRange(host, closeEnough, targetLineColor: Color.Green));

                // HACK: Repairable needs the actor to move to host center.
                // TODO: Get rid of this or at least replace it with something less hacky.
                if (repairableNear == null)
                {
                    QueueChild(move.MoveTo(targetCell, host.Actor));
                }

                var delta     = (self.CenterPosition - host.CenterPosition).LengthSquared;
                var transport = transportCallers.FirstOrDefault(t => t.MinimumDistance.LengthSquared < delta);
                if (transport != null)
                {
                    transport.RequestTransport(self, targetCell);
                }

                return(false);
            }

            // We don't want to trigger this until we've reached the resupplier and can start resupplying
            if (!actualResupplyStarted && activeResupplyTypes > 0)
            {
                actualResupplyStarted = true;
                foreach (var notifyResupply in notifyResupplies)
                {
                    notifyResupply.BeforeResupply(host.Actor, self, activeResupplyTypes);
                }
            }

            if (activeResupplyTypes.HasFlag(ResupplyType.Repair))
            {
                RepairTick(self);
            }

            if (activeResupplyTypes.HasFlag(ResupplyType.Rearm))
            {
                RearmTick(self);
            }

            foreach (var notifyResupply in notifyResupplies)
            {
                notifyResupply.ResupplyTick(host.Actor, self, activeResupplyTypes);
            }

            if (activeResupplyTypes == 0)
            {
                OnResupplyEnding(self);
                return(true);
            }

            return(false);
        }
예제 #8
0
 void INotifyResupply.ResupplyTick(Actor self, Actor target, ResupplyType types)
 {
     repairing = types.HasFlag(ResupplyType.Repair);
     rearming  = types.HasFlag(ResupplyType.Rearm);
 }