Пример #1
0
        /// <summary>
        /// Lets this Pet cast the given spell
        /// </summary>
        public void CastPetSpell(SpellId spellId, WorldObject target)
        {
            var spell = NPCSpells.GetReadySpell(spellId);
            SpellFailedReason err;

            if (spell != null)
            {
                if (spell.HasTargets)
                {
                    Target = m_master.Target;
                }

                err = spell.CheckCasterConstraints(this);
                if (err == SpellFailedReason.Ok)
                {
                    err = SpellCast.Start(spell, false, target != null ? new[] { target } : null);
                }
            }
            else
            {
                err = SpellFailedReason.NotReady;
            }

            if (err != SpellFailedReason.Ok && m_master is IPacketReceiver)
            {
                PetHandler.SendCastFailed((IPacketReceiver)m_master, spellId, err);
            }
        }
Пример #2
0
        private static void ApplyEventNPCData(WorldEvent worldEvent)
        {
            foreach (var eventNpcData in worldEvent.ModelEquips)
            {
                var spawnEntry = NPCMgr.GetSpawnEntry(eventNpcData.Guid);
                if (spawnEntry == null)
                {
                    Log.Warn("Invalid Spawn Entry in World Event NPC Data, Entry: {0}", eventNpcData.Guid);
                    continue;
                }

                if (eventNpcData.EntryId != 0)
                {
                    eventNpcData.OriginalEntryId = spawnEntry.EntryId;
                    spawnEntry.EntryId           = eventNpcData.EntryId;

                    spawnEntry.Entry = NPCMgr.GetEntry(spawnEntry.EntryId);
                    if (spawnEntry.Entry == null)
                    {
                        Log.Warn("{0} had an invalid World Event EntryId.", spawnEntry);
                        spawnEntry.EntryId = eventNpcData.OriginalEntryId;
                        spawnEntry.Entry   = NPCMgr.GetEntry(spawnEntry.EntryId);
                    }
                }

                if (eventNpcData.ModelId != 0)
                {
                    spawnEntry.DisplayIdOverride = eventNpcData.ModelId;
                }

                if (eventNpcData.EquipmentId != 0)
                {
                    eventNpcData.OriginalEquipmentId = spawnEntry.EquipmentId;
                    spawnEntry.EquipmentId           = eventNpcData.EquipmentId;

                    spawnEntry.Equipment = NPCMgr.GetEquipment(spawnEntry.EquipmentId);
                }

                foreach (var point in spawnEntry.SpawnPoints.ToArray().Where(point => point.IsActive))
                {
                    point.Respawn();
                    if (eventNpcData.SpellIdToCastAtStart == 0)
                    {
                        continue;
                    }

                    Spell spell = SpellHandler.Get(eventNpcData.SpellIdToCastAtStart);
                    if (spell == null)
                    {
                        continue;
                    }

                    SpellCast cast = point.ActiveSpawnling.SpellCast;
                    cast.Start(spell);
                }
            }
        }
Пример #3
0
        private void InitImmovable()
        {
            m_Movement.MayMove = false;

            // if immovables have a single AreaAura, better cast it
            if (HasSpells && Spells.Count == 1)
            {
                var spell = Spells.First();
                if (spell.IsAreaAura)
                {
                    AddMessage(() => SpellCast.Start(spell, true));
                }
            }
        }
Пример #4
0
		protected internal override void Apply()
		{
			if (spell == null)
			{
				var channel = m_aura.Controller as SpellChannel;
				if (channel != null)
				{
					origCast = channel.Cast;
				}
				else
				{
					origCast = m_aura.Auras.Owner.SpellCast;
				}

				if (origCast == null)
				{
					return;
					//throw new Exception("Cannot apply a Periodic Trigger Spell Aura on anyone but the Caster");
				}

				spell = m_spellEffect.TriggerSpell;
				if (spell == null)
				{
					LogManager.GetCurrentClassLogger().Warn("Found invalid periodic TriggerSpell in Spell {0} ({1}) ",
						m_spellEffect.Spell, 
						(uint)m_spellEffect.TriggerSpellId);
					return;
				}
			}

			cast = SpellCast.ObtainPooledCast(origCast.Caster);
			cast.TargetLoc = origCast.TargetLoc;
			cast.Selected = origCast.Selected;
			//cast.Start(spell, m_spellEffect, true);
			cast.Start(spell, true);
		}
