void RearmTick(Actor self) { var rearmComplete = true; foreach (var ammoPool in rearmable.RearmableAmmoPools) { if (!ammoPool.FullAmmo()) { if (--ammoPool.RemainingTicks <= 0) { ammoPool.RemainingTicks = ammoPool.Info.ReloadDelay; if (!string.IsNullOrEmpty(ammoPool.Info.RearmSound)) { Game.Sound.PlayToPlayer(SoundType.World, self.Owner, ammoPool.Info.RearmSound, self.CenterPosition); } ammoPool.GiveAmmo(self, ammoPool.Info.ReloadCount); } rearmComplete = false; } } if (rearmComplete) { activeResupplyTypes &= ~ResupplyType.Rearm; } }
public Resupply(Actor self, Actor host, WDist closeEnough) { this.host = Target.FromActor(host); this.closeEnough = closeEnough; allRepairsUnits = host.TraitsImplementing <RepairsUnits>().ToArray(); health = self.TraitOrDefault <IHealth>(); repairable = self.TraitOrDefault <Repairable>(); repairableNear = self.TraitOrDefault <RepairableNear>(); rearmable = self.TraitOrDefault <Rearmable>(); notifyResupplies = host.TraitsImplementing <INotifyResupply>().ToArray(); var cannotRepairAtHost = health == null || health.DamageState == DamageState.Undamaged || !allRepairsUnits.Any() || ((repairable == null || !repairable.Info.RepairActors.Contains(host.Info.Name)) && (repairableNear == null || !repairableNear.Info.RepairActors.Contains(host.Info.Name))); if (!cannotRepairAtHost) { activeResupplyTypes |= ResupplyType.Repair; } var cannotRearmAtHost = rearmable == null || !rearmable.Info.RearmActors.Contains(host.Info.Name) || rearmable.RearmableAmmoPools.All(p => p.FullAmmo()); if (!cannotRearmAtHost) { activeResupplyTypes |= ResupplyType.Rearm; } }
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; }); } }
void RepairTick(Actor self) { var repairsUnits = allRepairsUnits.FirstOrDefault(r => !r.IsTraitDisabled && !r.IsTraitPaused); if (repairsUnits == null) { if (!allRepairsUnits.Any(r => r.IsTraitPaused)) { activeResupplyTypes &= ~ResupplyType.Repair; } return; } if (health.DamageState == DamageState.Undamaged) { if (host.Actor.Owner != self.Owner) { var exp = host.Actor.Owner.PlayerActor.TraitOrDefault <PlayerExperience>(); if (exp != null) { exp.GiveExperience(repairsUnits.Info.PlayerExperience); } } Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", repairsUnits.Info.FinishRepairingNotification, self.Owner.Faction.InternalName); activeResupplyTypes &= ~ResupplyType.Repair; return; } if (remainingTicks == 0) { var hpToRepair = repairable != null && repairable.Info.HpPerStep > 0 ? repairable.Info.HpPerStep : repairsUnits.Info.HpPerStep; // Cast to long to avoid overflow when multiplying by the health var cost = Math.Max(1, (int)(((long)hpToRepair * unitCost * repairsUnits.Info.ValuePercentage) / (health.MaxHP * 100L))); if (!played) { played = true; Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", repairsUnits.Info.StartRepairingNotification, self.Owner.Faction.InternalName); } if (!playerResources.TakeCash(cost, true)) { remainingTicks = 1; return; } self.InflictDamage(host.Actor, new Damage(-hpToRepair, repairsUnits.Info.RepairDamageTypes)); remainingTicks = repairsUnits.Info.Interval; } else { --remainingTicks; } }
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))); } }
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.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 Resupply(Actor self, Actor host, WDist closeEnough, bool stayOnResupplier = false) { this.host = Target.FromActor(host); this.closeEnough = closeEnough; this.stayOnResupplier = stayOnResupplier; allRepairsUnits = host.TraitsImplementing <RepairsUnits>().ToArray(); health = self.TraitOrDefault <IHealth>(); repairable = self.TraitOrDefault <Repairable>(); repairableNear = self.TraitOrDefault <RepairableNear>(); rearmable = self.TraitOrDefault <Rearmable>(); notifyResupplies = host.TraitsImplementing <INotifyResupply>().ToArray(); notifyBeingResupplied = self.TraitsImplementing <INotifyBeingResupplied>().ToArray(); transportCallers = self.TraitsImplementing <ICallForTransport>().ToArray(); move = self.Trait <IMove>(); aircraft = move as Aircraft; moveInfo = self.Info.TraitInfo <IMoveInfo>(); playerResources = self.Owner.PlayerActor.Trait <PlayerResources>(); var valued = self.Info.TraitInfoOrDefault <ValuedInfo>(); unitCost = valued != null ? valued.Cost : 0; var cannotRepairAtHost = health == null || health.DamageState == DamageState.Undamaged || !allRepairsUnits.Any() || ((repairable == null || !repairable.Info.RepairActors.Contains(host.Info.Name)) && (repairableNear == null || !repairableNear.Info.RepairActors.Contains(host.Info.Name))); if (!cannotRepairAtHost) { activeResupplyTypes |= ResupplyType.Repair; // HACK: Reservable logic can't handle repairs, so force a take-off if resupply included repairs. // TODO: Make reservation logic or future docking logic properly handle this. wasRepaired = true; } var cannotRearmAtHost = rearmable == null || !rearmable.Info.RearmActors.Contains(host.Info.Name) || rearmable.RearmableAmmoPools.All(p => p.HasFullAmmo); if (!cannotRearmAtHost) { activeResupplyTypes |= ResupplyType.Rearm; } }
void INotifyResupply.ResupplyTick(Actor self, Actor target, ResupplyType types) { repairing = types.HasFlag(ResupplyType.Repair); rearming = types.HasFlag(ResupplyType.Rearm); }
void INotifyResupply.ResupplyTick(Actor self, Actor target, ResupplyType types) { }
public void BeforeResupply(Actor host, Actor target, ResupplyType types) { }