/// <summary> /// Cast a spell, with optional LOS check /// </summary> /// <param name="spell"></param> /// <param name="line"></param> /// <param name="checkLOS"></param> public virtual void CastSpell(Spell spell, SpellLine line, bool checkLOS) { if (IsIncapacitated) return; if (checkLOS) { CastSpell(spell, line); } else { Spell spellToCast = null; if (line.KeyName == GlobalSpellsLines.Mob_Spells) { // NPC spells will get the level equal to their caster spellToCast = (Spell)spell.Clone(); spellToCast.Level = Level; } else { spellToCast = spell; } base.CastSpell(spellToCast, line); } }
/// <summary> /// Cast a spell with LOS check to a player /// </summary> /// <param name="spell"></param> /// <param name="line"></param> public override void CastSpell(Spell spell, SpellLine line) { if (IsIncapacitated) return; if (m_runningSpellHandler != null || TempProperties.getProperty<Spell>(LOSCURRENTSPELL, null) != null) { return; } Spell spellToCast = null; if (line.KeyName == GlobalSpellsLines.Mob_Spells) { // NPC spells will get the level equal to their caster spellToCast = (Spell)spell.Clone(); spellToCast.Level = Level; } else { spellToCast = spell; } // Let's do a few checks to make sure it doesn't just wait on the LOS check int tempProp = TempProperties.getProperty<int>(LOSTEMPCHECKER); if (tempProp <= 0) { GamePlayer LOSChecker = TargetObject as GamePlayer; if (LOSChecker == null) { foreach (GamePlayer ply in GetPlayersInRadius(350)) { if (ply != null) { LOSChecker = ply; break; } } } if (LOSChecker == null) { TempProperties.setProperty(LOSTEMPCHECKER, 0); base.CastSpell(spellToCast, line); } else { TempProperties.setProperty(LOSTEMPCHECKER, 10); TempProperties.setProperty(LOSCURRENTSPELL, spellToCast); TempProperties.setProperty(LOSCURRENTLINE, line); TempProperties.setProperty(LOSSPELLTARGET, TargetObject); LOSChecker.Out.SendCheckLOS(LOSChecker, this, new CheckLOSResponse(StartSpellAttackCheckLOS)); } } else { TempProperties.setProperty(LOSTEMPCHECKER, tempProp - 1); } return; }
/// <summary> /// Add a scripted spell to a spellline /// will try to add to global spell list if not exists (preventing obvious harcoded errors...) /// </summary> /// <param name="spellLineID"></param> /// <param name="spell"></param> public static void AddScriptedSpell(string spellLineID, Spell spell) { // lock Skillbase for writes m_syncLockUpdates.EnterWriteLock(); Spell spcp = null; try { if (spell.ID > 0 && !m_spellIndex.ContainsKey(spell.ID)) { spcp = (Spell)spell.Clone(); // Level 1 for storing... spcp.Level = 1; m_spellIndex.Add(spell.ID, spcp); // Add Tooltip Index if (spcp.InternalID != 0 && !m_spellToolTipIndex.ContainsKey((ushort)spcp.InternalID)) m_spellToolTipIndex.Add((ushort)spcp.InternalID, spcp.ID); } } finally { m_syncLockUpdates.ExitWriteLock(); } // let the base handler do this... if (spcp != null) { AddSpellToSpellLine(spellLineID, spell.ID, spell.Level); return; } m_syncLockUpdates.EnterWriteLock(); try { // Cannot store it in spell index !! ID could be wrongly set we can't rely on it ! if (!m_lineSpells.ContainsKey(spellLineID)) m_lineSpells.Add(spellLineID, new List<Spell>()); // search for duplicates bool added = false; for (int r = 0; r < m_lineSpells[spellLineID].Count; r++) { try { if (m_lineSpells[spellLineID][r] != null && (spell.ID > 0 && m_lineSpells[spellLineID][r].ID == spell.ID && m_lineSpells[spellLineID][r].Name.ToLower().Equals(spell.Name.ToLower()) && m_lineSpells[spellLineID][r].SpellType.ToLower().Equals(spell.SpellType.ToLower())) || (m_lineSpells[spellLineID][r].Name.ToLower().Equals(spell.Name.ToLower()) && m_lineSpells[spellLineID][r].SpellType.ToLower().Equals(spell.SpellType.ToLower()))) { m_lineSpells[spellLineID][r] = spell; added = true; } } catch { } } // try regular add (this could go wrong if duplicate detection is bad...) if (!added) m_lineSpells[spellLineID].Add(spell); m_lineSpells[spellLineID] = m_lineSpells[spellLineID].OrderBy(e => e.Level).ThenBy(e => e.ID).ToList(); } finally { m_syncLockUpdates.ExitWriteLock(); } }