Пример #5
0
        /// <summary>
        /// Tries to land a mainhand hit + maybe offhand hit on the current Target
        /// </summary>
        protected virtual void CombatTick(int timeElapsed)
        {
            // if currently casting a spell, skip this
            if (IsUsingSpell && !m_spellCast.IsPending)
            {
                m_attackTimer.Start(DamageAction.DefaultCombatTickDelay);
                return;
            }

            if (!CheckCombatState())
            {
                if (m_isInCombat)
                {
                    // if still in combat - check soon again
                    m_attackTimer.Start(DamageAction.DefaultCombatTickDelay);
                }
                return;
            }

            if (!CanDoHarm || !CanMelee)
            {
                m_attackTimer.Start(DamageAction.DefaultCombatTickDelay);
                return;
            }

            var target = m_target;

            if (target == null || target.IsDead)
            {
                IsFighting = false;
                if (this is NPC)
                {
                    Movement.MayMove = true;
                }
                return;
            }
            var now = Environment.TickCount;

            var isRanged      = IsUsingRangedWeapon;
            var mainHandDelay = m_lastStrike + (isRanged ? RangedAttackTime : MainHandAttackTime) - now;

            var strikeReady = mainHandDelay <= 0;

            // try to strike
            if (strikeReady)
            {
                if (this is NPC)
                {
                    Movement.MayMove = true;
                }
                var distanceSq = GetDistanceSq(target);
                var mainWeapon = isRanged ? m_RangedWeapon : m_mainWeapon;
                if (mainWeapon != null)
                {
                    if (IsInAttackRangeSq(mainWeapon, target, distanceSq))
                    {
                        // close enough
                        if (m_AutorepeatSpell != null)
                        {
                            // Auto-shot (only when not running)
                            if (!IsMoving)
                            {
                                SpellCast.TargetFlags    = SpellTargetFlags.Unit;
                                SpellCast.SelectedTarget = target;
                                SpellCast.Start(m_AutorepeatSpell, false);
                                m_lastStrike   = now;
                                mainHandDelay += RangedAttackTime;
                            }
                        }
                        else
                        {
                            var chr = this as Character;
                            if (chr != null)
                            {
                                chr.IsMoving = false;
                            }
                            Strike(mainWeapon);
                            m_lastStrike   = now;
                            mainHandDelay += MainHandAttackTime;
                            if (this is NPC)
                            {
                                Movement.MayMove = false;
                            }
                        }
                    }
                    else
                    {
                        // too far away
                        if (UsesPendingAbility(mainWeapon))
                        {
                            // ability is pending -> Need to cancel
                            m_spellCast.Cancel(SpellFailedReason.OutOfRange);
                        }

                        // no pending ability
                        if (this is Character)
                        {
                            CombatHandler.SendAttackSwingNotInRange(this as Character);
                        }
                        else if (this is NPC)
                        {
                            Brain.OnCombatTargetOutOfRange();
                        }
                    }
                }
            }



            m_attackTimer.Start(mainHandDelay <= 0 ? 1000 : mainHandDelay);
        }
