コード例 #1
0
        public bool isSpellTargetViable(int spellId, [NotNull] DefaultEntityActorStateContainer actorState)
        {
            if (actorState == null)
            {
                throw new ArgumentNullException(nameof(actorState));
            }
            if (spellId <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(spellId));
            }

            SpellDefinitionDataModel definition = SpellDataCollection.GetSpellDefinition(spellId);

            foreach (var effect in SpellDataCollection.GetEffectsForSpell(spellId))
            {
                ISpellEffectTargetValidator effectTargetValidator = ValidatorFactory.Create(effect);

                //One effect's targets failed given the context. So this fails.
                if (!effectTargetValidator.ValidateTargetContext(definition, effect, actorState))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #2
0
        public SpellCastResult ValidateSpellCast(DefaultEntityActorStateContainer actorState, int spellId)
        {
            if (!TargetValidator.isSpellTargetViable(spellId, actorState))
            {
                return(SpellCastResult.SPELL_FAILED_BAD_TARGETS);
            }

            return(SpellCastResult.SPELL_FAILED_SUCCESS);
        }
コード例 #3
0
        protected NetworkEntityGuid GetEntityTarget([NotNull] DefaultEntityActorStateContainer state)
        {
            if (state == null)
            {
                throw new ArgumentNullException(nameof(state));
            }

            return(state.EntityData.GetEntityGuidValue(EntityObjectField.UNIT_FIELD_TARGET));;
        }
コード例 #4
0
        public SpellCastResult ValidateSpellCast(DefaultEntityActorStateContainer state, int spellId)
        {
            if (!MovementGeneratorMappable.RetrieveEntity(state.EntityGuid).isFinished)
            {
                return(SpellCastResult.SPELL_FAILED_MOVING);
            }

            return(SpellCastResult.SPELL_FAILED_SUCCESS);
        }
コード例 #5
0
        public SpellEffectTargetCreationContext(int spellId, SpellEffectIndex effectIndex, [NotNull] DefaultEntityActorStateContainer actorState)
        {
            if (spellId <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(spellId));
            }

            SpellId     = spellId;
            EffectIndex = effectIndex;
            ActorState  = actorState ?? throw new ArgumentNullException(nameof(actorState));
        }
コード例 #6
0
        public SpellCastResult ValidateSpellCast(DefaultEntityActorStateContainer state, int spellId)
        {
            if (PendingSpellCastMappable.ContainsKey(state.EntityGuid))
            {
                PendingSpellCastData pendingCast = PendingSpellCastMappable.RetrieveEntity(state.EntityGuid);

                if (!pendingCast.IsSpellcastFinished(TimeService.CurrentLocalTime))
                {
                    return(SpellCastResult.SPELL_FAILED_SPELL_IN_PROGRESS);
                }
            }

            return(SpellCastResult.SPELL_FAILED_SUCCESS);
        }
コード例 #7
0
        public SpellCastResult ValidateSpellCast(DefaultEntityActorStateContainer actorState, int spellId)
        {
            foreach (var validator in Validators)
            {
                SpellCastResult result = validator.ValidateSpellCast(actorState, spellId);

                //If not successful we failed and no longer need to validate. We know something is wrong.
                if (result != SpellCastResult.SPELL_FAILED_SUCCESS)
                {
                    return(result);
                }
            }

            return(SpellCastResult.SPELL_FAILED_SUCCESS);
        }
コード例 #8
0
        public SpellCastResult ValidateSpellCast([NotNull] DefaultEntityActorStateContainer actorState, int spellId)
        {
            if (actorState == null)
            {
                throw new ArgumentNullException(nameof(actorState));
            }

            int level = actorState.EntityData.GetFieldValue <int>(BaseObjectField.UNIT_FIELD_LEVEL);

            //TODO: Support correct entity class type.
            //If it's a player and we don't know the spell.
            if (actorState.EntityGuid.EntityType == EntityType.Player && !LearnedSpells.IsSpellKnown(spellId, EntityPlayerClassType.Mage, level))
            {
                return(SpellCastResult.SPELL_FAILED_NOT_KNOWN);
            }

            return(SpellCastResult.SPELL_FAILED_SUCCESS);
        }
コード例 #9
0
 public abstract SpellEffectTargetContext CalculateTargets(SpellDefinitionDataModel spellDefinition, SpellEffectDefinitionDataModel spellEffect, DefaultEntityActorStateContainer actorState, IPendingSpellCastData pendingSpellCast);
コード例 #10
0
        public IEnumerable <IActorRef> ComputeAllyTargets([NotNull] IPendingSpellCastData pendingSpellData, [NotNull] DefaultEntityActorStateContainer actorState)
        {
            if (pendingSpellData == null)
            {
                throw new ArgumentNullException(nameof(pendingSpellData));
            }
            if (actorState == null)
            {
                throw new ArgumentNullException(nameof(actorState));
            }

            //TODO: Handle hostility calculation. Right now it just only supports player targeting, and opts to self target if targeting a creature.
            yield return(pendingSpellData.SnapshotEntityTarget.EntityType == EntityType.Player ? ActorReferenceMappable.RetrieveEntity(pendingSpellData.SnapshotEntityTarget) : ActorReferenceMappable.RetrieveEntity(actorState.EntityGuid));
        }
