All pastes #798385 Raw Edit

Someone

public cpp v1 · immutable
#798385 ·published 2007-11-26 19:54 UTC
rendered paste body
Index: configure.ac===================================================================--- configure.ac	(revision 4771)+++ configure.ac	(working copy)@@ -48,9 +48,22 @@          pthread_create();,          [], [AC_MSG_ERROR([Missing pthread])])     ])++# LibEvent Checking+# Default: /usr/local/bin+LEVENT_INCLUDES="-I/usr/local/include $LEVENT_INCLUDES" +LEVENT_LIB="-L/usr/local/lib -levent $LEVENT_LIB"+AC_ARG_WITH(libeventdir, +AC_HELP_STRING([--with_libeventdir=DIRECTORY],[base directory for libevent]))+if test "$with_libeventdir" != "no"; then +LEVENT_INCLUDES="-I$with_libeventdir/include $LEVENT_INCLUDES" +LEVENT_LIB="-L$with_libeventdir/lib -levent $LEVENT_LIB" +fi+ AC_CHECK_LIB( z, compress, [ZLIB=-lz],[AC_MSG_ERROR([Missing zlib])] ) AC_CHECK_LIB( compat, ftime, [COMPATLIB=-lcompat] ) AC_CHECK_LIB( crypto, SHA1_Init, [SSLLIB=-lssl], [AC_MSG_ERROR([Missing openssl])])+AC_CHECK_LIB( event, event_init, [], [AC_MSG_ERROR(libevent is missing, install it or use --with-libevent=DIR.)])  AC_ARG_WITH(postgresql, [  --with-postgresql       Use PostgreSQL as a backend (default: no)],@@ -162,6 +175,7 @@ AC_CHECK_HEADERS([mysql.h mysql/mysql.h]) AC_CHECK_HEADERS([libpq-fe.h]) AC_CHECK_HEADERS([zlib.h])+AC_CHECK_HEADERS([event.h])  ## Check for typedefs, structures, and compiler characteristics. AC_HEADER_STDBOOL@@ -186,6 +200,8 @@ AC_CHECK_FUNCS([atexit ftime gethostbyaddr gethostbyname gethostname gettimeofday memmove memset pow realpath select socket sqrt strchr strdup strerror strstr])  ## Export defined variables+AC_SUBST(LEVENT_LIB)+AC_SUBST(LEVENT_INCLUDES) AC_SUBST(ZLIB) AC_SUBST(COMPATLIB) AC_SUBST(SSLLIB)@@ -223,7 +239,9 @@    src/mangosd/Makefile    src/mangosd/mangosd.conf    src/bindings/Makefile-   src/bindings/universal/Makefile+   src/bindings/ScriptDev2/Makefile+   src/bindings/ScriptDev2/sql/Makefile+   src/bindings/ScriptDev2/sql/Updates/Makefile ])  ## Disabled Makefiles, until they are ready for a successful make andIndex: src/bindings/Makefile.am===================================================================--- src/bindings/Makefile.am	(revision 4771)+++ src/bindings/Makefile.am	(working copy)@@ -14,4 +14,4 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA -SUBDIRS = universal+SUBDIRS = ScriptDev2Index: src/game/AggressorAI.cpp===================================================================--- src/game/AggressorAI.cpp	(revision 4773)+++ src/game/AggressorAI.cpp	(working copy)@@ -38,7 +38,7 @@     return PERMIT_BASE_NO; } -AggressorAI::AggressorAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK)+AggressorAI::AggressorAI(Creature &c) : i_creature(c), i_victimGuid(0), i_state(STATE_NORMAL), i_tracker(TIME_INTERVAL_LOOK), pAISpellSystem(&c) { } @@ -111,8 +111,10 @@ }  void-AggressorAI::UpdateAI(const uint32 /*diff*/)+AggressorAI::UpdateAI(const uint32 diff) {+    pAISpellSystem.Update(diff);+     // update i_victimGuid if i_creature.getVictim() !=0 and changed     if(!i_creature.SelectHostilTarget() || !i_creature.getVictim())         return;Index: src/game/AggressorAI.h===================================================================--- src/game/AggressorAI.h	(revision 4773)+++ src/game/AggressorAI.h	(working copy)@@ -21,6 +21,7 @@  #include "CreatureAI.h" #include "Timer.h"+#include "AISpellSystem.h"  class Creature; @@ -45,6 +46,7 @@         static int Permissible(const Creature *);      private:+        AISpellSystem pAISpellSystem;         Creature &i_creature;         uint64 i_victimGuid;         AggressorState i_state;Index: src/game/AISpellSystem.cpp===================================================================--- src/game/AISpellSystem.cpp	(revision 0)+++ src/game/AISpellSystem.cpp	(revision 0)@@ -0,0 +1,518 @@+/* + * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program; if not, write to the Free Software+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA+ */++#include "AISpellSystem.h"+#include "../shared/WorldPacket.h"+#include "Unit.h"+#include "Creature.h"+#include "Player.h"+#include "Spell.h"++//Global Cooldown+#define AI_GCD 1500++//0 - NONE, 1 - Self, 2 - Enemy, 3 - AE enemy, 4 - Friendly, 5 - Area Friendly+enum SpellTargetType+{+    SPELL_T_NULL        = 0,+    SPELL_T_SELF        = 1,+    SPELL_T_ENEMY       = 2,+    SPELL_T_AOEENEMY    = 4,+    SPELL_T_FRIEND      = 8,+    SPELL_T_AOEFRIEND   = 16,+};++//0 - NONE, 1 - Damage, 2 - Heal, 3 - Damage over time, 4 - heal over time, 5 - Crowd Control, 6 - Snare, 7 - Buff, 8 - Debuff+enum SpellEffectType+{+    SPELL_E_NULL        = 0,+    SPELL_E_DAMAGE      = 1,+    SPELL_E_HEAL        = 2,+    SPELL_E_DOT         = 4,+    SPELL_E_HOT         = 8,+    SPELL_E_CC          = 16,+    SPELL_E_SNARE       = 32,       //not used right now+    SPELL_E_BUFF        = 64,+    SPELL_E_DEBUFF      = 128,+};++//Also could be called the priority type. Later types = higher priority+enum SpellType+{+    TYPE_NONE = 0,+    TYPE_BUFF,+    TYPE_AREA_DAMAGE,+    TYPE_DIRECT_DAMAGE,+    TYPE_CROWD_CONTROL,+    TYPE_SNARE,+    TYPE_DEBUFF,+    TYPE_DAMAGE_OVER_TIME,+    TYPE_HEAL_OVER_TIME,+    TYPE_AREA_HEAL,+    TYPE_HEAL,+    TYPE_SELF_HEAL,++};++struct SpellHolder+{+    // Constants+    uint32 SpellId;+    uint32 RangeMin;+    uint32 RangeMax;+    uint32 Radius;+    uint32 Duration;+    uint32 CastTime;+    uint32 Cooldown;+    uint32 PowerCost;+    uint8 PowerType;++    uint8 Classication;+    uint8 Targets;++    // Variables+    uint32 CooldownRemaining;+};++bool Sort(SpellHolder* SH1, SpellHolder* SH2)+{+    return (SH1->Classication > SH2->Classication);+}++AISpellSystem::AISpellSystem(Creature* pCreature)+{+    ASSERT(pCreature);++    m_Unit = pCreature; ++    //We know size of spells is always 4+    ClassifySpells(pCreature->m_spells, 4);++    if (m_SpellList.size() > 1)+        m_SpellList.sort(std::ptr_fun(Sort));+}+AISpellSystem::AISpellSystem(Unit* pUnit, const uint32* pSpellArray, const uint32 Size)+{+    ASSERT(pUnit);++    m_Unit = pUnit;+    ClassifySpells(pSpellArray, Size);++    if (m_SpellList.size() > 1)+        m_SpellList.sort(std::ptr_fun(Sort));+}++AISpellSystem::~AISpellSystem()+{++    if (!m_SpellList.empty())+        for (std::list<SpellHolder*>::iterator i = m_SpellList.begin(); i != m_SpellList.end(); ++i)+        {+            SpellHolder* pSpell = (*i);+            delete pSpell;+        }++    m_SpellList.clear();+}++void AISpellSystem::ClassifySpells(const uint32* pSpellArray, const uint32 Size)+{+    if (!pSpellArray || !Size)+        return;++    //Different Entries we need to get cross referenced information from+    SpellEntry const* TempSpell;+    SpellRangeEntry const* TempRange;+    SpellRadiusEntry const* TempRadius;+    SpellDurationEntry const* TempDuration;+    SpellCastTimesEntry const* TempCastTime;+    +    uint32 TargetType = SPELL_T_NULL;+    uint32 EffectType = SPELL_E_NULL;++    //Check if each spell is viable(set it to null if not)+    for (uint32 i = 0; i < Size; i++)+    {++        TempSpell = sSpellStore.LookupEntry(pSpellArray[i]);++        //This spell doesn't exist+        if (!TempSpell)+            continue;++        //Gather spell Target information and Effect information+        for (int j=0; j<3; j++)+        {+            //***TARGETS***++            //self+        if ( TempSpell->EffectImplicitTargetA[j] == TARGET_SELF || +            TempSpell->EffectImplicitTargetB[j] == TARGET_SELF)+            TargetType |= SPELL_T_SELF;+        else++        //single enemy+        if ( TempSpell->EffectImplicitTargetA[j] == TARGET_CHAIN_DAMAGE ||+            TempSpell->EffectImplicitTargetA[j] == TARGET_CURRENT_SELECTED_ENEMY ||+            TempSpell->EffectImplicitTargetB[j] == TARGET_CHAIN_DAMAGE ||+            TempSpell->EffectImplicitTargetB[j] == TARGET_CURRENT_SELECTED_ENEMY)+            TargetType |= SPELL_T_ENEMY;+        else++        //AoE at enemy+        if ( TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA ||+            TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||+            TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED ||+            TempSpell->EffectImplicitTargetB[j] == TARGET_ALL_ENEMY_IN_AREA ||+            TempSpell->EffectImplicitTargetB[j] == TARGET_ALL_ENEMY_IN_AREA_INSTANT ||+            TempSpell->EffectImplicitTargetB[j] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED)+            TargetType |= SPELL_T_AOEENEMY;+        else++        //single friend+        if ( TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_FRIEND ||+            TempSpell->EffectImplicitTargetA[j] == TARGET_SINGLE_PARTY ||+            TempSpell->EffectImplicitTargetB[j] == TARGET_SINGLE_FRIEND ||+            TempSpell->EffectImplicitTargetB[j] == TARGET_SINGLE_PARTY)+            TargetType |= SPELL_T_FRIEND;+        else++        //aoe friends+        if ( TempSpell->EffectImplicitTargetA[j] == TARGET_ALL_PARTY_AROUND_CASTER ||+            TempSpell->EffectImplicitTargetA[j] == TARGET_AREAEFFECT_PARTY ||+            TempSpell->EffectImplicitTargetB[j] == TARGET_ALL_PARTY_AROUND_CASTER ||+            TempSpell->EffectImplicitTargetB[j] == TARGET_AREAEFFECT_PARTY)+            TargetType |= SPELL_T_AOEFRIEND;++        //***EFFECTS***++        //damage effect+        if ( TempSpell->Effect[j] == SPELL_EFFECT_SCHOOL_DAMAGE ||+            TempSpell->Effect[j] == SPELL_EFFECT_INSTAKILL ||+            TempSpell->Effect[j] == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE ||+            TempSpell->Effect[j] == SPELL_EFFECT_HEALTH_LEECH)+            EffectType |= SPELL_E_DAMAGE;+        else++        //healing effect+        if ( TempSpell->Effect[j] == SPELL_EFFECT_HEAL ||+            TempSpell->Effect[j] == SPELL_EFFECT_HEAL_MAX_HEALTH ||+            TempSpell->Effect[j] == SPELL_EFFECT_HEAL_MECHANICAL )+            EffectType |= SPELL_E_HEAL;+        else++        //Aura based effects+        if ( TempSpell->Effect[j] == SPELL_EFFECT_APPLY_AURA ||+            TempSpell->Effect[j] == SPELL_EFFECT_PERSISTENT_AREA_AURA ||+            TempSpell->Effect[j] == SPELL_EFFECT_APPLY_AREA_AURA)+            {++            //damage over time+            if ( TempSpell->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE ||+                TempSpell->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_LEECH)+                EffectType |= SPELL_E_DOT;+            else++            //heal over time+            if ( TempSpell->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_HEAL )+                EffectType |= SPELL_E_HOT;+            else++            //CC+            if ( TempSpell->EffectApplyAuraName[j] == SPELL_AURA_MOD_CONFUSE ||+                TempSpell->EffectApplyAuraName[j] == SPELL_AURA_MOD_FEAR ||+                TempSpell->EffectApplyAuraName[j] == SPELL_AURA_MOD_STUN ||+                TempSpell->EffectApplyAuraName[j] == SPELL_AURA_MOD_ROOT ||+                TempSpell->EffectApplyAuraName[j] == SPELL_AURA_MOD_SILENCE ||+                TempSpell->EffectApplyAuraName[j] == SPELL_AURA_MOD_PACIFY_SILENCE ||+                TempSpell->EffectApplyAuraName[j] == SPELL_AURA_PERIODIC_DAMAGE)+                EffectType |= SPELL_E_CC;+            else++            //Buff+            if ( IsPositiveEffect(pSpellArray[i], j))+                EffectType |= SPELL_E_BUFF;+            else++            //Debuff+            if ( !IsPositiveEffect(pSpellArray[i], j))+                EffectType |= SPELL_E_DEBUFF;++            //Mind Control+            //SPELL_AURA_MOD_POSSESS+            //SPELL_AURA_MOD_CHARM+            //SPELL_AURA_PERSUADED+            //SPELL_AURA_AOE_CHARM++            }+        }++        //*** Final Catagorization ***++        //Create a new holder for these spells+        SpellHolder* pSpellHolder = new SpellHolder;++        ASSERT(pSpellHolder);++        pSpellHolder->Classication = TYPE_NONE;++        //Reverse priority+        //This classifies each spell by its most powerful effect+        if (EffectType & SPELL_E_BUFF)+            pSpellHolder->Classication = TYPE_BUFF;++        if (EffectType & SPELL_E_DAMAGE)+            if (TargetType & SPELL_T_ENEMY)+                pSpellHolder->Classication = TYPE_DIRECT_DAMAGE;+            else pSpellHolder->Classication = TYPE_AREA_DAMAGE;++        if (EffectType & SPELL_E_CC)+            pSpellHolder->Classication = TYPE_CROWD_CONTROL;++        if (EffectType & SPELL_E_SNARE)+            pSpellHolder->Classication = TYPE_SNARE;++        if (EffectType & SPELL_E_DEBUFF)+            pSpellHolder->Classication = TYPE_DEBUFF;++        if (EffectType & SPELL_E_DOT)+            pSpellHolder->Classication = TYPE_DAMAGE_OVER_TIME;++        if (EffectType & SPELL_E_HOT)+            pSpellHolder->Classication = TYPE_HEAL_OVER_TIME;++        if (EffectType & SPELL_E_HEAL)+            if (TargetType & SPELL_T_SELF)+                pSpellHolder->Classication = TYPE_SELF_HEAL;+            else if (TargetType & SPELL_T_FRIEND)+                pSpellHolder->Classication = TYPE_HEAL;+            else if (TargetType & SPELL_T_AOEFRIEND)+                pSpellHolder->Classication = TYPE_AREA_HEAL;++        TempRange = sSpellRangeStore.LookupEntry(TempSpell->rangeIndex);+        TempRadius = sSpellRadiusStore.LookupEntry(TempSpell->EffectRadiusIndex[0]);+        TempDuration = sSpellDurationStore.LookupEntry(TempSpell->DurationIndex);+        TempCastTime = sCastTimesStore.LookupEntry(TempSpell->CastingTimeIndex);++        // Constants+        pSpellHolder->CastTime = TempCastTime ? TempCastTime->CastTime : 0;+        pSpellHolder->Cooldown = TempSpell->RecoveryTime;+        pSpellHolder->Duration = TempDuration ? TempDuration->Duration[0] : 0;+        pSpellHolder->Radius = TempRadius ? TempRadius->Radius : 0;+        pSpellHolder->PowerCost = TempSpell->manaCost;+        pSpellHolder->PowerType = TempSpell->powerType;+        pSpellHolder->RangeMax = TempRange ? TempRange->maxRange : 0;+        pSpellHolder->RangeMin = TempRange ? TempRange->minRange : 0;+        pSpellHolder->SpellId = pSpellArray[i]; +        pSpellHolder->Targets = TargetType; ++        // Reset Variables+        pSpellHolder->CooldownRemaining = 0;++        m_SpellList.push_back(pSpellHolder);+    }+}++bool AISpellSystem::Cast(SpellHolder* pSpell)+{+    //Silenced so we can't cast+    if (m_Unit->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED))+        return false;++    //Check for power+    if (m_Unit->GetPower((Powers)(pSpell->PowerType)) < pSpell->PowerCost)+        return false;++    //Still on cooldown+    if (pSpell->CooldownRemaining)+        return false;++    //Holder for Target. If target remains null spell will not be casted. +    Unit* pTarget = NULL;++    //Individual checks based on classification+    switch (pSpell->Classication)+    {+        //Replace with checks for friendly units hp when possible+        case TYPE_SELF_HEAL:+        case TYPE_HEAL:+        case TYPE_AREA_HEAL:+        case TYPE_HEAL_OVER_TIME:++            ASSERT(m_Unit->GetMaxHealth());++            if (m_Unit->GetHealth()*3/m_Unit->GetMaxHealth() < 2 &&+                !m_Unit->HasAura(pSpell->SpellId, 0) && !m_Unit->HasAura(pSpell->SpellId, 1) && !m_Unit->HasAura(pSpell->SpellId, 2))+                pTarget = m_Unit;+        break;++        case TYPE_DEBUFF:+        case TYPE_DAMAGE_OVER_TIME:+        {+            Unit* pTemp;++            if (m_Unit->getThreatManager().getThreatList().empty())+                break;++            std::list<HostilReference*>::iterator i = m_Unit->getThreatManager().getThreatList().begin();+            for (; i!=m_Unit->getThreatManager().getThreatList().end(); ++i)+            {+                pTemp = Unit::GetUnit((*m_Unit),(*i)->getUnitGuid());++                if (pTemp && pTemp->isAlive() &&+                    !pTemp->HasAura(pSpell->SpellId, 0) && !pTemp->HasAura(pSpell->SpellId, 1) && !pTemp->HasAura(pSpell->SpellId, 2) &&+                    (m_Unit->GetDistanceSq(pTemp) < pSpell->RangeMax*pSpell->RangeMax && m_Unit->GetDistanceSq(pTemp) > pSpell->RangeMin*pSpell->RangeMin))+                {+                    pTarget = pTemp;++                    //Set cooldown = to duration of spell to prevent spamming of dots and debuffs+                    //pSpell->CooldownRemaining = pSpell->Duration;+                    break;+                }+            }+        }+        break;++        case TYPE_CROWD_CONTROL:+        case TYPE_SNARE:+        {+            if (m_Unit->getThreatManager().getThreatList().size() < 2)+                break;++            Unit* pTemp;++            std::list<HostilReference*>::iterator i = m_Unit->getThreatManager().getThreatList().begin();+            for (; i!=m_Unit->getThreatManager().getThreatList().end(); ++i)+            {+                pTemp = Unit::GetUnit((*m_Unit),(*i)->getUnitGuid());++                if (pTemp && pTemp->isAlive() && m_Unit->getVictim() != pTemp &&+                    !pTemp->HasAura(pSpell->SpellId, 0) && !pTemp->HasAura(pSpell->SpellId, 1) && !pTemp->HasAura(pSpell->SpellId, 2) &&+                    (m_Unit->GetDistanceSq(pTemp) < pSpell->RangeMax*pSpell->RangeMax && m_Unit->GetDistanceSq(pTemp) > pSpell->RangeMin*pSpell->RangeMin))+                {+                    pTarget = pTemp;+                    break;+                }+            }+        }+        break;++        case TYPE_AREA_DAMAGE:+        {+            //Check that at least 2 players are within range+            Unit* pTemp;+            uint32 PlayersInRange = 0;++            if (m_Unit->getThreatManager().getThreatList().size() < 2)+                break;++            std::list<HostilReference*>::iterator i = m_Unit->getThreatManager().getThreatList().begin();+            for (; i!=m_Unit->getThreatManager().getThreatList().end(); ++i)+            {+                pTemp = Unit::GetUnit((*m_Unit),(*i)->getUnitGuid());+                if (pTemp && pTemp->isAlive() &&+                    (m_Unit->GetDistanceSq(pTemp) < pSpell->Radius))+                {+                    PlayersInRange++;+                }+            }++            //More than 1 player in range+            if (PlayersInRange > 1)+                pTarget = m_Unit;+        }+        break;++        case TYPE_DIRECT_DAMAGE:+        {+            //This causes the creature to cast on the first player that this target is allowed to hit (range issues etc)+            //Threat list is always in order from Highest threat to lowest+            Unit* pTemp;++            if (m_Unit->getThreatManager().getThreatList().empty())+                break;++            std::list<HostilReference*>::iterator i = m_Unit->getThreatManager().getThreatList().begin();+            for (; i!=m_Unit->getThreatManager().getThreatList().end(); ++i)+            {+                pTemp = Unit::GetUnit((*m_Unit),(*i)->getUnitGuid());+                if (pTemp && pTemp->isAlive() &&+                    (m_Unit->GetDistanceSq(pTemp) < pSpell->RangeMax*pSpell->RangeMax && m_Unit->GetDistanceSq(pTemp) > pSpell->RangeMin*pSpell->RangeMin))+                {+                    pTarget = pTemp;+                    break;+                }+            }+        }+        break;++        case TYPE_BUFF:+            //Later replace with checks for other creatures in area+            if (!m_Unit->HasAura(pSpell->SpellId, 0) && !m_Unit->HasAura(pSpell->SpellId, 1) && !m_Unit->HasAura(pSpell->SpellId, 2) && +                (!m_Unit->isInCombat() || m_Unit->GetPower((Powers)pSpell->PowerType) > m_Unit->GetMaxPower((Powers)pSpell->PowerType)-pSpell->PowerCost))+                pTarget = m_Unit;+        break;++        case TYPE_NONE:+            //Simply attempt to cast on current target since we have no idea what this spell does+            pTarget = m_Unit->getVictim();+            break;+    };++    if (!pTarget)+        return false;++    //Cast spell+    m_Unit->CastSpell(pTarget, pSpell->SpellId, false);+    pSpell->CooldownRemaining += pSpell->Cooldown + AI_GCD;++    return true;+}++bool AISpellSystem::Update(const uint32 diff)+{+    if (!m_Unit || m_SpellList.empty())+        return false;++    //Decrease cooldowns+    for (std::list<SpellHolder*>::iterator i = m_SpellList.begin(); i != m_SpellList.end(); ++i)+    {+        if ((*i)->CooldownRemaining)+            if ((*i)->CooldownRemaining > diff)+                (*i)->CooldownRemaining -= diff;+            else (*i)->CooldownRemaining = 0;+    }++    //Prevent Movement while casting+    if (m_Unit->IsNonMeleeSpellCasted(false))+    {+        m_Unit->StopMoving();++        return true;+    }++    //Cast first valid spell+    for (std::list<SpellHolder*>::iterator i = m_SpellList.begin(); i != m_SpellList.end(); ++i)+    {+        //Cast returns true if the spell was properly cast+        if (Cast((*i)))+            break;+    }++    return true;+}Index: src/game/AISpellSystem.h===================================================================--- src/game/AISpellSystem.h	(revision 0)+++ src/game/AISpellSystem.h	(revision 0)@@ -0,0 +1,39 @@+/* + * Copyright (C) 2005,2006,2007 MaNGOS <http://www.mangosproject.org/>+ *+ * This program is free software; you can redistribute it and/or modify+ * it under the terms of the GNU General Public License as published by+ * the Free Software Foundation; either version 2 of the License, or+ * (at your option) any later version.+ *+ * This program is distributed in the hope that it will be useful,+ * but WITHOUT ANY WARRANTY; without even the implied warranty of+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ * GNU General Public License for more details.+ *+ * You should have received a copy of the GNU General Public License+ * along with this program; if not, write to the Free Software+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA+ */++#include "Unit.h"++class Creature;+struct SpellHolder;++class AISpellSystem+{+public:+    AISpellSystem(Creature*);+    AISpellSystem(Unit*, const uint32* pSpellArray, const uint32 Size);+    ~AISpellSystem();++    bool Update(const uint32);++private:+    Unit* m_Unit;+    std::list<SpellHolder*> m_SpellList;++    void ClassifySpells(const uint32* pSpellArray, const uint32 Size);+    bool Cast(SpellHolder*);+};Index: src/game/BattleGroundMgr.cpp===================================================================--- src/game/BattleGroundMgr.cpp	(revision 4773)+++ src/game/BattleGroundMgr.cpp	(working copy)@@ -79,10 +79,34 @@     else         m_QueuedPlayers[queue_id].Horde++; -    /* temporary BG queue status message -    std::ostringstream str;-    str << "Battleground queue invited status: horde: " << m_QueuedPlayers[queue_id].Horde << ", aliance: " << m_QueuedPlayers[queue_id].Alliance;-    plr->Say(str.str(), LANG_UNIVERSAL);*/+    /* temporary BG queue status message */+	//#TODO: add proper check for the number of players in queue+	if ( m_QueuedPlayers[queue_id].Alliance == 5 || m_QueuedPlayers[queue_id].Alliance == 7 || m_QueuedPlayers[queue_id].Alliance == 10 ||+		m_QueuedPlayers[queue_id].Horde == 5 || m_QueuedPlayers[queue_id].Horde == 7 || m_QueuedPlayers[queue_id].Horde == 10 )+	{+	    std::ostringstream str;+		str << "Battleground queue invited status for ";+		switch (bgTypeId)+		{+		case 1:+			str << "Alterac Valley"; break;+		case 2:+			str << "Warsong Gulch"; break;+		case 3:+			str << "Arathi Basin"; break;+	//#TODO: add other cases+		default:+			str << "other bg / arena"; break;+		}+		str << ", for level ";+		if(plr->getLevel()!=sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))+		    str << (int)(plr->getLevel()/10)*10 << " - " << (int)(plr->getLevel()/10)*10+9;+		else+		    str << plr->getLevel(); +		str << ":\n Horde: " << m_QueuedPlayers[queue_id].Horde << ", Alliance: " << m_QueuedPlayers[queue_id].Alliance;+		sWorld.SendWorldText(str.str().c_str(), NULL);+	}+    /* plr->Say(str.str(), LANG_UNIVERSAL);*/      this->Update(bgTypeId, queue_id); }Index: src/game/Chat.cpp===================================================================--- src/game/Chat.cpp	(revision 4773)+++ src/game/Chat.cpp	(working copy)@@ -265,15 +265,18 @@         { "die",         SEC_ADMINISTRATOR, &ChatHandler::HandleDieCommand,              "",   NULL },         { "revive",      SEC_ADMINISTRATOR, &ChatHandler::HandleReviveCommand,           "",   NULL },         { "dismount",    SEC_PLAYER,        &ChatHandler::HandleDismountCommand,         "",   NULL },+		{ "activequests", SEC_PLAYER,  &ChatHandler::HandleActiveQuestsCommand,         "", NULL },         { "setmodel",    SEC_GAMEMASTER,    &ChatHandler::HandleSetModelCommand,         "",   NULL },         { "factionid",   SEC_GAMEMASTER,    &ChatHandler::HandleFactionIdCommand,        "",   NULL },         { "listgm",      SEC_PLAYER,        &ChatHandler::HandleGMListCommand,           "",   NULL },+         { "bug",         SEC_PLAYER,        &ChatHandler::HandleBugCommand,              "",   NULL },         { "gm",          SEC_MODERATOR,     &ChatHandler::HandleGMmodeCommand,           "",   NULL },         { "gps",         SEC_MODERATOR,     &ChatHandler::HandleGPSCommand,              "",   NULL },         { "guid",        SEC_GAMEMASTER,    &ChatHandler::HandleGUIDCommand,             "",   NULL },         { "help",        SEC_PLAYER,        &ChatHandler::HandleHelpCommand,             "",   NULL },         { "info",        SEC_PLAYER,        &ChatHandler::HandleInfoCommand,             "",   NULL },         { "npcinfo",     SEC_ADMINISTRATOR, &ChatHandler::HandleNpcInfoCommand,          "",   NULL },+		{ "creatureinfo", SEC_PLAYER,       &ChatHandler::HandleCreatureInfoCommand,     "",   NULL },         { "npcinfoset",  SEC_ADMINISTRATOR, &ChatHandler::HandleNpcInfoSetCommand,       "",   NULL },         { "addvendoritem",SEC_GAMEMASTER,   &ChatHandler::HandleAddVendorItemCommand,    "",   NULL },         { "delvendoritem",SEC_GAMEMASTER,   &ChatHandler::HandleDelVendorItemCommand,    "",   NULL },@@ -840,4 +843,4 @@     }      return obj;-}\ No newline at end of file+}Index: src/game/Chat.h===================================================================--- src/game/Chat.h	(revision 4773)+++ src/game/Chat.h	(working copy)@@ -91,6 +91,7 @@         bool HandleDismountCommand(const char* args);         bool HandleSaveCommand(const char* args);         bool HandleGMListCommand(const char* args);+         bool HandleBugCommand(const char* args);          bool HandleNamegoCommand(const char* args);         bool HandleGonameCommand(const char* args);@@ -254,6 +255,7 @@         bool HandleExploreCheatCommand(const char* args);         bool HandleTextEmoteCommand(const char* args);         bool HandleNpcInfoCommand(const char* args);+		bool HandleCreatureInfoCommand(const char* args);         bool HandleNpcInfoSetCommand(const char* args);         bool HandleHoverCommand(const char* args);         bool HandleLevelUpCommand(const char* args);@@ -292,6 +294,7 @@         bool HandleLookupSkillCommand(const char* args);         bool HandleLookupSpellCommand(const char* args);         bool HandleLookupQuestCommand(const char* args);+		bool HandleActiveQuestsCommand(const char* args);         bool HandleLookupCreatureCommand(const char* args);         bool HandleLookupObjectCommand(const char* args);         bool HandlePasswordCommand(const char* args);Index: src/game/Group.cpp===================================================================--- src/game/Group.cpp	(revision 4773)+++ src/game/Group.cpp	(working copy)@@ -575,6 +575,7 @@             {                 uint16 dest;                 LootItem *item = &(roll->loot->items[roll->itemSlot]);+				if(!item){roll->loot->NotifyItemRemoved(roll->itemSlot); roll->loot->unlootedCount--; RollId.erase(roll); return;}                 uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, roll->itemid, item->count, false );                 if ( msg == EQUIP_ERR_OK )                 {Index: src/game/Language.h===================================================================--- src/game/Language.h	(revision 4773)+++ src/game/Language.h	(working copy)@@ -375,6 +375,7 @@ #define LANG_COMMAND_GRAVEYARDERROR      "No faction in Graveyard with id= #%u , fix your DB" #define LANG_COMMAND_GRAVEYARD_NOTEAM    "invalid team, please fix database" #define LANG_COMMAND_GRAVEYARD_ANY       "any"+#define LANG_COMMAND_BUGREPORTED         "Aciu %s, Atsimink kad sita komanda galima naudoti tik norint pranesti zaidimo klaidas." #define LANG_COMMAND_GRAVEYARD_ALLIANCE  "alliance" #define LANG_COMMAND_GRAVEYARD_HORDE     "horde" #define LANG_COMMAND_GRAVEYARDNEAREST    "Graveyard #%u (faction: %s) is nearest from linked to zone #%u."@@ -478,6 +479,7 @@ #define LANG_MOVEGENS_UNKNOWN            "Unknown movement generator (%u)"  #define LANG_NPCINFO_CHAR                "Player selected NPC\nGUID: %u.\nFaction: %u.\nnpcFlags: %u.\nEntry: %u.\nDisplayID: %u (Native: %u)."+#define LANG_CREATUREINFO_CHAR           "Player selected Creature\nGUID: %u.\nEntry: %u." #define LANG_NPCINFO_LEVEL               "Level: %u." #define LANG_NPCINFO_HEALTH              "Health (base): %u. (max): %u. (current): %u." #define LANG_NPCINFO_FLAGS               "Field Flags: %u.\nDynamic Flags: %u.\nFaction Template: %u."Index: src/game/Level0.cpp===================================================================--- src/game/Level0.cpp	(revision 4773)+++ src/game/Level0.cpp	(working copy)@@ -297,3 +297,52 @@         SendSysMessage(LANG_BAD_VALUE);     return true; }++bool ChatHandler::HandleCreatureInfoCommand(const char* args)+{+    Creature* target = getSelectedCreature();++    if(!target)+    {+        SendSysMessage(LANG_SELECT_CREATURE);+        return true;+    }++    uint32 Entry = target->GetUInt32Value(OBJECT_FIELD_ENTRY);+    CreatureInfo const* cInfo = target->GetCreatureInfo();++    PSendSysMessage(LANG_CREATUREINFO_CHAR,  target->GetDBTableGUIDLow(), Entry);++    return true;+}++bool ChatHandler::HandleBugCommand(const char* args)+{+    if (!*args)+		return false;+    +	std::string bug=args;+	WorldDatabase.escape_string(bug);+	PSendSysMessage(LANG_COMMAND_BUGREPORTED, m_session->GetPlayerName());+	WorldDatabase.PExecute("INSERT INTO `bugs` (`name`, `bug`) VALUES ('%s', '%s')", m_session->GetPlayerName(), bug.c_str());+	return true;+}++bool ChatHandler::HandleActiveQuestsCommand(const char* args)+{+    QuestStatusMap* qmap = &(m_session->GetPlayer()->getQuestStatusMap());+    for(QuestStatusMap::iterator itr=qmap->begin(); itr!=qmap->end(); ++itr)+    {+        if(itr->second.m_status == QUEST_STATUS_INCOMPLETE)+        {+            std::ostringstream str;+            str << "Quest id #" << itr->first;+            QueryResult *result=WorldDatabase.PQuery("SELECT `Title` FROM `quest_template` WHERE `entry`='%u'", itr->first);+            if(result)+                { str << " - " << result->Fetch()[0].GetCppString(); delete result; }+            str << " is active.";+            PSendSysMessage(str.str().c_str());+        }+    }+    return true;+}\ No newline at end of fileIndex: src/game/Spell.cpp===================================================================--- src/game/Spell.cpp	(revision 4773)+++ src/game/Spell.cpp	(working copy)@@ -2554,6 +2554,8 @@         else if(m_spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MECHANIC_IMMUNITY)             mechanic_immune |= 1 << m_spellInfo->EffectMiscValue[i];     }+    //immune movement impairement and loss of control+    if(m_spellInfo->Id==(uint32)42292)mechanic_immune=0x9967da6;      //Check whether the cast should be prevented by any state you might have.     uint8 prevented_reason = 0;@@ -3417,7 +3419,7 @@             case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:             {                 if(m_caster->GetTypeId() != TYPEID_PLAYER) return SPELL_FAILED_TARGET_NOT_PLAYER;-                if(m_spellInfo->rangeIndex == 1 || m_spellInfo->rangeIndex == 2 || m_spellInfo->rangeIndex == 7)+                if(m_spellInfo->rangeIndex == 1 || m_spellInfo->rangeIndex == 2 || m_spellInfo->rangeIndex == 6 || m_spellInfo->rangeIndex == 7)                     break;                 Item *pItem = ((Player*)m_caster)->GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED );                 if(!pItem || pItem->IsBroken() || pItem->GetProto()->Class != ITEM_CLASS_WEAPON )Index: src/game/SpellAuras.cpp===================================================================--- src/game/SpellAuras.cpp	(revision 4773)+++ src/game/SpellAuras.cpp	(working copy)@@ -2645,8 +2645,9 @@  void Aura::HandleModMechanicImmunity(bool apply, bool Real) {-    uint32 mechanic = m_modifier.m_miscvalue;-+    uint32 mechanic = 1 << m_modifier.m_miscvalue;+    //immune movement impairement and loss of control+    if(GetId()==(uint32)42292)mechanic=0x9967da6;     if(apply)     {         Unit::AuraMap& Auras = m_target->GetAuras();@@ -2655,7 +2656,10 @@             next = iter;             next++;             SpellEntry const *spell = iter->second->GetSpellProto();-            if(spell->Mechanic == mechanic && !iter->second->IsPositive() && spell->Id != GetId())+            if( (1<<spell->Mechanic) & mechanic             //check for mechanic mask+                    && !( spell->Attributes & 0x20000000)    //spells unaffected by invulnerability+                    && !iter->second->IsPositive()          //only remove negative spells+                    && spell->Id != GetId())             {                 m_target->RemoveAurasDueToSpell(spell->Id);                 if(Auras.empty())Index: src/game/SpellEffects.cpp===================================================================--- src/game/SpellEffects.cpp	(revision 4773)+++ src/game/SpellEffects.cpp	(working copy)@@ -2887,7 +2887,7 @@     bool criticalhit = false;      WeaponAttackType attType = BASE_ATTACK;-    if(m_spellInfo->rangeIndex != 1 && m_spellInfo->rangeIndex != 2 && m_spellInfo->rangeIndex != 7)+    if(m_spellInfo->rangeIndex != 1 && m_spellInfo->rangeIndex != 2 && m_spellInfo->rangeIndex != 6 && m_spellInfo->rangeIndex != 7)     {         attType = RANGED_ATTACK; @@ -2952,7 +2952,7 @@     // take ammo     if(m_caster->GetTypeId() == TYPEID_PLAYER)     {-        if(m_spellInfo->rangeIndex != 1 && m_spellInfo->rangeIndex != 2 && m_spellInfo->rangeIndex != 7)+        if(m_spellInfo->rangeIndex != 1 && m_spellInfo->rangeIndex != 2 && m_spellInfo->rangeIndex != 6 && m_spellInfo->rangeIndex != 7)         {             Item *pItem = ((Player*)m_caster)->GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_RANGED );             if(!pItem  || pItem->IsBroken())Index: src/game/Unit.cpp===================================================================--- src/game/Unit.cpp	(revision 4773)+++ src/game/Unit.cpp	(working copy)@@ -3998,7 +3998,40 @@             CastSpell(pVictim,37378,true,castItem,triggredByAura);             return;         }+		// Windfury weapon+		case 33757:+		case 33756:+		case 33755:+		case 33754:+		case 33727:+		{+			// never proc from another windfury attack or the AP bonus will stack and we will get really huge criticals+			if ( !procSpell || ( procSpell->Id != 25504 && procSpell->Id != 33750 ) ){+				// give us temporary AP bonus +				if(GetTypeId() == TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(25504) )+					return;+				+				HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(dummySpell->EffectBasePoints[0]+1), true);++				int32 EffectBasePoints0 = CalculateDamage(BASE_ATTACK);+	           +				CastCustomSpell(pVictim,25504,&EffectBasePoints0,NULL,NULL,true,NULL,triggredByAura);            +				// cooldown+				((Player*)this)->AddSpellCooldown(25504,0,time(NULL) + 3);			++				if (haveOffhandWeapon())+				{+					int32 EffectBasePoints0 = CalculateDamage(OFF_ATTACK);+					CastCustomSpell(pVictim,33750,&EffectBasePoints0,NULL,NULL,true,NULL,triggredByAura);   +					// cooldown+					((Player*)this)->AddSpellCooldown(33750,0,time(NULL) + 3);+				}++				// remove it+				HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(dummySpell->EffectBasePoints[0]+1), false);+			}+		}         default: break;     } Index: src/mangosd/Makefile.am===================================================================--- src/mangosd/Makefile.am	(revision 4771)+++ src/mangosd/Makefile.am	(working copy)@@ -33,8 +33,8 @@ 	WorldRunnable.h  ## Link world daemon against the shared library-mangos_worldd_LDADD = ../bindings/universal/libmangosscript.la ../game/libmangosgame.a ../shared/libmangosdatabase.a ../shared/libmangosconfig.a ../shared/libmangosauth.a ../shared/libmangosshared.a ../shared/libmangosvmaps.a ../shared/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a-mangos_worldd_LDFLAGS = -L../../dep/src/zthread  -L../../dep/src/g3dlite -L../bindings/universal/ $(MYSQL_LIBS) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic+mangos_worldd_LDADD = ../bindings/ScriptDev2/libmangosscript.la ../game/libmangosgame.a ../shared/libmangosdatabase.a ../shared/libmangosconfig.a ../shared/libmangosauth.a ../shared/libmangosshared.a ../shared/libmangosvmaps.a ../shared/libmangosnetwork.a ../framework/libmangosframework.a ../../dep/src/zthread/libZThread.la ../../dep/src/g3dlite/libg3dlite.a+mangos_worldd_LDFLAGS = -L../../dep/src/zthread  -L../../dep/src/g3dlite -L../bindings/ScriptDev2/ $(MYSQL_LIBS) $(POSTGRE_LIBS) -L$(libdir) $(ZLIB) $(COMPATLIB) $(SSLLIB) -export-dynamic  ## Additional files to include when running 'make dist' #  Include world daemon configurationIndex: src/shared/Network/Socket.cpp===================================================================--- src/shared/Network/Socket.cpp	(revision 4771)+++ src/shared/Network/Socket.cpp	(working copy)@@ -345,6 +345,15 @@ 			SetCloseAndDelete(); 			return INVALID_SOCKET; 		}++        optval = 1;+        if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof(optval)) == -1)+        {+            Handler().LogError(this, "setsockopt(IPPROTO_TCP, TCP_NODELAY)", Errno, StrError(Errno), LOG_LEVEL_FATAL);+            closesocket(s);+            SetCloseAndDelete();+            return INVALID_SOCKET;+        } 	} 	return s; }@@ -1254,3 +1263,6 @@   +++