Example #1
0
        // Constructors.

        public DirectAttackAbility(
            NamedId abilityId, NamedId conditionId,
            Damage singleAttackDamage, float attackDuration, float attackMoment, float attackRange) :
            base(abilityId)
        {
            // Meta.
            this.conditionId = conditionId;

            //Attack properties.
            this.singleAttackDamage = singleAttackDamage;
            this.attackDuration     = Floats.SetPositive(attackDuration);
            this.attackMoment       = Floats.LimitPositive(attackMoment, this.attackDuration);
            this.attackRange        = Floats.SetPositive(attackRange);
        }
        // Constructors.

        public DirectAttackCondition(
            UnitPresentation target, Damage singleAttackDamage,
            float attackDuration, float attackMoment, float attackRange,
            NamedId id)
        {
            // Meta.
            this.id = id;

            // Attack properties.
            this.target             = target ?? throw new ArgumentNullException(nameof(target));
            this.singleAttackDamage = singleAttackDamage;
            this.attackDuration     = Floats.SetPositive(attackDuration);
            this.attackMoment       = Floats.LimitPositive(attackMoment, this.attackDuration);
            this.attackRange        = Floats.SetPositive(attackRange);

            // Progress.
            accumulatedTime = 0f;
            attacked        = false;
            atStart         = true;
        }
        // Updating.

        private protected override void OnAct(out bool finished)
        {
            ValidateContext();

            // Check if finished.
            if (target is null || target.Durability.Fallen)
            {
                finished = true;
                return;
            }
            finished = false;

            // Update time.
            if (Context.GameTimeDelta == 0)
            {
                return;
            }
            accumulatedTime += Context.GameTimeDelta;

            // Update rotation.
            UpdateRotation();

            // Process continuous attack.
            if (attackDuration == 0)
            {
                accumulatedTime = 0;
                attacked        = false;
                atStart         = true;
                if (!TryAttack(float.PositiveInfinity))
                {
                    finished = true;
                }
                return;
            }

            // Process usual attack.
            float attackCount = 0;

            if (!attacked && accumulatedTime >= attackMoment)
            {
                attacked     = true;
                attackCount += 1;
            }
            if (accumulatedTime >= attackDuration)
            {
                atStart = true;
                float finishCount = Mathf.Floor(accumulatedTime / attackDuration);
                if (finishCount > 1)
                {
                    attackCount += finishCount - 1;
                }
                accumulatedTime = Floats.LimitPositive(accumulatedTime - finishCount * attackDuration, attackDuration);
                attacked        = (accumulatedTime >= attackMoment);
                if (attacked)
                {
                    attackCount += 1;
                }
            }
            else
            {
                atStart = false;
            }

            // Attack.
            if (attackCount > 0)
            {
                if (!TryAttack(attackCount))
                {
                    finished = true;
                }
            }
        }