Пример #6
0
        /// <summary>
        /// Tries to land a mainhand hit + maybe offhand hit on the current Target
        /// </summary>
        protected virtual void CombatTick(int timeElapsed)
        {
            // if currently casting a spell, skip this
            if (IsUsingSpell && !m_spellCast.IsPending)
            {
                m_attackTimer.Start(DamageAction.DefaultCombatTickDelay);
                return;
            }

            if (!CheckCombatState())
            {
                if (m_isInCombat)
                {
                    // if still in combat - check soon again
                    m_attackTimer.Start(DamageAction.DefaultCombatTickDelay);
                }
                return;
            }

            if (!CanDoHarm || !CanMelee)
            {
                m_attackTimer.Start(DamageAction.DefaultCombatTickDelay);
                return;
            }

            var target = m_target;

            var now         = Environment.TickCount;
            var usesOffHand = UsesDualWield;

            var isRanged      = IsUsingRangedWeapon;
            var mainHandDelay = m_lastStrike + (isRanged ? RangedAttackTime : MainHandAttackTime) - now;
            int offhandDelay;

            var  strikeReady = mainHandDelay <= 0;
            bool offHandReady;

            if (usesOffHand)
            {
                offhandDelay = m_lastOffhandStrike + OffHandAttackTime - now;
                offHandReady = true;
            }
            else
            {
                offhandDelay = int.MaxValue;
                offHandReady = false;
            }

            // try to strike
            if (strikeReady || offHandReady)
            {
                if (this is Character && !target.IsInFrontOf(this))
                {
                    CombatHandler.SendAttackSwingBadFacing(this as Character);
                }
                else
                {
                    var distanceSq = GetDistanceSq(target);
                    if (strikeReady)
                    {
                        var mainWeapon = isRanged ? m_RangedWeapon : m_mainWeapon;
                        if (mainWeapon != null)
                        {
                            if (IsInAttackRangeSq(mainWeapon, target, distanceSq))
                            {
                                // close enough
                                if (m_AutorepeatSpell != null)
                                {
                                    // Auto-shot (only when not running)
                                    if (!IsMoving)
                                    {
                                        SpellCast.TargetFlags    = SpellTargetFlags.Unit;
                                        SpellCast.SelectedTarget = target;
                                        SpellCast.Start(m_AutorepeatSpell, false);
                                        m_lastStrike   = now;
                                        mainHandDelay += RangedAttackTime;
                                    }
                                }
                                else
                                {
                                    Strike(mainWeapon);
                                    m_lastStrike   = now;
                                    mainHandDelay += MainHandAttackTime;
                                }
                            }
                            else
                            {
                                // too far away
                                if (UsesPendingAbility(mainWeapon))
                                {
                                    // ability is pending -> Need to cancel
                                    m_spellCast.Cancel(SpellFailedReason.OutOfRange);
                                }

                                // no pending ability
                                if (this is Character)
                                {
                                    CombatHandler.SendAttackSwingNotInRange(this as Character);
                                }
                                else if (this is NPC)
                                {
                                    Brain.OnCombatTargetOutOfRange();
                                }
                            }
                        }
                    }

                    if (offHandReady)
                    {
                        if (IsInAttackRangeSq(m_offhandWeapon, target, distanceSq))
                        {
                            // in range for a strike
                            Strike(m_offhandWeapon);
                            m_lastOffhandStrike = now;
                            offhandDelay       += OffHandAttackTime;
                        }
                        else
                        {
                            // too far away
                            if (UsesPendingAbility(m_offhandWeapon))
                            {
                                // ability is pending -> Need to cancel
                                m_spellCast.Cancel(SpellFailedReason.OutOfRange);
                            }
                        }
                    }
                }
            }

            // determine the next strike
            int delay;

            strikeReady  = mainHandDelay <= 0;
            offHandReady = usesOffHand && offhandDelay <= 0;

            if (strikeReady)
            {
                // mainhand is ready but not in reach
                if (offHandReady || !usesOffHand)
                {
                    // mainhand is ready and offhand is either also ready or not present
                    delay = DamageAction.DefaultCombatTickDelay;
                }
                else
                {
                    // mainhand is ready and offhand is still waiting
                    delay = Math.Min(DamageAction.DefaultCombatTickDelay, offhandDelay);
                }
            }
            else
            {
                // mainhand is not ready
                if (offHandReady)
                {
                    // mainhand is not ready but offhand is ready
                    delay = Math.Min(DamageAction.DefaultCombatTickDelay, mainHandDelay);
                }
                else
                {
                    if (usesOffHand)
                    {
                        // mainhand and offhand are both not ready
                        delay = Math.Min(offhandDelay, mainHandDelay);
                    }
                    else
                    {
                        // mainhand is not ready and there is no offhand
                        delay = mainHandDelay;
                    }
                }
            }

            m_attackTimer.Start(delay);
        }
