示例#1
0
        public async Task <UseAbilityResult> RunAbility()
        {
            UseAbilityResult result = UseAbilityResult.OK;

            try
            {
                //REMEMBER: This runs in the context of the SOURCE.
                //Any checks on the target will need to be awaited on the target's fiber.

                if (State == AbilityState.Casting)
                {
                    await Task.Delay(EndTime - Environment.TickCount, m_cancellationTokenSource.Token);
                }

                if (Vector2.DistanceSquared(Target.Position, Source.Position) > Math.Pow(Ability.Range, 2))
                {
                    result = UseAbilityResult.OutOfRange;
                }
                else if (Source.Power < Ability.SourcePowerDelta)
                {
                    result = UseAbilityResult.NotEnoughPower;
                }
                else if (Target.IsDead)
                {
                    result = UseAbilityResult.InvalidTarget;
                }
                else
                {
                    Target.ApplyHealthDelta(Ability.TargetHealthDelta, Source);
                    Target.ApplyPowerDelta(Ability.TargetPowerDelta, Source);
                    Source.ApplyHealthDelta(Ability.SourceHealthDelta, Source);
                    Source.ApplyPowerDelta(Ability.SourcePowerDelta, Source);

                    result = UseAbilityResult.OK;
                }

                State = AbilityState.Finished;
            }
            catch (TaskCanceledException)
            {
                State  = AbilityState.Cancelled;
                result = UseAbilityResult.Cancelled;
            }

            return(result);
        }
示例#2
0
        private async void Handle_UseAbility(UseAbility_C2S ability)
        {
            IEntity          target       = default(IEntity);
            AbilityModel     abilityModel = m_abilityRepository.GetAbilityByID(ability.AbilityID);
            UseAbilityResult result       = UseAbilityResult.Failed;

            string targetName = "[No Target]";

            if (abilityModel == null)
            {
                result = UseAbilityResult.Failed;
            }
            else if (m_lastAbility.State == AbilityState.Casting)
            {
                result = UseAbilityResult.AlreadyCasting;
            }
            else if (Environment.TickCount - m_lastAbilityAcceptTime <= GLOBAL_COOLDOWN_MS)
            {
                result = UseAbilityResult.OnCooldown;
            }
            else if (Power + abilityModel.SourcePowerDelta < 0)
            {
                result = UseAbilityResult.NotEnoughPower;
            }
            else
            {
                if (ability.TargetID != 0)
                {
                    target = await CurrentZone.GetTarget(ability.TargetID);

                    if (target != null)
                    {
                        targetName = target.Name;
                    }
                }

                if (abilityModel.AbilityType != AbilityModel.ETargetType.AOE && target == null)
                {
                    result = UseAbilityResult.InvalidTarget;
                }
                else if (target is NPCInstance && abilityModel.AbilityType == AbilityModel.EAbilityType.HELP)
                {
                    result = UseAbilityResult.InvalidTarget;
                }
                else if (Vector2.DistanceSquared(target.Position, Position) > Math.Pow(abilityModel.Range, 2))
                {
                    result = UseAbilityResult.OutOfRange;
                }
                else
                {
                    m_lastAbility.Dispose();
                    m_lastAbility = new AbilityInstance(this, target, abilityModel);

                    if (m_lastAbility.State == AbilityState.Casting)
                    {
                        Send(new AbilityCastNotification()
                        {
                            StartTime = m_lastAbility.StartTime, EndTime = m_lastAbility.EndTime
                        });
                    }

                    result = await m_lastAbility.RunAbility();
                }
            }

            if (result == UseAbilityResult.OK)
            {
                List <IEntity> nearPlayers = m_nearEntities;

                AbilityUsedNotification notification = new AbilityUsedNotification();
                notification.AbilityID = abilityModel.AbilityID;
                notification.SourceID  = ID;
                notification.TargetID  = target != null ? target.ID : 0;
                notification.Timestamp = Environment.TickCount;

                for (int i = 0; i < nearPlayers.Count; i++)
                {
                    PlayerPeer player = nearPlayers[i] as PlayerPeer;
                    if (player != null)
                    {
                        player.EnqueueSend(notification);
                    }
                }
            }

            string abilityName = abilityModel != null ? abilityModel.InternalName : string.Format("[INVALID ID {0}]", ability.AbilityID);

            Info("Used ability {0} on target {1} with result {2}", abilityName, targetName, result);

            Respond(ability, new UseAbility_S2C()
            {
                Result = (int)result
            });
        }