rendered paste bodyIndex: 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 @@ +++