Пример #7
0
        /// <summary>
        /// Is called after Character has been added to a map the first time and
        /// before it receives the first Update packet
        /// </summary>
        internal protected void InitializeCharacter()
        {
            World.AddCharacter(this);
            m_initialized = true;

            try
            {
                Regenerates = true;
                ((PlayerSpellCollection)m_spells).PlayerInitialize();

                OnLogin();

                if (m_record.JustCreated)
                {
                    if (!m_client.Account.Role.IsStaff)
                    {
                        CharacterHandler.SendCinematic(this);
                    }
                    if (m_zone != null)
                    {
                        m_zone.EnterZone(this, null);
                    }

                    m_spells.AddDefaultSpells();
                    m_reputations.Initialize();

                    if (Class == ClassId.Warrior && Spells.Contains(SpellId.ClassSkillBattleStance))
                    {
                        CallDelayed(1000, obj => SpellCast.Start(SpellId.ClassSkillBattleStance, false));
                    }
                    else if (Class == ClassId.DeathKnight && Spells.Contains(SpellId.ClassSkillBloodPresence))
                    {
                        CallDelayed(1000, obj => SpellCast.Start(SpellId.ClassSkillBloodPresence, false));
                    }

                    // set initial weapon skill max values
                    Skills.UpdateSkillsForLevel(Level);
                }
                else
                {
                    LoadDeathState();
                    LoadEquipmentState();
                }

                // load items
#if DEV
                // do this check in case that we did not load Items yet
                if (ItemMgr.Loaded)
#endif
                InitItems();

                // load ticket information
                var ticket = TicketMgr.Instance.GetTicket(EntityId.Low);
                if (ticket != null)
                {
                    Ticket = ticket;
                    Ticket.OnOwnerLogin(this);
                }

                // initialize sub systems
                GroupMgr.Instance.OnCharacterLogin(this);
                GuildMgr.Instance.OnCharacterLogin(this);
                RelationMgr.Instance.OnCharacterLogin(this);

                // set login date
                LastLogin = DateTime.Now;
                var isNew = m_record.JustCreated;

                // perform some stuff ingame
                AddMessage(() =>
                {
                    if (LastLogout == null)
                    {
                        RealmCommandHandler.ExecFirstLoginFileFor(this);
                    }

                    RealmCommandHandler.ExecAllCharsFileFor(this);

                    if (Account.Role.IsStaff)
                    {
                        RealmCommandHandler.ExecFileFor(this);
                    }

                    Stunned--;

                    if (m_record.NextTaxiVertexId != 0)
                    {
                        // we are on a Taxi
                        var vertex = TaxiMgr.GetVertex(m_record.NextTaxiVertexId);
                        if (vertex != null &&
                            vertex.MapId == m_Map.Id &&
                            vertex.ListEntry.Next != null &&
                            IsInRadius(vertex.Pos, vertex.ListEntry.Next.Value.DistFromPrevious))
                        {
                            TaxiPaths.Enqueue(vertex.Path);
                            TaxiMgr.FlyUnit(this, true, vertex.ListEntry);
                        }
                        else
                        {
                            m_record.NextTaxiVertexId = 0;
                        }
                    }
                    else
                    {
                        // cannot stand up instantly because else no one will see the char sitting in the first place
                        StandState = StandState.Stand;
                    }
                    GodMode = m_record.GodMode;

                    if (isNew)
                    {
                        // newly created Char logs in the first time
                        var evt = Created;
                        if (evt != null)
                        {
                            evt(this);
                        }
                    }

                    //if (Role.IsStaff)
                    if (GodMode)
                    {
                        //Notify("Your GodMode is " + (GodMode ? "ON" : "OFF") + "!");
                        Notify(RealmLangKey.GodModeIsActivated);
                    }

                    var login = LoggedIn;
                    if (login != null)
                    {
                        login(this, true);
                    }
                });

                if (isNew)
                {
                    SaveLater();
                    m_record.JustCreated = false;
                }
                else
                {
                    RealmServer.IOQueue.AddMessage(() =>
                    {
                        try
                        {
                            m_record.Update();
                        }
                        catch (Exception ex)
                        {
                            SaveLater();
                            LogUtil.ErrorException(ex, "Failed to Update CharacterRecord: " + m_record);
                        }
                    });
                }
            }
            catch (Exception e)
            {
                if (m_record.JustCreated)
                {
                    m_record.CanSave = false;
                    m_record.Delete();
                }
                World.RemoveCharacter(this);
                LogUtil.ErrorException(e, "Failed to initialize Character: " + this);
                m_client.Disconnect();
            }
        }