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); }
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); } } }
protected override void OnEventFired(object source, SpellCastingStateChangedEventArgs args) { if (Logger.IsInfoEnabled) { Logger.Info($"Player started casting Spell: {args.CastingSpellId}"); } //Spell casting stopped. Disable the bar. if (!args.isCasting) { CastingBar.SetElementActive(false); CastingBar.CastingBarFillable.FillAmount = 0; CastingState = new BarCastingState(false); } else { SpellDefinitionDataModel spellDefinition = SpellDataCollection.GetSpellDefinition(args.CastingSpellId); CastingState = new BarCastingState(true, spellDefinition, args.CastingStartTimeStamp); CastingBar.CastingBarSpellNameText.Text = spellDefinition.SpellName; CastingBar.SetElementActive(true); } }