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; } } }
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; }); } }
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); } } }
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; } }
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))); } }
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); } }
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); }
void INotifyResupply.ResupplyTick(Actor self, Actor target, ResupplyType types) { repairing = types.HasFlag(ResupplyType.Repair); rearming = types.HasFlag(ResupplyType.Rearm); }