/// <summary> /// Creates a new, unique clone of the spell. /// Uses the effect metadata to create new instances of /// effects too. /// </summary> /// <param name="owner"></param> /// <returns></returns> public Spell CreateInstance(Player owner) { var spell = new Spell { ID = ID, TargetType = TargetType, TargetGroup = TargetGroup, UID = SID.New() }; foreach (var effect in EffectData) { // Need to create a new instance of effect for every spell! spell.Effects.Add(Game.SpellEffects.CreateInstance(effect.Name, effect.Attributes)); } return spell; }
/// <summary> /// Generates a list of targets from the spell and player data, /// then casts the spell on them. /// </summary> /// <param name="player">Player who is casting spell</param> /// <param name="spell">Spell to cast</param> /// <param name="pickedTarget">The creature/commander to target with spell, if needed.</param> /// <returns>True if spell cast started (even if spell was blocked), false if invalid target given.</returns> public bool Cast(Player player, Spell spell, Creature pickedTarget = null) { var targets = GetPossibleTargets(player, spell); switch (spell.TargetType) { case TargetType.Random: Cast(spell, new List<Creature> { targets[ServerRandom.Generator.Next(targets.Count)] }); return true; case TargetType.Single: if (targets.Contains(pickedTarget)) { Cast(spell, new List<Creature> { pickedTarget }); return true; } return false; case TargetType.None: Cast(spell, targets); return true; default: throw new ArgumentOutOfRangeException(); } }
protected virtual void OnSpellCast(Spell arg1, List<Creature> arg2) { var handler = SpellCast; handler?.Invoke(arg1, arg2); }
protected virtual bool OnPreSpellCast(Spell spell) { // If there is any subscribers, invoke them and // use their result. Otherwise return true! return PreSpellCast?.Invoke(spell) ?? true; }
protected virtual void OnPostSpellCast(Spell spell) { PostSpellCast?.Invoke(spell); }
/// <summary> /// Builds up a list of possible targets for the given spell and player. /// </summary> /// <param name="owner">Owner of the spell</param> /// <param name="spell">Spell in question</param> /// <returns></returns> public List<Creature> GetPossibleTargets(Player owner, Spell spell) { var creatures = new List<Creature>(); if (spell.TargetGroup.IsFlagSet(TargetGroup.None)) { return creatures; } if (spell.TargetGroup.IsFlagSet(TargetGroup.Champions)) { if (spell.TargetGroup.IsFlagSet(TargetGroup.Allies)) { creatures.Add(owner.Commander); } if (spell.TargetGroup.IsFlagSet(TargetGroup.Enemies)) { creatures.AddRange(from p in Players where p != owner select p.Commander); } } if (!spell.TargetGroup.IsFlagSet(TargetGroup.Minions)) return creatures; if (spell.TargetGroup.IsFlagSet(TargetGroup.Allies)) { creatures.AddRange(owner.Creatures.Where(c => !c.Commander)); } if (spell.TargetGroup.IsFlagSet(TargetGroup.Enemies)) { creatures.AddRange(from p in Players from c in p.Creatures where !c.Commander select c); } return creatures; }
/// <summary> /// Casts spell at specified targets, use Cast(Player, Spell, Creature) to /// cast spells normally (with their correct targets). /// </summary> /// <param name="spell">Spell to cast</param> /// <param name="targets">Targets to cast it on</param> public void Cast(Spell spell, List<Creature> targets) { Console.WriteLine("CASTING: " + spell.ID); if (!OnPreSpellCast(spell)) return; spell.Cast(targets); OnPostSpellCast(spell); }
/// <summary> /// Generates a Spell base from an XML node /// </summary> /// <param name="spellData">XML containing the spell data</param> /// <param name="name">The ID the spell is to be given.</param> /// <returns></returns> private static Spell GetSpell(XmlNode spellData, string name) { // Create a new blank spell, with the given name and // TargetGroup + Type var spell = new Spell { ID = name, TargetGroup = Conversion.StringToEnum<TargetGroup>(spellData["targetGroup"].InnerText), TargetType = Conversion.StringToEnum<TargetType>(spellData["targetType"].InnerText) }; // Load in the spell's effects using the generic effect loading method XmlNode effects = spellData["effects"]; spell.EffectData.AddRange(LoadEffects(effects, EffectType.spell)); return spell; }