public static IEnumerator <AbilityDeliveryTarget> Deliver(AbilityExecutionContext context, TargetWrapper targetWrapper) { UnitEntityData target = targetWrapper.Unit; if (target == null) { UberDebug.LogError("Target unit is missing"); yield break; } UnitEntityData caster = context.Caster; if (caster.GetThreatHand() == null) { UberDebug.LogError("Invalid caster's weapon"); yield break; } UnitMovementAgent agentASP = caster.View.AgentASP; caster.View.StopMoving(); agentASP.IsCharging = true; agentASP.ForcePath(new ForcedPath(new List <Vector3> { caster.Position, target.Position })); caster.Descriptor.State.IsCharging = true; caster.Descriptor.AddBuff(BlueprintRoot.Instance.SystemMechanics.ChargeBuff, context, 1.Rounds().Seconds); UnitAttack unitAttack = new UnitAttack(target); unitAttack.Init(caster); float timeSinceStart = 0f; while (unitAttack.ShouldUnitApproach) { timeSinceStart += Game.Instance.TimeController.GameDeltaTime; if (timeSinceStart > 6f) { UberDebug.Log("Charge: timeSinceStart > 6f"); yield break; } else if (caster.GetThreatHand() == null) { UberDebug.Log("Charge: caster.GetThreatHand() == null"); yield break; } else if (!caster.Descriptor.State.CanMove) { UberDebug.Log("Charge: !caster.Descriptor.State.CanMove"); yield break; } else if (!(bool)agentASP) { UberDebug.Log("Charge: !(bool)caster.View.AgentASP"); yield break; } else if (!agentASP.IsReallyMoving) { agentASP.ForcePath(new ForcedPath(new List <Vector3> { caster.Position, target.Position })); if (!agentASP.IsReallyMoving) { UberDebug.Log("Charge: !caster.View.AgentASP.IsReallyMoving"); yield break; } } agentASP.MaxSpeedOverride = Math.Max(agentASP.MaxSpeedOverride ?? 0f, caster.CombatSpeedMps * 2f); yield return(null); } caster.View.StopMoving(); unitAttack.IgnoreCooldown(null); unitAttack.IsCharge = true; caster.Commands.AddToQueueFirst(unitAttack); }