コード例 #11
0
        public override SpellEffectTargetContext CalculateTargets([NotNull] SpellDefinitionDataModel spellDefinition, [NotNull] SpellEffectDefinitionDataModel spellEffect, [NotNull] DefaultEntityActorStateContainer actorState, [NotNull] IPendingSpellCastData pendingSpellCast)
        {
            if (spellDefinition == null)
            {
                throw new ArgumentNullException(nameof(spellDefinition));
            }
            if (spellEffect == null)
            {
                throw new ArgumentNullException(nameof(spellEffect));
            }
            if (actorState == null)
            {
                throw new ArgumentNullException(nameof(actorState));
            }
            if (pendingSpellCast == null)
            {
                throw new ArgumentNullException(nameof(pendingSpellCast));
            }

            return(new SpellEffectTargetContext(ComputeAllyTargets(pendingSpellCast, actorState)));
        }
コード例 #12
0
        protected override bool ValidateTargeting(SpellDefinitionDataModel spellDefinition, SpellEffectDefinitionDataModel spellEffect, DefaultEntityActorStateContainer actorState)
        {
            if (spellDefinition == null)
            {
                throw new ArgumentNullException(nameof(spellDefinition));
            }
            if (spellEffect == null)
            {
                throw new ArgumentNullException(nameof(spellEffect));
            }
            if (actorState == null)
            {
                throw new ArgumentNullException(nameof(actorState));
            }

            NetworkEntityGuid guid = GetEntityTarget(actorState);

            //Does the entity exist, small window of time between valid cast start and now where entity can despawn
            //so minor chance it doesn't exist anymore.
            if (!KnownEntitySet.isEntityKnown(guid))
            {
                return(false);
            }

            //TODO: We shouldn't assume they are enemies just because they aren't use. We need a system for hostility masking for entities
            return(guid != NetworkEntityGuid.Empty && guid.EntityType == EntityType.Creature && guid != actorState.EntityGuid);
        }
コード例 #13
0
 protected override bool ValidateTargeting(SpellDefinitionDataModel spellDefinition, SpellEffectDefinitionDataModel spellEffect, DefaultEntityActorStateContainer actorState)
 {
     //Ally targeting is always valid. Even if targeting an enemy
     //This is because we'll just cast it on ourselves if we're
     //targeting an enemy.
     return(true);
 }
コード例 #14
0
        public void DispatchSpellCast([NotNull] IPendingSpellCastData pendingSpellCast, DefaultEntityActorStateContainer casterData)
        {
            if (pendingSpellCast == null)
            {
                throw new ArgumentNullException(nameof(pendingSpellCast));
            }

            if (!SpellDataCollection.ContainsSpellDefinition(pendingSpellCast.SpellId))
            {
                throw new InvalidOperationException($"Tried to cast Spell: {pendingSpellCast.SpellId} but no definition exists.");
            }

            IActorRef casterActorReference           = ActorReferenceMappable.RetrieveEntity(casterData.EntityGuid);
            SpellDefinitionDataModel spellDefinition = SpellDataCollection.GetSpellDefinition(pendingSpellCast.SpellId);

            //Each spell can have N effects with individual unique targeting attributes.
            //So we need to handle each spell effect seperately, compute their effects/targets
            //and send an effect application message to the involved actors.
            foreach (SpellEffectIndex effectIndex in spellDefinition.EnumerateSpellEffects())
            {
                SpellEffectDefinitionDataModel effectDefinition = SpellDataCollection.GetSpellEffectDefinition(spellDefinition.GetSpellEffectId(effectIndex));

                SpellEffectTargetContext targetContext = EffectTargetSelectorFactory
                                                         .Create(effectDefinition)
                                                         .CalculateTargets(spellDefinition, effectDefinition, casterData, pendingSpellCast);

                ApplySpellEffectMessage spellEffectApplicationMessage = SpellEffectApplicationMessageFactory.Create(new SpellEffectApplicationMessageCreationContext(casterData.EntityGuid, pendingSpellCast.SpellId, effectIndex));

                //For each actor target in the target context
                //we need to send the spell application message for handling
                foreach (var target in targetContext.SpellEffectTargets)
                {
                    if (Logger.IsDebugEnabled)
                    {
                        Logger.Debug($"Entity: {casterData.EntityGuid} casted spell with effect that targets Target: {target.Path.Name}");
                    }

                    target.Tell(spellEffectApplicationMessage, casterActorReference);
                }
            }
        }
コード例 #15
0
        public bool ValidateTargetContext([NotNull] SpellDefinitionDataModel spellDefinition, [NotNull] SpellEffectDefinitionDataModel spellEffect, [NotNull] DefaultEntityActorStateContainer actorState)
        {
            if (spellDefinition == null)
            {
                throw new ArgumentNullException(nameof(spellDefinition));
            }
            if (spellEffect == null)
            {
                throw new ArgumentNullException(nameof(spellEffect));
            }
            if (actorState == null)
            {
                throw new ArgumentNullException(nameof(actorState));
            }

            //We don't validate effect targeting matching the validators effect targeting
            //because a validator may have MULTIPLE targeting handling.

            return(ValidateTargeting(spellDefinition, spellEffect, actorState));
        }
コード例 #16
0
 /// <summary>
 /// Parameters are never null.
 /// </summary>
 /// <param name="spellDefinition"></param>
 /// <param name="spellEffect"></param>
 /// <param name="actorState"></param>
 /// <returns></returns>
 protected abstract bool ValidateTargeting(SpellDefinitionDataModel spellDefinition, SpellEffectDefinitionDataModel spellEffect, DefaultEntityActorStateContainer actorState);